Open Bug 1059382 Opened 6 years ago Updated 5 years ago

History API bug -- window.history.state should not fire popstate after load.


(Core :: DOM: Navigation, defect)

25 Branch
Windows 7
Not set





(Reporter: agamemnus, Unassigned)


User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0 (Beta/Release)
Build ID: 20131025151332

Steps to reproduce:

See also:

Examine the code below.

<!DOCTYPE html>
<html lang="en">
  <script type="text/javascript">
   var history_control = new history_control_object ()
   function history_control_object (new_state) {
    window.addEventListener ('popstate', function (evt) {console.log (evt.state)})
    history.replaceState ({url: 'apple'}, "")

Actual results:

Going to e.g., then the page with the code below, then back to and back again to this page, should not fire the onpopstate event.

Expected results:

The onpopstate event is fired.

Detail: this bug occurs because the HTML5 History API spec was not followed to the letter.

'[1] (step 12-14 in particular)'

"12) Let state changed be true if the Document of the specified entry has a latest entry, and that entry is not the specified entry; otherwise let it be false."

1) The document being navigated to is called the "specified entry".
2) The document being navigated from is called the "latest entry".
3) Steps 12-14 discuss the "specified entry" and the "latest entry", not the last entry. Chrome, Firefox, and IE11 all have this bug where the word "last" is confused for "latest".
Ugh. I meant that it is expected that the onpopstate event is NOT FIRED, but the actual is that it IS... can anyone edit the text above?
Component: Untriaged → Document Navigation
Product: Firefox → Core
> Chrome, Firefox, and IE11 all have this bug where the word "last" is confused for
> "latest".

It's very possible that the spec simply got changed after they all implemented it... or that it was agreed to be changed and wasn't.  There have been a bunch of flip-flops in the spec about when popstate should or should not fire, and it's not clear to me whether the current text reflects the last thing that was agreed on...
Flags: needinfo?(jonas)
If the spec was changed, it was definitely for the better as the current implementation, where a "trick-move" creates unexpected behavior, is not really optimal.
Is it at all possible for anyone to edit the initial text to say that the expected results are that the onpopstate event is not fired? I feel I might have to do-over here as it could be too confusing. :\
Bug comments aren't editable.
I believe we did several rounds of fixing the spec. So it did indeed change over time. It makes me very sad if the final spec was still not getting this stuff right.

The proper behavior should be that popstate should only fire when transitioning between two session-history entries that use the same Document. Any time that the user presses back/forward and we switch Document, that should never fire popstate.

So popstate is an event for indicating session-history traversal within a Document. pageshow/pagehide (as well as load/unload) are events for indication session-history traversal across Documents.

But there's lots of complex edge cases. The code in comment 0 triggers one of them. It appears to be mutating the session-history entry while we are still loading that entry. But I agree that I would not expect popstate to fire there.

Also adding Olli here since he's a docshell peer where all of this code lives.
Flags: needinfo?(jonas)
Thank you. I indeed cannot reproduce the bug if I add a delay to the thing -- I think.
I went ahead and filed
There seem to be a cluster of (probably related) issues affecting Firefox in that case.
You need to log in before you can comment on or make changes to this bug.