Skip to content
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

How javascript URLs interact with session history #6798

Closed
jakearchibald opened this issue Jun 23, 2021 · 8 comments · Fixed by #6315
Closed

How javascript URLs interact with session history #6798

jakearchibald opened this issue Jun 23, 2021 · 8 comments · Fixed by #6315

Comments

@jakearchibald
Copy link
Contributor

  1. https://iframe-session-history.glitch.me/
  2. Click "navigate to hash"

This creates the following session history:

Screenshot 2021-06-23 at 14 12 44

Then:

  1. Click "navigate to JavaScript URL"

Using terminology from the model I'm working on in #6315, Chrome seems to replace the document in the current document state. So:

Screenshot 2021-06-23 at 14 13 07

That means clicking back and forth does not change the document.

Whereas Firefox seems to replace the document state of the current entry:

Screenshot 2021-06-23 at 14 13 33

This means going back & forth takes you to a different document.

It also initially discards page-doc, so it'll reload when traversing back. But then you can go back and forth getting entries from the bfcache.

In both cases, if the js-doc is discarded or the entry is reloaded, /#foo is fetched.

Safari doesn't seem to support javascript: URLs returning strings.

I don't really have a preference of behaviour here. Safari's is simplest 😄

@jakearchibald
Copy link
Contributor Author

In Firefox, if I call document.write('hello') rather than clicking the JS link, then the outcome is more like Chrome, so it seems like the Firefox JS-link behaviour is a bit of an outlier.

@annevk
Copy link
Member

annevk commented Jun 23, 2021

When I run #1896 (comment) through Live DOM Viewer, the [Load javascript: "bar"] button is the only one that works in Safari for me.

I do like the idea of a javascript: URL navigation solely resetting document state. It would mean we have to change navigation to detect this earlier as currently javascript: URLs are processed from a task. It would also mean they end up not really navigating.

cc @smaug---- @mystor @zetafunction

@jakearchibald
Copy link
Contributor Author

It seems good to keep location.href = 'javascript:…' async though.

@domenic
Copy link
Member

domenic commented Jun 23, 2021

I do like the idea of a javascript: URL navigation solely resetting document state. It would mean we have to change navigation to detect this earlier as currently javascript: URLs are processed from a task.

Hmm, why would this be necessary? To be clear, the detection is synchronous currently; it just queues a task to do anything about it.

It would also mean they end up not really navigating.

Would this mean no longer going through "process a navigate response" and all that it entails? That seems like a somewhat scary change.

@annevk
Copy link
Member

annevk commented Jun 23, 2021

Yeah, I think you're right that there is a lot to be said for how Firefox goes about this. I guess the initial question is to what extent others would be willing to adopt that.

@jakearchibald
Copy link
Contributor Author

Some thoughts after an internal chat:

Chrome's current model, where it changes the document across multiple history entries… the only other thing I'm aware of that does that is refresh.

Firefox's current model, where it changes the document state of the current entry only, is more like location.replace().

@domenic
Copy link
Member

domenic commented Jun 23, 2021

Since it seems like this might lead to respeccing JavaScript URL navigation in general, probably the biggest constraint to keep in mind is the one discussed in #1896 which is about real compat problems Gecko has encountered.

@jakearchibald
Copy link
Contributor Author

Some more observations:

  1. Navigate via POST.
  2. Navigate to javascript:'hello'.
  3. Refresh.

Chrome: Prompts to resubmit data.
Firefox: Reloads URL as GET.

The good news is both cases are consistent with the model. By changing the document within the document state, Chrome leave the document state's resource untouched, which is the POST data.

Firefox replaces the history entry with a new one with a new document state, so reloading is just a GET. Pressing back takes you back to a page that required a POST submission.

Similarly:

  1. pushState({ foo: 'bar' }, '', '/yo').
  2. Navigate to javascript:'hello'.
  3. Check history.state.

Chrome: history.state is { foo: 'bar' }.
Firefox: history.state is null.

Again, this is consistent.

I have a slight preference for what Firefox does, since it's more like a replacement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

3 participants