On 08/11/2015 05:08 PM, Majid Valipour wrote:
According to HTML5 spec persisted user state (scroll, scale, form values,
etc)
should be restored before dispatching popstate event. (See steps 9 and 14 in
history traversal algorithm[1]).

Gecko and IE follow the spec order for scroll position but in Blink and
WebKit
the order is reversed specifically:
1. 'popstate' event dispatched
2.  scroll position restored  (only if user has not scrolled)
3. 'hashchanged' event dispatched (only if hash changed)

We have learned that single-page applications depend on this reverse order
to
implement a simple workaround to override automatic scroll position
restoration with their own application specific one. The workaround is to
record the scroll position on (1), and restore it on (3). In fact, a recent
change in the Blink's order [2] broke major sites that depended on this
reverse order and we had to revert it.

At the same time, this means that the scroll restoration for any sites that
uses this workaround does not work well in Firefox and IE. I have heard
examples of this from Mozilla engineers.

Indeed. There is a patch ready to implement popstate, scroll restoration, 
hashchanged
behavior in Gecko. That fixes Github back-forward for example.
But the patch didn't land because of being against the spec.


There are two options to get an interop solution:
Option 1. Change the spec to reverse order, making the workaround supported
officially.
Does anybody know if there was any specific reasons behind the current
order?

If we do this, I think popstate event should also become cancelable, so that 
web page could easily
prevent  scrolling (in that case there wouldn't be need to play with 
scrollRestoration always)


Option 2. Keep the spec order, and have Blink and Webkit match it.
This depends on having a reliable methods for controlling scroll restoration
so that current workaround users can switch to it. Fortunately
history.scrollRestoration [3, 4] provides exactly this alternative and we
are
working toward shipping it in blink in the next release [5].



I prefer option 2 mainly because the current order has the advantage that
when
'popstate' is dispatched the application is guaranteed that the user-agent
is
done with restoring the state, and current values are reliable. Furthermore,
the workaround has multiple other limitations:
     - scroll position needs to be restored synchronously otherwise a jump is
       visible
     - requires apps to create artificial hashchange events

Have I missed any other solution?

Majid

[1]
https://html.spec.whatwg.org/multipage/browsers.html#traverse-the-history
[2] https://crbug.com/474579
[3]
https://lists.w3.org/Archives/Public/public-whatwg-archive/2015May/0063.html
[4]
https://html.spec.whatwg.org/multipage/browsers.html#traverse-the-history
[5] https://crbug.com/444094


Reply via email to