From e9eb9ea063d11f698a9fb111798162de0200c27a Mon Sep 17 00:00:00 2001
From: "Michael[tm] Smith" The current The current Returns an array of Returns an array of Returns true if the current Returns true if the current Returns true if the current Returns true if the current Each Each Each Let she be sessionHistory[backwardIndex]. If she’s origin is same origin with currentSHE’s origin, then prepend she to appHistorySHEs. If she’s origin is same origin with currentSHE’s origin, then prepend she to appHistorySHEs. Otherwise, break. Let she be sessionHistory[forwardIndex]. If she’s origin is same origin with currentSHE’s origin, then append she to appHistorySHEs. If she’s origin is same origin with currentSHE’s origin, then append she to appHistorySHEs. Otherwise, break. For each she of appHistorySHEs: If appHistory’s entry list contains an If appHistory’s entry list contains an Otherwise: Let newAHE be a new Let newAHE be a new Set newAHE’s session history entry to she. Set appHistory’s current index to newCurrentIndex. For same-document navigations only the current index and the indices of the various For same-document navigations only the current index and the indices of the various One of " One of " True if Generally speaking, this will be true whenever the destination URL is rewritable relative to the page’s current URL, except for cross-document back/forward navigations, where it will always be false. True if Generally speaking, this will be true whenever the destination URL is rewritable relative to the page’s current URL, except for cross-document back/forward navigations, where it will always be false. True if this navigation was due to a user clicking on an True if this navigation was due to a user clicking on an True if this navigation is a fragment navigation; false otherwise. True if this navigation is a fragment navigation; false otherwise. The The An arbitrary JavaScript value passed via other app history APIs that initiated this navigation, or null if the navigation was initiated by the user or via a non-app history API. Synchronously converts this navigation into a same-document navigation to the destination URL. The given newNavigationAction promise is used to signal the duration, and success or failure, of the navigation. After it settles, the browser signals to the user (e.g. via a loading spinner UI, or assistive technology) that the navigation is finished. Additionally, it fires This method will throw a " The given newNavigationAction promise is used to signal the duration, and success or failure, of the navigation. After it settles, the browser signals to the user (e.g. via a loading spinner UI, or assistive technology) that the navigation is finished. Additionally, it fires This method will throw a " The An An destination URL, a URL classic history API serialized data, a serialized state-or-null It has the following associated value that is used when its It has the following associated value that is used when its destination entry, a session history entry1.
};
-
-
+ appHistory
. current
appHistory
. current
AppHistoryEntry
.
+ appHistory
. entries()
AppHistoryEntry
. appHistory
. entries()
AppHistoryEntry
instances representing the current app history list, i.e. all session history entries for this Window
that are same origin and contiguous to the current session history entry.
+ appHistory
. canGoBack
AppHistoryEntry
instances representing the current app history list, i.e. all session history entries for this Window
that are same origin and contiguous to the current session history entry. appHistory
. canGoBack
AppHistoryEntry
is not the first one in the app history entries list.
+ appHistory
. canGoForward
AppHistoryEntry
is not the first one in the app history entries list. appHistory
. canGoForward
AppHistoryEntry
is not the last one in the app history entries list. AppHistoryEntry
is not the last one in the app history entries list. AppHistory
object has an associated entry list, a list of AppHistoryEntry
objects, initially empty.AppHistory
object has an associated entry list, a list of AppHistoryEntry
objects, initially empty.AppHistory
object has an associated current index, an integer, initially −1.current
getter steps are:
@@ -840,7 +840,7 @@ 1.
1.
1.
AppHistoryEntry
existingAHE whose session history entry is she, then append existingAHE to newEntryList.AppHistoryEntry
existingAHE whose session history entry is she, then append existingAHE to newEntryList.
- AppHistoryEntry
created in the relevant realm of appHistory.AppHistoryEntry
created in the relevant realm of appHistory.1.
AppHistoryEntry
objects will ultimately be updated by this algorithm. Implementations can special-case same-document navigations and avoid reassembling the entry list. AppHistoryEntry
objects will ultimately be updated by this algorithm. Implementations can special-case same-document navigations and avoid reassembling the entry list. 2. The
navigate
event[
-
event .
+ navigationType
event .
navigationType
push
", "replace
", or "traverse
", indicating what type of navigation this is. event .
+ canRespond
push
", "replace
", or "traverse
", indicating what type of navigation this is. event .
canRespond
respondWith()
can be called to convert this navigation into a single-page navigation; false otherwise. event .
+ userInitiated
respondWith()
can be called to convert this navigation into a single-page navigation; false otherwise. event .
userInitiated
a
element, submitting a form
element, or using the browser UI to navigate; false otherwise. event .
+ hashChange
a
element, submitting a form
element, or using the browser UI to navigate; false otherwise. event .
hashChange
event .
+ formData
event .
formData
FormData
representing the submitted form entries for this navigation, if this navigation is a POST form submission; null otherwise. event .
+ info
FormData
representing the submitted form entries for this navigation, if this navigation is a POST form submission; null otherwise. event .
info
event .
+ respondWith
( newNavigationAction )event .
respondWith
( newNavigationAction )navigatesuccess
or navigateerror
events as appropriate, which other parts of the web application can respond to. SecurityError
" DOMException
if canRespond
is false, or if isTrusted
is false. It will throw an "InvalidStateError
" DOMException
if not called synchronously, during event dispatch. navigatesuccess
or navigateerror
events as appropriate, which other parts of the web application can respond to. SecurityError
" DOMException
if canRespond
is false, or if isTrusted
is false. It will throw an "InvalidStateError
" DOMException
if not called synchronously, during event dispatch. navigationType
, canRespond
, userInitiated
, hashChange
, formData
, and info
getter steps are to return the value that the corresponding attribute was initialized to.AppHistoryNavigateEvent
has the following associated values that are used when its navigationType
is "push
" or "replace
":AppHistoryNavigateEvent
has the following associated values that are used when its navigationType
is "push
" or "replace
":
- navigationType
is "traverse
":navigationType
is "traverse
":
Initialize event’s navigationType
to navigationType.
Initialize event’s navigationType
to navigationType.
Initialize event’s info
to navigateInfo.
Initialize event’s info
to navigateInfo.
If navigationType is either "push
" or "replace
":
If navigationType is either "push
" or "replace
":
Assert: destinationURL was given, and destinationEntry was not.
@@ -1055,15 +1055,15 @@then initialize event’s hashChange
to true. Otherwise, initialize it to false.
then initialize event’s hashChange
to true. Otherwise, initialize it to false.
If destinationURL is rewritable relative to currentURL, and either isSameDocument is true or navigationType is not "traverse
", then initialize event’s canRespond
to true. Otherwise, initialize it to false.
If destinationURL is rewritable relative to currentURL, and either isSameDocument is true or navigationType is not "traverse
", then initialize event’s canRespond
to true. Otherwise, initialize it to false.
If either userInvolvement is not "browser UI
" or navigationType is not "traverse
", then initialize event’s cancelable
to true.
If either userInvolvement is not "browser UI
" or navigationType is not "traverse
", then initialize event’s cancelable
to true.
If userInvolvement is "none
", then initialize event’s userInitiated
to false. Otherwise, initialize it to true.
If userInvolvement is "none
", then initialize event’s userInitiated
to false. Otherwise, initialize it to true.
If formDataEntryList is not null, then initialize event’s formData
to a new FormData
created in realm, associated to formDataEntryList. Otherwise, initialize it to null.
If formDataEntryList is not null, then initialize event’s formData
to a new FormData
created in realm, associated to formDataEntryList. Otherwise, initialize it to null.
Let result be the result of dispatching event at appHistory.
Fire an event named navigatesuccess
at appHistory.
Fire an event named navigatesuccess
at appHistory.
Fire an event named navigateerror
at appHistory using ErrorEvent
, with error
initialized to rejectionReason, and message
, filename
, lineno
, and colno
initialized to appropriate values that can be extracted from rejectionReason in the same underspecified way the user agent typically does for the report an exception algorithm.
Fire an event named navigateerror
at appHistory using ErrorEvent
, with error
initialized to rejectionReason, and message
, filename
, lineno
, and colno
initialized to appropriate values that can be extracted from rejectionReason in the same underspecified way the user agent typically does for the report an exception algorithm.
If event’s navigation action promise is non-null, then respondWith()
was called and so we’re performing a same-document navigation, for which we want to fire navigatesuccess
or navigateerror
events as appropriate. Otherwise, if the navigation is same-document and was not canceled, we still fire navigatesuccess
after a microtask.
If event’s navigation action promise is non-null, then respondWith()
was called and so we’re performing a same-document navigation, for which we want to fire navigatesuccess
or navigateerror
events as appropriate. Otherwise, if the navigation is same-document and was not canceled, we still fire navigatesuccess
after a microtask.
Return result.
@@ -1094,8 +1094,8 @@https://example.com/foo?bar#baz
is rewritable relative to https://example.com/qux
.
- However, the concept is not the same as the two URLs' origins being the same: https://user:password@example.com/qux
is not rewritable relative to https://example.com/qux
.
Similarly, about:blank
or blob:
URLs are not rewritable relative to https:
URLs, despite there being cases where a https
:-URL Document
is same origin with an about:blank
or blob:
-derived Document
.
However, the concept is not the same as the two URLs' origins being the same: https://user:password@example.com/qux
is not rewritable relative to https://example.com/qux
.
Similarly, about:blank
or blob:
URLs are not rewritable relative to https:
URLs, despite there being cases where a https
:-URL Document
is same origin with an about:blank
or blob:
-derived Document
.
[Exposed =Window ] @@ -1112,31 +1112,31 @@
-
-entry .
+key
entry .
key
- -
A user agent-generated random UUID string representing this app history entry’s place in the app history list. This value will be reused by other
+AppHistoryEntry
instances that replace this one due to replace-style navigations. This value will survive session restores.A user agent-generated random UUID string representing this app history entry’s place in the app history list. This value will be reused by other
AppHistoryEntry
instances that replace this one due to replace-style navigations. This value will survive session restores.This is useful for navigating back to this location in the app history entry list, using
-appHistory.goTo(key)
.entry .
+id
entry .
id
- -
A user agent-generated random UUID string representing this specific app history entry. This value will not be reused by other
+AppHistoryEntry
instances. This value will survive session restores.A user agent-generated random UUID string representing this specific app history entry. This value will not be reused by other
AppHistoryEntry
instances. This value will survive session restores.This is useful for associating data with this app history entry using other storage APIs.
-entry .
+url
entry .
url
The URL of this app history entry.
-entry .
+index
entry .
index
- -
The index of this app history entry within
-appHistory.entries()
, or −1 if the entry is not in the app history list.entry .
+sameDocument
The index of this app history entry within
+appHistory.entries()
, or −1 if the entry is not in the app history list.entry .
sameDocument
- -
Indicates whether or not this app history entry is for the same
-Document
as the currentdocument
value, or not. This will be true, for example, in cases of fragment navigations or single-page app navigations.entry .
+getState()
Indicates whether or not this app history entry is for the same
+Document
as the currentdocument
value, or not. This will be true, for example, in cases of fragment navigations or single-page app navigations.entry .
getState()
Returns the deserialization of the state stored in this entry, which was added to the entry using
appHistory.navigate()
. This state survives session restores.Note that in general, unless the state value is a primitive,
-entry.getState() !== entry.getState()
, since a fresh copy is returned each time.This state is unrelated to the classic history API’s
+history.state
.This state is unrelated to the classic history API’s
history.state
.Each
-AppHistoryEntry
has an associated session history entry, which is a session history entry.Each
+AppHistoryEntry
has an associated index, which is an integer.Each
+AppHistoryEntry
has an associated session history entry, which is a session history entry.Each
AppHistoryEntry
has an associated index, which is an integer.Thekey
getter steps are:@@ -1192,13 +1192,13 @@
-
Return StructuredDeserialize(this's session history entry's app history state).
Unlike
+history.state
, this will deserialize upon each access.Unlike
history.state
, this will deserialize upon each access.This can in theory throw an exception, if attempting to deserialize a large
ArrayBuffer
when not enough memory is available.4. Patches to fire the
navigate
eventThe following section details monkeypatches to [HTML] that cause the
navigate
event to be fired appropriately, and for canceling the event to cancel the navigation. The first few sections detail slight tweaks to existing algorithms to pass through useful information into the navigation and history traversal algorithms. Then, § 4.3 Navigation algorithm updates contains the actual firing of the event.4.1. Form submission patches
-To properly thread the form entry list from its creation through to
+AppHistoryNavigateEvent
'sformData
property, we need the following modifications:To properly thread the form entry list from its creation through to
AppHistoryNavigateEvent
'sformData
property, we need the following modifications:Modify the navigate algorithm to take a list of entries or null entryList (default null), replacing its navigationType parameter. Then insert a step somewhere early in the algorithm to convert this back into the navigationType variable used by the in parallel section that is ultimately passed to [CSP]:@@ -1220,7 +1220,7 @@
Modify the submit as entity body algorithm to pass entry list along to plan to navigate as a second argument.
4.2. Browser UI/user-initiated patches
-To more rigorously specify when a navigation is initiated from browser UI or by the user interacting with
+a
,area
, andform
elements, both for the purposes of theAppHistoryNavigateEvent
'suserInitiated
property and for prohibiting interception of certain types of browser-UI-initiated navigations, we need the following modifications:To more rigorously specify when a navigation is initiated from browser UI or by the user interacting with
a
,area
, andform
elements, both for the purposes of theAppHistoryNavigateEvent
'suserInitiated
property and for prohibiting interception of certain types of browser-UI-initiated navigations, we need the following modifications:Introduce (right before the definition of the navigate algorithm) the concept of a user navigation involvement, which is one of the following:
-
- "
browser UI
" @@ -1233,14 +1233,14 @@
The navigation was not initiated by the user
Define the user navigation involvement for an
+Event
event as "activation
" if event’sisTrusted
attribute is initialized to true, and "none
" otherwise.Define the user navigation involvement for an
Event
event as "activation
" if event’sisTrusted
attribute is initialized to true, and "none
" otherwise.Modify the navigate algorithm to take an optional named argument userInvolvement (default "
none
"). Then, update the paragraph talking about browser-UI initiated navigation as follows:A user agent may provide various ways for the user to explicitly cause a browsing context to navigate, in addition to those defined in this specification. Such cases must set the userInvolvement argument to "browser UI
".This infrastructure partially solves whatwg/html#5381, and it’d be ideal to update the `
-Sec-Fetch-Site
` spec at the same time.Modify the navigate to a fragment algorithm to take a new userInvolvement argument. Then, update the call to it from navigate to set userInvolvement to this userInvolvement value.
+Modify the navigate to a fragment algorithm to take a new userInvolvement argument. Then, update the call to it from navigate to set userInvolvement to this userInvolvement value.
Modify the traverse the history by a delta argument to take an optional named argument userInvolvement (default "
none
"). Then, update the paragraph talking about user-initiated navigation as follows:When the user navigates through a browsing context, e.g. using a browser’s back and forward buttons, the user agent must traverse the history by a delta with a delta equivalent to the action specified by the user @@ -1260,7 +1260,7 @@
- Modify the activation behavior ofa
elements by replacing its follow the hyperlink step with the following: + Modify the activation behavior ofa
elements by replacing its follow the hyperlink step with the following:
Otherwise, follow the hyperlink created by element with the user navigation involvement for event.
@@ -1272,12 +1272,12 @@
Modify the plan to navigate algorithm to take a userInvolvement argument. Then, update the call to it from navigate to set userInvolvement to this userInvolvement value.
-Modify the submit algorithm to take an optional userInvolvement argument (default "
+none
"). Have the submit algorithm pass along its value to all invocations of plan to navigate.Modify the submit algorithm to take an optional userInvolvement argument (default "
none
"). Have the submit algorithm pass along its value to all invocations of plan to navigate.Modify the definition of the activation behavior for
-input
elements to take an event argument. Then, pass along this argument to the invocation of the input activation behavior.Modify the Submit Button state’s input activation behavior by having it take an event argument and pass along the user navigation involvement for event as the final argument when it calls submit.
-Modify the Image Button state’s input activation behavior by having it take an event argument and pass along the user navigation involvement for event as the final argument when it calls submit.
-Modify the
-button
element’s activation behavior by having it take an event argument and, in the Submit Button case, to pass along the user navigation involvement for event as the final argument when it calls submit.Modify the no-submit button case for implicit form submission to pass along "
+activation
" as the final argument when it calls submit.Modify the Submit Button state’s input activation behavior by having it take an event argument and pass along the user navigation involvement for event as the final argument when it calls submit.
+Modify the Image Button state’s input activation behavior by having it take an event argument and pass along the user navigation involvement for event as the final argument when it calls submit.
+Modify the
+button
element’s activation behavior by having it take an event argument and, in the Submit Button case, to pass along the user navigation involvement for event as the final argument when it calls submit.Modify the no-submit button case for implicit form submission to pass along "
activation
" as the final argument when it calls submit.The case of implicit submission when a submit button is present is automatically taken care of because it fires a (trusted) click event at the submit button.
4.3. Navigation algorithm updates
With the above infrastructure in place, we can actually fire and handle the
@@ -1287,7 +1287,7 @@navigate
event in the following locations:
Let appHistory be history’s relevant global object's app history.
- -
Let navigationType be "
+push
" if isPush is true, and "replace
" otherwise.Let navigationType be "
push
" if isPush is true, and "replace
" otherwise.Let continue be the result of firing a navigate event at appHistory with navigationType set to navigationType, isSameDocument set to true, destinationURL set to newURL, and classicHistoryAPISerializedData set to serializedData.
- @@ -1295,12 +1295,12 @@
- Modify the navigate to a fragment algorithm by prepending the following steps. Recall that per § 4.2 Browser UI/user-initiated patches we have introduced a userInvolvement argument. + Modify the navigate to a fragment algorithm by prepending the following steps. Recall that per § 4.2 Browser UI/user-initiated patches we have introduced a userInvolvement argument.
Let appHistory be the current entry’s document’s relevant global object's app history.
- -
Let navigationType be "
+push
" if historyHandling is "default
"; otherwise, "replace
".Let navigationType be "
push
" if historyHandling is "default
"; otherwise, "replace
".Let continue be the result of firing a navigate event at appHistory given with navigationType set to navigationType, isSameDocument set to true, userInvolvement set to userInvolvement, and destinationURL set to url.
- @@ -1320,21 +1320,21 @@
browsingContext’s active document's origin is not same origin-domain with the source browsing context's active document's origin
- -
browsingContext’s only entry in its session history is the
+about:blank
Document
that was added when browsingContext was createdbrowsingContext’s only entry in its session history is the
about:blank
Document
that was added when browsingContext was createdthen:
Let appHistory be browsingContext’s active window's app history.
- -
Let navigationType be "
+push
" if historyHandling is "default
"; otherwise, "replace
".Let navigationType be "
push
" if historyHandling is "default
"; otherwise, "replace
".Let continue be the result of firing a navigate event at appHistory with navigationType set to navigationType, isSameDocument set to false, userInvolvement set to userInvolvement, formDataEntryList set to entryList, and destinationURL set to url.
If continue is false, return.
"
-entry update
" is excluded sincenavigate
would have fired earlier as part of traversing the history by a delta."
+browser UI
" or cross origin-domain navigations that cause fragment navigations do fire thenavigate
event; those are handled as part of the navigate to a fragment algorithm called earlier in navigate, which is not guarded by this condition."
browser UI
" or cross origin-domain navigations that cause fragment navigations do fire thenavigate
event; those are handled as part of the navigate to a fragment algorithm called earlier in navigate, which is not guarded by this condition.@@ -1348,7 +1348,7 @@
If either isSameDocument is true or userInvolvement is not " browser UI
", then:@@ -1373,12 +1373,12 @@
- -
Let continue be the result of firing a navigate event at appHistory with navigationType set to "
+traverse
", isSameDocument set to isSameDocument, userInvolvement set to userInvolvement, and destinationEntry set to specified entry.Let continue be the result of firing a navigate event at appHistory with navigationType set to "
traverse
", isSameDocument set to isSameDocument, userInvolvement set to userInvolvement, and destinationEntry set to specified entry.If continue is false, abort these steps.
update the session history with the new page algorithm’s "replace
" case by adding the following step after the construction of newEntry:
- -
If newEntry’s origin is the same as sessionHistory’s current entry's origin, then set newEntry’s app history key to sessionHistory’s current entry's app history key.
+If newEntry’s origin is the same as sessionHistory’s current entry's origin, then set newEntry’s app history key to sessionHistory’s current entry's app history key.
5.3. Tracking the origin member
Update the update the session history with the new page algorithm’s "
-replace
" and "default
" cases to set newEntry’s origin to newDocument’s origin as part of its creation.Update the navigate to a fragment algorithm to set the new session history entry's origin to the current entry's document's origin.
+Update the navigate to a fragment algorithm to set the new session history entry's origin to the current entry's document's origin.
Update the URL and history update steps algorithm to set the new session history entry's origin to document’s origin.
Potentially update the traverse the history algorithm to consult the new origin field, instead of checking the document's origin, since the document can disappear?? Needs further investigation.
5.4. Updating the
@@ -1396,7 +1396,7 @@AppHistory
objectUpdate the entries of document’s relevant global object's app history. -
We do not update the entries when initially creating a new browsing context, as we intentionally don’t want to include the initial
+about:blank
Document
in any app history entry list.We do not update the entries when initially creating a new browsing context, as we intentionally don’t want to include the initial
about:blank
Document
in any app history entry list.Index
@@ -1517,9 +1517,9 @@1. The AppHistory class (2) (3)
2. The navigate event (2) - 3. App history entries - 4.3. Navigation algorithm updates - 5.4. Updating the AppHistory object + 3. App history entries + 4.3. Navigation algorithm updates + 5.4. Updating the AppHistory object