Gecko:FullScreenAPI

Revision as of 00:32, 6 August 2010 by Roc (talk | contribs) (→‎Examples)

Requirements

  • Scripts should be able to initiate and terminate fullscreen
    • Allows custom, in-page, discoverable UI to active fullscreen
  • Arbitrary Web content should be visible fullscreen
    • <video>, <canvas>, multicolumn text, etc
    • Required for scripted video controls
  • Entering and exiting fullscreen must trigger events
    • To allow scripted changes to content, e.g. resizing of canvas content
  • Scripts should be able to opt in to having alphanumeric keyboard input disabled during fullscreen
    • Enables less restrictive anti-spoofing measures
  • Actual fullscreen transitions must be allowed to be asynchronous and entirely at the discretion of the UA
    • To enable passive notification/confirmation UI
    • To enable a wide range of security measures to prevent spoofing or other abuse
  • Making a single element fullscreen should be as simple as possible
  • Content in IFRAMEs should be able go fullscreen
    • To enable "widgets" such as embedded videos to offer fullscreen UI

Proposed Specification

A Document can be in the "fullscreen state". What exactly this means is up to the UA, but typically it means that the Document covers most or all of the screen and some or all of the normal UA UI is not visible.

It is possible for non-toplevel browsing contexts to have their Document in the fullscreen state. The parent browsing context of a browsing context with its Document in the fullscreen state must also have its Document in the fullscreen state.

The user agent may transition a Document into or out of the fullscreen state at any time, whether or not script has requested it. User agents are encouraged to provide standard UI to exit the fullscreen state, for example if the user presses the Escape key.

Toplevel browsing contexts can be in a "keys disabled" state. In this state, the user agent must suppress all keyup, keydown and keypress events whose keyCode is not in one of the following ranges:

  • DOM_VK_CANCEL to DOM_VK_CAPS_LOCK, inclusive
  • DOM_VK_SPACE to DOM_VK_DELETE, inclusive
  • DOM_VK_SEMICOLON to DOM_VK_EQUALS, inclusive
  • DOM_VK_MULTIPLY to DOM_VK_META, inclusive

Such events are not dispatched to any nodes in any document of the toplevel browsing context or descendant browsing contexts. This includes suppression of any internal key event processing that would insert text into form controls or editable content. The user agent might respond to such events by leaving fullscreen mode.

Each document has an optional "current fullscreen element".

New methods of Document:

  • void cancelFullScreen()

Requests that the UA exit fullscreen mode. The UA is not required to honor this, for example the UA might require that only a Document that last triggered fullscreen can cancel it.

The current fullscreen element for the document is cleared.

New attributes of Element:

  • const unsigned short ALLOW_KEYBOARD_INPUT = 1

New methods of Element:

  • void requestFullScreen(unsigned short flags)

The current fullscreen element for the document is set to this element.

Typically the user agent would react by transitioning the Document to the fullscreen state, or by presenting asynchronous confirmation UI and transitioning to the fullscreen state if/when the user responds affirmatively. However, the user agent is not required to do anything at all in response to requestFullScreen.

When the ALLOW_KEYBOARD_INPUT flag is not specified, requestFullScreen hints to the UA that while in fullscreen state, the toplevel browsing context for this Document should have keys disabled. While keys are disabled, there may be a reduced risk of spoofing attacks inducing the user to input inappropriate data, and the UA may choose to relax restrictions on entering fullscreen state with keys disabled.

New DOM attribute of Document:

  • readonly attribute boolean fullScreen

Returns true while the document is in the fullscreen state.

  • readonly attribute boolean fullScreenKeyboardInputAllowed

Returns true while the window's toplevel browsing context is fullscreen and not in a "keys disabled" state.

New content attribute of the <iframe> element:

  • allowfullscreen

This is a boolean attribute. When this attribute is not set, UAs should ignore fullscreen requests in the iframe or its descendant frames.

New events:

  • fullscreenchange

When a Document enters or leaves the fullscreen state, the user agent must queue a task to dispatch this event. When the event is dispatched, if the document's current fullscreen element is an element in the document, then the event target is that element, otherwise the event target is the document. The event bubbles and is not cancellable.

The 'onfullscreenchange' event handling attribute is supported on HTML elements.

New CSS psuedoclasses:

  • :full-screen

While a Document is in the fullscreen state, and the document's current fullscreen element is an element in the document, the 'full-screen' pseudoclass applies to that element. Also, an <iframe>, <object> or <embed> element whose child browsing context's Document is in the fullscreen state has the 'full-screen' pseudoclass applied.

  • :full-screen-document

While a Document is in the fullscreen state, the 'full-screen-document' pseudoclass applies to the root element of that Document.

Suggested UA stylesheet rule:

/* A fullscreen element that is not the root element should be stretched
   to cover the viewport. */
:full-screen:not(:root) {
  position:fixed;
  top:0;
  left:0;
  right:0;
  bottom:0;
  z-index:2147483647;
  background:black;
}
/* In fullscreen mode, if the root element itself is not fullscreen then
   we should hide the viewport scrollbar. */
:full-screen-document:not(:full-screen) {
  overflow:hidden;
}

Note that it is possible for a document to position content over an element with the :full-screen pseudo-class, for example if the :full-screen element is in a container with z-index not 'auto'.

Examples

1. Make a video element display fullscreen when clicked and leave fullscreen when it ends.

<video src="pelican.webm" autoplay
       onclick="event.target.requestFullScreen()"
       onended="document.cancelFullScreen()">
</video>

2. Make a canvas element display fullscreen in response to user input. Resize the canvas to the appropriate resolution while it's fullscreen.

<script>
function redrawCanvas(c) { ... }
function resizeCanvas() {
  var c = document.getElementById("c");
  var rect = c.getBoundingClientRect();
  c.width = rect.width;
  c.height = rect.height;
  redrawCanvas(c);
}
</script>
<canvas id="c" onfullscreenchange="resizeCanvas()"></canvas>
<button onclick="document.getElementById('c').requestFullScreen()">
  Go Fullscreen!
</button>

3. Hide advertisements while the window is fullscreen.

:full-screen-document .advertisement { display:none; }

Firefox Requirements

  • Integrate scripted fullscreen with user-chosen fullscreen

Gecko Implementation

Initially we won't support fullscreening of IFRAMEs.

We store the following state:

  • a boolean on the toplevel window indicating whether the toplevel window is in fullscreen state (nsGlobalWindow::mFullScreen)
  • a boolean in the toplevel window indicating if keyboard input is disabled (nsGlobalWindow::mFullScreenKeysDisabled)
  • in each document, the fullscreen element (if any)

Definitions:

  • A window is in the fullscreen state if the toplevel chrome window for the window has mFullScreen set and the window is the toplevel chrome window or a toplevel content window
  • A window is in the "keys disabled" state if the toplevel chrome window for the window has mFullScreenKeysDidsabled set

For styling, Documents whose (inner) windows are in the fullscreen state will have NS_DOCUMENT_STATE_FULL_SCREEN set on them.

APIs:

  • nsGlobalWindow::GetFullScreen returns the fullscreen state of the window
  • nsGlobalWindow::SetFullScreen(KeysEnabled), when called by chrome, will put the toplevel window in the fullscreen state, or take it out of the fullscreen state, and set the keys-enabled state.
  • A FullScreenRequested event that gets fired at the chrome event listener if fullscreen is requested (and we should not ignore it --- e.g. request in inactive tab). Pass a reference to the element and window in the event. The event also contains a flag to indicate if keys-disabled was requested.
  • A FullScreenCanceled event that gets fired if a window wants to cancel fullscreen. The event contains a reference to the element that had been requested and the window.

Chrome's policy code could work like this:

  • The user has ultimate control: the user can request fullscreen at any time (F11), as now.
  • Chrome can store a "current fullscreen request" for each <browser>, including a flag to indicate whether it wanted to disable keys.
  • Each FullScreenRequested events received sets the current fullscreen request for that <browser>.
  • Each FullScreenCanceled event clears the current fullscreen request for that <browser>. If that <browser> is the active tab, exit fullscreen mode.
  • Whenever a request is approved (it might be approved instantly), call SetFullScreen on the chrome window to make everything fullscreen.

Plan

  • Part 1: Implement fullscreen window state, content events and styling
    • Basic fullscreen stuff should work if the user manually enters fullscreen
  • Part 2: Implement request APIs and dispatching of chrome events
  • Part 3: Implement key disabling
  • Part 4: Implement extended nsGlobalWindow API to enter fullscreen mode with optional key disabling
  • Part 5: Hook up chrome events to prototype browser UI and trigger fullscreen