- From: Majid Valipour <majidvp@chromium.org>
- Date: Tue, 07 Apr 2015 12:47:57 +0000
- To: WHATWG <whatwg@whatwg.org>
Re-sending my response with my member email address to ensure it is included in the mailing list archive. Sorry about duplication :(. ---------- Forwarded message --------- From: Majid Valipour <majidvp@google.com> Date: Wed, Mar 25, 2015 at 8:22 PM On Wed, Mar 25, 2015 at 4:32 PM Jonas Sicking <jonas@sicking.cc> wrote: > Is this really something we should tie to the pushState/replaceState API? > > It seems like websites that lazily add more content as the user scroll > down, like the facebook feed or twitter feed, might not use > pushState/replaceState, but would still like to handle restoring > scroll position themselves. > > / Jonas > > History spec models history entry as having two types of states: 1)user state, 2)user agent defined state. Scroll position is part of the user agent defined state[1] which may also include form data, zoom factor, etc. During history navigation when an entry is poped, the user agent defined state is automatically restored while the application is responsible for restoring user state. Both history.pushState() and history.replaceState() are really meant to allow Javascript to manipulate history entries. They are currently limited to modifying only the user state, url, and title of an entry. I think using these methods for controlling user agent defined states in addition to user state is a natural extension of their functionality and consistent with existing history model where an entry contains two types of state. The current proposal only suggests a control knob for scroll position but I can definitely imagine providing additional knobs for other parts of user agent state such as form data, zoom factor, etc. The dictionary is specifically used to provide this flexibility. The example of sites that you mentioned can simply use a replaceState. This does not require them to opt into fully managing their navigation using pushState or creating new URLs client side. window.addEventListener('popstate', s => { history.replaceState(null, null, null, {restoreScroll:false}) }); Note that the browser always creates a default history entry on page load. In this case, history.replaceState updates this default history entry and changes its default user agent state to no longer have scroll restoration. This becomes even more elegant if we adopt the above proposal to pass a single dictionary i.e. history.replace({restoreScroll:false}). [1] "Each session history entry consists, at a minimum, of a URL, and each entry may in addition have a state object, a title, a Document object, form data, a scroll position, and other information associated with it." > On Wed, Mar 25, 2015 at 6:54 AM, Anne van Kesteren <annevk@annevk.nl> > wrote: > > On Thu, Mar 19, 2015 at 6:31 PM, Majid Valipour <majidvp@chromium.org> > wrote: > >> partial interface History { > >> void pushState(in any data, in DOMString title, in optional DOMString > >> url, in optional StateOptions options); > >> void replaceState(in any data, in DOMString title, in optional > DOMString > >> url, in optional StateOptions options); > >> readonly attribute StateOptions options; > >> }; > >> > >> dictionary StateOptions { > >> Boolean restoreScroll = true, > >> } > > > > The only suggestion I have is that instead of having four-argument > > methods we might want to consider introducing two new methods that > > take a dictionary. E.g. history.push() and history.replace(). Giving > > the page more control over the scroll position when navigating makes > > sense to me. > > > > > Adding two new methods that take a dictionary provides a cleaner API. I also think replace() and push() better capture their intended use which is to manipulate the history *entry* as opposed to only the entry's user state. In fact current method names are not exactly accurate as they manipulate not only the user state but also its title, and URL. My only concern is to make sure that these new methods replace history.pushState() and history.replaceState() in the spec. Otherwise I feel the benefits of a cleaner API is not worth the additional confusion of having different methods for doing (almost) the same thing. Thanks Majid
Received on Tuesday, 7 April 2015 12:48:25 UTC