Open Bug 1245331 Opened 8 years ago Updated 2 years ago

Investigate how changing history state in iframe affects tab history

Categories

(Core :: DOM: Navigation, defect, P4)

defect

Tracking

()

ASSIGNED

People

(Reporter: arni2033, Assigned: smaug)

References

Details

Attachments

(6 files)

STR:
1. Save "relevant testcase" and extract all files in one folder
2. Open http://example.com/ in a new tab
3. Drag file "testcase - frames history.html" to the tab from Step 2
4. Wait 2 seconds

AR:  http://example.com/ is loaded in that tab instead of "testcase - frames history.html"
ER:  No history jumps (right?)


Notes:
(In reply to Olli Pettay [:smaug] from bug 1244517 comment 13)
> > I'm pretty sure this scenario is supposed to be wrong by Mozilla, but what's wrong exactly?
> Not sure what you mean here?
IMO: from the 1st sight the result here is unwanted, and iframes are "unaware" of what's happening with tab history (outside of iframe), so they are "not to blame"(?!). The rules for iframes to avoid such result are unclear, but I thought that there ARE some rules I'm unaware of (I'm still learning stuff). So I explicitly asked what the rules are not met.
If there're no such rules, they should be created, OR browser should have some sort of "protection"

I also suppose that any work to fix bug 1244517 and similar ones will be pointless if the decision on iframe history in general case will be "to handle each frame's history separately from tab history".
Flags: needinfo?(bugs)
So each browsing context has their separate session history, but things 
like history.go() deal with, per HTML specification, 'the joint session history'.
https://html.spec.whatwg.org/multipage/browsers.html#traverse-the-history-by-a-delta
In the testcase if you change the last go(-1) to go(-2), also chrome for example navigates to
example.com.

(Unrelated to this bug, but there is a very special case for session history during load event dispatch. In that case newly initiated normal loads become replace loads. )

I'm investigating why the testcase behaves differently than in some other browsers.
Assignee: nobody → bugs
Flags: needinfo?(bugs)
Does that mean that the testcase is bad in the way it uses history.go() at all?
Because (as I see it) no iframe can actually rely on window.history, because it can easily be modified by another iframe or the page itself in the middle of some important actions in iframe

But here we go, there're some ads frames out there that do use history.go().
I personally don't like the spec since it's not "reliable": it neither completely prohibit using history.go() in iframes, nor support some basic actions with history.go() in iframes which won't break the page
Of course I wouldn't argue about The Spec, but this is strange.
I'm having hard time to understand Chrome's behavior.

First @1 is pushed to session history, then we go back (@2). Then @2.5 is pushed (it is now the most recent current entry), then go(1) @3 is called, but since we're at the end of the joint session history, nothing should happen. Then @3.5 we do go(-1) so we're at the initial state, and then @4 we call go(-1) again and go to the previous page.
So as far as I see, Gecko follows the spec. 


Perhaps Majid could explains the behavior in Chrome.
I guess it does something when history.go(1) is called, but don't understand what and why.
(In reply to arni2033 from comment #2)
> Does that mean that the testcase is bad in the way it uses history.go() at
> all?
Not bad at all. It just shows how weird history API is even in the HTML specification.


> Because (as I see it) no iframe can actually rely on window.history, because
> it can easily be modified by another iframe or the page itself in the middle
> of some important actions in iframe
history.go() uses the joint history, so indeed it is very fragile API.
https://html.spec.whatwg.org/multipage/browsers.html#dom-history-go
https://html.spec.whatwg.org/multipage/browsers.html#joint-session-history


> But here we go, there're some ads frames out there that do use history.go().
> I personally don't like the spec since it's not "reliable": it neither
> completely prohibit using history.go() in iframes, nor support some basic
> actions with history.go() in iframes which won't break the page
> Of course I wouldn't argue about The Spec, but this is strange.
It is totally fine to argue that the specification is wrong or buggy. That happens all the time.
Specifications tend to be mostly just untested pseudo code (written often in prose) and contain bugs just 
like any non-pseudo code.
But changing History API has proved to be extremely regression prone. Even a small change to its behavior tends to
break many web sites. History API has after all been there in some form since Netscape 2 or 3.
(reminder to myself, there seems to be a spec bug where go(-1) may actually load some newer entry than what is a current entry in a browsing context. But getting late, will investigate tomorrow.)
majidvp, could you perhaps take a look at comment 3.
Flags: needinfo?(majidvp)
¡Hola!

Confirming based on https://bugzilla.mozilla.org/show_bug.cgi?id=1245331#c5

¡Gracias!
Status: UNCONFIRMED → NEW
Ever confirmed: true
This is not confirmed to be a bug.
This is confirmed to be a bug once it is clear we're doing something against the spec.
Status: NEW → UNCONFIRMED
Ever confirmed: false
Olli, Chrome behaves the same as Firefox here as explained in #3 but to see that you either need to load the test case from a web-sever or turn off web security (flag: "--disable-web-security"). 

I think you are correct that the odd behaviour is because history.go() works on the joint session history which is shared across all frames. This is how the spec is defined.


Here the explanation of why the flag is needed:

The issue is that, if you load the testcase from local file (i.e, file:// URL) then trying to pushState another 'file://' URL fails with an exception[1]. The failure is due to security limitations because Chrome treats such documents to have a unique origin preventing them from accessing each other.

[1] "Uncaught SecurityError: Failed to execute 'pushState' on 'History': A history state object with URL[..] cannot be created in a document with origin 'null'."
Flags: needinfo?(majidvp)
oh, very possible that I loaded the files locally. Thanks.
Might this bug be a cause of Firefox not working properly with Gitter? As demonstrated in the attached screen recording.

<https://gitter.im/>

Cross reference: 

Chat Frame not matching Room URL (#1410) · Issues · GitLab.org / gitter / webapp · GitLab
<https://gitlab.com/gitlab-org/gitter/webapp/issues/1410>

I'll attach four frames from the recording. 

In the third frame we have the first evidence of the mismatch – the title of the room within the window (within the frame) is not a match for the URL. 

In the fourth frame, the HTML title is also not a match for the URL. 

Also maybe worth noting: in the status bar, maybe three different parts of a CDN.
It seems when switching between chatrooms on gitter, the iframe's document.URL keeps the same. 

Say I start with 
https://gitter.im/w3c/web-platform-tests

window[0].document.URL gives me
"https://gitter.im/w3c/web-platform-tests/~chat#"

Switch to gitterHQ/gitter, the URL bar address becomes
https://gitter.im/gitterHQ/gitter

But window[0].document.URL is still
"https://gitter.im/w3c/web-platform-tests/~chat#"

That URL would be what Firefox tries to restore to the iframe on history navigation, so it ends up showing a wrong place. From what I found currently Firefox behaves as expected.

To reproduce it without extensions, set the preference "browser.sessionhistory.max_total_viewers" to 0 to disable bfcache, navigate to any gitter.im chatroom and switch to another chatroom, then navigate to a different website (say https://www.mozilla.com) and press back.
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Priority: -- → P4
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: