-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add navigation hooks for WebDriver BiDi history traversal #6921
base: main
Are you sure you want to change the base?
Conversation
I'll review Monday (although can you try fixing the build first?). Sadly this algorithm does not match browsers very well, but I imagine we can slot something in for now. /cc @jakearchibald as something to take into account when rewriting. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nits; great spec work as always.
source
Outdated
data-x="dom-PopStateEvent-state">state</code> attribute initialized to <var>state</var>. | ||
</p></li> | ||
|
||
<li><p>Invoke <span>WebDriver BiDi pop state</span> with <var>newDocument</var>'s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just double checking that you actually want to carry over the idiosyncratic semantics of popstate and hashchange to WebDriver BiDi consumers? Web developer feedback has been pretty adamant that these events are kinda useless; see e.g. #5562 . But I'm not sure what the WebDriver BiDi consumer use case is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We current proposal for WebDriver doesn't actually expose these events, it's basically just ensuring that a user traverses history in a way that just pops state, we return a response to the traverse history command at the point where we're done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to bundle them both into a single hook then? Maybe the same hook as page show even? But I defer to your judgment as to what are the best hook points for your spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I think it's more likely we're going to end up exposing more stuff via webdriver than less, and having seperate hooks minimises the chance we'll need further changes to HTML. Most likely I think page show will be exposed, and popstate won't, but I'm not sure (hash change is actually already exposed).
6f9478b
to
725ca64
Compare
961fab4
to
2c7e630
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed some editorial fixes in the hopes of moving this along. But I found several instances of referencing undeclared variables so there might be some deeper logic issues...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could summarize this review as: ensuring exactly one callback for the right reasons is hard!
source
Outdated
<span>joint session history</span>, then:</p> | ||
|
||
<ol> | ||
<li><p>Invoke <span>WebDriver BiDi navigation failed</span> with <var>source browsing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this will happen for all calls of this algorithm, including history.go(1000)
in JS, this could incorrectly end an ongoing BiDi navigation. history.go(1000)
is really a no-op, and shouldn't affect BiDi.
I see a two options:
- Use a return value instead
- Add a wrapper for this algorithm only used by BiDi
An option that works but isn't a candidate for me is some form of COMEFROM
, maybe using navigationId
to mean "called from BiDi" and not invoking the callback otherwise. Ugh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also just drop navigationFailed
with null navigation id on the BiDi side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, if BiDi always passing a navigation ID and nothing else does, that would work. If some other spec later integrated with HTML and uses navigation IDs I'm not sure what will happen, but we could punt on that hypothetical.
source
Outdated
<li><p>If the <var>specified browsing context</var>'s <span>active document</span>'s <span>unload | ||
counter</span> is greater than 0, then return.</p></li> | ||
<ol> | ||
<li><p>Invoke <span>WebDriver BiDi navigation failed</span> with <var>source browsing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This too could presumably happen for reasons other than a BiDi command, and influence other BiDi commands that don't invoke this algorithm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the concern with influencing other BiDi commands? If a BiDi command invokes this it has to provide a navigation id, and that id is used to associate these callbacks with the ongoing command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, so same answer with using the navigation ID. That should work!
source
Outdated
data-x="concept-document-url">URL</span>.</p></li> | ||
|
||
<li><p><p>Invoke <span>WebDriver BiDi fragment navigated</span> with <var>browsingContext</var>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's hard to spot in the diff where different algorithms start and end, so noting for other reviewers that this is the end of "navigate to a fragment" and this "WebDriver BiDi fragment navigated" invocation ends up at the end of "traverse the history" (below) which is invoked above.
source
Outdated
and the <code data-x="dom-HashChangeEvent-newURL">newURL</code> attribute initialized to | ||
<var>newURL</var>.</p></li> | ||
|
||
<li><p>Invoke <span>WebDriver BiDi fragment navigated</span> with <var>newDocument</var>'s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous invocation of "WebDriver BiDi fragment navigated" was unconditional but this one depends on hashChanged being true.
Does this mean that trying to navigate to the current URL never gets a callback? Or is there a callback somewhere and before this change we had a broken situation with two callbacks being invoked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So is there a case where hashchanged
is false, statechanged
is false, and there isn't going to be a later load
event (assuming the navigation isn't cancelled)? If there is such an event I think we're missing a callback, but it at least makes sense to me that we don't want to do the fragment navigation steps on the BiDi side unless the fragment is actually navigated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it does make sense to make this callback conditional, the previous state of things was more strange.
My "navigate to the current URL" example seems more complicated than I thought, what happens depends on whether there's a fragment, tested with window.location.href = window.location.href
in DevTools. For https://whatwg.org/faq it will reload the page, and for https://whatwg.org/faq#the-whatwg it does "nothing".
I think https://whatwg.org/faq#the-whatwg is the interesting case. If BiDi's browsingContext.navigate command navigates to that URL when it's already the current URL, I think that's such a case. Or what would cause that command to eventually succeed or fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so I added an extra clause to ensure that if the document didn't change and the hash didn't change, and there wasn't any state change, we still end up with a callback. Although now I write this I'm wondering if it's possible this breaks in the case of bfcache.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my worry about bfcache is unfounded, since different loads of the same URL will result in different documents, so something like A -> B -> A' (where A and A' have the same URL), and then back to A, will end up with a different document in the entry even though the URLs might match and no actual load occured.
WebDriver BiDi wants to invoke the 'traverse the history by a delta` algorithm, and get a callback whenever the algoritihm has run to completion, either by failing or by the navigation or state restoration completing. w3c/webdriver-bidi#109 is the WebDriver BiDi side of this change.
…ill be no load event. In particular if webdriver initiates a navigation to the current URL and it includes a fragment, this seems to be required to ensure the navigation completes on the WebDriver side.
e0fc9dc
to
9afc0d6
Compare
@jgraham Can I help make progress on this somehow? It's blocking w3c/webdriver-bidi#109, right? |
At this point, any work in this area should be done against the branch in #6315. Note that traversing can traverse multiple frames (and this is much more explicit in that branch), or maybe zero (if bfcache is not in effect and the server ends up with a 204/download). I imagine that might affect the "one callback, once" idea... |
I tried to resolve conflicts, but everything except the first 2-line change to link definitions conflicts. I think the best approach is to go hook-by-hook and find the right place to invoke it in the new spec:
|
OK, I've put everything where I think it needs to be. I'll do a self-review to point out things I'd like feedback on. |
<li><p>Invoke <span>WebDriver BiDi pop state</span> with <var>document</var>'s | ||
<span data-x="concept-document-bc">browsing context</span> and a new <span>WebDriver | ||
BiDi navigation status</span> whose <span data-x="navigation-status-id">id</span> is | ||
<var>document</var>'s <span data-x="concept-document-navigation-id">navigation id</span>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm skeptical that we should use document's navigation id here and below. We should instead pass it through as an argument to "update document for history step application".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I'm not sure these changes are needed, because we're inside of "update document for history step application". When that's called from "navigate to a fragment" it will be followed by invoking "WebDriver BiDi fragment navigated".
But when it's called from "apply the history step" it's much harder to follow all of the call sites. I think there are ways for "traverse the history by a delta" to end without invoking any BiDi callback. But more importantly that algorithm doesn't take a navigation id because I failed to carry that forward when resolving conflicts, see https://github.com/whatwg/html/pull/6921/files/9afc0d64707caa64ae750dc8117cbb2c4194a52a for @jgraham's original changes.
WebDriver BiDi wants to invoke the 'traverse the history by a delta`
algorithm, and get a callback whenever the algoritihm has run to
completion, either by failing or by the navigation or state
restoration completing.
w3c/webdriver-bidi#109 is the WebDriver BiDi
side of this change.
/browsing-the-web.html ( diff )
/history.html ( diff )
/infrastructure.html ( diff )
/browsing-the-web.html ( diff )
/infrastructure.html ( diff )