diff --git a/index.bs b/index.bs
index f3ca41c..fbaaf11 100644
--- a/index.bs
+++ b/index.bs
@@ -39,6 +39,7 @@ spec:dom; type:dfn; text:origin
spec:dom; type:interface; text:Document
spec:html; type:attribute; for:HTMLMediaElement; text:readyState
spec:html; type:dfn; for:/; text:browsing context
+spec:html; type:dfn; text:allowed to use
spec:infra; type:dfn; text:user agent
spec:infra; type:dfn; for:list; text:item
@@ -167,53 +168,31 @@ to initiate and control this behavior by exposing the following sets of properti
# Concepts # {#concepts}
-## Internal Slot Definitions ## {#defines}
+## Definitions ## {#defines}
+
+A Picture-in-Picture window is a window displaying the <{video}> element.
+
+A {{DocumentOrShadowRoot}} has:
+
+1. A Picture-in-Picture element, which is an {{Element}} or `null`, initially `null`.
+
+A traversable navigable has:
+1. A picture-in-picture parallel queue, which is a [=parallel queue=] created by
+ [=starting a new parallel queue=].
+
A user agent has:
1. An initiators of active Picture-in-Picture sessions
list of zero or more origins, which is initially empty.
-Note: In case a user agent supports multiple Picture-in-Picture
- windows, the list allows duplicates.
+ Note: In case a user agent supports multiple Picture-in-Picture windows, the list allows duplicates.
An origin is said to have an active Picture-in-Picture session if any
of the origins in initiators of active Picture-in-Picture sessions
are same origin-domain with origin.
-## Request Picture-in-Picture ## {#request-pip}
-
-When the request Picture-in-Picture algorithm with |video| is invoked,
-the user agent MUST run the following steps:
-
-1. If Picture-in-Picture support is `false`, throw a
- {{NotSupportedError}} and abort these steps.
-2. If the document is not allowed to use the policy-controlled feature
- named `"picture-in-picture"`, throw a {{SecurityError}} and abort these
- steps.
-3. If |video|'s {{readyState}} attribute is {{HAVE_NOTHING}}, throw a
- {{InvalidStateError}} and abort these steps.
-4. If |video| has no video track, throw a {{InvalidStateError}} and abort
- these steps.
-5. If |video|'s {{HTMLVideoElement/disablePictureInPicture}} is true,
- the user agent MAY throw an {{InvalidStateError}} and abort these steps.
-6. If {{pictureInPictureElement}} is `null`:
- 1. If this's relevant global object does not have
- transient activation, throw a {{NotAllowedError}} and abort these steps.
- 2. [=Consume user activation=] given this's relevant global object.
-7. If |video| is {{pictureInPictureElement}}, abort these steps.
-8. Set {{pictureInPictureElement}} to |video|.
-9. Let Picture-in-Picture window be a new instance of
- {{PictureInPictureWindow}} associated with {{pictureInPictureElement}}.
-10. Append relevant settings object's origin to
- initiators of active Picture-in-Picture sessions.
-11. Queue a task to fire an event named
- {{enterpictureinpicture}} using {{PictureInPictureEvent}} at the
- |video| with its {{bubbles}} attribute initialized to `true` and its
- {{PictureInPictureEvent/pictureInPictureWindow}} attribute initialized to
- Picture-in-Picture window.
-12. If {{pictureInPictureElement}} is fullscreenElement, it is
- RECOMMENDED to exit fullscreen.
+## Picture-in-Picture ## {#pip}
It is RECOMMENDED that video frames are not rendered in the page and in the
Picture-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
minimum size. For example, it could be restricted to be between a quarter and
a half of one dimension of the screen.
-When a {{DocumentOrShadowRoot}}'s {{pictureInPictureElement}} attribute is set,
+When a {{DocumentOrShadowRoot}}'s Picture-in-Picture element is set,
the [=Picture-in-Picture window=] MUST be visible, even when the
{{DocumentOrShadowRoot}}'s [=relevant global object=]'s [=associated Document=]'s
[=Document/visibility state=] is "hidden".
@@ -332,16 +311,48 @@ partial interface HTMLVideoElement {
};
-The {{requestPictureInPicture()}} method, when invoked, MUST
-return a new promise |promise| and run the following steps in
-parallel:
+The {{requestPictureInPicture()}} method steps request Picture-in-Picture:
+
+1. If [=Picture-in-Picture support=] is `false`, return [=a promise rejected with=] {{NotSupportedError}} {{DOMException}}.
+2. Let |doc| be [=this=]'s [=node document=].
+3. If |doc| is not [=allowed to use=] the [=policy-controlled feature=]
+ named `"picture-in-picture"`, return [=a promise rejected with=] {{NotAllowedError}} {{DOMException}}.
+4. If [=this=]'s {{readyState}} attribute is {{HAVE_NOTHING}}, return [=a promise rejected with=] {{InvalidStateError}} {{DOMException}}.
+5. If [=this=] has no video track, return [=a promise rejected with=] {{InvalidStateError}} {{DOMException}}.
+6. If [=this=]'s {{HTMLVideoElement/disablePictureInPicture}} is true, user agent may return [=a promise rejected with=] {{InvalidStateError}} {{DOMException}}.
+7. If |doc|'s [=Picture-in-Picture element=] is `null`:
+ 1. If [=this=]'s [=relevant global object=] does not have a [=transient activation=], then return [=a
+ promise rejected with=] {{NotAllowedError}} {{DOMException}}.
+ 2. [=Consume user activation=] given [=this=]'s [=relevant global object=].
+8. If [=this=] is |doc|'s [=Picture-in-Picture element=]:
+ 1. Return [=a promise resolved with=] the [=Picture-in-Picture window=] associated with |doc|'s [=Picture-in-Picture element=].
+9. Let |global| be [=this=]'s [=relevant global object=].
+10. Let |p| be [=a new promise=] created in [=this=]'s [=relevant realm=].
+11. Return |p|, and [=enqueue the following steps=] to |doc|'s [=picture-in-picture parallel queue=]:
+ 1. If [=this=] is |doc|'s [=Picture-in-Picture element=]:
+ 1. [=Queue a global task=] on the [=media element event task source=] given |global| to
+ [=/resolve=] |p| with the [=Picture-in-Picture window=] associated with
+ [=this=].
+ 2. Abort these steps.
+ 2. Attempt to associate a [=Picture-in-Picture window=] with [=this=].
+ 3. If the previous step failed:
+ 1. [=Queue a global task=] on the [=media element event task source=] given |global| to
+ [=/reject=] |p| with {{InvalidStateError}} {{DOMException}}.
+ 2. Abort these steps.
+ 4. Let |pipWindow| be a new instance of {{PictureInPictureWindow}} that represents [=this=]'s associated [=Picture-in-Picture window=].
+ 5. [=Queue a global task=] on the [=media element event task source=] given |global|, to perform
+ the following steps:
+ 1. If {{pictureInPictureElement}} is not `null`, run the [=exit Picture-in-Picture algorithm=].
+ 2. Set |doc|'s [=Picture-in-Picture element=] to [=this=].
+ 3. [=list/Append=] [=relevant settings object=]'s [=origin=] to [=initiators of active
+ Picture-in-Picture sessions=].
+ 4. If [=this=] is [=fullscreenElement=], [=exit fullscreen=].
+ 5. [=Fire an event=] named {{enterpictureinpicture}} using {{PictureInPictureEvent}} at
+ [=this=] with its {{bubbles}} attribute initialized to `true` and its
+ {{PictureInPictureEvent/pictureInPictureWindow}} attribute initialized to
+ [=Picture-in-Picture window=].
+ 6. [=/Resolve=] |p| with |pipWindow|.
-1. Let |video| be the video element on which the method was invoked.
-2. Run the request Picture-in-Picture algorithm with |video|.
-3. If the previous step threw an exception, reject |promise| with that
- exception and abort these steps.
-4. [=/Resolve=] |promise| with the Picture-in-Picture window associated with
- {{pictureInPictureElement}}.
## Extensions to Document ## {#document-extensions}
@@ -382,8 +393,7 @@ The {{pictureInPictureElement}} attribute's getter must run these steps:
1. If this is a shadow root and its host
is not connected, return `null` and abort these steps.
-2. Let |candidate| be the result of retargeting Picture-in-Picture
- element against this.
+2. Let |candidate| be the result of [=retargeting=] [=Picture-in-Picture element=] against [=this=].
3. If |candidate| and this are in the same tree,
return |candidate| and abort these steps.
4. Return `null`.
@@ -468,8 +478,8 @@ regardless of the browsing context.
## Permissions Policy ## {#permissions-policy}
This specification defines a policy-controlled feature named
-`"picture-in-picture"` that controls whether the request Picture-in-Picture
-algorithm may return a {{SecurityError}} and whether
+`"picture-in-picture"` that controls whether [=request Picture-in-Picture=]
+returns a {{SecurityError}} and whether
{{pictureInPictureEnabled}} is `true` or `false`.
The default allowlist for this feature is `*`.