@@ -39,6 +39,7 @@ spec:dom; type:dfn; text:origin
3939spec:dom; type:interface; text:Document
4040spec:html; type:attribute; for:HTMLMediaElement; text:readyState
4141spec:html; type:dfn; for:/; text:browsing context
42+ spec:html; type:dfn; text:allowed to use
4243spec:infra; type:dfn; text:user agent
4344spec:infra; type:dfn; for:list; text:item
4445</pre>
@@ -167,53 +168,31 @@ to initiate and control this behavior by exposing the following sets of properti
167168
168169# Concepts # {#concepts}
169170
170- ## Internal Slot Definitions ## {#defines}
171+ ## Definitions ## {#defines}
172+
173+ A <dfn>Picture-in-Picture window</dfn> is a window displaying the <{video}> element.
174+
175+ A {{DocumentOrShadowRoot}} has:
176+
177+ 1. A <dfn>Picture-in-Picture element</dfn> , which is an {{Element}} or `null`, initially `null`.
178+
179+ A <a for="/">traversable navigable</a> has:
180+ 1. A <dfn>picture-in-picture parallel queue</dfn> , which is a [=parallel queue=] created by
181+ [=starting a new parallel queue=] .
182+
171183
172184A <a>user agent</a> has:
173185
1741861. An <dfn>initiators of active Picture-in-Picture sessions</dfn>
175187 list of zero or more <a>origins</a> , which is initially empty.
176188
177- Note: In case a <a>user agent</a> supports multiple Picture-in-Picture
178- windows, the list allows duplicates.
189+ Note: In case a <a>user agent</a> supports multiple Picture-in-Picture windows, the list allows duplicates.
179190
180191An origin is said to have an active Picture-in-Picture session if any
181192of the origins in <a>initiators of active Picture-in-Picture sessions</a>
182193are <a>same origin-domain</a> with origin.
183194
184- ## Request Picture-in-Picture ## {#request-pip}
185-
186- When the <dfn>request Picture-in-Picture algorithm</dfn> with |video| is invoked,
187- the user agent MUST run the following steps:
188-
189- 1. If <a>Picture-in-Picture support</a> is `false`, throw a
190- {{NotSupportedError}} and abort these steps.
191- 2. If the document is not <a>allowed to use</a> the <a>policy-controlled feature</a>
192- named `"picture-in-picture"`, throw a {{SecurityError}} and abort these
193- steps.
194- 3. If |video|'s {{readyState}} attribute is {{HAVE_NOTHING}} , throw a
195- {{InvalidStateError}} and abort these steps.
196- 4. If |video| has no video track, throw a {{InvalidStateError}} and abort
197- these steps.
198- 5. If |video|'s {{HTMLVideoElement/disablePictureInPicture}} is true,
199- the user agent MAY throw an {{InvalidStateError}} and abort these steps.
200- 6. If {{pictureInPictureElement}} is `null`:
201- 1. If <a>this</a> 's <a>relevant global object</a> does not have
202- <a>transient activation</a> , throw a {{NotAllowedError}} and abort these steps.
203- 2. [=Consume user activation=] given <a>this</a> 's <a>relevant global object</a> .
204- 7. If |video| is {{pictureInPictureElement}} , abort these steps.
205- 8. Set {{pictureInPictureElement}} to |video|.
206- 9. Let <dfn>Picture-in-Picture window</dfn> be a new instance of
207- {{PictureInPictureWindow}} associated with {{pictureInPictureElement}} .
208- 10. Append <a>relevant settings object</a> 's <a>origin</a> to
209- <a>initiators of active Picture-in-Picture sessions</a> .
210- 11. <a>Queue a task</a> to <a>fire an event</a> named
211- {{enterpictureinpicture}} using {{PictureInPictureEvent}} at the
212- |video| with its {{bubbles}} attribute initialized to `true` and its
213- {{PictureInPictureEvent/pictureInPictureWindow}} attribute initialized to
214- <a>Picture-in-Picture window</a> .
215- 12. If {{pictureInPictureElement}} is <a>fullscreenElement</a> , it is
216- RECOMMENDED to <a>exit fullscreen</a> .
195+ ## Picture-in-Picture ## {#pip}
217196
218197It is RECOMMENDED that video frames are not rendered in the page and in the
219198Picture-in-Picture window at the same time but if they are, they MUST be kept
@@ -233,7 +212,7 @@ It is also RECOMMENDED that the Picture-in-Picture window has a maximum and
233212minimum size. For example, it could be restricted to be between a quarter and
234213a half of one dimension of the screen.
235214
236- When a {{DocumentOrShadowRoot}} 's {{pictureInPictureElement}} attribute is set,
215+ When a {{DocumentOrShadowRoot}} 's <a>Picture-in-Picture element</a> is set,
237216the [=Picture-in-Picture window=] MUST be visible, even when the
238217{{DocumentOrShadowRoot}} 's [=relevant global object=]' s [=associated Document=] 's
239218[=Document/visibility state=] is "hidden".
@@ -332,16 +311,48 @@ partial interface HTMLVideoElement {
332311};
333312</pre>
334313
335- The {{requestPictureInPicture()}} method, when invoked, MUST
336- return <a>a new promise</a> |promise| and run the following steps <a>in
337- parallel</a> :
314+ The {{requestPictureInPicture()}} method steps <dfn export>request Picture-in-Picture</dfn> :
315+
316+ 1. If [=Picture-in-Picture support=] is `false`, return [=a promise rejected with=] {{NotSupportedError}} {{DOMException}} .
317+ 2. Let |doc| be [=this=] 's [=node document=] .
318+ 3. If |doc| is not [=allowed to use=] the [=policy-controlled feature=]
319+ named `"picture-in-picture"`, return [=a promise rejected with=] {{NotAllowedError}} {{DOMException}} .
320+ 4. If [=this=] 's {{readyState}} attribute is {{HAVE_NOTHING}} , return [=a promise rejected with=] {{InvalidStateError}} {{DOMException}} .
321+ 5. If [=this=] has no video track, return [=a promise rejected with=] {{InvalidStateError}} {{DOMException}} .
322+ 6. If [=this=] 's {{HTMLVideoElement/disablePictureInPicture}} is true, user agent may return [=a promise rejected with=] {{InvalidStateError}} {{DOMException}} .
323+ 7. If |doc|'s [=Picture-in-Picture element=] is `null`:
324+ 1. If [=this=] 's [=relevant global object=] does not have a [=transient activation=] , then return [=a
325+ promise rejected with=] {{NotAllowedError}} {{DOMException}} .
326+ 2. [=Consume user activation=] given [=this=] 's [=relevant global object=] .
327+ 8. If [=this=] is |doc|'s [=Picture-in-Picture element=] :
328+ 1. Return [=a promise resolved with=] the [=Picture-in-Picture window=] associated with |doc|'s [=Picture-in-Picture element=] .
329+ 9. Let |global| be [=this=] 's [=relevant global object=] .
330+ 10. Let |p| be [=a new promise=] created in [=this=] 's [=relevant realm=] .
331+ 11. Return |p|, and [=enqueue the following steps=] to |doc|'s [=picture-in-picture parallel queue=] :
332+ 1. If [=this=] is |doc|'s [=Picture-in-Picture element=] :
333+ 1. [=Queue a global task=] on the [=media element event task source=] given |global| to
334+ [=/resolve=] |p| with the [=Picture-in-Picture window=] associated with
335+ [=this=] .
336+ 2. Abort these steps.
337+ 2. Attempt to associate a [=Picture-in-Picture window=] with [=this=] .
338+ 3. If the previous step failed:
339+ 1. [=Queue a global task=] on the [=media element event task source=] given |global| to
340+ [=/reject=] |p| with {{InvalidStateError}} {{DOMException}} .
341+ 2. Abort these steps.
342+ 4. Let |pipWindow| be a new instance of {{PictureInPictureWindow}} that represents [=this=] 's associated [=Picture-in-Picture window=] .
343+ 5. [=Queue a global task=] on the [=media element event task source=] given |global|, to perform
344+ the following steps:
345+ 1. If {{pictureInPictureElement}} is not `null`, run the [=exit Picture-in-Picture algorithm=] .
346+ 2. Set |doc|'s [=Picture-in-Picture element=] to [=this=] .
347+ 3. [=list/Append=] [=relevant settings object=] 's [=origin=] to [=initiators of active
348+ Picture-in-Picture sessions=] .
349+ 4. If [=this=] is [=fullscreenElement=] , [=exit fullscreen=] .
350+ 5. [=Fire an event=] named {{enterpictureinpicture}} using {{PictureInPictureEvent}} at
351+ [=this=] with its {{bubbles}} attribute initialized to `true` and its
352+ {{PictureInPictureEvent/pictureInPictureWindow}} attribute initialized to
353+ [=Picture-in-Picture window=] .
354+ 6. [=/Resolve=] |p| with |pipWindow|.
338355
339- 1. Let |video| be the video element on which the method was invoked.
340- 2. Run the <a>request Picture-in-Picture algorithm</a> with |video|.
341- 3. If the previous step threw an exception, reject |promise| with that
342- exception and abort these steps.
343- 4. [=/Resolve=] |promise| with the <a>Picture-in-Picture window</a> associated with
344- {{pictureInPictureElement}} .
345356
346357## Extensions to <code> Document</code> ## {#document-extensions}
347358
@@ -382,8 +393,7 @@ The {{pictureInPictureElement}} attribute's getter must run these steps:
382393
3833941. If <a>this</a> is a <a for=/>shadow root</a> and its <a for=DocumentFragment>host</a>
384395 is not <a>connected</a> , return `null` and abort these steps.
385- 2. Let |candidate| be the result of <a>retargeting</a> Picture-in-Picture
386- element against <a>this</a> .
396+ 2. Let |candidate| be the result of [=retargeting=] [=Picture-in-Picture element=] against [=this=] .
3873973. If |candidate| and <a>this</a> are in the same <a>tree</a> ,
388398 return |candidate| and abort these steps.
3893994. Return `null`.
@@ -468,8 +478,8 @@ regardless of the <a>browsing context</a>.
468478## Permissions Policy ## {#permissions-policy}
469479
470480This specification defines a <a>policy-controlled feature</a> named
471- `"picture-in-picture"` that controls whether the <a> request Picture-in-Picture
472- algorithm</a> may return a {{SecurityError}} and whether
481+ `"picture-in-picture"` that controls whether [= request Picture-in-Picture=]
482+ returns a {{SecurityError}} and whether
473483{{pictureInPictureEnabled}} is `true` or `false`.
474484
475485The <a>default allowlist</a> for this feature is `*`.
0 commit comments