1.
The
AppHistory
class
partial interface Window {readonly attribute AppHistory appHistory ; };
Each
Window
object
has
an
associated
app
history
,
which
is
a
new
AppHistory
instance
created
alongside
the
Window
.
The
appHistory
getter
steps
are
to
return
this
's
app
history
.
[Exposed =Window ]interface :AppHistory EventTarget {attribute AppHistoryEntry ?current ;sequence <AppHistoryEntry >entries ();readonly attribute boolean canGoBack ;readonly attribute boolean canGoForward ;Promise <undefined >navigate (USVString ,url optional AppHistoryNavigateOptions = {});options Promise <undefined >navigate (optional AppHistoryNavigateOptions = {});options attribute EventHandler onnavigate ;attribute EventHandler onnavigatesuccess ;attribute EventHandler onnavigateerror ; };dictionary {AppHistoryNavigationOptions any ; };navigateInfo dictionary :AppHistoryNavigateOptions AppHistoryNavigationOptions {any ;state boolean =replace false ; };
Each
AppHistory
object
has
an
associated
entry
list
,
a
list
of
AppHistoryEntry
objects,
initially
empty.
Each
AppHistory
object
has
an
associated
current
index
,
an
integer,
initially
−1.
Each
AppHistory
object
has
an
associated
ongoing
navigate
event
,
an
AppHistoryNavigateEvent
or
null,
initially
null.
Each
AppHistory
object
has
an
associated
navigate
method
call
promise
,
which
is
either
a
Promise
or
null,
initially
null.
Each
AppHistory
object
has
an
associated
navigate
method
call
serialized
state
,
which
is
either
a
serialized
state
or
null,
initially
null.
1.1. Introspecting the app history entry list
-
appHistory.current -
The current
AppHistoryEntry. -
appHistory.entries() -
Returns an array of
AppHistoryEntryinstances representing the current app history list, i.e. all session history entries for thisWindowthat are same origin and contiguous to the current session history entry. -
appHistory.canGoBack -
Returns true if the current
AppHistoryEntryis not the first one in the app history entries list. -
appHistory.canGoForward -
Returns true if the current
AppHistoryEntryis not the last one in the app history entries list.
current
getter
steps
are:
-
If this 's relevant global object 's associated Document is not fully active , then return null.
-
If this 's current index is −1, then return null.
This occurs if accessing the API while on the initial
about:blankDocument, where the update the entries algorithm will not yet have been run to completion. -
Return this 's entry list [ this 's current index ].
entries()
method
steps
are:
-
If this 's relevant global object 's associated Document is not fully active , then return the empty list.
-
Return this 's entries list .
canGoBack
getter
steps
are:
-
If this 's relevant global object 's associated Document is not fully active , then return false.
-
If this 's current index is −1, then return false.
-
If this 's current index is 0, then return false.
-
Return true.
canGoForward
getter
steps
are:
-
If this 's relevant global object 's associated Document is not fully active , then return false.
-
If this 's current index is −1, then return false.
-
If this 's current index is equal to this 's entry list 's size − 1, then return false.
-
Return true.
AppHistory
instance
appHistory
:
-
Let browsingContext be appHistory ’s relevant global object 's associated Document 's browsing context .
-
Assert : browsingContext is not null.
-
Let sessionHistory be browsingContext ’s session history .
-
If browsingContext is still on its initial
about:blankDocument, then:-
Assert: appHistory ’s entry list is empty .
-
Return.
This can occur if running the URL and history update steps , e.g. via
document.open(), on the initialabout:blankDocument. The app history API chooses not to expose the initialabout:blankDocument, so we bail early. -
-
Let appHistorySHEs be a new empty list.
-
Let currentSHE be sessionHistory ’s current entry .
-
Let backwardIndex be the index of currentSHE within sessionHistory , minus 1.
-
While backwardIndex > 0:
-
Let she be sessionHistory [ backwardIndex ].
-
If she ’s origin is same origin with currentSHE ’s origin , then prepend she to appHistorySHEs .
-
Otherwise, break .
-
Set backwardIndex to backwardIndex − 1.
-
-
Append currentSHE to appHistorySHEs .
-
Let forwardIndex be the index of currentSHE within sessionHistory , plus 1.
-
While forwardIndex < sessionHistory ’s size :
-
Let she be sessionHistory [ forwardIndex ].
-
If she ’s origin is same origin with currentSHE ’s origin , then append she to appHistorySHEs .
-
Otherwise, break .
-
Set forwardIndex to forwardIndex + 1.
-
-
Let newCurrentIndex be the index of currentSHE within appHistorySHEs .
-
Let newEntryList be an empty list.
-
For each oldAHE of appHistory ’s entry list :
-
Set oldAHE ’s index to −1.
-
-
Let index be 0.
-
For each she of appHistorySHEs :
-
If appHistory ’s entry list contains an
AppHistoryEntryexistingAHE whose session history entry is she , then append existingAHE to newEntryList . -
Otherwise:
-
Let newAHE be a new
AppHistoryEntrycreated in the relevant realm of appHistory . -
Set newAHE ’s session history entry to she .
-
Append newAHE to newEntryList .
-
-
Set newEntryList [ index ]'s index to index .
-
Set index to index + 1.
-
-
Set appHistory ’s entry list to newEntryList .
-
Set appHistory ’s current index to newCurrentIndex .
For
same-document
navigations
only
the
current
index
and
the
indices
of
the
various
AppHistoryEntry
objects
will
ultimately
be
updated
by
this
algorithm.
Implementations
can
special-case
same-document
navigations
and
avoid
reassembling
the
entry
list
.
1.2. Navigating
awaitappHistory.navigate( url )awaitappHistory.navigate( url , options )Navigates the current page to the given url . options can contain the following values:
replacecan be set to true to replace the current session history entry, instead of pushing a new onenavigateInfocan be set to any value; it will populate theinfoproperty of the correspondingnavigateevent.statecan be set to any serializable value; it will populate the state retrieved byappHistory.current.getState()once the navigation completes, for same-document navigations. (It will be ignored for navigations that end up cross-document.)
By default this will perform a full navigation (i.e., a cross-document navigation, unless the given URL differs only in a fragment from the current one). The
navigateevent’srespondWith()method can be used to convert it into a same-document navigation.The returned promise will behave as follows:
For same-document navigations created by using the
navigateevent’srespondWith()method, it will fulfill or reject according to the promise passed torespondWith().For other same-document navigations (e.g., non-intercepted fragment navigations ), it will fulfill immediately.
For cross-document navigations, it will never settle.
awaitappHistory.navigate( options )Navigates to the same URL as the current page. options needs to contain at least one of
navigateInfoorstate, which behave as described above.The default behavior of performing a full navigation to the current page can be overriden by using the
navigateevent’srespondWith()method. Doing so will mean this call only updates state or passes along the appropriatenavigateInfo.The returned promise behaves as described above.
navigate(
url
,
options
)
method
steps
are:
Parse url relative to this 's relevant settings object . If that returns failure, then return a promise rejected with a "
SyntaxError"DOMException. Otherwise, let urlRecord be the resulting URL record .Return the result of performing an app history navigation given this , urlRecord , and options .
navigate(
options
)
method
steps
are:
If neither options ["
navigateInfo"] nor options ["state"] exists , then return a promise rejected with aTypeError.Set options ["
replace"] to true.This is not technically necessary, as the main navigate algorithm will override any non-"
replace" history handling behavior for same-URL navigations.Let urlRecord be this 's relevant global object 's active document 's URL .
Return the result of performing an app history navigation given this , urlRecord , and options .
AppHistory
object
appHistory
,
a
URL
url
,
and
an
AppHistoryNavigateOptions
options
:Let browsingContext be appHistory ’s relevant global object 's browsing context .
Let historyHandling be "
replace" if options ["replace"] exists and is true; otherwise, "default".Let navigateInfo be options ["
navigateInfo"] if it exists; otherwise, undefined.Let serializedState be null.
If options ["
state"] exists , then set serializedState to StructuredSerializeForStorage ( options ["state"]). If this throws an exception, return a promise rejected with that exception.Let promise be a new promise created in appHistory ’s relevant Realm .
Let previousPromise be appHistory ’s navigate method call promise .
Let previousState be appHistory ’s navigate method call serialized state .
Set appHistory ’s navigate method call promise to promise .
Set appHistory ’s navigate method call serialized state to serializedState .
Navigate browsingContext to url with historyHandling set to historyHandling , appHistoryInfo set to navigateInfo , appHistoryState set to serializedState , and the source browsing context set to browsingContext .
If navigate method call serialized state is non-null, then set browsingContext ’s session history 's current entry 's app history state to appHistory ’s navigate method call serialized state .
Set appHistory ’s navigate method call promise to previousPromise .
Set appHistory ’s navigate method call serialized state to previousState .
Return promise .
Unlike
location.assign()
and
friends,
which
are
exposed
across
origin-domain
boundaries,
appHistory.navigate()
can
only
be
accessed
by
code
with
direct
synchronous
access
to
the
appHistory
property.
Thus,
we
avoid
the
complications
around
tracking
source
browsing
contexts
,
and
we
don’t
need
to
deal
with
the
allowed
to
navigate
check
and
its
accompanying
exceptionsEnabled
flag.
We
just
treat
all
navigations
as
being
initiated
by
the
AppHistory
object
itself.
1.3. Event handlers
The
following
are
the
event
handlers
(and
their
corresponding
event
handler
event
types
)
that
must
be
supported,
as
event
handler
IDL
attributes
,
by
objects
implementing
the
AppHistory
interface:
| Event handler | Event handler event type |
|---|---|
onnavigate
|
navigate
|
onnavigatesuccess
|
navigatesuccess
|
onnavigateerror
|
navigateerror
|
2.
The
navigate
event
2.1.
The
AppHistoryNavigateEvent
class
[Exposed =Window ]interface :AppHistoryNavigateEvent Event {(constructor DOMString ,type optional AppHistoryNavigateEventInit = {});eventInit readonly attribute AppHistoryNavigationType navigationType ;; ; ; // readonly attribute AppHistoryEntry destination;readonly attribute AppHistoryDestination destination ;readonly attribute boolean canRespond ;readonly attribute boolean userInitiated ;readonly attribute boolean hashChange ; // readonly attribute AbortSignal signal;readonly attribute FormData ?formData ;;readonly attribute any info ;);undefined respondWith (Promise <undefined >); };newNavigationAction dictionary :AppHistoryNavigateEventInit EventInit {AppHistoryNavigationType = "push";navigationType ; ; ; // required AppHistoryEntry destination;required AppHistoryDestination ;destination boolean =canRespond false ;boolean =userInitiated false ;boolean =hashChange false ; // required AbortSignal signal;FormData ?=formData null ;;any =info null ; };enum {AppHistoryNavigationType ,"push" ,"replace" };"traverse"
-
event .navigationType -
One of "
push", "replace", or "traverse", indicating what type of navigation this is. -
event .destination An
AppHistoryDestinationrepresenting the destination of the navigation.event .canRespond-
True if
respondWith()can be called to convert this navigation into a single-page navigation; false otherwise.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.
-
event .userInitiated -
True if this navigation was due to a user clicking on an
aelement, submitting aformelement, or using the browser UI to navigate; false otherwise. -
event .hashChange -
True if this navigation is a fragment navigation ; false otherwise.
-
event .formData -
The
FormDatarepresenting the submitted form entries for this navigation, if this navigation is a POST form submission ; null otherwise. -
event .info -
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.
-
event .respondWith( newNavigationAction ) -
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
navigatesuccessornavigateerrorevents as appropriate, which other parts of the web application can respond to.This method will throw a "
SecurityError"DOMExceptionifcanRespondis false, or ifisTrustedis false. It will throw an "InvalidStateError"DOMExceptionif not called synchronously, during event dispatch.
The
navigationType
,
destination
,
canRespond
,
userInitiated
,
hashChange
,
formData
,
and
info
getter
steps
are
to
return
the
value
that
the
corresponding
attribute
was
initialized
to.
An
AppHistoryNavigateEvent
has
the
following
associated
values
that
which
are
only
conditionally
used:
classic history API serialized data , a serialized state -or-null, used when its
navigationTypeis "push" or "replace":"-
destination
URLentry , aURL classicsession historyAPI serialized data , a serialized state -or-null It has the following associated value that isentry , used when itsnavigationTypeis "traverse": destination entry , a session history entry"
These
are
One
of
these
is
set
appropriately
when
the
event
is
fired
.
An
AppHistoryNavigateEvent
also
has
an
associated
Promise
-or-null
navigation
action
promise
,
initially
null.
respondWith(
newNavigationAction
)
method
steps
are:
-
If this 's relevant global object 's browsing context is null, then throw an "
InvalidStateError"DOMException. -
If this 's
isTrustedattribute was initialized to false, then throw a "SecurityError"DOMException. -
If this 's
canRespondattribute was initialized to false, then throw a "SecurityError"DOMException. -
If this 's dispatch flag is unset, then throw an "
InvalidStateError"DOMException. -
If this 's canceled flag is set, then throw an "
InvalidStateError"DOMException. -
Set this 's canceled flag .
-
Set this 's navigation action promise to newNavigationAction .
2.2.
The
AppHistoryDestination
class
[Exposed =Window ]interface {AppHistoryDestination readonly attribute USVString url ;readonly attribute boolean sameDocument ;any getState (); };
event .destination.urlThe URL being navigated to.
event .destination.sameDocumentIndicates whether or not this navigation is to the same
Documentas the currentdocumentvalue, or not. This will be true, for example, in cases of fragment navigations orhistory.pushState()navigations.Note that this property indicates the original nature of the navigation. If a cross-document navigation is converted into a same-document navigation using
event.respondWith(), that will not change the value of this property.event .destination.getState()For "
traverse" navigations, returns the deserialization of the state stored in the destination session history entry.For "
push" and "replace" navigations, returns the deserialization of the state passed toappHistory.navigate(), if the navigation was initiated in that way, or null if it wasn’t.
An
AppHistoryDestination
has
an
associated
URL
,
which
is
a
URL
.
An
AppHistoryDestination
has
an
associated
state
,
which
is
a
serialized
state
-or-null.
An
AppHistoryDestination
has
an
associated
is
same
document
,
which
is
a
boolean.
The
url
getter
steps
are
to
return
this
's
URL
,
serialized
.
The
sameDocument
getter
steps
are
to
return
this
's
is
same
document
.
getState()
method
steps
are:
Return StructuredDeserialize ( this 's state ).
2.3. Firing the event
navigate
event
at
an
AppHistory
appHistory
given
a
session
history
entry
destinationEntry
,
a
boolean
isSameDocument
,
an
optional
user
navigation
involvement
userInvolvement
(default
"
none
"),
and
an
optional
JavaScript
value
info
(default
undefined):
Let destinationURL be destinationEntry ’s URL .
Let destinationState be destinationEntry ’s app history state .
Let event be the result of creating an event given
AppHistoryNavigateEvent, in appHistory ’s relevant Realm .Set event ’s destination entry to destinationEntry .
Return the result of performing the inner navigate event firing algorithm given appHistory , event , "
traverse", isSameDocument , destinationURL , destinationState , userInvolvement , info , and null.
navigate
event
at
an
AppHistory
appHistory
given
an
AppHistoryNavigationType
navigationType
,
a
URL
destinationURL
,
a
boolean
isSameDocument
,
an
optional
user
navigation
involvement
userInvolvement
(default
"
none
"),
and
an
optional
value
FormData
entries
or
null
formDataEntryList
(default
null),
and
an
optional
Let event be the result of creating an
optional session history entryevent givenAppHistoryNavigateEvent, indestinationEntryappHistory ’s relevant Realm .Set event ’s classic history API serialized data to classicHistoryAPISerializedData .
Return the result of performing the inner navigate event firing algorithm given appHistory , event , navigationType , isSameDocument , destinationURL , state , userInvolvement , info , and formDataEntryList .
navigate
event
firing
algorithm
is
the
following
steps,
given
an
:
AppHistory
appHistory
,
an
AppHistoryNavigateEvent
event
,
an
AppHistoryNavigationType
navigationType
,
a
boolean
isSameDocument
,
a
URL
destinationURL
,
a
serialized
state
-or-null
destinationState
,
a
user
navigation
involvement
userInvolvement
,
a
JavaScript
value
info
,
and
a
list
of
FormData
entries
or
null
formDataEntryList
:
-
If appHistory ’s relevant global object 's browsing context is still on its initial
about:blankDocument, then return true. -
Let realm be appHistory ’s relevant Realm . Let event be the result of creating an event given AppHistoryNavigateEvent , in realm .Initialize event ’stypeto "navigate". -
Initialize event ’s
navigationTypeto navigationType . -
Initialize event ’s
infotonavigateInfoinfo . -
IfLetnavigationTypedestinationis either " pushbe a new" or "replaceAppHistoryDestination": Assert : destinationURL was given, andcreated indestinationEntryappHistorywas not.’s relevant Realm . -
Set
eventdestination ’sdestinationURL to destinationURL . -
Set
eventdestination ’sclassic history API serialized datastate toclassicHistoryAPISerializedDatadestinationState .Otherwise: Assert : destinationEntry was given -
Assert : destinationURL was not given, andSetclassicHistoryAPISerializedDatadestinationand’s is same document toformDataEntryList are null.isSameDocument . -
SetInitialize event ’sdestinationtoentrydestinationEntrydestination . -
Let currentURL be appHistory ’s relevant global object 's associated document 's URL .
-
If all of the following are true:
-
isSameDocument is true;
-
destinationURL equals currentURL with exclude fragments set to true; and
-
destinationURL ’s fragment is not identical to currentURL ’s fragment
then initialize event ’s
hashChangeto 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 ’scanRespondto true. Otherwise, initialize it to false. -
If either userInvolvement is not "
browser UI" or navigationType is not "traverse", then initialize event ’scancelableto true. -
If userInvolvement is "
none", then initialize event ’suserInitiatedto false. Otherwise, initialize it to true. -
If formDataEntryList is not null, then initialize event ’s
formDatato a newFormDatacreated in realm , associated to formDataEntryList . Otherwise, initialize it to null. -
Assert : appHistory ’s ongoing navigate event is null.
-
Set appHistory ’s ongoing navigate event to event .
-
Let result be the result of dispatching event at appHistory .
-
Set appHistory ’s ongoing navigate event to null.
-
If
this 'sappHistory ’s relevant global object 's browsing context is null, then return false.-
Signal an aborted navigation for appHistory .
Return false.
This can
occurroccur if an event listener disconnected theiframecorresponding to this 's relevant global object . -
-
If event ’s navigation action promise is non-null, then:
-
If event ’s
navigationTypeattribute was initialized to "push" or "replace":-
Let isPush be true if event ’s
navigationTypeattribute was initialized to "push"; otherwise, false. -
Run the URL and history update steps given event ’s relevant global object 's associated document and event ’s
destination's URL , with serializedData set to event ’s classic history API serialized data and isPush set to isPush .
-
-
Otherwise:
-
Traverse the history of event ’s relevant global object 's browsing context to destination entry .
-
-
-
If event ’s navigation action promise is non-null, or both result and isSameDocument are true, then:
-
If event ’s navigation action promise is null, then set it to a promise resolved with undefined, created in realm .
-
Let navigateMethodCallPromise be appHistory ’s navigate method call promise .
React to event ’s navigation action promise with the following fulfillment
steps:steps given fulfillmentValue :-
Fire an event named
navigatesuccessat appHistory . -
If navigateMethodCallPromise is non-null, then resolve navigateMethodCallPromise with fulfillmentValue .
-
Fire an event named
navigateerrorat appHistory usingErrorEvent, witherrorinitialized to rejectionReason , andmessage,filename,lineno, andcolnoinitialized 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 navigateMethodCallPromise is non-null, then reject navigateMethodCallPromise with rejectionReason .
-
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 firenavigatesuccessornavigateerrorevents as appropriate.events, and resolve or reject the promise returned by the correspondingappHistory.navigate()call if one exists. Otherwise, if the navigation is same-document and was not canceled, we stillfireperform these actions after a microtask, treating them as an instantly-successful navigation. -
Otherwise:
Set appHistory ’s navigate method call serialized state to null.
This ensures that any call to
navigatesuccessappHistory.navigate()after a microtask.which triggered this algorithm does not overwrite the app history state of the current entry for cross-document navigations or canceled navigations.If event ’s navigation action promise is null and result is false, then signal an aborted navigation for appHistory .
-
Return result .
AppHistory
appHistory
:Queue a microtask on appHistory ’s relevant agent 's event loop to perform the following steps:
Let error be a new "
AbortError"DOMException, created in appHistory ’s relevant Realm .Fire an event named
navigateerrorat appHistory usingErrorEvent, witherrorinitialized to error ,messageinitialized to the value of error ’smessageproperty,filenameinitialized to the empty string, andlinenoandcolnoinitialized to 0.If appHistory ’s navigate method call promise is non-null, then reject appHistory ’s navigate method call promise with error .
navigate
event
for
an
AppHistory
appHistory
:
-
If appHistory ’s ongoing navigate event is non-null, then:
-
Set appHistory ’s ongoing navigate event 's canceled flag to true.
-
Set appHistory ’s ongoing navigate event 's navigation action promise to null.
-
A URL is rewritable relative to another URL if they differ in only the path , query , or fragment components.
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
.
3. App history entries
[Exposed =Window ]interface :AppHistoryEntry EventTarget {readonly attribute DOMString key ;readonly attribute DOMString id ;;readonly attribute USVString url ;readonly attribute long long index ;;readonly attribute boolean sameDocument ;();any getState (); // TODO event handlers };
-
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
AppHistoryEntryinstances 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 -
A user agent -generated random UUID string representing this specific app history entry. This value will not be reused by other
AppHistoryEntryinstances. This value will survive session restores.This is useful for associating data with this app history entry using other storage APIs.
-
entry .url -
The URL of this app history entry.
-
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 -
Indicates whether or not this app history entry is for the same
Documentas the currentdocumentvalue, or not. This will be true, for example,in cases ofwhen the entry represents a fragmentnavigationsnavigation 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.
Each
AppHistoryEntry
has
an
associated
session
history
entry
,
which
is
a
session
history
entry
.
Each
AppHistoryEntry
has
an
associated
index
,
which
is
an
integer.
key
getter
steps
are:
-
If this 's relevant global object 's associated Document is not fully active , then return the empty string.
-
Return this 's session history entry 's app history key .
id
getter
steps
are:
-
If this 's relevant global object 's associated Document is not fully active , then return the empty string.
-
Return this 's session history entry 's app history id .
url
getter
steps
are:
-
If this 's relevant global object 's associated Document is not fully active , then return the empty string.
-
Return this 's session history entry 's URL , serialized .
index
getter
steps
are:
-
If this 's relevant global object 's associated Document is not fully active , then return −1.
-
Return this 's session history entry 's index .
sameDocument
getter
steps
are:
-
If this 's relevant global object 's associated Document is not fully active , then return false.
-
Return true if this 's session history entry 's document equals this 's relevant global object 's associated Document , and false otherwise.
getState()
method
steps
are:
-
If this 's relevant global object 's associated Document is not fully active , then return null.
-
If this 's session history entry 's app history state is null, then return null.
-
Return StructuredDeserialize ( this 's session history entry 's app history state ).
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
event
The
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
's
formData
property,
we
need
the
following
modifications:
-
Let navigationType be "
form-submission" if entryList is non-null; otherwise, "other".
-
Navigate target browsing context to destination , with historyHandling set to historyHandling
and navigationType set to "entryList set to entryList .form-submission"
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
,
and
form
elements,
both
for
the
purposes
of
the
AppHistoryNavigateEvent
's
userInitiated
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" -
The navigation was initiated by the user via browser UI mechanisms
-
"
activation" -
The navigation was initiated by the user via the activation behavior of an element
-
"
none" -
The navigation was not initiated by the user
Define
the
user
navigation
involvement
for
an
Event
event
as
"
activation
"
if
event
’s
isTrusted
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
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 userand, the browsing context being operated on , and userInvolvement set to "browser UI" .
Modify the follow the hyperlink algorithm to take a new userInvolvement argument. Then, update the call to it from navigate to set userInvolvement to this userInvolvement value.
area
elements
by
introducing
the
event
argument
and
replacing
the
follow
the
hyperlink
step
with
the
following:
-
Otherwise, follow the hyperlink created by element with the user navigation involvement for event .
a
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 .
Expand
the
section
on
"
Providing
users
with
a
means
to
follow
hyperlinks
created
using
the
link
element
"
by
adding
the
following
sentence:
Such
invocations
of
follow
the
hyperlink
algorithm
must
set
the
userInvolvement
argument
to
"
browser
UI
".
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
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
.
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
navigate
event
in
the
following
locations:
-
Let appHistory be history ’s relevant global object 's app history .
-
Cancel any ongoing navigate event for appHistory .
-
Let navigationType be "
push" if isPush is true, and "replace" otherwise. -
Let continue be the result of firing a push or replace navigate event at appHistory with navigationType set to navigationType , isSameDocument set to true, destinationURL set to newURL , and classicHistoryAPISerializedData set to serializedData .
-
If continue is false, return.
-
Let appHistory be the current entry
’s's document ’s relevant global object 's app history . -
Let navigationType be "
push" if historyHandling is "default"; otherwise, "replace". -
Let continue be the result of firing a push or replace navigate event at appHistory given with navigationType set to navigationType , isSameDocument set to true, userInvolvement set to userInvolvement , and destinationURL set to url .
-
If continue is false, return.
-
Let appHistory be specified browsing context ’s active window 's app history .
-
Cancel any ongoing navigate event for appHistory .
-
Let isSameDocument be true if specified browsing context ’s active document equals specified entry ’s document ; otherwise, false.
-
If either isSameDocument is true or userInvolvement is not "
browser UI", then:-
Let continue be the result of firing a traversal navigate event at appHistory with
navigationTypedestinationEntry set to" traverse ",specified entry , isSameDocument set to isSameDocument , and userInvolvement set to userInvolvement, and destinationEntry set to specified entry. -
If continue is false, abort these steps.
-
5. Patches to session history
This
section
details
monkeypatches
to
[HTML]
to
track
appropriate
data
for
associating
an
AppHistory
with
a
session
history
entry
.
5.1. New session history entry items
Each session history entry gains the following new items :
-
origin , an origin
-
app history key , a string, initially set to the result of generating a random UUID
-
app history id , a string, initially set to the result of generating a random UUID
-
app history state , which is serialized state or null, initially null
5.2. Carrying over the app history key
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 .
5.3. Carrying over the app history state
5.4. 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 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.
5.5.
Updating
the
AppHistory
object
-
Update the entries of newDocument ’s relevant global object 's app history .
-
Update 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.