You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+15-12
Original file line number
Diff line number
Diff line change
@@ -480,25 +480,28 @@ Similarly, cross-document navigations initiated from other windows are not somet
480
480
481
481
As for`document.open()`, it is a terrible legacy APIwith lots of strange side effects, which makes supporting it not worth the implementation cost. Modern sites which use the newnavigationAPI should never be using `document.open()`.
482
482
483
-
Second, the following navigations **cannot be canceled** using `event.preventDefault()`, and as such will have `event.cancelable` equal to false:
484
-
483
+
Second, **traversals have special restrictions on canceling the navigation** via `event.preventDefault()`. Traversals are:
485
484
- User-initiated traversals via the browser's back/forward buttons (either same- or cross-document)
486
485
- Programmatic traversals via `history.back()`/`history.forward()`/`history.go()`
487
-
- Programmatic traversals via `navigation.back()`/`navigation.forward()`/`navigation.go()`
486
+
- Programmatic traversals via `navigation.back()`/`navigation.forward()`/`navigation.traverseTo()`
487
+
488
+
Traversals may only be canceled (and `event.cancelable` will be equal to true) if:
489
+
- The navigate event is firing in the top window
490
+
- The traversal is same-origin
491
+
- The traversal was not user-initiated, or there is a consumable activation in the current window.
488
492
489
-
We would like to make these cancelable in the future. However, we need to take care when doing so:
493
+
Allowing cancelation only in the top window is to ensure that there is a single authoritative source for deciding whether or not to cancel the traversal. If all windows were allowed to cancel and a traversal navigated multiple windows, and some canceled but others proceeded, there would not be a good way to keep all windows in sync with the joint session history. Cross-origin traversals are uncancelable in order to lessen the risk of trapping the user. Similarly, user activation is required for user-initiated traversals in order to minimize the possibility of trapping: `event.preventDefault()` on a traversal consumes the user activation, ensuring that the user can always break out of an application that is canceling traversals by, e.g., pressing the browser's back button twice in a row.
490
494
491
-
- Canceling user-initiated traversals can be abused to trap the user by disabling their back button. Note that adding a same-origin restriction would not help here: imagine a user which navigates to `https://evil-in-disguise.example/`, and then clicks a link to `https://evil-in-disguise.example/2`. If `https://evil-in-disguise.example/2` were allowed to cancel same-origin browser back button navigations, they have effectively disabled the user's back button.
492
-
- Both user-initiated and programmatic traversals ofthis sort are hard to intercept for technical reasons, as doing so can require cross-process communication.
495
+
By _consumable activation_, we mean a variant of [user activation](https://html.spec.whatwg.org/multipage/interaction.html#tracking-user-activation) that we wish to add to the HTML spec. _Sticky activation_ is obviously not correct for preventing trapping the user, because then a single errant click or tap could disable back/forward navigations entirely. However, we are also concerned about using _transient activation_: it meets our requirement that the user activation can be used once before it is consumed, but the possibility of it expiring due to its _transient activation duration_ elapsing means that web applications may suddenly and unexpectedly get an uncancelable traversal if a back or forward button is pressed and the user happens not to have interacted with the page for a modest period of time. We therefore intend to add a third mode of user activation to the HTML spec, _consumable activation_, which can be consumed like _transient activation_, but does not expire based on the _transient activation duration_.
493
496
494
-
See discussion in [#32](https://github.com/WICG/navigation-api/issues/32) about how we can make user-initiated traversals cancelable in a safe way, and [#178](https://github.com/WICG/navigation-api/issues/178) for the general discussion of loosening the cancelability restrictions over time.
497
+
In order to enable cancelation, traversals need to fire the `navigate` event at a precise time. Most navigations fire `navigate` at the time of navigation start, but that is not a viable time for traversals, because browser architecture may require an async step to determine which frames must navigate as part of the traversal (and therefore which frames need a `navigate` event). Alternately, we could fire at `unload` time, but that is very late: by then, network requests have already been performed. `beforeunload` time splits the difference: after determining which frames will be navigated, but before any network requests or other side effects have happened. The downside of this timing is that it builds on the rickety foundation of `beforeunload` (which is widely considered to be a regrettable web platform feature). However, we are avoiding the most problematic part of `beforeunload`, which is the modal user-facing dialog it creates. Simply reusing the internal browser and spec architecture for firing `navigate` at the same time as `beforeunload` is more benign.
495
498
496
499
Finally, the following navigations **cannot be replaced with same-document navigations** by using `event.intercept()`, and as such will have `event.canIntercept` equal to false:
497
500
498
501
- Any navigation to a URL which differs in scheme, username, password, host, or port. (I.e., you can only intercept URLs which differ in path, query, or fragment.)
499
502
- Any [cross-document](#appendix-types-of-navigations) back/forward navigations. Transitioning two adjacent history entries from cross-document to same-document has unpleasant ripple effects on web application and browser implementation architecture.
500
503
501
-
We'll note that these restrictions still allow canceling cross-origin non-back/forward navigations. Although this might be surprising, in general it doesn't grant additional power. That is, web developers can already intercept `<a>``click` events, or modify their code that would set `location.href`, even if the destination URL is cross-origin.
504
+
We'll note that these restrictions allow canceling cross-origin non-back/forward navigations. Although this might be surprising, in general it doesn't grant additional power. That is, web developers can already intercept `<a>``click` events, or modify their code that would set `location.href`, even if the destination URL is cross-origin.
- \* = No if the URL differs from the page's current one in components besides path/query/fragment, or is cross-origin from the current page and differs in any component besides fragment.
1494
1497
- Δ = No if cross-document and initiated from a [cross origin-domain](https://html.spec.whatwg.org/multipage/origin.html#same-origin-domain) window, e.g. `frames['cross-origin-frame'].location.href = ...` or `<a target="cross-origin-frame">`
1495
1498
- ◊ = fragment navigations initiated by `<meta http-equiv="refresh">` or the `Refresh` header are only same-document in some browsers: [whatwg/html#6451](https://github.com/whatwg/html/issues/6451)
1496
-
- ❖ = We would like to make these cancelable in the future, after additional implementation and spec work: see [#178](https://github.com/WICG/navigation-api/issues/178) and [#32](https://github.com/WICG/navigation-api/issues/32).
1499
+
- ❖ = Only in the top window, if the traversal is same-origin, and either the traversal is not user-initiated, or there is a consumable user activation in the current window.
1497
1500
1498
1501
See the discussion on [restrictions](#restrictions-on-firing-canceling-and-responding) to understand the reasons why the last few columns are filled out in the way they are.
0 commit comments