[whatwg] Proposal for a tab visibility API

Sorry for the delayed reply.  I sent a number of responses over the past
week, but it just came to my attention that due to some kind of mailing-list
snafu, they never actually were sent out.  I've attempted to bring all of my
replies into this one message.  Sorry for the impression that I had
abandoned this thread--that was not my intention!


Regarding the fact that background tabs aren't necessarily invisible:
-----

> On December 8, Boris Zbarsky wrote:

There is no such guarantee for background tabs.  For example, browsers may
> show tab previews in various contexts (Panorama in Firefox 4, e.g.).

-----

The point of the API, as proposed, is that page scripts will know when their
content is guaranteed to be invisible to the user--that is, the API will not
provide a false positive about invisibility.  However, the API may provide
false negatives about invisibility, for reasons many others on this thread
have been pointed out (including different windowing systems, multiple
monitors, partial transparency, etc.).

The easiest way to achieve this guarantee is to only consider a tab hidden
when it is a background tab within* *a window.  The window itself, of
course, may be on a little-noticed second monitor, partially obscured, etc.
 But as you point out, there are still some edge cases where even a
background tab is visible.  In this specific example, I think the right
answer would be to have an additional visibility value of "preview", which,
for the purposes of the isVisible property, would be considered a hidden
state.  There are some cases where a tab would consider a tab preview to be
hidden (like the puzzle timer use case) and some cases where it would be
considered visible (like the video playing use case).  This would allow web
developers to decide for themselves how they wanted to respond to that case.

Regarding the additional abuse potential:
------

> On December 8th, Boris Zbarksy wrote:

I'd really appreciate some comment on this.  I'm pretty worried about adding
> features that we then have to start working around people abusing almost
> immediately...

-----
Although I agree that there is some additional potential for abuse, I don't
think it's a particularly large incremental potential.  Sites that want to
be annoying already have a very large toolbox today.  Sites today could
easily hook up a script that detects inactivity on a tab (e.g. lack of
scrolling or mouse movement) and pops an alert, refocussing the tab.  In
practice, this is not a common occurrence--users can vote with their address
bar and avoid sites that are needlessly annoying.

There would be some easy defenses browser implementors could enact if this
focus-grabbing did indeed become a problem.  For example, code running in
response to a visibilitychange event could be forbidden to open an alert
(something that would be easy for moderately-savvy developers to circumvent
via a setTimeout).  Additionally, if a site pops multiple alerts when the
tab is hidden, the alert shown to the user could contain an additional
option to "Prevent this site from grabbing focus in the future" that would
not allow alerts when the tab is hidden.

Although there is some additional opportunity for abuse, I think that it is
not particularly large, possible to defend against if necessary, and
outweighed by the advantages such an API would provide to legitimate web
developers.

Regarding the video player use case from the initial proposal:
-----

> On December 8th, Maciej Stachowiak wrote:
> This use case can be handled without help from the page. In Safari, video
> (whether through media elements or plugins) won't start playing when a user
> opens a tab in the background, until the user switches to that tab.


-----

Although what you describe satisfies the specific use case, it doesn't
address the more general use case of animations (either explicit via
javascript or via CSS Animations) or content that is not a plugin/video
file.

Regarding solving the use cases that cannot be addressed currently:
------
On December 8th, Maciej Stachowiak wrote:

That leaves the following use cases:
* A puzzle game has a timer that keeps track of how long the user has taken
to solve the puzzle.  It wants to pause the timer when the user has hidden
the tab.
* A web app that uses polling to fetch dynamic content can pause polling
when it knows the page is hidden from the user.
* A page wants to detect when it is being prerendered so it can behave
appropriately.
I am not sure what the third needs exactly, but it seems like first two
could be better served with an API that sets a timer which will only fire
when the page is visible. That kind of API might be easier to use right, and
avoids the need for JS to run when switching tabs, just to cancel and
restart timers.

-----

Although that API might be easier to use correctly (I don't know if I'm
convinced), note that it would still have the same abuse concerns as the
proposed API.  A website developer determined to be annoying could register
two timers--one that would not fire when the page is invisible, and one that
would continue firing even when the page is invisible.  The first would
update some global variable with a timestamp every time it fires; the second
would check to see if the timestamp was significantly more stale than the
first's timer interval, and then could trigger a re-focussing alert.  Of
course, the other benefit you note is that this idea wouldn't require
running javascript every time a user switches tabs, for this class of use
cases.

The initial use cases listed might be unintentionally narrow.  Another use
case is:

* An in-browser collaborative editing environment wants to update a user's
status to away when the tab is in the background.

(Although the timer API you mention could be used to address even this use
case (indirectly) because it implicitly exposes the key information of
whether the tab is invisible.)

Regarding building on top of pagehide/pageshow API:
----

> On December 8th, Maciej Stachowiak wrote:
> Also I wonder if pagehide and pageshow could be broadened to help the
> prerendering use case. It seems a bit speculative to make API just so Web
> pages can find out about an experimental feature being used.

-----

 The motivator that got us first thinking about this API in earnest was the
prerendering case--although the other use cases, which we also think are
important, appear to dovetail nicely.  An initial draft attempted to
piggyback on the existing pageshow/pagehide API.  In practice it was
extremely difficult to do correctly, because the visibility/prerender-status
of the tab is independent of the load event.   The user could click on the
predicted link before load fires, or after it has fired.  In contrast, the
existing pageshow/pagehide API guarantees that pageshow fires after load (at
least according to this page:
https://developer.mozilla.org/En/Using_Firefox_1.5_caching).

I would be interested to hear more about a plan that could use the existing
pageshow/pagehide API for prerendering in a way that is backwards
compatible.

--Alex

On Fri, Dec 10, 2010 at 3:00 PM, Thomas Broyer <t.broyer at gmail.com> wrote:

> On Fri, Dec 10, 2010 at 1:14 PM, Dennis Joachimsthaler <dennis at efjot.de>
> wrote:
> >
> > Maybe we can disallow the "visibilitychange" event to produce any dialogs
> > or anything else that could give focus?
>
> window.onvisibilitychange = function(e) {
>  setTimeout(function() {
>    alert("Worked around!");
>  }, 0);
> };
>
> Or would browsers be able to track that the code was initially
> triggered from visibilitychange? (including when programmatically
> creating and dispatching another DOM events, instead of or in addition
> to the setTimeout?)
>
> --
> Thomas Broyer
> /t?.ma.b?wa.je/ <http://xn--nna.ma.xn--bwa-xxb.je/>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/whatwg-whatwg.org/attachments/20101215/1892dcbb/attachment-0001.htm>

Received on Wednesday, 15 December 2010 11:27:51 UTC