-
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
Expose history.index
in addition to history.length
#2710
Comments
@majido thoughts from Chrome's perspective? |
Just wondering, what would the benefit of this be over just adding your own index to the history state? Local Storage could likely be used for this purpose as well. Knowing the actual history index doesn't seem all that useful because there could be any number of unrelated history states before and after the ones you are interested in. |
@Yay295 Significant benefits: the state in the history stack is very fragile - anyone can overwrite it. In fact the conflicts between app routes and other history uses are very common. History state in the stack is also very hard to use. It's much easier to make judgements about |
I can't immediately see problems with this from Chrome's perspective (we already propagate the history index to each renderer process, it's just not exposed to the web platform). In terms of privacy/security, |
I added some more details in the description to highlight the current difficulties with history API. |
Well, you cannot read the latter, but the former is updated in a top-level document when a cross-origin child document navigates, as history is shared across documents, right? |
@annevk |
@natechapin and I are ready to make this change in Chrome. |
Please see https://whatwg.org/working-mode#additions. I don't understand why WICG would be involved here. What this really needs is interest from more than one implementer. Maybe @smaug---- has thoughts? |
@cdumez Any thoughts from WebKit? If it's true that this doesn't have any new privacy implications above exposing |
I agree that this would be a huge benefit to web devs but I think it doesn't go far enough. I think there should be a second unique id in addition to the index. This is because I think devs should be able to differentiate between replace'd states from their original push. Also -- would this index max out at 50 like the history.length? Would the same page then have a different index if it were stored? For instance:
In that case they'd only be indexes into a history "slice" but not really absolute indexes, which makes them about as useful as history.length (which, in my opinion, isn't useful at all). The only new information such a limited index would expose is direction in popstate events. Which don't get me wrong, would be a bit more information than we have today. |
The spec doesn't limit |
I misremembered - it's actually 50. for (let i = 0; i < 100; i++) { Will log the first 50 and then repeat at 50. |
@RByers I don't see anything particular bad with supporting history.index in WebKit given that we already expose history.length. It also seems like it would be a added with minimal effort. cc @geoffreygaren in case he has a different opinion. |
@tbondwilkinson @Yay295 "Huh" on |
@tbondwilkinson And I agree, more things could probably be done about history. This is just a low-effort idea that could simplify many use cases. |
No objection. If we do discover a privacy or security problem, we can consider mitigations like per-domain history lists. |
@cdumez @geoffreygaren thanks for taking a look! Should we take this as "implementer interest" from WebKit, and start working on the spec/tests? |
Sure. |
Awesome! It looks like the spec will be pretty short; something like "return the index of the current entry in the session history within the top-level browsing context's joint session history." Plus, throwing if not fully active, like all other I can do that spec PR easily. But writing the web platform tests will be the real work, especially given all the iframe cases, nested iframes, multiple iframes contributing to form a single joint session history, non-fully-active Documents, and such. I won't have time for that for a few weeks, but maybe @spanicker and @natechapin can work on that as part of their change to Blink? |
PR posted: #2944. Review appreciated! |
It's worth noting that history.length can decrease in Firefox. For example, open the following link in Firefox: http://freesamael.github.io/gecko/shistory/length-change/page1.html Wait for Page 1 to load iframe 1/2/3/4/5, and then follow the links to Page 2/3/4/5. If you don't have any addon causing bfcache being disabled (such as lastpass), you'll notice that history.length decreases when navigating from Page 4 to Page 5. This is because we're binding the session history entries of dynamically added subframes to the lifetime of the frame element, so when bfcache drops the document, all the associated dynamic subframe entries are removed as well. In addition, gecko would merge duplicated root entries in this case, so history.length would change. This same behavior will apply to history.index if we implement it. For a single page application, this indicates the start index can change in some cases. I'm not sure web developers are able to deal with it, if they start relying on history.index. |
Reopening to make sure the above comment gets considered. cc @smaug---- |
Last time I checked, also IE/Edge shrink session history when iframes are removed. But I'm not sure whether removing entries changes much here. The current session history entry has still an index in the session history transaction list. |
I'm not quite sure what the use case would be, but if a single page application stores a |
That is very true. Should we expose some kind of start/end indexes. I mean, startIndex would be the initial page load and endIndex the last pushState/fragmentNavigation |
But yeah, I think .index as such shouldn't be added to the spec. |
What's the advise for web developers to deal with this now? |
I've already posted above but just reiterating that index and length are
both useless for anything but the simplest checks and that's something that
should definitely be fixed.
I spent a long time creating workarounds for Google search's interface with
the history API and search isn't the only google product that has a wrapper
to provide extra utility on top of history that could be implemented by the
browser.
…On Thu, Aug 31, 2017 at 6:03 PM Dima Voytenko ***@***.***> wrote:
@freesamael <https://github.com/freesamael>
For a single page application, this indicates the start index can change
in some cases. I'm not sure web developers are able to deal with it, if
they start relying on history.index.
What's the advise for web developers to deal with this now?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2710 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ACRDfmNoIN241Zkkai-ZO1JNLSvGyVVRks5sdtlPgaJpZM4NoHAX>
.
|
@tbondwilkinson To be fair, the suggested I'll be happy to see a more universal and mature Web History API. But I think this should be developed outside of this bug'd scope. I don't know if there's an effort to create a better API at this time. If you know of any, please let me know. |
@tbondwilkinson, et al, I took a stub and created a bigger-scope #2992. I'd still like to get a definitive on on the |
What if we add something similar to In this way things are more controllable to web developers, since the startIndex is always 0 and length only counts session history entries inside the single page application. Would that be helpful? |
@freesamael Not sure. I'm a bit skeptical of moderate changes to this API. I feel like it either needs to be a major review (e.g. #2992) or some minor addons to make current API slightly easier. Specifically with your idea of
|
One issue with the History API in the spec is that it doesn't map at all to what browsers implement. So modifying the API in the spec may end up revealing that mismatch with implementations. |
@dvoytenko I image reloading wouldn't be a problem (a normal reload wouldn't clear length/index; force reload would both clear the length/index and bring user to the initial view) but yes the iframe issue remains. I don't have better suggestions for now :/ |
I'm going to close this issue for now. |
It seems that |
An integer
history.index < history.length
would be a big simplification for many history-based routers. Currently, many of these push/replace a "fake" first state when the app starts up only to record such an index.There might be some privacy/security concerns, but I can't think of any negatives that are not already possible with
history.length
,history.back()
, etc.History state is used often for view-to-view routing in a single-page webapps. But it's also used for simpler features, such as closing popups and dialogs on back button. Doing this with the current history object is relatively hard. An approach I've run across a lot goes something like this:
history.replaceState({index: 0})
replaceState
andpushState
APIs to ensure that no one can accidentally overwrite this{index: X}
.pushState
method is patched to increment{index: index + 1}
for each push operation.popstate
event is is ambiguous: it could be due to link navigation or due to back/forward buttons. Thus, the app would keep{index: X}
if available, or would assume a fragment navigation and would set{index: index + 1}
.This is all to be able to reconstruct
index
on anypopstate
operation. It's trivial then to do operations such as closing a popup/dialog and other history-based functions. This is best effort since a user can go back or forward several steps or iframe can push/pop state - which could easily get to the state that the app cannot track. In other words,{index: X}
and the real current index could easily go out of sync.Ultimately, what a system like this does - it emulates
history.index
property that I request here. Having this property would simplify things a lot and avoid patching the existing API.The text was updated successfully, but these errors were encountered: