Close tabs after in-page redirect in Safari#19
Open
Sissing wants to merge 1 commit into
Open
Conversation
Safari does not reliably fire tabs.onUpdated for in-page History API navigations and does not support webNavigation.onHistoryStateUpdated, so services that reach their closable URL via a client-side route change (e.g. Linear landing on ...?noRedirect=1) are never seen by the background script and the leftover tab is never closed. Add a content script on the predefined service hosts that reports location.href changes to the background script, which then runs its existing scheduleClose() matching logic. No pattern changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
In Safari, tabs that reach their final closable URL through an in-page navigation never get closed.
The clearest example is Linear. When you click a Linear link, it does its desktop-app handoff and the tab ends up on
...?noRedirect=1. That final URL is reached via a client-side route change, not a full page load. The predefined Linear pattern already matches...?noRedirect=1correctly, so the regex isn't the problem. The problem is that the background script never sees that URL in Safari.Two reasons for that:
tabs.onUpdatedfor in-page History API navigations (pushState/replaceState).webNavigation.onHistoryStateUpdated, so the usual SPA workaround isn't available either.So in Safari the only
onUpdatedevent is the initial load, and by the time the URL settles on...?noRedirect=1nothing fires. The tab stays open.The change
A small content script (
content-spa-nav.js) runs on the hosts TabCloser already targets. It watcheslocation.href(poll +popstate/hashchange) and reports URL changes to the background script. The background script feeds those into the existingscheduleClose(), so all the matching, interval, and cancel-on-navigate logic is unchanged.Notes:
history.pushStatefrom the content script isn't reliable (it only patches the content script's own copy). Pollinglocation.hrefworks regardless.predefinedUrlPatternshosts, so the script does nothing on unrelated pages.Testing
Tested in Safari (unsigned/temporary extension):
?noRedirect=1. This is the case I reproduced and verified end to end.I haven't verified every service individually. The ones I didn't test use the same code path, so I'd expect them to behave the same, but it'd be good to confirm. Some of them may already have worked if their redirect is a full load rather than an in-page one. In that case this just doesn't change anything for them, since
scheduleClose()already de-dupes per tab.Possible follow-up
The content script polls every 500ms for the tab's lifetime. It only sends a message when the URL actually changes, so it's not chatty, but stopping the interval after a match or after some idle time would be a reasonable tightening if you'd prefer. Happy to add that if you want it in this PR.