diff --git a/review-drafts/2020-01.bs b/review-drafts/2020-01.bs new file mode 100644 index 0000000..9c08c17 --- /dev/null +++ b/review-drafts/2020-01.bs @@ -0,0 +1,776 @@ +
+Group: WHATWG +Date: 2020-01-29 +H1: Fullscreen API +Shortname: fullscreen +Text Macro: TWITTER fullscreenapi +Abstract: The Fullscreen API standard defines an API for elements to display themselves fullscreen. +Translation: ja https://triple-underscore.github.io/fullscreen-ja.html +Markup Shorthands: css no ++ +
+spec:dom + type:dfn; for:/; text:element + type:interface; text:Document +spec:infra + type:dfn; for:set; text:for each + type:dfn; text:string ++ +
+urlPrefix: https://w3c.github.io/screen-orientation/#dfn- + type: dfn + text: triggered by a user generated orientation change ++ +
+{ + "CSS": { + "aliasOf": "CSS2" + }, + "SVG": { + "aliasOf": "SVG11" + } +} ++ + + +
This specification depends on the Infra Standard. [[!INFRA]] + +
Most terminology used in this specification is from CSS, DOM, HTML, and Web IDL. [[!CSS]] +[[!DOM]] [[!HTML]] [[!WEBIDL]] + +
A browsing context A is called a descendant browsing context +of a browsing context B if and only if B is an +ancestor browsing context of A. + + + +
All elements have an associated fullscreen flag. Unless stated otherwise it is +unset. + +
All <{iframe}> elements have an associated iframe fullscreen flag. Unless +stated otherwise it is unset. + +
All documents have an associated fullscreen element. The +fullscreen element is the topmost element in the document's +top layer whose fullscreen flag is set, if any, and null otherwise. + +
All documents have an associated list of pending fullscreen events, which +is an ordered set of (string, element) pairs. It is initially empty. + +
To fullscreen an element, set element's fullscreen flag +and add it to its node document's top layer. + +
To unfullscreen an element, unset element's +fullscreen flag and iframe fullscreen flag (if any), and remove it from +its node document's top layer. + +
To unfullscreen a document, +unfullscreen all elements, within document's +top layer, whose fullscreen flag is set. + +
To fully exit fullscreen a document document, run these steps: + +
If document's fullscreen element is null, terminate these steps. + +
Unfullscreen elements whose fullscreen flag is + set, within document's top layer, except for document's + fullscreen element. + +
Exit fullscreen document. +
Whenever the removing steps run with a removedNode, run +these steps: + +
Let document be removedNode's node document. + +
Let nodes be removedNode's + shadow-including inclusive descendants that have their fullscreen flag set, in + shadow-including tree order. + +
For each node in nodes: + +
If node is document's fullscreen element, + exit fullscreen document. + +
Otherwise, unfullscreen node. + +
If document's top layer contains node, + remove node from document's top layer. + +
Other specifications can add and remove elements from top layer, so + node might not be document's fullscreen element. For example, + node could be an open <{dialog}> element. +
Whenever the unloading document cleanup steps run with a document, +fully exit fullscreen document. + +
Fullscreen is supported if there is no previously-established user preference, +security risk, or platform limitation. + +
An algorithm is allowed to request fullscreen if one of the following is true: + +
The algorithm is triggered by user activation. + +
The algorithm is triggered by a user generated orientation change. +
To run the fullscreen steps for a document document, run these +steps: + +
Let pairs be document's list of pending fullscreen events. + +
Empty document's list of pending fullscreen events. + +
For each (type, element) in pairs: + +
Let target be element if element is connected + and its node document is document, and otherwise let target be + document. + +
Fire an event named type, with its {{Event/bubbles}} and + {{Event/composed}} attributes set to true, at target. +
These steps integrate with the event loop defined in HTML. [[!HTML]] + + + +
+enum FullscreenNavigationUI { + "auto", + "show", + "hide" +}; + +dictionary FullscreenOptions { + FullscreenNavigationUI navigationUI = "auto"; +}; + +partial interface Element { + Promise<void> requestFullscreen(optional FullscreenOptions options = {}); + + attribute EventHandler onfullscreenchange; + attribute EventHandler onfullscreenerror; +}; + +partial interface Document { + [LenientSetter] readonly attribute boolean fullscreenEnabled; + [LenientSetter, Unscopable] readonly attribute boolean fullscreen; // historical + + Promise<void> exitFullscreen(); + + attribute EventHandler onfullscreenchange; + attribute EventHandler onfullscreenerror; +}; + +partial interface mixin DocumentOrShadowRoot { + [LenientSetter] readonly attribute Element? fullscreenElement; +}; ++ + +
promise = element . requestFullscreen([options])
+ navigationUI
member indicates whether showing
+ navigation UI while in fullscreen is preferred or not. If set to "show
", navigation
+ simplicity is preferred over screen space, and if set to "hide
", more screen space
+ is preferred. User agents are always free to honor user preference over the application's. The
+ default value "auto
" indicates no application preference.
+
+ document . {{Document/fullscreenEnabled}}
+ Returns true if document has the ability to display elements fullscreen + and fullscreen is supported, or false otherwise. + +
promise = document . {{Document/exitFullscreen()}}
+ Stops document's fullscreen element from being displayed fullscreen and + resolves promise when done. + +
document . {{DocumentOrShadowRoot/fullscreenElement}}
+ Returns document's fullscreen element. + +
shadowroot . {{DocumentOrShadowRoot/fullscreenElement}}
+ Returns shadowroot's fullscreen element. +
A fullscreen element ready check for an element element returns true +if all of the following are true, and false otherwise: + +
element is connected. + +
element's node document is allowed to use the "fullscreen
" feature.
+
+
The requestFullscreen(options)
method,
+when invoked, must run these steps:
+
+
Let pending be the context object. + +
Let pendingDoc be pending's node document. + +
Let promise be a new promise. + +
If pendingDoc is not fully active, then reject promise with a
+ TypeError
exception and return promise.
+
+
Let error be false. + +
If any of the following conditions are false, then set error to true: + +
pending's namespace is the HTML namespace or
+ pending is an
+ SVG svg
or
+ MathML math
+ element. [[!SVG]] [[!MATHML]]
+
+
pending is not a <{dialog}> element. + +
The fullscreen element ready check for pending returns true. + +
This algorithm is allowed to request fullscreen. +
Return promise, and run the remaining steps in parallel. + +
If error is false, then resize pendingDoc's
+ top-level browsing context's active document's viewport's dimensions, optionally
+ taking into account options's navigationUI
member:
+
+
+
value | +viewport dimensions | +
---|---|
"hide " |
+ full dimensions of the screen of the output device | +
"show " |
+ dimensions of the screen of the output device clamped to allow the user agent to show page navigation controls | +
"auto " |
+ user-agent defined, but matching one of the above | +
Optionally display a message how the end user can revert this. + +
If any of the following conditions are false, then set error to true: + +
pending's node document is pendingDoc. + +
The fullscreen element ready check for pending returns true. + +
If error is true: + +
Append (fullscreenerror
, pending) to
+ pendingDoc's list of pending fullscreen events.
+
+
Reject promise with a TypeError
exception and terminate these
+ steps.
+
Let fullscreenElements be an ordered set initially consisting of + pending. + +
While the last element in fullscreenElements is in a + nested browsing context: append its browsing context container to + fullscreenElements. + + +
For each element in fullscreenElements: + +
Let doc be element's node document. + +
If element is doc's fullscreen element, continue. + +
No need to notify observers when nothing has changed. + +
If element is pending and pending is an <{iframe}> + element, then set element's iframe fullscreen flag. + +
Fullscreen element within doc. + +
Append (fullscreenchange
, element) to
+ doc's list of pending fullscreen events.
+
The order in which elements are fullscreened + is not observable, because run the fullscreen steps is invoked in tree order. + +
Resolve promise with undefined. +
Implementations with out-of-process browsing contexts are left as an +exercise to the reader. Input welcome on potential improvements. + +
The fullscreenEnabled
attribute's getter must
+return true if the context object is allowed to use the "fullscreen
" feature and fullscreen is supported, and
+false otherwise.
+
+
The fullscreen
attribute's getter must return
+false if context object's fullscreen element is null, and true otherwise.
+
+
Use the {{DocumentOrShadowRoot/fullscreenElement}} attribute instead. + +
The
+fullscreenElement
+attribute's getter must run these steps:
+
+
If the context object is a shadow root and its + host is not connected, then return null.
Let candidate be the result of retargeting fullscreen element + against the context object. + +
If candidate and the context object are in the same tree, then + return candidate. + +
Return null. +
A document is said to be a simple fullscreen document if there is exactly one +element in its top layer that has its fullscreen flag set. + +
A document with two elements in its top layer can be a +simple fullscreen document. For example, in addition to the fullscreen element there +could be an open <{dialog}> element. + +
To collect documents to unfullscreen given doc, run these steps: + +
Let docs be an ordered set consisting of doc. + +
While true: + +
Let lastDoc be docs's last document. + +
Assert: lastDoc's fullscreen element is not null. + +
If lastDoc is not a simple fullscreen document, break. + +
Let container be lastDoc's browsing context container, if + any, and otherwise break. + +
If container's iframe fullscreen flag is set, break. + +
Append container's node document to docs. +
Return docs. + +
This is the set of documents for which the fullscreen element will be + unfullscreened, but the last document in docs might + have more than one element in its top layer with the fullscreen flag set, + in which case that document will still remain in fullscreen. +
To exit fullscreen a document doc, run these steps: + +
Let promise be a new promise. + +
If doc is not fully active or doc's fullscreen element
+ is null, then reject promise with a TypeError
exception and return
+ promise.
+
+
Let resize be false. + +
Let docs be the result of + collecting documents to unfullscreen given + doc. + + +
Let topLevelDoc be doc's top-level browsing context's + active document. + + +
If topLevelDoc is in docs, and it is a + simple fullscreen document, then set doc to topLevelDoc and + resize to true. + +
If doc's fullscreen element is not connected: +
Append (fullscreenchange
, doc's
+ fullscreen element) to doc's
+ list of pending fullscreen events.
+
Return promise, and run the remaining steps in parallel. + +
If resize is true, resize doc's viewport to its "normal" dimensions. + +
If doc's fullscreen element is null, then resolve promise with + undefined and terminate these steps. + +
Let exitDocs be the result of + collecting documents to unfullscreen given + doc. + + +
Let descendantDocs be an ordered set consisting of doc's + descendant browsing contexts' active documents whose fullscreen element is + non-null, if any, in tree order. + + +
For each exitDoc in exitDocs: + +
Append (fullscreenchange
, exitDoc's
+ fullscreen element) to exitDoc's list of pending fullscreen events.
+
+
If resize is true, unfullscreen + exitDoc. + +
Otherwise, unfullscreen exitDoc's + fullscreen element. +
For each descendantDoc in descendantDocs: + +
Append (fullscreenchange
, descendantDoc's
+ fullscreen element) to descendantDoc's
+ list of pending fullscreen events.
+
+
The order in which documents are unfullscreened + is not observable, because run the fullscreen steps is invoked in tree order. + +
Resolve promise with undefined. +
The exitFullscreen()
method, when invoked, must
+return the result of running exit fullscreen on the context object.
+
+
The following are the event handlers (and their corresponding +event handler event types) that must be supported by {{Element}} and {{Document}} objects as +event handler IDL attributes: + +
event handler + | event handler event type + |
---|---|
onfullscreenchange
+ | fullscreenchange
+ |
onfullscreenerror
+ | fullscreenerror
+ |
These are not supported by {{ShadowRoot}} or {{Window}} objects, and there are no +corresponding event handler content attributes for {{Element}} objects in any namespace. + + + +
User agents are encouraged to implement native media fullscreen controls in terms of +{{Element/requestFullscreen()}} and {{Document/exitFullscreen()}}. + +
If the end user instructs the user agent to end a fullscreen session initiated via +{{Element/requestFullscreen()}}, fully exit fullscreen the +top-level browsing context's active document. + +
The user agent may end any fullscreen session without instruction from the end user +or call to {{Document/exitFullscreen()}} whenever the user agent deems it necessary. + + + +
This section is to be interpreted equivalently to the Rendering section of HTML. [[!HTML]] + +
Long term CSS will define the top layer concept and its associated
+::backdrop
pseudo-element as part of CSS' stacking context model. Patching CSS
+as done here is sketchy as hell.
+
+
+
This specification introduces a new stacking layer to the +Elaborate description of Stacking Contexts of CSS +2.1. It is called the top layer, comes after step 10 in the painting order, and is +therefore rendered closest to the user within a viewport. Each document has one +associated viewport and therefore also one top layer. [[!CSS]] + +
The terminology used in this and following subsection attempts to match CSS 2.1 +Appendix E. + +
The top layer is an ordered set of elements, rendered in the order they appear in +the set. The last element in the set is rendered last, and thus appears on top. + +
The z-index
property has no effect in the top layer.
+
+
Each element and ::backdrop
pseudo-element in a top layer has the
+following characteristics:
+
+
It generates a new stacking context. + +
Its parent stacking context is the root stacking context. + +
If it consists of multiple layout boxes, the first box is used. + + +
It is rendered as an atomic unit as if it were a sibling of its root. + +
Ancestor elements with overflow, opacity, masks, etc. cannot affect + it. + +
If its position
property computes to fixed
, its containing block
+ is the viewport, and the initial containing block otherwise.
+
+
If it is an element, it and its ::backdrop
pseudo-element are not
+ rendered if its shadow-including inclusive ancestor has the display
property
+ set to none
.
+
+
If its specified display
property is contents
, it computes to
+ block
.
+
+
If its specified position
property is not absolute
or
+ fixed
, it computes to absolute
.
+
+
Its outline, if any, is to be rendered before step 10 in the painting order. + +
Unless overridden by another specification, its static position for left
,
+ right
, and top
is zero.
+
To add an element to a top layer, +remove it from top layer and then append it to +top layer. + +
In other words, element is moved to the end of top layer if it +is already present. + + +
::backdrop
pseudo-elementEach element in a top layer has a
+::backdrop
pseudo-element. This pseudo-element
+is a box rendered immediately below the element (and above the element before the element in the
+set, if any), within the same top layer.
+
+
The ::backdrop
pseudo-element can be used to create a backdrop
+that hides the underlying document for an element in a top layer (such as an element that is
+displayed fullscreen).
+
+
It does not inherit from any element and is not inherited from. No restrictions are made on what +properties apply to this pseudo-element either. + + + + +
:fullscreen
pseudo-classThe :fullscreen
pseudo-class must match any
+element element for which one of the following conditions is true:
+
+
element's fullscreen flag is set. + +
element is a shadow host and the result of retargeting its + node document's fullscreen element against element is element. +
This makes it different from the +{{DocumentOrShadowRoot/fullscreenElement}} API, which returns the topmost fullscreen element. + +
+@namespace "http://www.w3.org/1999/xhtml"; + +*|*:not(:root):fullscreen { + position:fixed !important; + top:0 !important; right:0 !important; bottom:0 !important; left:0 !important; + margin:0 !important; + box-sizing:border-box !important; + min-width:0 !important; + max-width:none !important; + min-height:0 !important; + max-height:none !important; + width:100% !important; + height:100% !important; + transform:none !important; + + /* intentionally not !important */ + object-fit:contain; +} + +iframe:fullscreen { + border:none !important; + padding:0 !important; +} + +::backdrop { + position:fixed; + top:0; right:0; bottom:0; left:0; +} + +*|*:not(:root):fullscreen::backdrop { + background:black; +} ++ + + +
This specification defines a policy-controlled feature identified by the string
+"fullscreen
". Its default allowlist is
+'self'
.
+
+
A document's feature policy determines whether any content in that document is allowed to +go fullscreen. If disabled in any document, no content in the document will be allowed to use +fullscreen. + +
The <{iframe/allowfullscreen}> attribute of the HTML <{iframe}> element affects the container
+policy for any document nested in that iframe. Unless overridden by the <{iframe/allow}>
+attribute, setting <{iframe/allowfullscreen}> on an iframe is equivalent to <iframe
+allow="fullscreen *">
, as described in
+[[FEATURE-POLICY#iframe-allowfullscreen-attribute]].
+
User agents should ensure, e.g., by means of an overlay, that the end user is aware something is +displayed fullscreen. User agents should provide a means of exiting fullscreen that always works and +advertise this to the user. This is to prevent a site from spoofing the end user by recreating the +user agent or even operating system environment when fullscreen. See also the definition of +{{Element/requestFullscreen()}}. + +
To enable content in a nested browsing context to go fullscreen, it needs to be
+specifically allowed via feature policy, either through the <{iframe/allowfullscreen}> attribute of
+the HTML <{iframe}> element, or an appropriate declaration in the <{iframe/allow}> attribute of the
+HTML <{iframe}> element, or through a `Feature-Policy
` HTTP header
+delivered with the document through which it is nested.
+
+
This prevents, e.g., content from third parties to go fullscreen without explicit permission. + + + +
Many thanks to Robert O'Callahan for designing the initial model and being awesome. + + +
Thanks to +Andy Earnshaw, +Changwan Hong, +Chris Pearce, +Darin Fisher, +Dave Tapuska, +fantasai, +Giuseppe Pascale, +Glenn Maynard, +Ian Clelland, +Ian Hickson, +Ignacio Solla, +João Eiras, +Josh Soref, +Kagami Sascha Rosylight, +Matt Falkenhagen, +Mihai Balan, +Mounir Lamouri, +Øyvind Stenhaug, +Pat Ladd, +Rafał Chłodnicki, +Riff Jiang, +Rune Lillesveen, +Sigbjørn Vik, +Simon Pieters, +Tab Atkins, +Takayoshi Kochi, +Theresa O'Connor, +triple-underscore, +Vincent Scheib, and +Xidorn Quan +for also being awesome. + +
This standard is edited by Philip Jägenstedt +(Google, +philip@foolip.org). It was originally written by +Anne van Kesteren +(Mozilla, +annevk@annevk.nl). +Tantek Çelik +(Mozilla, +tantek@cs.stanford.edu) sorted out legal hassles.