What is the issue with the HTML Standard?
commit a navigate event allows ongoing navigate event to change before deferred history traversal resumes
In the "traverse" + intercepted case, commit a navigate event appends session history traversal steps that later run “resume applying the traverse history step…”, instead of executing them immediately.
However, these steps are deferred without any guarantee that the same "ongoing navigate event" is still active when they run. In the meantime, inner-navigate-event-firing-algorithm may run for a new navigation and replace the "ongoing navigate event".
This creates a race where:
- The resumed traversal steps logically belong to one navigate event.
- But observe a different (or null) ongoing navigate event at execution time.
The spec does not appear to establish an ordering or invariant preventing this interleaving, which can lead to inconsistent behavior or incorrect assertions in later steps that assume the original event is still current.
Should the spec guarantee that:
A. The deferred traversal steps run before any new navigation can replace ongoing navigate event or
B. otherwise capture the relevant event state explicitly?
I don't think B is possible. Since we have race here, making the spec unimplementable (from a non-race/safety perspective), plumbing the state through, just means now we execute handlers in all sorts of weird ways.
It seems A is only the possible approach to solve this.
@noamr && @farre
What is the issue with the HTML Standard?
commit a navigate event allows ongoing navigate event to change before deferred history traversal resumes
In the "traverse" + intercepted case, commit a navigate event appends session history traversal steps that later run “resume applying the traverse history step…”, instead of executing them immediately.
However, these steps are deferred without any guarantee that the same "ongoing navigate event" is still active when they run. In the meantime, inner-navigate-event-firing-algorithm may run for a new navigation and replace the "ongoing navigate event".
This creates a race where:
The spec does not appear to establish an ordering or invariant preventing this interleaving, which can lead to inconsistent behavior or incorrect assertions in later steps that assume the original event is still current.
Should the spec guarantee that:
A. The deferred traversal steps run before any new navigation can replace ongoing navigate event or
B. otherwise capture the relevant event state explicitly?
I don't think B is possible. Since we have race here, making the spec unimplementable (from a non-race/safety perspective), plumbing the state through, just means now we execute handlers in all sorts of weird ways.
It seems A is only the possible approach to solve this.
@noamr && @farre