Tuesday, 3 December 2013

Why does the HTML fullscreen API ask for approval after entering fullscreen, rather than before?

The HTML fullscreen API is a little different from other JS APIs that require permission, in that it doesn't ask permission before entering fullscreen, it asks forgiveness *after* entering fullscreen.

Firefox's fullscreen approval dialog, which asks "forgiveness" rather than permission.
The rationale for having our fullscreen API implementation ask forgiveness rather than request permission is to make it easier on script authors.

When the original API was designed, we had a number of HTML/JS APIs like the geolocation API that would ask permission. The user was prompted to approve, deny, or ignore the request, though they could re-retrieve the request later from an icon in the URL bar to approve the request at a later time.

Geolocation approval dialog, from Dive Into HTML's geolocation example.
The problem with this design for script authors is that they can't tell if the user has ignored the approval request, or is just about to go back and approve it by bringing up the geolocation door-hanger again.

This model of requesting permission has been seen to cause problems for web apps in the wild using the geolocation API. Often if a user ignores the geolocation permission request, the web app doesn't work right, and if you approve the request some time later, the site often doesn't start working correctly. The app just doesn't know if it should throw up a warning, or if it's about to be granted permission.

So the original developers of the fullscreen spec (Robert O'Callahan, and later I and others were involved), opted to solve this problem by having our implementation ask forgiveness. Once you've entered fullscreen, the user is asked to confirm the action.

This forces the user to approve or deny the request immediately, and this means that script will immediately know whether fullscreen was engaged, so script will know whether it needs to take its fallback path or not.

Note that the specification for requestFullscreen() defines that most of the requestFullscreen() algorithm should run asynchronously, so there is scope to change the fullscreen approval dialog to being a permission request before entering fullscreen instead if future maintainers, or other implementors/browser, wish to do so.

6 comments:

Jeff Walden said...

Not to mention, presumably, that fullscreen is something the browser can "claw back" from the user. :-) But once you tell the site where the user is, it's kind of too late to undo that.

Manuel Strehl said...

@Jeff Walden that was my thought, too. But the browser would have the power to go an extra mile here: Allow access, but ask for user's permission before the next HTTP request is issued. (Kind of "tainted" flag for page's network access.)

The basic result would be mostly similar to the user, because, e.g., re-centering a map will inevitably trigger a HTTP request. But for the app it'd be similar to just a delayed HTTP request, and it could resume as usual with other business.

Robert said...

Yes, it's very important to distinguish cases where we can undo an action from those where we can't.

Manuel: that's very difficult to make secure. There are lots of ways a page could leak information back to its site. For example you could have a separate tab open to a different site run by the same operator, and the page with the secret information could using a timing channel to leak secret bits to the other tab.

elmcom said...

Isn't there an option to opt out of alphanumeric input so that no prompt is shown (only a warning, automatically dismissed, like Flash)?

I think this was planned but never made it?

Chris Pearce said...

@elmcom: Our implementation used to have a way to opt-out of alphanumeric input, but we dropped that since it would be confusing to users to have two modes with two different behaviours.

Paul Neave said...

The current solution makes perfect sense. Geolocation/camera access etc affects the user’s privacy. Full screen does not.