Skip to content

Commit

Permalink
Some updates... navigate event still pretty borked
Browse files Browse the repository at this point in the history
  • Loading branch information
domenic committed May 14, 2021
1 parent 82e4f1b commit 0d5f28a
Showing 1 changed file with 45 additions and 11 deletions.
56 changes: 45 additions & 11 deletions spec.bs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
text: exceptionsEnabled; url: browsing-the-web.html#exceptions-enabled
type: method
for: Document; text: open(unused1, unused2); url: multipage/dynamic-markup-insertion.html#dom-document-open
spec: html; urlPrefix: https://whatpr.org/html/6315/
type: dfn
text: traversable navigable; for: navigable; url: history.html#nav-traversable
text: current session history entry; for: navigable; url: history.html#nav-current-history-entry
text: get the session history entries; for: navigable; url: history.html#getting-session-history-entries
text: session history traversal queue; for: traversable navigable; url: history.html#tn-session-history-traversal-queue
text: step; for: session history entry; url: history.html#she-step
text: apply the history step; url: history.html#apply-the-history-step
text: checkForUserCancelation; for: apply the history step; url: history.html#apply-the-history-step
text: initiatorToCheck; for: apply the history step; url: history.html#apply-the-history-step
spec: uuid; type: dfn; urlPrefix: https://wicg.github.io/uuid/
text: generate a random UUID; url: #dfn-generate-a-random-uuid
</pre>
Expand Down Expand Up @@ -457,8 +467,6 @@ Each {{AppHistory}} object has an associated <dfn for="AppHistory">navigate meth

1. If [=this=]'s [=AppHistory/current index=] is &minus;1, then return [=a promise rejected with=] an "{{InvalidStateError}}" {{DOMException}}.

1. If [=this=]'s [=AppHistory/entry list=][[=this=]'s [=AppHistory/current index=]]'s [=AppHistoryEntry/session history entry=]'s [=session history entry/app history key=] equals |key|, then return [=a promise resolved with=] undefined.

1. If [=this=]'s [=AppHistory/entry list=] does not contain any {{AppHistoryEntry}} whose [=AppHistoryEntry/session history entry=]'s [=session history entry/app history key=] equals |key|, then return [=a promise rejected with=] an "{{InvalidStateError}}" {{DOMException}}.

1. Return the result of [=performing an app history traversal=] given [=this=], |key|, and |options|.
Expand All @@ -485,29 +493,53 @@ Each {{AppHistory}} object has an associated <dfn for="AppHistory">navigate meth
</div>

<div algorithm>
<p class="advisement">The following algorithm is specified in terms of the <a href="https://github.com/whatwg/html/pull/6315">session history rewrite pull request</a> against the HTML Standard, because the existing session history traversal infrastructure is broken enough that it's hard to build on. It is expected to track that work as it continues.</p>

To <dfn>perform an app history traversal</dfn> given an {{AppHistory}} object |appHistory|, a string |key|, and an {{AppHistoryNavigationOptions}} |options|:

1. If |appHistory|'s [=relevant global object=]'s [=associated Document=] is not [=Document/fully active=], then return [=a promise rejected with=] an "{{InvalidStateError}}" {{DOMException}}.

1. If |appHistory|'s [=relevant global object=]'s [=associated Document=]'s <a spec="HTML">unload counter</a> is greater than 0, then return [=a promise rejected with=] an "{{InvalidStateError}}" {{DOMException}}.

1. Let |jsh| be |appHistory|'s [=relevant global object=]'s [=Window/browsing context=]'s [=top-level browsing context=]'s <a spec="HTML">joint session history</a>.
1. If |appHistory|'s [=AppHistory/entry list=][|appHistory|'s [=AppHistory/current index=]]'s [=AppHistoryEntry/session history entry=]'s [=session history entry/app history key=] equals |key|, then return [=a promise resolved with=] undefined.

1. Let |currentEntryIndex| be the index of the <a spec="HTML" lt="current entry of the joint session history">current entry</a> within |jsh|.
1. Let |navigateInfo| be |options|["{{AppHistoryNavigationOptions/navigateInfo}}"] if it [=map/exists=], or undefined otherwise.

1. Let |destinationIndex| be the index of the closest [=session history entry=] to the <a spec="HTML" lt="current entry of the joint session history">current entry</a>, such that either that entry's [=session history entry/app history key=] equals |key|, or that entry is "standing in place of" another entry whose [=session history entry/app history key=] equals |key|. Here, |entryA| "standing in place of" <var ignore>entryB</var> means that they occupy the same "slot" within the joint session history, but only |entryA| is included because it most recently became the [=session history/current entry=] of its [=session history=].
1. Let |navigable| be |appHistory|'s [=relevant global object=]'s [=associated Document=]'s navigable.

<p class="issue">This imprecise phrasing will go away when the great session history overhaul documented in <a href="https://github.com/whatwg/html/issues/5767">whatwg/html#5767</a> is completed and we have a clear inventory of all [=session history entries=] in each slot in the <a spec="HTML">joint session history</a>.
1. Let |traversable| be |navigable|'s [=navigable/traversable navigable=].

1. [=Assert=]: exactly one such entry must exist.
1. Let |initiatorBC| be |appHistory|'s [=relevant global object=]'s [=Window/browsing context=].

1. If |appHistory|'s [=relevant global object=]'s [=Window/browsing context=] is not <a spec="HTML">allowed to navigate</a> any of the browsing contexts which would be navigated by traversing to |destinationIndex|, then return [=a promise rejected with=] a "{{SecurityError}}" {{DOMException}}.
1. Let |promise| be [=a new promise=] created in |appHistory|'s [=relevant Realm=].

<p class="issue">This is super-vague. And probably cannot be determined synchronously. Revisit this after <a href="https://github.com/whatwg/html/issues/5767">whatwg/html#5767</a>.
1. [=parallel queue/Enqueue the following steps=] on |traversable|'s [=traversable navigable/session history traversal queue=]:

1. Let |navigateInfo| be |options|["{{AppHistoryNavigationOptions/navigateInfo}}"] if it [=map/exists=], or undefined otherwise.
1. Let |navigableEntries| be the result of [=navigable/getting the session history entries=] given |navigable|.

1. Let |targetEntry| be the [=session history entry=] in |navigableEntries| whose [=session history entry/app history key=] equals |key|. If no such entry exists, then:

1. [=Reject=] |promise| with an "{{InvalidStateError}}" {{DOMException}}.

1. Abort these steps.

1. <a spec="HTML">Traverse the history by a delta</a> given |destinationIndex| &minus; |currentEntryIndex| and |appHistory|'s [=relevant global object=]'s [=Window/browsing context=], with <i>[=traverse the history by a delta/appHistoryInfo=]</i> set to |navigateInfo|.
<p class="note">This can occur if the |appHistory| object's view of session history is outdated, which can happen for brief periods while all the relevant threads and processes are being synchronized in reaction to a history change (such as the user clearing their history).

1. Assert: |targetEntry| is not |navigable|'s [=navigable/current session history entry=].

1. Let |targetStep| be |targetEntry|'s [=session history entry/step=].

1. [=Apply the history step=] |targetStep| to |traversable|, with <i>[=apply the history step/checkForUserCancelation=]</i> set to true, <i>[=apply the history step/initiatorToCheck=]</i> set to |initiatorBC|, and <i>[=apply the history step/appHistoryInfo=]</i> set to |navigateInfo|.

- If this aborts due to user-canceled unloading, then [=reject=] |promise| with an "{{AbortError}}" {{DOMException}}.

- If this aborts due to the initiator allowed-to-navigate check, then [=reject=] |promise| with a "{{SecurityError}}" {{DOMException}}.

- TODO: deal with another traversal aborting this one. (The HTML spec PR doesn't support this yet.) Should result in "{{AbortError}}" {{DOMException}}.

<p class="advisement">Eventually [=apply the history step=] will have well-specified hooks for communicating these conditions back to its caller.</p>

TODO: this doesn't deal with the navigate event...
</div>

<h3 id="global-events">Event handlers</h3>
Expand Down Expand Up @@ -1060,6 +1092,8 @@ With the above infrastructure in place, we can actually fire and handle the {{Ap
1. If either |isSameDocument| is true or |userInvolvement| is not "<code>[=user navigation involvement/browser UI=]</code>", then:
1. Let |continue| be the result of [=firing a traversal navigate event=] at |appHistory| with <i>[=fire a traversal navigate event/destinationEntry=]</i> set to <var ignore>specified entry</var>, <i>[=fire a traversal navigate event/isSameDocument=]</i> set to |isSameDocument|, <i>[=fire a traversal navigate event/userInvolvement=]</i> set to |userInvolvement|, and <i>[=fire a traversal navigate event/info=]</i> set to |appHistoryInfo|.
1. If |continue| is false, abort these steps.

<p class="advisement">The <a href="https://github.com/whatwg/html/pull/6315">session history rewrite pull request</a> will largely replace the above algorithm with [=apply the history step=].
</div>

<h2 id="session-history-patches">Patches to session history</h2>
Expand Down

0 comments on commit 0d5f28a

Please sign in to comment.