From 4c58bff2aebf3d05e2c5c3f3e02b3dcb904744db Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Fri, 6 Feb 2026 16:32:48 +0100 Subject: [PATCH 01/34] Add commands for screencasting --- index.bs | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) diff --git a/index.bs b/index.bs index 217e2ae4c..960c09ee3 100644 --- a/index.bs +++ b/index.bs @@ -289,12 +289,17 @@ spec: CSSOM-VIEW; urlPrefix: https://drafts.csswg.org/cssom-view/ text: web-exposed screen area; url: #web-exposed-screen-area spec: DOM; urlPrefix: https://dom.spec.whatwg.org/ type: dfn + text: add an event listener; url: #add-an-event-listener text: root; url: #concept-tree-root text: document element; url: #ref-for-dom-document-documentelement text: evaluate; url: #dom-xpathevaluatorbase-evaluate text: nodes; url: #concept-node text: ORDERED_NODE_SNAPSHOT_TYPE; url: #dom-xpathresult-ordered_node_snapshot_type text: snapshotItem; url: #dom-xpathresult-snapshotitem +spec: FILE-API; urlPrefix: https://w3c.github.io/FileAPI/ + type: dfn + text: Blob; url: #dfn-Blob + text: blobParts; url: #dfn-blobParts spec: FULLSCREEN; urlPrefix: https://fullscreen.spec.whatwg.org/ type: dfn text: fullscreen an element; url: #fullscreen-an-element @@ -319,6 +324,14 @@ spec: ACCNAME; urlPrefix:https://www.w3.org/TR/accname-1.2 spec: CORE-AAM; urlPrefix:https://www.w3.org/TR/core-aam-1.2 type: dfn text: computed role; url: /#roleMappingComputedRole +spec: MEDIACAPTURE-RECORD; urlPrefix: https://w3c.github.io/mediacapture-record/ + type: dfn + text: is type supported; url: #abstract-opdef-is-type-supported + text: MediaRecorder; url: #mediarecorder-api + text: MediaRecorderOptions; url: #mediarecorderoptions-section +spec: MEDIACAPTURE-SCREEN-SHARE; urlPrefix: https://w3c.github.io/mediacapture-screen-share/ + type: dfn + text: capture a browser tab; url: #dfn-capture-a-browser-tab spec: MEDIAQUERIES4; urlPrefix: https://drafts.csswg.org/mediaqueries-4/ type: dfn text: resolution media feature; url: #resolution @@ -671,6 +684,9 @@ with the following additional codes:
no such request
Tried to continue an unknown [=/request=]. +
no such screencast +
Tried to stop an unknown screencast recording. +
no such script
Tried to remove an unknown [=preload script=]. @@ -3146,6 +3162,8 @@ BrowsingContextCommand = ( browsingContext.Print // browsingContext.Reload // browsingContext.SetViewport // + browsingContext.StartScreencast // + browsingContext.StopScreencast // browsingContext.TraverseHistory ) @@ -3165,6 +3183,8 @@ BrowsingContextResult = ( browsingContext.PrintResult / browsingContext.ReloadResult / browsingContext.SetViewportResult / + browsingContext.StartScreencastResult / + browsingContext.StopScreencastResult / browsingContext.TraverseHistoryResult ) @@ -3234,6 +3254,13 @@ weak map between [=user context|user contexts=] and [=unhandled prompt behavior A [=remote end=] has a scripting enabled overrides map which is a weak map between [=/navigables=] or [=user context|user contexts=] and boolean. +A [=BiDi session=] has a screencast recordings map which is a [=/map=] in +which the keys are [[!RFC9562|UUID]]s, and the values are [=structs=] with +an [=struct/item=] named mediaRecorder, which is a {{MediaRecorder}}, +an [=struct/item=] named mimeType, which is a string, +an [=struct/item=] named recordedChunks, which is a list, +an [=struct/item=] named context, which is a navigable. + ### Types ### {#module-browsingcontext-types} #### The browsingContext.BrowsingContext Type #### {#type-browsingContext-Browsingcontext} @@ -5086,6 +5113,179 @@ The [=remote end steps=] with |command parameters| are: +#### The browsingContext.startScreencast Command #### {#command-browsingContext-startScreencast} + +The browsingContext.startScreencast command +starts the screencast of a given navigable according to provided options. + +
+
Command Type
+
+
+      browsingContext.StartScreencast = (
+        method: "browsingContext.startScreencast",
+        params: browsingContext.StartScreencastParameters
+      )
+
+      browsingContext.StartScreencastParameters = {
+        context: browsingContext.BrowsingContext,
+        mimeType: text,
+        ? streamOptions: browsingContext.MediaStreamOptions,
+      }
+
+      browsingContext.MediaStreamOptions = {
+         ? video: bool / browsingContext.MediaTrackConstraints .default true;
+         ? audio: bool / browsingContext.MediaTrackConstraints .default false;
+      }
+
+      browsingContext.MediaTrackConstraints = {
+         ? width: js-uint,
+         ? height: js-uint,
+         ? aspectRatio: js-uint,
+         ? frameRate: js-uint,
+         ? facingMode: text,
+         ? resizeMode: text,
+         ? sampleRate: js-uint,
+         ? sampleSize: js-uint,
+         ? echoCancellation: bool / text,
+         ? autoGainControl: bool,
+         ? noiseSuppression: bool,
+         ? latency: js-uint,
+         ? channelCount: js-uint,
+         ? deviceId: text,
+         ? groupId: text,
+         ? backgroundBlur: bool
+      }
+
+      
+
+
Return Type
+
+
+      browsingContext.StartScreencastResult = {
+         screencast: browsingContext.Screencast
+      }
+
+      browsingContext.Screencast = text
+    
+
+
+ +
+The [=remote end steps=] with |command parameters| are: + +1. Let |navigable| be the result of [=trying=] to [=get a navigable=] + with |command parameters|["context"]. + +1. If |navigable| is not a [=/top-level traversable=], return [=error=] with + [=error code=] [=invalid argument=]. + +1. Let |mime type| to be |command parameters|["mimeType"]. + +1. If [=is type supported=] with |mime type| returns false, return [=error=] with + [=error code=] [=invalid argument=]. + +1. If the implementation is unable to record a screencast of |navigable| for any + reason then return [=error=] with [=error code=] [=unsupported operation=]. + +1. Let |media stream| be the result of [=trying=] to [=capture a browser tab=] with + |navigable| and |command parameters|["streamOptions"]. + +1. Let |recorded chunks| be an empty [=/list=]. + +1. Let |media recorder options| be a struct with mimeType |mime type|. + +1. Let |media recorder| be a new {{MediaRecorder}} with {{MediaRecorder/stream}} |media stream| and + {{MediaRecorderOptions}} |media recorder options|. + +1. [=Add an event listener=] to |media recorder| with type {{MediaRecorder/dataavailable}} + and callback that performs the following steps given |event|: + + 1. Let |data| be |event|'s {{BlobEvent/data}}. + + 1. [=list/Append=] |data| to |recorded chunks|. + +1. Call {{MediaRecorder/start()}} on |media recorder|. + +1. Let |screencast| be the string representation of a [[!RFC9562|UUID]]. + +1. Set [=screencast recordings map=][|screencast|] to a struct with + mediaRecorder |media recorder|, + mimeType |mime type|, + recordedChunks |recorded chunks|, + context |navigable|. + +1. Return a new [=/map=] matching the browsingContext.StartScreencastResult + with the screencast field set to |screencast|. + +
+ +#### The browsingContext.stopScreencast Command #### {#command-browsingContext-stopScreencast} + +The browsingContext.stopScreencast command +stops the screencast. + +
+
Command Type
+
+
+      browsingContext.StopScreencast = (
+        method: "browsingContext.stopScreencast",
+        params: browsingContext.StopScreencastParameters
+      )
+
+      browsingContext.StopScreencastParameters = {
+        screencast: browsingContext.Screencast
+      }
+      
+
+
Return Type
+
+
+      browsingContext.StopScreencastResult = {
+         path: text
+      }
+    
+
+
+ +
+The [=remote end steps=] with |command parameters| are: + +1. Let |screencast| be the value of the "screencast" field in |command + parameters|. + +1. If [=screencast recordings map=] does not contain |screencast|, return + [=error=] with [=error code=] [=no such screencast=]. + +1. Let |screencast recording| be [=screencast recordings map=][|screencast|]. + +1. Let |media recorder| be |screencast recording|["mediaRecorder"]. + +1. Let |recorded chunks| be |screencast recording|["recordedChunks"]. + +1. Call {{MediaRecorder/stop()}} on |media recorder|. + +1. Wait until |media recorder|'s {{MediaRecorder/stop}} [=fire an event|event fires=]. + +1. Let |blob options| be a struct with type |screencast recording|["mimeType"]. + +1. Let |blob| to be a new {{Blob}} with {{blobParts}} |recorded chunks| and + {{BlobPropertyBag}} |blob options|. + +1. Let |path| be an implementation-defined file path where the recording will be stored. + +1. Let |bytes| be |blob|'s underlying [=byte sequence=]. + +1. Write |bytes| to the file system at |path|. + +1. [=map/Remove=] |screencast| from [=screencast recordings map=]. + +1. Return a new [=/map=] matching the browsingContext.StopScreencastResult + with the path field set to |path|. + +
+ #### The browsingContext.traverseHistory Command #### {#command-browsingContext-traverseHistory} The browsingContext.traverseHistory command From 6bdfd0e88c5506c1cc217ae135625d5281468904 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Mon, 9 Feb 2026 13:37:06 +0100 Subject: [PATCH 02/34] Await on the promise returned from "capture a browser tab". --- index.bs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.bs b/index.bs index 960c09ee3..9c959632d 100644 --- a/index.bs +++ b/index.bs @@ -5188,9 +5188,11 @@ The [=remote end steps=] with |command parameters| are: 1. If the implementation is unable to record a screencast of |navigable| for any reason then return [=error=] with [=error code=] [=unsupported operation=]. -1. Let |media stream| be the result of [=trying=] to [=capture a browser tab=] with +1. Let |promise| be the result of [=trying=] to [=capture a browser tab=] with |navigable| and |command parameters|["streamOptions"]. +1. Let |media stream| be Await(|promise|). + 1. Let |recorded chunks| be an empty [=/list=]. 1. Let |media recorder options| be a struct with mimeType |mime type|. From 55bcbcc360d1c93d35578dc7a2e83b99e3abcb18 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Mon, 9 Feb 2026 14:31:53 +0100 Subject: [PATCH 03/34] Create MediaRecorder and Blob in navigable's window realm. --- index.bs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index 9c959632d..7be355766 100644 --- a/index.bs +++ b/index.bs @@ -5174,8 +5174,10 @@ starts the screencast of a given navigable according to provided options.
The [=remote end steps=] with |command parameters| are: +1. Let |navigable id| be |command parameters|["context"]. + 1. Let |navigable| be the result of [=trying=] to [=get a navigable=] - with |command parameters|["context"]. + with |navigable id|. 1. If |navigable| is not a [=/top-level traversable=], return [=error=] with [=error code=] [=invalid argument=]. @@ -5188,6 +5190,9 @@ The [=remote end steps=] with |command parameters| are: 1. If the implementation is unable to record a screencast of |navigable| for any reason then return [=error=] with [=error code=] [=unsupported operation=]. +1. Let realm be the result of [=trying=] to [=get a realm from a navigable=] + with |navigable id| and null. + 1. Let |promise| be the result of [=trying=] to [=capture a browser tab=] with |navigable| and |command parameters|["streamOptions"]. @@ -5197,7 +5202,8 @@ The [=remote end steps=] with |command parameters| are: 1. Let |media recorder options| be a struct with mimeType |mime type|. -1. Let |media recorder| be a new {{MediaRecorder}} with {{MediaRecorder/stream}} |media stream| and +1. Let |media recorder| be a new {{MediaRecorder}} in |realm| + with {{MediaRecorder/stream}} |media stream| and {{MediaRecorderOptions}} |media recorder options|. 1. [=Add an event listener=] to |media recorder| with type {{MediaRecorder/dataavailable}} @@ -5266,13 +5272,18 @@ The [=remote end steps=] with |command parameters| are: 1. Let |recorded chunks| be |screencast recording|["recordedChunks"]. +1. Let |navigable id| be the [=navigable id=] for |screencast recording|["navigable"]. + +1. Let realm be the result of [=trying=] to [=get a realm from a navigable=] + with |navigable id| and null. + 1. Call {{MediaRecorder/stop()}} on |media recorder|. 1. Wait until |media recorder|'s {{MediaRecorder/stop}} [=fire an event|event fires=]. 1. Let |blob options| be a struct with type |screencast recording|["mimeType"]. -1. Let |blob| to be a new {{Blob}} with {{blobParts}} |recorded chunks| and +1. Let |blob| to be a new {{Blob}} in |realm| with {{blobParts}} |recorded chunks| and {{BlobPropertyBag}} |blob options|. 1. Let |path| be an implementation-defined file path where the recording will be stored. From b0d2460e09f00d9497dcec44f729b21e7788fe98 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Mon, 9 Feb 2026 14:54:29 +0100 Subject: [PATCH 04/34] Remove "facingMode" and "backgroundBlur" from "streamOptnios" since they are camera specific. --- index.bs | 2 -- 1 file changed, 2 deletions(-) diff --git a/index.bs b/index.bs index 7be355766..bcc1e8c52 100644 --- a/index.bs +++ b/index.bs @@ -5143,7 +5143,6 @@ starts the screencast of a given navigable according to provided options. ? height: js-uint, ? aspectRatio: js-uint, ? frameRate: js-uint, - ? facingMode: text, ? resizeMode: text, ? sampleRate: js-uint, ? sampleSize: js-uint, @@ -5154,7 +5153,6 @@ starts the screencast of a given navigable according to provided options. ? channelCount: js-uint, ? deviceId: text, ? groupId: text, - ? backgroundBlur: bool } From 2da09c5e30cd392083e74055978474b915b43279 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Fri, 13 Feb 2026 17:32:42 +0100 Subject: [PATCH 05/34] Update index.bs Co-authored-by: Maksim Sadym <69349599+sadym-chromium@users.noreply.github.com> --- index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.bs b/index.bs index bcc1e8c52..21eb4910b 100644 --- a/index.bs +++ b/index.bs @@ -3258,7 +3258,7 @@ A [=BiDi session=] has a screencast recordings map which is a [=/map= which the keys are [[!RFC9562|UUID]]s, and the values are [=structs=] with an [=struct/item=] named mediaRecorder, which is a {{MediaRecorder}}, an [=struct/item=] named mimeType, which is a string, -an [=struct/item=] named recordedChunks, which is a list, +an [=struct/item=] named recordedChunks, which is a [=/list=] of {{BlobEvent/data}}, an [=struct/item=] named context, which is a navigable. ### Types ### {#module-browsingcontext-types} From 28d45b43ae668b440b07251fb0ae201ab87fc6f5 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Fri, 13 Feb 2026 18:20:27 +0100 Subject: [PATCH 06/34] Limit "browsingContext.MediaTrackConstraints". --- index.bs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/index.bs b/index.bs index 21eb4910b..f8ecbc1fb 100644 --- a/index.bs +++ b/index.bs @@ -5135,24 +5135,12 @@ starts the screencast of a given navigable according to provided options. browsingContext.MediaStreamOptions = { ? video: bool / browsingContext.MediaTrackConstraints .default true; - ? audio: bool / browsingContext.MediaTrackConstraints .default false; + ? audio: bool .default false; } browsingContext.MediaTrackConstraints = { ? width: js-uint, ? height: js-uint, - ? aspectRatio: js-uint, - ? frameRate: js-uint, - ? resizeMode: text, - ? sampleRate: js-uint, - ? sampleSize: js-uint, - ? echoCancellation: bool / text, - ? autoGainControl: bool, - ? noiseSuppression: bool, - ? latency: js-uint, - ? channelCount: js-uint, - ? deviceId: text, - ? groupId: text, } From 00a00946d28376f25f10cc1a0cdb85666f305269 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Fri, 20 Feb 2026 17:26:27 +0100 Subject: [PATCH 07/34] Update index.bs Co-authored-by: Julian Descottes --- index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.bs b/index.bs index f8ecbc1fb..f79ab43ce 100644 --- a/index.bs +++ b/index.bs @@ -5168,7 +5168,7 @@ The [=remote end steps=] with |command parameters| are: 1. If |navigable| is not a [=/top-level traversable=], return [=error=] with [=error code=] [=invalid argument=]. -1. Let |mime type| to be |command parameters|["mimeType"]. +1. Let |mime type| be |command parameters|["mimeType"]. 1. If [=is type supported=] with |mime type| returns false, return [=error=] with [=error code=] [=invalid argument=]. From f8c150ce1dbef80f187067b5d61070eeec273ffb Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Tue, 24 Feb 2026 15:26:10 +0100 Subject: [PATCH 08/34] Use "capture a browsing context viewport" algorithm instead "capture a browser tab". --- index.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index f79ab43ce..37e542d7b 100644 --- a/index.bs +++ b/index.bs @@ -329,9 +329,9 @@ spec: MEDIACAPTURE-RECORD; urlPrefix: https://w3c.github.io/mediacapture-record/ text: is type supported; url: #abstract-opdef-is-type-supported text: MediaRecorder; url: #mediarecorder-api text: MediaRecorderOptions; url: #mediarecorderoptions-section -spec: MEDIACAPTURE-SCREEN-SHARE; urlPrefix: https://w3c.github.io/mediacapture-screen-share/ +spec: MEDIACAPTURE-VIEWPORT; urlPrefix: https://w3c.github.io/mediacapture-viewport/ type: dfn - text: capture a browser tab; url: #dfn-capture-a-browser-tab + text: capture a browsing context viewport; url: #dfn-capture-a-browsing-context-viewport spec: MEDIAQUERIES4; urlPrefix: https://drafts.csswg.org/mediaqueries-4/ type: dfn text: resolution media feature; url: #resolution @@ -5179,7 +5179,7 @@ The [=remote end steps=] with |command parameters| are: 1. Let realm be the result of [=trying=] to [=get a realm from a navigable=] with |navigable id| and null. -1. Let |promise| be the result of [=trying=] to [=capture a browser tab=] with +1. Let |promise| be the result of [=trying=] to [=capture a browsing context viewport=] with |navigable| and |command parameters|["streamOptions"]. 1. Let |media stream| be Await(|promise|). From d60f8bccbc937f21db8724c4e25bacc6c71eaa09 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Tue, 24 Feb 2026 16:18:50 +0100 Subject: [PATCH 09/34] Add "size" to the "browsingContext.stopScreencast" return result. --- index.bs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/index.bs b/index.bs index 37e542d7b..8556b38ed 100644 --- a/index.bs +++ b/index.bs @@ -5237,7 +5237,8 @@ stops the screencast.
       browsingContext.StopScreencastResult = {
-         path: text
+         path: text,
+         size: js-uint
       }
     
@@ -5281,7 +5282,7 @@ The [=remote end steps=] with |command parameters| are: 1. [=map/Remove=] |screencast| from [=screencast recordings map=]. 1. Return a new [=/map=] matching the browsingContext.StopScreencastResult - with the path field set to |path|. + with the path field set to |path| and size field set to |blob|'s {{Blob/size}}. From e77992592f9f474a54ac0c940b00eaf0e64e76bf Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Tue, 24 Feb 2026 17:13:44 +0100 Subject: [PATCH 10/34] Write to the file while recording the screencast --- index.bs | 52 ++++++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/index.bs b/index.bs index 8556b38ed..c398399e0 100644 --- a/index.bs +++ b/index.bs @@ -3258,7 +3258,8 @@ A [=BiDi session=] has a screencast recordings map which is a [=/map= which the keys are [[!RFC9562|UUID]]s, and the values are [=structs=] with an [=struct/item=] named mediaRecorder, which is a {{MediaRecorder}}, an [=struct/item=] named mimeType, which is a string, -an [=struct/item=] named recordedChunks, which is a [=/list=] of {{BlobEvent/data}}, +an [=struct/item=] named path, which is a string, +an [=struct/item=] named size, which is a number, an [=struct/item=] named context, which is a navigable. ### Types ### {#module-browsingcontext-types} @@ -5149,7 +5150,8 @@ starts the screencast of a given navigable according to provided options.
       browsingContext.StartScreencastResult = {
-         screencast: browsingContext.Screencast
+         screencast: browsingContext.Screencast,
+         path: text
       }
 
       browsingContext.Screencast = text
@@ -5184,7 +5186,7 @@ The [=remote end steps=] with |command parameters| are:
 
 1. Let |media stream| be Await(|promise|).
 
-1. Let |recorded chunks| be an empty [=/list=].
+1. Let |path| be an implementation-defined file path where the recording will be stored.
 
 1. Let |media recorder options| be a struct with mimeType |mime type|.
 
@@ -5192,25 +5194,33 @@ The [=remote end steps=] with |command parameters| are:
    with {{MediaRecorder/stream}} |media stream| and
    {{MediaRecorderOptions}} |media recorder options|.
 
+1. Let |recording| be a new [=struct=] with
+   mediaRecorder |media recorder|,
+   mimeType |mime type|,
+   path |path|,
+   size 0,
+   context |navigable|.
+
 1. [=Add an event listener=] to |media recorder| with type {{MediaRecorder/dataavailable}}
    and callback that performs the following steps given |event|:
 
    1. Let |data| be |event|'s {{BlobEvent/data}}.
 
-   1. [=list/Append=] |data| to |recorded chunks|.
+   1. Let |bytes| be |data|'s underlying [=byte sequence=].
 
-1. Call {{MediaRecorder/start()}} on |media recorder|.
+   1. Append |bytes| to the file at |path|.
+
+   1. Set |recording|["size"] to |recording|["size"] + |bytes|'s length.
+
+1. Call {{MediaRecorder/start()}} on |media recorder| with 1000.
 
 1. Let |screencast| be the string representation of a [[!RFC9562|UUID]].
 
-1. Set [=screencast recordings map=][|screencast|] to a struct with
-   mediaRecorder |media recorder|,
-   mimeType |mime type|,
-   recordedChunks |recorded chunks|,
-   context |navigable|.
+1. Set [=screencast recordings map=][|screencast|] to |recording|.
 
 1. Return a new [=/map=] matching the browsingContext.StartScreencastResult
-   with the screencast field set to |screencast|.
+   with the screencast field set to |screencast| and path field
+   set to |path|.
 
 
 
@@ -5257,32 +5267,18 @@ The [=remote end steps=] with |command parameters| are:
 
 1. Let |media recorder| be |screencast recording|["mediaRecorder"].
 
-1. Let |recorded chunks| be |screencast recording|["recordedChunks"].
-
-1. Let |navigable id| be the [=navigable id=] for |screencast recording|["navigable"].
-
-1. Let realm be the result of [=trying=] to [=get a realm from a navigable=]
-   with |navigable id| and null.
+1. Let |path| be |screencast recording|["path"].
 
 1. Call {{MediaRecorder/stop()}} on |media recorder|.
 
 1. Wait until |media recorder|'s {{MediaRecorder/stop}} [=fire an event|event fires=].
 
-1. Let |blob options| be a struct with type |screencast recording|["mimeType"].
-
-1. Let |blob| to be a new {{Blob}} in |realm| with {{blobParts}} |recorded chunks| and
-   {{BlobPropertyBag}} |blob options|.
-
-1. Let |path| be an implementation-defined file path where the recording will be stored.
-
-1. Let |bytes| be |blob|'s underlying [=byte sequence=].
-
-1. Write |bytes| to the file system at |path|.
+1. Let |size| be |screencast recording|["size"].
 
 1. [=map/Remove=] |screencast| from [=screencast recordings map=].
 
 1. Return a new [=/map=] matching the browsingContext.StopScreencastResult
-   with the path field set to |path| and size field set to |blob|'s {{Blob/size}}.
+   with the path field set to |path| and size field set to |size|.
 
 
 

From b2d6c410b171981503b3673ab1672cade23ec64b Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Tue, 24 Feb 2026 17:21:20 +0100
Subject: [PATCH 11/34] Stop screencast media recorders during a session
 cleanup

---
 index.bs | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/index.bs b/index.bs
index c398399e0..0d7ddfbbf 100644
--- a/index.bs
+++ b/index.bs
@@ -1709,6 +1709,12 @@ To cleanup the session given |session|:
    1. For each |collected data| in [=collected network data=], [=remove collector from data=]
       with |collected data| and |collector id|.
 
+1. For each |screencast recording| in |session|'s [=screencast recordings map=]:
+
+   1. Let |media recorder| be |screencast recording|["mediaRecorder"].
+
+   1. Call {{MediaRecorder/stop()}} on |media recorder|.
+
 1. If [=active sessions=] is [=list/empty=], [=cleanup remote end state=].
 
 1. Perform any implementation-specific cleanup steps.

From 47af8584d24e08f418540032b8188b9f63abdf31 Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Tue, 24 Feb 2026 18:20:33 +0100
Subject: [PATCH 12/34] Use linkable definition in "screencast recordings map".

---
 index.bs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/index.bs b/index.bs
index 0d7ddfbbf..2eefab015 100644
--- a/index.bs
+++ b/index.bs
@@ -3262,11 +3262,11 @@ map between [=/navigables=] or [=user context|user contexts=] and boolean.
 
 A [=BiDi session=] has a screencast recordings map which is a [=/map=] in
 which the keys are [[!RFC9562|UUID]]s, and the values are [=structs=] with
-an [=struct/item=] named mediaRecorder, which is a {{MediaRecorder}},
-an [=struct/item=] named mimeType, which is a string,
-an [=struct/item=] named path, which is a string,
-an [=struct/item=] named size, which is a number,
-an [=struct/item=] named context, which is a navigable.
+an [=struct/item=] named mediaRecorder, which is a {{MediaRecorder}},
+an [=struct/item=] named mimeType, which is a string,
+an [=struct/item=] named path, which is a string,
+an [=struct/item=] named size, which is a number,
+an [=struct/item=] named context, which is a navigable.
 
 ### Types ### {#module-browsingcontext-types}
 

From 96a9c40b9ca9b132493f5e9b8ee1b67c3b84a92c Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Wed, 25 Feb 2026 11:28:41 +0100
Subject: [PATCH 13/34] Fix "screencast recording" struct.

---
 index.bs | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/index.bs b/index.bs
index 2eefab015..3c04328c7 100644
--- a/index.bs
+++ b/index.bs
@@ -3261,12 +3261,10 @@ A [=remote end=] has a scripting enabled overrides map which is a wea
 map between [=/navigables=] or [=user context|user contexts=] and boolean.
 
 A [=BiDi session=] has a screencast recordings map which is a [=/map=] in
-which the keys are [[!RFC9562|UUID]]s, and the values are [=structs=] with
-an [=struct/item=] named mediaRecorder, which is a {{MediaRecorder}},
-an [=struct/item=] named mimeType, which is a string,
-an [=struct/item=] named path, which is a string,
-an [=struct/item=] named size, which is a number,
-an [=struct/item=] named context, which is a navigable.
+which the keys are [[!RFC9562|UUID]]s, and the values are screencast recording, which is a [=struct=] with
+an [=struct/item=] named mediaRecorder, which is a {{MediaRecorder}},
+an [=struct/item=] named path, which is a string,
+an [=struct/item=] named size, which is a number.
 
 ### Types ### {#module-browsingcontext-types}
 
@@ -5200,12 +5198,10 @@ The [=remote end steps=] with |command parameters| are:
    with {{MediaRecorder/stream}} |media stream| and
    {{MediaRecorderOptions}} |media recorder options|.
 
-1. Let |recording| be a new [=struct=] with
+1. Let |recording| be a new [=screencast recording=] with
    mediaRecorder |media recorder|,
-   mimeType |mime type|,
    path |path|,
-   size 0,
-   context |navigable|.
+   size 0.
 
 1. [=Add an event listener=] to |media recorder| with type {{MediaRecorder/dataavailable}}
    and callback that performs the following steps given |event|:
@@ -5271,15 +5267,15 @@ The [=remote end steps=] with |command parameters| are:
 
 1. Let |screencast recording| be [=screencast recordings map=][|screencast|].
 
-1. Let |media recorder| be |screencast recording|["mediaRecorder"].
+1. Let |media recorder| be |screencast recording|'s [=screencast recording/mediaRecorder=].
 
-1. Let |path| be |screencast recording|["path"].
+1. Let |path| be |screencast recording|'s [=screencast recording/path=].
 
 1. Call {{MediaRecorder/stop()}} on |media recorder|.
 
 1. Wait until |media recorder|'s {{MediaRecorder/stop}} [=fire an event|event fires=].
 
-1. Let |size| be |screencast recording|["size"].
+1. Let |size| be |screencast recording|'s [=screencast recording/size=].
 
 1. [=map/Remove=] |screencast| from [=screencast recordings map=].
 

From 324013f2b859b4a8c6c746f523c70f0bf5858938 Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Wed, 25 Feb 2026 12:21:00 +0100
Subject: [PATCH 14/34] Fix remaining "screencast recording" items linking.

---
 index.bs | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/index.bs b/index.bs
index 3c04328c7..297027043 100644
--- a/index.bs
+++ b/index.bs
@@ -5192,16 +5192,17 @@ The [=remote end steps=] with |command parameters| are:
 
 1. Let |path| be an implementation-defined file path where the recording will be stored.
 
-1. Let |media recorder options| be a struct with mimeType |mime type|.
+1. Let |media recorder options| be a [=struct=] with an [=struct/item=] named mimeType
+   with the value |mime type|.
 
 1. Let |media recorder| be a new {{MediaRecorder}} in |realm|
    with {{MediaRecorder/stream}} |media stream| and
    {{MediaRecorderOptions}} |media recorder options|.
 
 1. Let |recording| be a new [=screencast recording=] with
-   mediaRecorder |media recorder|,
-   path |path|,
-   size 0.
+   [=screencast recording/mediaRecorder=] |media recorder|,
+   [=screencast recording/path=] |path|,
+   [=screencast recording/size=] 0.
 
 1. [=Add an event listener=] to |media recorder| with type {{MediaRecorder/dataavailable}}
    and callback that performs the following steps given |event|:
@@ -5212,7 +5213,7 @@ The [=remote end steps=] with |command parameters| are:
 
    1. Append |bytes| to the file at |path|.
 
-   1. Set |recording|["size"] to |recording|["size"] + |bytes|'s length.
+   1. Set |recording|'s [=screencast recording/size=] to |recording|'s [=screencast recording/size=] + |bytes|'s length.
 
 1. Call {{MediaRecorder/start()}} on |media recorder| with 1000.
 

From 7f881a8ffad57c9cbcc0aae922b61d01832e40ea Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Tue, 3 Mar 2026 16:24:47 +0100
Subject: [PATCH 15/34] Add "no such screencast" error to CDDL

---
 index.bs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/index.bs b/index.bs
index 297027043..6d624bafa 100644
--- a/index.bs
+++ b/index.bs
@@ -732,6 +732,7 @@ ErrorCode = "invalid argument" /
             "no such network data" /
             "no such node" /
             "no such request" /
+            "no such screencast" /
             "no such script" /
             "no such storage partition" /
             "no such user context" /

From 5b5859b3a3a28158d6445cf9e1d2948645ffdcb2 Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Wed, 4 Mar 2026 12:03:49 +0100
Subject: [PATCH 16/34] Add a command parameter for MediaRecorder timeslice.

---
 index.bs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/index.bs b/index.bs
index 6d624bafa..93996b061 100644
--- a/index.bs
+++ b/index.bs
@@ -5137,6 +5137,7 @@ starts the screencast of a given navigable according to provided options.
         context: browsingContext.BrowsingContext,
         mimeType: text,
         ? streamOptions: browsingContext.MediaStreamOptions,
+        ? timeslice: js-uint .default 1000
       }
 
       browsingContext.MediaStreamOptions = {
@@ -5216,7 +5217,7 @@ The [=remote end steps=] with |command parameters| are:
 
    1. Set |recording|'s [=screencast recording/size=] to |recording|'s [=screencast recording/size=] + |bytes|'s length.
 
-1. Call {{MediaRecorder/start()}} on |media recorder| with 1000.
+1. Call {{MediaRecorder/start()}} on |media recorder| with |command parameters|["timeslice"].
 
 1. Let |screencast| be the string representation of a [[!RFC9562|UUID]].
 

From 8322c7ddf547f7f552aab6bdd17050afeee38492 Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Wed, 4 Mar 2026 17:49:22 +0100
Subject: [PATCH 17/34] Return an error from "browsingContext.stopScreencast"
 when writing to a file fails.

---
 index.bs | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/index.bs b/index.bs
index 93996b061..32632705c 100644
--- a/index.bs
+++ b/index.bs
@@ -3265,7 +3265,8 @@ A [=BiDi session=] has a screencast recordings map which is a [=/map=
 which the keys are [[!RFC9562|UUID]]s, and the values are screencast recording, which is a [=struct=] with
 an [=struct/item=] named mediaRecorder, which is a {{MediaRecorder}},
 an [=struct/item=] named path, which is a string,
-an [=struct/item=] named size, which is a number.
+an [=struct/item=] named size, which is a number,
+an [=struct/item=] named writeError, which is a string.
 
 ### Types ### {#module-browsingcontext-types}
 
@@ -5213,9 +5214,14 @@ The [=remote end steps=] with |command parameters| are:
 
    1. Let |bytes| be |data|'s underlying [=byte sequence=].
 
-   1. Append |bytes| to the file at |path|.
+   1. If appending |bytes| to the file at |path| fails:
 
-   1. Set |recording|'s [=screencast recording/size=] to |recording|'s [=screencast recording/size=] + |bytes|'s length.
+      1. Set |recording|'s [=screencast recording/writeError=] to an
+         implementation-defined string describing the write failure.
+
+      1. Call {{MediaRecorder/stop()}} on |media recorder|.
+
+   1. Otherwise, set |recording|'s [=screencast recording/size=] to |recording|'s [=screencast recording/size=] + |bytes|'s length.
 
 1. Call {{MediaRecorder/start()}} on |media recorder| with |command parameters|["timeslice"].
 
@@ -5270,6 +5276,9 @@ The [=remote end steps=] with |command parameters| are:
 
 1. Let |screencast recording| be [=screencast recordings map=][|screencast|].
 
+1. If |screencast recording| contains [=screencast recording/writeError=], return
+   [=error=] with [=error code=] [=unknown error=].
+
 1. Let |media recorder| be |screencast recording|'s [=screencast recording/mediaRecorder=].
 
 1. Let |path| be |screencast recording|'s [=screencast recording/path=].

From 916d8bb9e438e7cf2b9eb14939f53259aa2ec0b3 Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Mon, 9 Mar 2026 09:40:23 +0100
Subject: [PATCH 18/34] Update index.bs

Co-authored-by: jgraham 
---
 index.bs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/index.bs b/index.bs
index 32632705c..86cb92b7a 100644
--- a/index.bs
+++ b/index.bs
@@ -5214,7 +5214,7 @@ The [=remote end steps=] with |command parameters| are:
 
    1. Let |bytes| be |data|'s underlying [=byte sequence=].
 
-   1. If appending |bytes| to the file at |path| fails:
+   1. Append |bytes| to the file at |path|. If this fails:
 
       1. Set |recording|'s [=screencast recording/writeError=] to an
          implementation-defined string describing the write failure.

From 02a4a03f58562ce3e9452f2be5efbd59ee8758cc Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Mon, 9 Mar 2026 14:55:57 +0100
Subject: [PATCH 19/34] Use map instead of struct for media recorder options.

---
 index.bs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/index.bs b/index.bs
index 86cb92b7a..0760a97e4 100644
--- a/index.bs
+++ b/index.bs
@@ -5195,8 +5195,8 @@ The [=remote end steps=] with |command parameters| are:
 
 1. Let |path| be an implementation-defined file path where the recording will be stored.
 
-1. Let |media recorder options| be a [=struct=] with an [=struct/item=] named mimeType
-   with the value |mime type|.
+1. Let |media recorder options| be a new [=/map=] with the mimeType field
+   set to |mime type|.
 
 1. Let |media recorder| be a new {{MediaRecorder}} in |realm|
    with {{MediaRecorder/stream}} |media stream| and

From 7e39e5ae8990d840db966dd8450fe23dd3cffa9b Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Mon, 9 Mar 2026 17:14:26 +0100
Subject: [PATCH 20/34] Use ECMA script Call when calling MediaRecorder
 methods.

---
 index.bs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/index.bs b/index.bs
index 0760a97e4..2d783981e 100644
--- a/index.bs
+++ b/index.bs
@@ -1714,7 +1714,7 @@ To cleanup the session given |session|:
 
    1. Let |media recorder| be |screencast recording|["mediaRecorder"].
 
-   1. Call {{MediaRecorder/stop()}} on |media recorder|.
+   1. [=Call=]({{MediaRecorder/stop}}, |media recorder|).
 
 1. If [=active sessions=] is [=list/empty=], [=cleanup remote end state=].
 
@@ -5219,11 +5219,11 @@ The [=remote end steps=] with |command parameters| are:
       1. Set |recording|'s [=screencast recording/writeError=] to an
          implementation-defined string describing the write failure.
 
-      1. Call {{MediaRecorder/stop()}} on |media recorder|.
+      1. [=Call=]({{MediaRecorder/stop}}, |media recorder|).
 
    1. Otherwise, set |recording|'s [=screencast recording/size=] to |recording|'s [=screencast recording/size=] + |bytes|'s length.
 
-1. Call {{MediaRecorder/start()}} on |media recorder| with |command parameters|["timeslice"].
+1. [=Call=]({{MediaRecorder/start}}, |media recorder|, |command parameters|["timeslice"]).
 
 1. Let |screencast| be the string representation of a [[!RFC9562|UUID]].
 
@@ -5283,7 +5283,7 @@ The [=remote end steps=] with |command parameters| are:
 
 1. Let |path| be |screencast recording|'s [=screencast recording/path=].
 
-1. Call {{MediaRecorder/stop()}} on |media recorder|.
+1. [=Call=]({{MediaRecorder/stop}}, |media recorder|).
 
 1. Wait until |media recorder|'s {{MediaRecorder/stop}} [=fire an event|event fires=].
 

From 1e3db0dd33f91627ae16547b66dae63a8e5179e5 Mon Sep 17 00:00:00 2001
From: Alexandra Borovova 
Date: Mon, 9 Mar 2026 17:16:06 +0100
Subject: [PATCH 21/34] Update the description from the
 "browsingContext.startScreencast" command and a note about the file cleanup.

---
 index.bs | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/index.bs b/index.bs
index 2d783981e..56b99213f 100644
--- a/index.bs
+++ b/index.bs
@@ -5123,7 +5123,12 @@ The [=remote end steps=] with |command parameters| are:
 #### The browsingContext.startScreencast Command ####  {#command-browsingContext-startScreencast}
 
 The browsingContext.startScreencast command
-starts the screencast of a given navigable according to provided options.
+starts the screencast of a given navigable and writes it to a file.
+
+Note: The [=remote end=] creates and writes the screencast file, but does not delete it.
+Cleaning up the file is left to the [=local end=]. In some configurations this might not be
+possible — for example, if the [=remote end=] has read/write access to the filesystem but
+the [=local end=] has only read-only access.
 
 
Command Type
From b2e14882059e497271527c30ef1cc053da6e85cd Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Tue, 10 Mar 2026 11:57:30 +0100 Subject: [PATCH 22/34] Remove "Add event listener". --- index.bs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/index.bs b/index.bs index 56b99213f..7e55bd328 100644 --- a/index.bs +++ b/index.bs @@ -289,7 +289,6 @@ spec: CSSOM-VIEW; urlPrefix: https://drafts.csswg.org/cssom-view/ text: web-exposed screen area; url: #web-exposed-screen-area spec: DOM; urlPrefix: https://dom.spec.whatwg.org/ type: dfn - text: add an event listener; url: #add-an-event-listener text: root; url: #concept-tree-root text: document element; url: #ref-for-dom-document-documentelement text: evaluate; url: #dom-xpathevaluatorbase-evaluate @@ -327,6 +326,7 @@ spec: CORE-AAM; urlPrefix:https://www.w3.org/TR/core-aam-1.2 spec: MEDIACAPTURE-RECORD; urlPrefix: https://w3c.github.io/mediacapture-record/ type: dfn text: is type supported; url: #abstract-opdef-is-type-supported + text: fire a blob event; url: #fire-a-blob-event text: MediaRecorder; url: #mediarecorder-api text: MediaRecorderOptions; url: #mediarecorderoptions-section spec: MEDIACAPTURE-VIEWPORT; urlPrefix: https://w3c.github.io/mediacapture-viewport/ @@ -5212,12 +5212,10 @@ The [=remote end steps=] with |command parameters| are: [=screencast recording/path=] |path|, [=screencast recording/size=] 0. -1. [=Add an event listener=] to |media recorder| with type {{MediaRecorder/dataavailable}} - and callback that performs the following steps given |event|: +1. Whenever the implementation is going to [=fire a blob event=] named {{MediaRecorder/dataavailable}} + at |media recorder| with |blob|, run the following steps: - 1. Let |data| be |event|'s {{BlobEvent/data}}. - - 1. Let |bytes| be |data|'s underlying [=byte sequence=]. + 1. Let |bytes| be |blob|'s underlying [=byte sequence=]. 1. Append |bytes| to the file at |path|. If this fails: From 0f0be03e5dbfd76ab2c4766d38d5071b240c8565 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Tue, 10 Mar 2026 12:08:27 +0100 Subject: [PATCH 23/34] React to promise instead of awaiting. --- index.bs | 57 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/index.bs b/index.bs index 7e55bd328..41ec8237b 100644 --- a/index.bs +++ b/index.bs @@ -312,7 +312,8 @@ spec: SELECTORS4; urlPrefix: https://drafts.csswg.org/selectors-4/ spec: WEB-IDL; urlPrefix: https://webidl.spec.whatwg.org/ type: dfn text: DOMException; url: #idl-DOMException - text: SyntaxError; url:#syntaxerror + text: SyntaxError; url: #syntaxerror + text: react; url: #dfn-perform-steps-once-promise-is-settled spec: UNICODE; urlPrefix: https://www.unicode.org/versions/Unicode15.0.0/ type: dfn text: Unicode Default Case Conversion algorithm; url: ch03.pdf#G34944 @@ -5196,45 +5197,49 @@ The [=remote end steps=] with |command parameters| are: 1. Let |promise| be the result of [=trying=] to [=capture a browsing context viewport=] with |navigable| and |command parameters|["streamOptions"]. -1. Let |media stream| be Await(|promise|). +1. [=React=] to promise: -1. Let |path| be an implementation-defined file path where the recording will be stored. + 1. If |promise| was rejected, return [=error=] with [=error code=] [=unknown error=]. -1. Let |media recorder options| be a new [=/map=] with the mimeType field - set to |mime type|. + 1. If |promise| was fulfilled with value |media stream|, then: -1. Let |media recorder| be a new {{MediaRecorder}} in |realm| - with {{MediaRecorder/stream}} |media stream| and - {{MediaRecorderOptions}} |media recorder options|. + 1. Let |path| be an implementation-defined file path where the recording will be stored. -1. Let |recording| be a new [=screencast recording=] with - [=screencast recording/mediaRecorder=] |media recorder|, - [=screencast recording/path=] |path|, - [=screencast recording/size=] 0. + 1. Let |media recorder options| be a new [=/map=] with the mimeType field + set to |mime type|. -1. Whenever the implementation is going to [=fire a blob event=] named {{MediaRecorder/dataavailable}} - at |media recorder| with |blob|, run the following steps: + 1. Let |media recorder| be a new {{MediaRecorder}} in |realm| + with {{MediaRecorder/stream}} |media stream| and + {{MediaRecorderOptions}} |media recorder options|. - 1. Let |bytes| be |blob|'s underlying [=byte sequence=]. + 1. Let |recording| be a new [=screencast recording=] with + [=screencast recording/mediaRecorder=] |media recorder|, + [=screencast recording/path=] |path|, + [=screencast recording/size=] 0. - 1. Append |bytes| to the file at |path|. If this fails: + 1. Whenever the implementation is going to [=fire a blob event=] named {{MediaRecorder/dataavailable}} + at |media recorder| with |blob|, run the following steps: - 1. Set |recording|'s [=screencast recording/writeError=] to an - implementation-defined string describing the write failure. + 1. Let |bytes| be |blob|'s underlying [=byte sequence=]. - 1. [=Call=]({{MediaRecorder/stop}}, |media recorder|). + 1. Append |bytes| to the file at |path|. If this fails: - 1. Otherwise, set |recording|'s [=screencast recording/size=] to |recording|'s [=screencast recording/size=] + |bytes|'s length. + 1. Set |recording|'s [=screencast recording/writeError=] to an + implementation-defined string describing the write failure. -1. [=Call=]({{MediaRecorder/start}}, |media recorder|, |command parameters|["timeslice"]). + 1. [=Call=]({{MediaRecorder/stop}}, |media recorder|). -1. Let |screencast| be the string representation of a [[!RFC9562|UUID]]. + 1. Otherwise, set |recording|'s [=screencast recording/size=] to |recording|'s [=screencast recording/size=] + |bytes|'s length. -1. Set [=screencast recordings map=][|screencast|] to |recording|. + 1. [=Call=]({{MediaRecorder/start}}, |media recorder|, |command parameters|["timeslice"]). -1. Return a new [=/map=] matching the browsingContext.StartScreencastResult - with the screencast field set to |screencast| and path field - set to |path|. + 1. Let |screencast| be the string representation of a [[!RFC9562|UUID]]. + + 1. Set [=screencast recordings map=][|screencast|] to |recording|. + + 1. Return a new [=/map=] matching the browsingContext.StartScreencastResult + with the screencast field set to |screencast| and path field + set to |path|. From eae5706c4d677e3675be711524c79cd9ba51bc0c Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Tue, 10 Mar 2026 12:38:56 +0100 Subject: [PATCH 24/34] Create sandbox for MediaRecorder. --- index.bs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/index.bs b/index.bs index 41ec8237b..9d7f24587 100644 --- a/index.bs +++ b/index.bs @@ -5191,9 +5191,6 @@ The [=remote end steps=] with |command parameters| are: 1. If the implementation is unable to record a screencast of |navigable| for any reason then return [=error=] with [=error code=] [=unsupported operation=]. -1. Let realm be the result of [=trying=] to [=get a realm from a navigable=] - with |navigable id| and null. - 1. Let |promise| be the result of [=trying=] to [=capture a browsing context viewport=] with |navigable| and |command parameters|["streamOptions"]. @@ -5208,6 +5205,11 @@ The [=remote end steps=] with |command parameters| are: 1. Let |media recorder options| be a new [=/map=] with the mimeType field set to |mime type|. + 1. Let |screencast| be the string representation of a [[!RFC9562|UUID]]. + + 1. Let |realm| be result of [=trying=] to [=get or create a sandbox realm=] given + |screencast| and |navigable|. + 1. Let |media recorder| be a new {{MediaRecorder}} in |realm| with {{MediaRecorder/stream}} |media stream| and {{MediaRecorderOptions}} |media recorder options|. @@ -5233,8 +5235,6 @@ The [=remote end steps=] with |command parameters| are: 1. [=Call=]({{MediaRecorder/start}}, |media recorder|, |command parameters|["timeslice"]). - 1. Let |screencast| be the string representation of a [[!RFC9562|UUID]]. - 1. Set [=screencast recordings map=][|screencast|] to |recording|. 1. Return a new [=/map=] matching the browsingContext.StartScreencastResult From ed19972b26e12f1cda7f80711a33f48d22f5ac7d Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Mon, 23 Mar 2026 10:38:17 +0100 Subject: [PATCH 25/34] Run "Prepare to run script" to initialize the JS for screencast recording in the specification execution environment. --- index.bs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/index.bs b/index.bs index 9d7f24587..7cdcd2cbf 100644 --- a/index.bs +++ b/index.bs @@ -5191,10 +5191,15 @@ The [=remote end steps=] with |command parameters| are: 1. If the implementation is unable to record a screencast of |navigable| for any reason then return [=error=] with [=error code=] [=unsupported operation=]. +1. Let |environment settings| be the [=environment settings object=] representing + a specification execution environment. + +1. [=Prepare to run script=] with |environment settings|. + 1. Let |promise| be the result of [=trying=] to [=capture a browsing context viewport=] with |navigable| and |command parameters|["streamOptions"]. -1. [=React=] to promise: +1. [=React=] to |promise|: 1. If |promise| was rejected, return [=error=] with [=error code=] [=unknown error=]. @@ -5235,6 +5240,8 @@ The [=remote end steps=] with |command parameters| are: 1. [=Call=]({{MediaRecorder/start}}, |media recorder|, |command parameters|["timeslice"]). + 1. [=Clean up after running script=] with |environment settings|. + 1. Set [=screencast recordings map=][|screencast|] to |recording|. 1. Return a new [=/map=] matching the browsingContext.StartScreencastResult From cb35b0c52e5417a1234f05df3328a14f36b49cf8 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Mon, 23 Mar 2026 11:02:24 +0100 Subject: [PATCH 26/34] Use "the specification execution environment" realm to work with MediaRecorder and add the issue. --- index.bs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/index.bs b/index.bs index 7cdcd2cbf..a83ae5af6 100644 --- a/index.bs +++ b/index.bs @@ -5194,6 +5194,8 @@ The [=remote end steps=] with |command parameters| are: 1. Let |environment settings| be the [=environment settings object=] representing a specification execution environment. + Issue: The specification execution environment has to be better defined. + 1. [=Prepare to run script=] with |environment settings|. 1. Let |promise| be the result of [=trying=] to [=capture a browsing context viewport=] with @@ -5212,8 +5214,7 @@ The [=remote end steps=] with |command parameters| are: 1. Let |screencast| be the string representation of a [[!RFC9562|UUID]]. - 1. Let |realm| be result of [=trying=] to [=get or create a sandbox realm=] given - |screencast| and |navigable|. + 1. Let |realm| be |environment settings|' [=realm execution context=]'s Realm component. 1. Let |media recorder| be a new {{MediaRecorder}} in |realm| with {{MediaRecorder/stream}} |media stream| and From 3d63dcec03919cfad3e6546a9ccd8cf848da9e64 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Tue, 14 Apr 2026 11:58:45 +0200 Subject: [PATCH 27/34] Remove unneeded spec imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: François Daoust --- index.bs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/index.bs b/index.bs index a83ae5af6..7d8240f71 100644 --- a/index.bs +++ b/index.bs @@ -295,10 +295,6 @@ spec: DOM; urlPrefix: https://dom.spec.whatwg.org/ text: nodes; url: #concept-node text: ORDERED_NODE_SNAPSHOT_TYPE; url: #dom-xpathresult-ordered_node_snapshot_type text: snapshotItem; url: #dom-xpathresult-snapshotitem -spec: FILE-API; urlPrefix: https://w3c.github.io/FileAPI/ - type: dfn - text: Blob; url: #dfn-Blob - text: blobParts; url: #dfn-blobParts spec: FULLSCREEN; urlPrefix: https://fullscreen.spec.whatwg.org/ type: dfn text: fullscreen an element; url: #fullscreen-an-element @@ -313,7 +309,6 @@ spec: WEB-IDL; urlPrefix: https://webidl.spec.whatwg.org/ type: dfn text: DOMException; url: #idl-DOMException text: SyntaxError; url: #syntaxerror - text: react; url: #dfn-perform-steps-once-promise-is-settled spec: UNICODE; urlPrefix: https://www.unicode.org/versions/Unicode15.0.0/ type: dfn text: Unicode Default Case Conversion algorithm; url: ch03.pdf#G34944 @@ -326,10 +321,7 @@ spec: CORE-AAM; urlPrefix:https://www.w3.org/TR/core-aam-1.2 text: computed role; url: /#roleMappingComputedRole spec: MEDIACAPTURE-RECORD; urlPrefix: https://w3c.github.io/mediacapture-record/ type: dfn - text: is type supported; url: #abstract-opdef-is-type-supported text: fire a blob event; url: #fire-a-blob-event - text: MediaRecorder; url: #mediarecorder-api - text: MediaRecorderOptions; url: #mediarecorderoptions-section spec: MEDIACAPTURE-VIEWPORT; urlPrefix: https://w3c.github.io/mediacapture-viewport/ type: dfn text: capture a browsing context viewport; url: #dfn-capture-a-browsing-context-viewport From 7902a5a81219e588bd08b5d10457ccbb14a5a401 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Tue, 14 Apr 2026 12:08:50 +0200 Subject: [PATCH 28/34] Add back "is type supported" import --- index.bs | 1 + 1 file changed, 1 insertion(+) diff --git a/index.bs b/index.bs index 7d8240f71..ddb3d20f5 100644 --- a/index.bs +++ b/index.bs @@ -321,6 +321,7 @@ spec: CORE-AAM; urlPrefix:https://www.w3.org/TR/core-aam-1.2 text: computed role; url: /#roleMappingComputedRole spec: MEDIACAPTURE-RECORD; urlPrefix: https://w3c.github.io/mediacapture-record/ type: dfn + text: is type supported; url: #abstract-opdef-is-type-supported text: fire a blob event; url: #fire-a-blob-event spec: MEDIACAPTURE-VIEWPORT; urlPrefix: https://w3c.github.io/mediacapture-viewport/ type: dfn From d500592457bcc185d46dcfc706e865d910d698db Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Wed, 15 Apr 2026 11:06:36 +0200 Subject: [PATCH 29/34] Use the correct syntax for an autolink to the "abstract-op"-type definition. --- index.bs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.bs b/index.bs index ddb3d20f5..f1b3f70c4 100644 --- a/index.bs +++ b/index.bs @@ -321,7 +321,6 @@ spec: CORE-AAM; urlPrefix:https://www.w3.org/TR/core-aam-1.2 text: computed role; url: /#roleMappingComputedRole spec: MEDIACAPTURE-RECORD; urlPrefix: https://w3c.github.io/mediacapture-record/ type: dfn - text: is type supported; url: #abstract-opdef-is-type-supported text: fire a blob event; url: #fire-a-blob-event spec: MEDIACAPTURE-VIEWPORT; urlPrefix: https://w3c.github.io/mediacapture-viewport/ type: dfn @@ -5178,7 +5177,7 @@ The [=remote end steps=] with |command parameters| are: 1. Let |mime type| be |command parameters|["mimeType"]. -1. If [=is type supported=] with |mime type| returns false, return [=error=] with +1. If [$is type supported$] with |mime type| returns false, return [=error=] with [=error code=] [=invalid argument=]. 1. If the implementation is unable to record a screencast of |navigable| for any From 21ab43228c1f1aff936e22a4fee098190e655912 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Thu, 23 Apr 2026 18:21:57 +0200 Subject: [PATCH 30/34] Don't allow video parameter being disabled. --- index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.bs b/index.bs index f1b3f70c4..f11f2038b 100644 --- a/index.bs +++ b/index.bs @@ -5140,7 +5140,7 @@ the [=local end=] has only read-only access. } browsingContext.MediaStreamOptions = { - ? video: bool / browsingContext.MediaTrackConstraints .default true; + ? video: true / browsingContext.MediaTrackConstraints; ? audio: bool .default false; } From a8a90a02b82d5318d7e959bbc04bed58f83e2828 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Thu, 23 Apr 2026 18:22:25 +0200 Subject: [PATCH 31/34] Don't validate mimeType --- index.bs | 3 --- 1 file changed, 3 deletions(-) diff --git a/index.bs b/index.bs index f11f2038b..6e567594b 100644 --- a/index.bs +++ b/index.bs @@ -5177,9 +5177,6 @@ The [=remote end steps=] with |command parameters| are: 1. Let |mime type| be |command parameters|["mimeType"]. -1. If [$is type supported$] with |mime type| returns false, return [=error=] with - [=error code=] [=invalid argument=]. - 1. If the implementation is unable to record a screencast of |navigable| for any reason then return [=error=] with [=error code=] [=unsupported operation=]. From d77a6d68d62ca537da44ded2f961c467dcd89573 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Mon, 4 May 2026 18:05:50 +0200 Subject: [PATCH 32/34] Do not expose "timeslice" as a parameter --- index.bs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index 6e567594b..e74dc30a1 100644 --- a/index.bs +++ b/index.bs @@ -5135,8 +5135,7 @@ the [=local end=] has only read-only access. browsingContext.StartScreencastParameters = { context: browsingContext.BrowsingContext, mimeType: text, - ? streamOptions: browsingContext.MediaStreamOptions, - ? timeslice: js-uint .default 1000 + ? streamOptions: browsingContext.MediaStreamOptions } browsingContext.MediaStreamOptions = { @@ -5228,7 +5227,9 @@ The [=remote end steps=] with |command parameters| are: 1. Otherwise, set |recording|'s [=screencast recording/size=] to |recording|'s [=screencast recording/size=] + |bytes|'s length. - 1. [=Call=]({{MediaRecorder/start}}, |media recorder|, |command parameters|["timeslice"]). + 1. Let |timeslice| be an implementation-defined value. + + 1. [=Call=]({{MediaRecorder/start}}, |media recorder|, |timeslice|). 1. [=Clean up after running script=] with |environment settings|. From 0518ea889bd5f18e9e6c350f79ca5cbaf0cd6395 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Mon, 4 May 2026 18:09:00 +0200 Subject: [PATCH 33/34] Add "frameRate" parameter to "browsingContext.startScreencast". --- index.bs | 1 + 1 file changed, 1 insertion(+) diff --git a/index.bs b/index.bs index e74dc30a1..1b6e2a539 100644 --- a/index.bs +++ b/index.bs @@ -5146,6 +5146,7 @@ the [=local end=] has only read-only access. browsingContext.MediaTrackConstraints = { ? width: js-uint, ? height: js-uint, + ? frameRate: js-uint, }
From b8241ec73b9d213a1b3cae8fd73dc28a85d7fadf Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Mon, 4 May 2026 18:14:07 +0200 Subject: [PATCH 34/34] Make "mimeType" parameter optional --- index.bs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/index.bs b/index.bs index 1b6e2a539..32d962a74 100644 --- a/index.bs +++ b/index.bs @@ -5134,7 +5134,7 @@ the [=local end=] has only read-only access. browsingContext.StartScreencastParameters = { context: browsingContext.BrowsingContext, - mimeType: text, + ? mimeType: text, ? streamOptions: browsingContext.MediaStreamOptions } @@ -5175,7 +5175,11 @@ The [=remote end steps=] with |command parameters| are: 1. If |navigable| is not a [=/top-level traversable=], return [=error=] with [=error code=] [=invalid argument=]. -1. Let |mime type| be |command parameters|["mimeType"]. +1. If |command parameters| [=map/contains=] the mimeType field: + + 1. Let |mime type| be |command parameters|["mimeType"]. + +1. Otherwise, set |mime type| to the implementation-defined default format. 1. If the implementation is unable to record a screencast of |navigable| for any reason then return [=error=] with [=error code=] [=unsupported operation=].