Re: [whatwg] JavaScript Hovers and Back Button

2016-04-14 Thread Majid Valipour
> A very common abuse is that when pulling the mouse to hit the back
> button because you are not interested in a page, a hover comes up and
> when the hover comes up, the back button no longer works.

Does 'hover' refer to modal dialog e.g., window.alert?
That is the only way I know that you can block a user to click back button.
Here is a simple page that does this: http://jsbin.com/fuwosaxefa

That behavior is a side-effect of how a browser may decide to implement
modal dialog which is dependent also on the OS. I tested a few browsers on
Linux & Mac and this is what I found:

*Mac*
Firefox, Chrome, Safari: Navigation buttons are usable while modal dialog
is shown.
*Linux*
Chrome: Navigation buttons are block while modal dialog is shown.
Firefox: Navigation buttons remain usable.
*Windows*


Perhaps this is worth a non-normative note in the spec in "user-prompt"
section [1]

[1] https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts

Majid

On Thu, Apr 14, 2016 at 4:38 AM Delfi Ramirez  wrote:

> Agree.
>
> May it be done within the History API spec?
>
> Just wondering.
>
> ---
>
> Delfi Ramirez
>
> My digital signature [1]
>
> +34 633 589231
>  del...@segonquart.net [2]
>
> twitter: delfinramirez
>
>  IRC: segonquart Skype: segonquart [3]
>
> http://segonquart.net
>
> http://delfiramirez.info
>  [4]
>
> On 2016-04-13 21:44, Michael A. Peters wrote:
>
> > It needs to be made very clear as a web standard that no JavaScript
> action can disable UI functions such as the back button.
> >
> > A very common abuse is that when pulling the mouse to hit the back
> button because you are not interested in a page, a hover comes up and when
> the hover comes up, the back button no longer works.
> >
> > This is a browser UI issue but it needs to specified that browsers must
> not disable the back button in response to JavaScript. The web is enough of
> a cesspool as it is.
>
>
> Links:
> --
> [1] http://delfiramirez.info/public/dr_public_key.asc
> [2] mail:%20del...@segonquart.net
> [3] skype:segonquart
> [4] http://delfiramirez.info
>


Re: [whatwg] Order of popstate event and scroll restoration - interop issue

2015-08-13 Thread Majid Valipour
On Wed, Aug 12, 2015 at 11:47 PM Jonas Sicking  wrote:

> On Wed, Aug 12, 2015 at 3:31 AM, Olli Pettay  wrote:
> >> 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)
>
> Is there an advantage to having two ways to prevent scoll restoration?
>
I think it will be confusing. Note that history.scrollRestoration works
also for cross-document history navigation which cannot be done with
popstate.

Majid


Re: [whatwg] Order of popstate event and scroll restoration - interop issue

2015-08-12 Thread Majid Valipour
>
> > Does anybody know if there was any specific reasons behind the current
> > order?
>
> Are the reasons you discovered yourself not sufficient?

They are pretty compelling but was wondering if there is anything I am
missing.


> I guess the
> question is whether Chrome can still change at this point and what
> will happen to Safari.
>
> I am optimistic that this is possible to fix in Chrome once a widely
supported, inter-operable, and reliable alternative solution is in place.
It requires evangelism and will take some time to deprecate. AFAICT the
workaround use is still limited and they have considerable drawbacks which
helps drive their deprecation in favor of a better solution.

As for what will happen to Safari, I am also curious to find out as well. I
have filed a webkit bug  to
see if they are interested in implementing scrollRestoration. I am waiting
to see if I there is enough traction there to be hopeful.

Majid


[whatwg] Order of popstate event and scroll restoration - interop issue

2015-08-11 Thread Majid Valipour
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.

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?

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


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-07-13 Thread Majid Valipour
On Sun, Jul 12, 2015 at 1:51 PM Anne van Kesteren  wrote:

> On Sun, Jul 12, 2015 at 7:49 PM, Jonas Sicking  wrote:
> > I think we've already made that assumption given that history.state
> > already relies on this.
>
> Good point. I'm still somewhat skeptical of introducing new objects
> just for the purpose of grouping some properties if they don't serve a
> purpose on their own.
>

It is only used as way to group properties (perhaps similar to
ValidityState?) and to keep History interface clean and stack-like. If that
is not valuable enough to introduce a new interface then putting these on
the History interface is fine.

Majid


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-07-10 Thread Majid Valipour
On Mon, Jun 29, 2015 at 5:20 PM Jonas Sicking  wrote:

> FWIW I still prefer an API like
>
> history.scrollRestoration = 'manual';
>
> The main reason is that it seems to me that pushState/replaceState has
> a largely orthogonal set of use cases that it tries to address from
> scroll restoration. So I suspect that grouping the two together will
> create awkwardness in the API in the future.
>
> But I don't have time to chase this issue.
>
> / Jonas
>
> Jonas,

After some offline discussion with Rick, we have decided to converge to
your preferred API. I hope this addresses your concern about potential
future awkwardness and help make adoption easier.

I have updated the proposed spec
 to
reflect this change. The semantic of history.options.scrollRestoration is
based on our previous discussion in this thread [1]. It short, it does not
change any previous entries and navigating across documents resets its
value so it only applies to entries created for the same document.

Minor bikeshed:
I have put scrollRestoration on history.options instead of directly history
itself in order to use history.options as an interface to contain any other
restoration related attributes which have similar semantics (e.g., recorder
scroll position, scale restoration, recorded scale).

Majid

[1]
https://lists.w3.org/Archives/Public/public-whatwg-archive/2015Apr/0123.html


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-06-29 Thread Majid Valipour
On Wed, May 20, 2015 at 11:00 AM Majid Valipour 
wrote:

>
> It will be great if we could make progress on getting a consensus on the
> API so that we can actually ship this feature. I think we have narrowed it
> down to two main options:
>
> 1- Setting scroll options using history.{push, replace}State. This is what
> we have implemented in chrome (see IDLs above).
>  history.replaceState(history.state, '','', {scrollRestoration:
> 'manual'})
>
> 2- Setting scroll options directly on history object. This is what Jonas
> has proposed. Per our earlier discussions in this thread it should be
> possible to define the semantics such that we get per-entry control.
> history.options.scrollRestoration = 'manual'
>
> Both  are equally powerful with #1 being better for complex situations
> where different entries may need to have different scroll restoration
> behaviour  and #2 being better for simpler case where the application wants
> the same scroll restoration for all its entries. As an experiment, I have
> created a small script
> <https://gist.github.com/majido/4cbd0b68d742de319aeb#file-scroll-restoration-global-flag-js>
> that implements #2 on top of #1.
>
> Jonas prefers #2. I am partial to #1. Spec editors (Anne, Ian, Simon,
> Robin):
> Do you have a preference here?
>

Anne, Ian, Simon, Robin,

Do you have a preference one way or another for either of the above APIs?

I have a git repo <https://github.com/majido/scroll-restoration-proposal> where
I have spec'd the first option
<http://majido.github.io/scroll-restoration-proposal/history-based-api.html>
(as
implemented in Chromium) and am tracking issues against it. Unless there is
a strong preference against #1, I feel it is reasonable to try to ship it.

Majid


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-05-20 Thread Majid Valipour
Hi all,

I wanted to give you an update on the progress. I have implemented this in
Chromium in version 44 behind a runtime enabled experimental feature flag
. Here are the
relevant IDL files for the API:
- StateOptions.idl

- History.idl


It will be great if we could make progress on getting a consensus on the
API so that we can actually ship this feature. I think we have narrowed it
down to two main options:

1- Setting scroll options using history.{push, replace}State. This is what
we have implemented in chrome (see IDLs above).
 history.replaceState(history.state, '','', {scrollRestoration:
'manual'})

2- Setting scroll options directly on history object. This is what Jonas
has proposed. Per our earlier discussions in this thread it should be
possible to define the semantics such that we get per-entry control.
history.options.scrollRestoration = 'manual'

Both  are equally powerful with #1 being better for complex situations
where different entries may need to have different scroll restoration
behaviour  and #2 being better for simpler case where the application wants
the same scroll restoration for all its entries. As an experiment, I have
created a small script

that implements #2 on top of #1.

Jonas prefers #2. I am partial to #1. Spec editors (Anne, Ian, Simon,
Robin):
Do you have a preference here?

As a side note, I think it is possible to combine both these in a single
API. I just don't feel if the benefit is large enough to justify the added
complexity. Simply take #1 and remove "readonly" limitation from
'history.options' and make it the effective default options value for the
page (with the semantic we discussed earlier). Both pushState and
replaceState will continue to take an optional options parameter that can
overrides values set in history.options.

Regards
Majid


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-05-07 Thread Majid Valipour
On Thu, Apr 9, 2015 at 3:05 PM Ian Hickson  wrote:
>
> Also, I'd recommend an option name that suggests more strongly that the
> author is expected to restore the position themselves, rather than just
> that the position shouldn't be restored. For example, calling it something
> like "willRestoreScrollPosition" (defaulting to false, meaning the UA
> should do it).
>

How about:
enum ScrollRestoration { 'auto', 'manual'};
defaulting to 'auto' meaning UA should do it.

I think 'manual' and 'auto' work better here. I was trying to use
'willRestoreScroll' but it is confusing as it does not convey who will
restore the scroll position. auto|manual makes this clear and the advantage
of enum is that we can add other values in future too if needed.

Majid


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-04-29 Thread Majid Valipour
On Tue, Apr 28, 2015 at 3:24 PM Jonas Sicking  wrote:

> On Tue, Apr 28, 2015 at 9:16 AM, Majid Valipour 
> wrote:
> > On Mon, Apr 27, 2015 at 9:54 PM Jonas Sicking  wrote:
> >>
> >> Jumping in at the end here.
> >>
> >> As I've said before, I like the general idea of giving pages more
> >> control over scroll restoration, but I don't think we should tie this
> >> to pushState()/replaceState()/onscroll.
> >>
> >> My proposal is instead that we add an API like
> >>
> >> history.restoreScroll = boolean;
> >
> >
> > Interesting. I believe Simon has also proposed a similar API for which
> you
> > can find my original objections here.
> >
> > One of my objections was that any proposed API should give developers
> > control of scroll restoration per individual history entry. Initially I
> > assumed a single boolean flag cannot provide that control but now I
> believe
> > what you are proposing here can in fact provide per-entry control. More
> on
> > this later.
> >
> > My other objection was that because scroll restoration behaviour is
> > ultimately tied to a specific history entry, the API to control it should
> > reflect this underlying fact. IMO a flag on history object hides this
> fact
> > while original proposal does not.
> >
> > I understand that for pages that do not create any state other than their
> > default initial state (e.g., infinite scrollers) setting
> > history.restoreScroll is simpler than using
> > history.replaceState({restorScroll: false}). But I think this additional
> > complexity is not prohibitive and can be justified when the upside is an
> API
> > that better explains the underlying behaviour and is simpler for pages
> that
> > do create multiple states using history.pushState.
>
> I agree that the difference between
>
> history.restoreScroll = false;
> and
> history.replaceState({restoreScroll: false});
>
> is not that big and mainly comes down to taste. I like the former more.
>
>  I agree it comes down to taste. In fact there are three API proposed:
1. Using a fourth optional dictionary parameter on {push|replace}State:
 backward compatible and consistent.
2. New history.push, history.replace methods accepting a bool flag: cleaner
API that allows us to clean minor old warts such as making 'url' required
and 'title' optional (or even remove it).
3. Options dictionary on history object that contain boolean flags
(history.options.restoreScroll): Simplified usage for pages that don't use
pushState API.

There has been support for all three in particular Spec editor favoring #1.
Soon I am hoping to get feedback for #1 by implementing it in Blink behind
a runtime flag.

Note that all three options are extensible enough to allow exposing
recorded scroll position in future.

>> This property would default to true. Whenever pushState() is called,
> >> or the user navigates away from the current page, for example by
> >> clicking a  the value of history.restoreScroll is copied
> >> into the session-history-entry data that the browser keeps internally.
> >> As soon as the new session-history-entry is created, restoreScroll is
> >> set to true again.
> >
> > So history.restoreScroll is copied into current history entry anytime a
> new
> > history entry is created (or replaced). If my reading is correct then
> this
> > makes sense and it can give per history entry control. The value of
> > history.restoreScroll is reset to its default when a new document is
> loaded.
> >
> > Consider this case where page A uses pushState once and then navigates to
> > page B. This creates three history entries: 2 for A and one for B.
> >
> > A  -->  Ai  (*)   ==> B
> > where:
> > -->  pushState
> > ==> navigation to new page
> > (*) history.restoreScroll is set to 'false'
> >
> > This is what I think should happen:
> > on A load:  history.restoreScroll is reset to default value: TRUE.
> >   history entry is created for A.
> >
> > on -->:current entry (A) is updated with current restoreScroll:
> TRUE
> >history entry is created for Ai
> >
> > on (*):  history.restoreScroll is set to 'FALSE'.
> >
> > on ==>:current entry (Ai) is updated with current restoreScroll:
> > FALSE
> >
> > on B load:  history.restoreScroll is reset to default value: TRUE
> >history entry for B is created.
> >
> > A gets TRUE
> > Ai gets FALSE
> 

[whatwg] R: Proposal: Allow disabling of default scroll restoration behavior

2015-04-28 Thread Majid Valipour
r both history and
non-history navigations (e.g., same page being loaded as a result of
clicking back button or a link).

Providing scroll position is nice to have but not required. I think it
requires additional spec work to exactly define the behaviour of scroll
restoration across different browsers. Right now different vendors have
different behaviour when it comes to restoring scroll position for iframes,
and inner scrollables etc. So it is not really clear how exactly this
'scroll position' should look like.

Getting this boolean flag should not be blocked on providing scroll
position.

But history.restoredScrollPosition would reduce boilerplate code.
> Also, using sessionStorage is somewhat complex to do correctly given
> that the user might visit the same URL multiple times in the same
> session.

(As an aside, it would be great if we had something like
> sessionStorage, but specific for a given page. Right now
> sessionStorage seems to make it very hard to store page specific state
> unless I'm missing something obvious?)


Using sessionStorage for page storage requires that developers be aware
that it is shared by the whole domain in order to avoid making certain
mistakes. A per page storage makes things simpler but I am not sure about
its implications.

Majid


> / Jonas
>
>
> On Thu, Apr 23, 2015 at 3:25 PM, Majid Valipour 
> wrote:
> > On Tue, Apr 21, 2015 at 4:58 PM Ian Hickson  wrote:
> >
> >> On Sun, 12 Apr 2015, Anne van Kesteren wrote:
> >> > On Thu, Apr 9, 2015 at 9:05 PM, Ian Hickson  wrote:
> >> > > I'd strongly recommend against adding new methods. It'll mean we now
> >> > > have two different ways to do the same thing, which means more bugs,
> >> > > which means less interoperability, more confusing behaviour for
> >> > > authors, more to document, etc.
> >> >
> >> > If the existing method didn't have the flaw with the title argument I
> >> > wouldn't have suggested it. Also, since they both built upon the same
> >> > primitive I think we'd be okay in the bugs and interop department.
> >>
> >> You are more optimistic than I. In any case, I strongly recommend
> against
> >> such redundancy.
> >>
> >>
> >> On Wed, 15 Apr 2015, Majid Valipour wrote:
> >> >
> >> > Actually URL is optional in current spec and it defaults to current
> URL.
> >> > Why is this suboptimal?
> >>
> >> Because it means you can't bookmark the state or share the state,
> >> reloading the page loses the state, etc.
> >>
> >>
> >> > In anycase If making URL required is a goal then it is best done by
> >> > introducing a new method to avoid breaking compatibility.
> >>
> >> Why is that better?
> >>
> >> Changing the optional third argument to become required on the existing
> > methods will break any call site that is not passing it. This is a non
> > trivial compatibility issue which does not exists with a new method.
> >
> >
> >>
> >> > I personally find a dictionary with only optional members which have
> >> > appropriate defaults to be very convenient.
> >>
> >> I don't disagree... for new APIs. But when we already have an existing
> >> API, maintaining consistency and lack of redundancy IMHO trumps pretty
> >> much everything else, if you want the end result to be usable.
> >>
> >> A lot of the pain with using the Web's APIs is the inconsistency and
> >> redundancy that is rampant throughout.
> >>
> >
> > I understand the desire for maintaining consistency and reducing
> > redundancy. On the other hand a new API will allow fixing some existing
> > warts. I can see merits in both arguments. I am happy to defer the API
> > decision to spec editors.
> >
> > I created the W3C bug for this proposal:
> > https://www.w3.org/Bugs/Public/show_bug.cgi?id=28553
> >
> > Majid
>


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-04-23 Thread Majid Valipour
On Tue, Apr 21, 2015 at 4:58 PM Ian Hickson  wrote:

> On Sun, 12 Apr 2015, Anne van Kesteren wrote:
> > On Thu, Apr 9, 2015 at 9:05 PM, Ian Hickson  wrote:
> > > I'd strongly recommend against adding new methods. It'll mean we now
> > > have two different ways to do the same thing, which means more bugs,
> > > which means less interoperability, more confusing behaviour for
> > > authors, more to document, etc.
> >
> > If the existing method didn't have the flaw with the title argument I
> > wouldn't have suggested it. Also, since they both built upon the same
> > primitive I think we'd be okay in the bugs and interop department.
>
> You are more optimistic than I. In any case, I strongly recommend against
> such redundancy.
>
>
> On Wed, 15 Apr 2015, Majid Valipour wrote:
> >
> > Actually URL is optional in current spec and it defaults to current URL.
> > Why is this suboptimal?
>
> Because it means you can't bookmark the state or share the state,
> reloading the page loses the state, etc.
>
>
> > In anycase If making URL required is a goal then it is best done by
> > introducing a new method to avoid breaking compatibility.
>
> Why is that better?
>
> Changing the optional third argument to become required on the existing
methods will break any call site that is not passing it. This is a non
trivial compatibility issue which does not exists with a new method.


>
> > I personally find a dictionary with only optional members which have
> > appropriate defaults to be very convenient.
>
> I don't disagree... for new APIs. But when we already have an existing
> API, maintaining consistency and lack of redundancy IMHO trumps pretty
> much everything else, if you want the end result to be usable.
>
> A lot of the pain with using the Web's APIs is the inconsistency and
> redundancy that is rampant throughout.
>

I understand the desire for maintaining consistency and reducing
redundancy. On the other hand a new API will allow fixing some existing
warts. I can see merits in both arguments. I am happy to defer the API
decision to spec editors.

I created the W3C bug for this proposal:
https://www.w3.org/Bugs/Public/show_bug.cgi?id=28553

Majid


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-04-15 Thread Majid Valipour
>
>
> > I think the original approach of adding a fourth argument is much better.
> >
> > It's also a better API in general, since the URL should always be given.
> > If we had a one-argument form with a dictionary, people would consider
> not
> > giving the URL but just disabling scrolling, which is suboptimal.
>
> You can require arguments with dictionaries.
>

Actually URL is optional in current spec and it defaults to current URL.
Why is this suboptimal? In anycase If making URL required is a goal then it
is best done by introducing a new method to avoid breaking compatibility.

I personally find a dictionary with only optional members which have
appropriate defaults to be very convenient. Here are some reasonable
defaults:
 - url: current URL
 - title: current title
 - state: null
 - restoreScroll: true (or willRestoreScrollPosition: false)


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-04-10 Thread Majid Valipour
> > Below is the IDL for the proposed changes:
> >
> > 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,
> > }
>
> I'm not sure there's much point exposing history.options, what's the
> purpose of that?
>

Its main purpose is to allow feature detection because it is not possible
to feature detect the existence of the new optional fourth argument on its
own. Exposing option allows the following feature detection:

var canControlScrollRestoration = ‘options’ in window.history &&
‘restoreScroll’ in window.history.options;

As a minor advantage, it may be useful for libraries that will handle
scroll restoration. They can check history.options.restoreScroll and decide
whether they need to restore scroll or user agents will do so. The same can
be done with a boolean in state itself so this is just a nice to have.

Of course if we were to add a new method this would not be needed.

Also, I'd recommend an option name that suggests more strongly that the
> author is expected to restore the position themselves, rather than just
> that the position shouldn't be restored. For example, calling it something
> like "willRestoreScrollPosition" (defaulting to false, meaning the UA
> should do it).
>

I think this is a good idea.


> On Wed, 25 Mar 2015, Jonas Sicking 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.
>
> On Thu, 26 Mar 2015, Simon Pieters wrote:
> >
> > Yeah... also consider navigating back and forth between two different
> > sites/apps, without navigating within each site/app. Should they be able
> > to turn off scroll restore?
> >
> > Is this something that should be toggled on a per-page basis or on a
> > per-navigation basis? If per-page, is it enough to just be able to turn
> > it off (i.e. not turn it on again)?
>
> These are interesting points.
>
> It seems like what you really want is a way to hook into the scroll
> behaviour. For example, we could fire an event at the document saying
> "we're about to automatically scroll to 75% of the way down the page,
> cancel this if you want to do it yourself". The real problem with that,
> though, is that 75% means nothing in the cases where you'd want to
> actually do it yourself. It's not clear to me how you could convey the
> information that is actually needed.
>
> Maybe infinite-scroll pages _should_ use replaceState(), to say how much
> they have loaded. At which point, the boolean flag seems reasonable again.
>
I think a method to prevent/customize scrolls
 might be
helpful in this situation but it may be a while before such an API actually
becomes available. In the meantime, this proposal is simple and easy to
implement and addresses a serious issue for developers.


>
> Are there other vendors interested in implementing this?
>
> If not, I recommend that Chrome implement this as the fourth argument with
> a dictionary with a boolean that implies that the author will perform the
> scroll position restoration behaviour themselves, and then filing a bug on
> the spec with the Target Milestone set to "Needs Impl Interest".


Sounds like a reasonable plan. Hopefully we can get more vendors interested
and I am more than happy to adjust the proposal to help this happen.

Majid


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-04-07 Thread Majid Valipour
Hi Nils,

I am not advocating for breaking the back button but in fact the opposite.
The idea is to allow single-page applications that are creating new history
entries and for whom the automatic scroll restoration is *broken* (because
the page is being re-creating on popstate event) to be able to replace
user-agent's default scroll restoration with their own custom
implementation.

Note that in practice, major mobile optimized sites are implementing their
own scroll restoration via various ugly hacks because the user agent scroll
restoration is broken for them. In my proposal, I have listed a few of
these hacks (e.g., double scroll, inner scrolling div) and their negative
implications. Websites that are trying to provide good back button behavior
should not resort to hacks and suffer for it.

Also the proposal is backward compatible and opts for restoring scroll
position  by default so existing websites will continue to behave as before.

Majid

On Tue, Apr 7, 2015 at 1:50 PM Nils Dagsson Moskopp <
n...@dieweltistgarnichtso.net> wrote:

> Majid Valipour  writes:
>
> > For example a news site may want to always send user to the page top
> where
> > top news are displayed regardless of where the user was before. This is
> > currently being achieved by resorting to workarounds such as setting body
> > size to 100% and using inner divs (e.g., CBC news
> > <http://www.cbc.ca/m/news/>).
>
> Note that many users consider breaking the back button an annoyance. I
> do not want “take me back where I came from” to suddenly mean “take me
> back where the site owner would like to me to get”. Especially with
> “social” news feeds, following a link and then not being able to get
> back to the position on the page you came from is very frustrating.
>
> --
> Nils Dagsson Moskopp // erlehmann
> <http://dieweltistgarnichtso.net>
>


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-04-07 Thread Majid Valipour
On Thu, Mar 26, 2015 at 11:12 AM Anne van Kesteren  wrote:

> On Thu, Mar 26, 2015 at 3:57 PM, Majid Valipour 
> wrote:
> > That is fair. Assuming clear documentation helps alleviate potential
> > confusion I am fine with deprecation route. I suppose the purpose of the
> > spec is to not only document the current recommended behavior but also
> > capture any legacy ones until it is fully removed.
>
> Yeah, we don't want any new user agents such as Spartan or Servo run
> into pages that only work with history.replaceState(). They'd then
> have to reverse engineer it rather than simply reading a specification
> which is not nice.
>

** Re-sending with my member email address. Apologies for duplication.

I have updated the proposal document
<https://docs.google.com/a/chromium.org/document/d/1Tiu8PjvBtNOAgeh6yrs7bOrXxQcavQLiNtRJ_ToLlVM>
based
on feedback around API design:

partial interface History {

  void push(in optional HistoryEntry entry);

  void replace(in optional HistoryEntry entry);

}


dictionary HistoryEntry {

  any state,

  DOMString title,

  DOMString url,

  Boolean restoreScroll = true,

}


Now instead of adding a fourth optional parameter to existing methods it
introduces new methods (push, replace) which accept dictionaries.


Although not required I think it improves API completeness if the following
two modifications are also included:


   1. Add a readonly 'history.current' attribute which returns the current
   entry in joint history session analogous to how history.state behaves now.
   This allows developers to access title, url, and restoreScroll of the
   current history entry.
   2. Add a new attribute 'entry' of type HistoryEntry to PopStateEvent in
   addition to 'state'. This one may actually be unnecessary if we have
   history.current and knowing that there can only ever be one PopState event
   in flight.

Thanks


Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-04-07 Thread Majid Valipour
** Re-sending my response with my member email address to ensure it is included
in the mailing list archive. Apologies for duplication.

On Thu, Mar 26, 2015 at 5:16 AM Simon Pieters 
…

> Yeah... also consider navigating back and forth between two different
> sites/apps, without navigating within each site/app. Should they be able
> to turn off scroll restore?
>

Yes. It think it should be possible for the application to control scroll
restoration for all of its own history entries including the one implicitly
created by the user agent upon initial load and the ones that are
explicitly create by itself for the purpose of internal navigation.

For example a news site may want to always send user to the page top where
top news are displayed regardless of where the user was before. This is
currently being achieved by resorting to workarounds such as setting body
size to 100% and using inner divs (e.g., CBC news
).

Note that currently scroll is consistently restored regardless of the type
of the navigation (intra-app, inter-app). I don't think we should start
treating them distinctly or even change their default restoration behavior
as long as we provide ability for application to opt out of scroll
restoration for either type. The current proposal does just that and lets
the application decide what is best for their particular need.
…


> Is this something that should be toggled on a per-page basis or on a
> per-navigation basis? If per-page, is it enough to just be able to turn it
> off (i.e. not turn it on again)?
>
> e.g.
>
> history.restoreScroll = false;
>
> or
>
> history.disableRestoreScroll();
>
>
We did consider a per-page global flags as an alternative design and it is
discussed in the original proposal document
.
Here is a summary of  why we think an API that gives per-navigation control
is a better fit:

   - Scroll is restored per-navigation so an API for controlling it
   per-navigation is more natural and better represents the underlying
   behavior. A global per-page switch hides this fact and is harder to reason
   about unless we also change the scroll restoration to become per-page.
   - Controlling scroll restoration per-navigation is more flexible than
   per-page. It is trivial to implement a pollyfill for disabling scroll
   restoration per-page if we have the per-navigation version but the reverse
   is not true. I imagine libraries such as History.js and jQuery UI will be
   providing a flag to disable it per-page (or per app).
   - There are legitimate usecases where an application may want to have
   different scroll restoration behavior for its different UI state (i.e., per
   navigation). For example Facebook may want to have automatic restoration in
   timeline but disable it on photo pages.

Thanks


[whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-04-07 Thread Majid Valipour
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 
Date: Wed, Mar 25, 2015 at 8:22 PM

On Wed, Mar 25, 2015 at 4:32 PM Jonas Sicking  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 
> wrote:
> > On Thu, Mar 19, 2015 at 6:31 PM, Majid Valipour 
> 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


[whatwg] Proposal: Allow disabling of default scroll restoration behavior

2015-03-19 Thread Majid Valipour
# Problem
Almost all browsers restore scroll position when a user traverses history.
This behavior works well for document style web sites but it is often not
appropriate for single-page web applications where the page content may be
reconstructed (often asynchronously) upon navigation and where the
application
wants to control the details of visual transition between UI states.

Currently it is not possible to disable the scroll behavior so web
developers
have resorted to various hacks [1]. Here are the two most popular:
- Avoid document scrolling altogether by fixing body size and putting
content
  in an inner scrollable div. This breaks browser features that depend on
  document scrolling such as top controls hiding, or overscroll visuals and
in
  some cases disables fast scroll optimizations for document scrolling.
- Use a secondary scroll after browser's initial attempts to restore scroll.
  This leads to two visible jumps and bad UX.

Few documented cases of web developers struggling with this problem may be
found in [2, 3, 4].

# Proposal
Allow web applications to explicitly disable user agents default scroll
restoration behavior via History API. This is achieved by adding a fourth
optional parameter 'options' to both history.pushState,
history.replaceState.
Obviously the default values will be backward compatible. We should also
provide a new attribute (history.options)  that exposes the current
effective
value of this new property and use it to provide a simple feature detection.

Below is the IDL for the proposed changes:

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,
}

Here is a more complete version of this proposal with details around
background, current proposal design, and considered alternative designs:
https://docs.google.com/a/chromium.org/document/d/1Tiu8PjvBtNOAgeh6yrs7bOrXxQcavQLiNtRJ_ToLlVM

We like to implement this or something similar in blink and would be
interested to hear from other vendors. All feedback on proposed design is
welcome. :)

Thanks
Majid Valipour

[1]
http://stackoverflow.com/questions/10742422/prevent-browser-scroll-on-html5-history-popstate
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=679458
[3] https://github.com/rackt/react-router/issues/707
[4] http://andrz.me/blog/scrollx-scroll-why-history