1. Introduction
This section is non-normative.
WebDriver defines a protocol for introspection and remote control of user agents. This specification extends WebDriver by introducing bidirectional communication. In place of the strict command/response format of WebDriver, this permits events to stream from the user agent to the controlling software, better matching the evented nature of the browser DOM.
2. Infrastructure
This specification depends on the Infra Standard. [INFRA]
Network protocol messages are defined using CDDL. [RFC8610]
This specification defines a wait queue which is a map.
Surely there’s a better mechanism for doing this "wait for an event" thing.
When an algorithm algorithm running in parallel awaits a set of events Ereignisse, and resume id:
-
Pause the execution of algorithm.
-
Assert: wait queue does not contain resume id.
-
Set wait queue[resume id] to (Ereignisse, algorithm).
-
If wait queue does not contain id, return.
-
Let (Ereignisse, algorithm) be wait queue[id]
-
For each event in Ereignisse:
-
If event equals name:
-
Entfernen Sie id from wait queue.
-
Resume running the steps in algorithm from the point at which they were paused, passing name and parameters as the result of the await.
Should we have something like microtasks to ensure this runs before any other tasks on the event loop?
-
-
3. Protocol
This section defines the basic concepts of the WebDriver BiDi protocol. These terms are distinct from their representation at the transport layer.
The protocol is defined using a CDDL definition. For the convenience of implementers two separate CDDL definitions are defined; the remote end definition which defines the format of messages produced on the local end and consumed on the remote end, and the local end definition which defines the format of messages produced on the remote end and consumed on the local end
3.1. Definition
This section gives the initial contents of the remote end definition and local end definition. These are augmented by the definition fragments defined in the remainder of the specification.
Command = { id: js-uint, CommandData, Extensible, } CommandData = ( BrowserCommand // BrowsingContextCommand // InputCommand // NetworkCommand // ScriptCommand // SessionCommand // StorageCommand ) EmptyParams = { Extensible }
Message = ( CommandResponse / ErrorResponse / Event ) CommandResponse = { type: "success", id: js-uint, result: ResultData, Extensible } ErrorResponse = { type: "error", id: js-uint / null, error: ErrorCode, message: text, ? stacktrace: text, Extensible } ResultData = ( BrowsingContextResult / EmptyResult / NetworkResult / ScriptResult / SessionResult / StorageResult ) EmptyResult = { Extensible } Event = { type: "event", EventData, Extensible } EventData = ( BrowsingContextEvent // LogEvent // NetworkEvent // ScriptEvent )
Remote end definition and Local end definition
Extensible = (*text => any) js-int = -9007199254740991..9007199254740991 js-uint = 0..9007199254740991
3.2. Session
WebDriver BiDi extends the session concept from WebDriver.
A session has a BiDi flag, which is false unless otherwise stated.
A BiDi session is a session which has the BiDi flag set to true.
-
Let BiDi sessions be a new list.
-
For each session in active sessions:
-
If session is a BiDi session append session to BiDi sessions.
-
-
Return BiDi sessions.
3.3. Modules
The WebDriver BiDi protocol is organized into modules.
Each module represents a collection of related commands and events pertaining to a certain aspect of the user agent. For example, a module might contain functionality for inspecting and manipulating the DOM, or for script execution.
Each module has a module name which is a string. The command name and event name for commands and events defined in the
module start with the module name followed by a period ".
".
Modules which contain commands define remote end definition fragments. These provide choices in the CommandData
group for the
module’s commands, and can also define additional definition properties. They
can also define local end definition fragments that provide additional choices
in the ResultData
group for the results of commands in the module.
Modules which contain events define local end definition fragments that are
choices in the Event
group for the module’s Ereignisse.
An implementation may define extension modules. These must have a module name that contains a single colon ":
" character. The
part before the colon is the prefix; this is typically the same for all extension modules specific to a given implementation and should be unique for a
given implementation.
Other specifications may define their own WebDriver-BiDi modules that extend the protocol.
Such modules must not have a name which contains a colon (:
) character,
nor must they define command names, event names, or property names that contain that character.
Authors of external specifications are encouraged to to add new modules rather than extending existing ones. Where it is desired to extend an existing module, it is preferred to integrate the extension directly into the specification containing the original module definition.
3.4. Commands
A command is an asynchronous operation, requested by the local end and run on the remote end, resulting in either a result or an error being returned to the local end. Multiple commands can run at the same time, and commands can potentially be long-running. As a consequence, commands can finish out-of-order.
Each command is defined by:
-
A command type which is defined by a remote end definition fragment containing a group. Each such group has two fields:
-
method
which is a string literal of the form[module name].[method name]
. This is the command name. -
params
which defines a mapping containing data that to be passed into the command. The populated value of this map is the command parameters.
-
-
A result type, which is defined by a local end definition fragment.
-
A set of remote end steps which define the actions to take for a command given a BiDi session and command parameters and return an instance of the command result type.
A command that can run without an active session is a static command. Commands are not static commands unless stated in their definition.
When commands are sent from the local end they have a command id. This is an identifier used by the local end to identify the response from a particular command. From the point of view of the remote end this identifier is opaque and cannot be used internally to identify the command.
Note: This is because the command id is entirely controlled by the local end and isn’t necessarily unique over the course of a session. For example a local end which ignores all responses could use the same command id for each command.
The set of all command names is a set containing all the defined command names, including any belonging to extension modules.
3.5. Errors
WebDriver BiDi extends the set of error codes from WebDriver with the following additional codes:
- no such handle
- Tried to deserialize an unknown
RemoteObjectReference
. - no such history entry
- Tried to havigate to an unknown session history entry.
- no such intercept
- Tried to remove an unknown network intercept.
- no such node
- Tried to deserialize an unknown
SharedReference
. - no such request
- Tried to continue an unknown request.
- no such script
- Tried to remove an unknown preload script.
- no such storage partition
- Tried to access data in a non-existent storage partition.
- no such user context
- Tried to reference an unknown user context.
- unable to close browser
- Tried to close the browser, but failed to do so.
- unable to set cookie
- Tried to create a cookie, but the user agent rejected it.
- underspecified storage partition
- Tried to interact with data in a storage partition which was not adequately specified.
- unable to set file input
- Tried to set a file input, but failed to do so.
ErrorCode = "invalid argument" / "invalid selector" / "invalid session id" / "move target out of bounds" / "no such alert" / "no such element" / "no such frame" / "no such handle" / "no such history entry" / "no such intercept" / "no such node" / "no such request" / "no such script" / "no such storage partition" / "no such user context" / "session not created" / "unable to capture screen" / "unable to close browser" / "unable to set cookie" / "unable to set file input" / "underspecified storage partition" / "unknown command" / "unknown error" / "unsupported operation"
3.6. Events
An event is a notification, sent by the remote end to the local end, signaling that something of interest has occurred on the remote end.
-
An event type is defined by a local end definition fragment containing a group. Each such group has two fields:
-
A remote end event trigger which defines when the event is triggered and steps to construct the event type data.
-
Optionally, a set of remote end subscribe steps, which define steps to take when a local end subscribes to an event. Where defined these steps have an associated subscribe priority which is an integer controlling the order in which the steps are run when multiple events are enabled at once, with lower integers indicating steps that run earlier.
A BiDi session has a global event set which is a set containing the event names for events that are enabled for all navigables. This initially contains the event name for events that are in the default event set.
A BiDi session has a navigable event map, which is a map with top-level traversable keys and values that are a set of event names for events that are enabled in the given navigable.
To obtain a list of event enabled navigables given session and event name:
-
Let navigables be an empty set.
-
For each navigable → Ereignisse of session’s navigable event map:
-
If Ereignisse contains event name, append navigable to navigables
-
-
Return navigables.
The set of sessions for which an event is enabled given event name and navigables is:
-
Let sessions be a new set.
-
For each session in active BiDI sessions:
-
If event is enabled with session, event name and navigables, append session to sessions.
-
-
Return sessions.
To determine if an event is enabled given session, event name and navigables:
Note: navigables is a set because a shared worker can be associated with multiple contexts.
-
Let top-level traversables be an empty set.
-
For each navigable of navigables, append navigable’s top-level traversable to top-level traversables.
-
Let event map be the navigable event map for session.
-
For each navigable of top-level traversables:
-
If the global event set for session contains event name return true.
-
Return false.
-
Let Ereignisse be an empty set.
-
If name contains a U+002E (period):
-
If name is the event name for an event, append name to Ereignisse and return success with data Ereignisse.
-
Return an error with error code invalid argument
-
-
Otherwise name is interpreted as representing all the events in a module. If name is not a module name return an error with error code invalid argument.
-
Append the event name for each event in the module with name name to Ereignisse.
-
Return success with data Ereignisse.
4. Transport
Message transport is provided using the WebSocket protocol. [RFC6455]
Note: In the terms of the WebSocket protocol, the local end is the client and the remote end is the server / remote host.
Note: The encoding of commands and events as messages is similar to JSON-RPC, but this specification does not normatively reference it. [JSON-RPC] The normative requirements on remote ends are instead given as a precise processing model, while no normative requirements are given for local ends.
A WebSocket listener is a network endpoint that is able to accept incoming WebSocket connections.
A WebSocket listener has a host, a port, a secure flag, and a list of WebSocket resources.
When a WebSocket listener listener is created, a remote end must start to listen for WebSocket connections on the host and port given by listener’s host and port. If listener’s secure flag is set, then connections established from listener must be TLS encrypted.
A remote end has a set of WebSocket listeners active listeners, which is initially empty.
A remote end has a set of WebSocket connections not associated with a session, which is initially empty.
A WebSocket connection is a network connection that follows the requirements of the WebSocket protocol
A BiDi session has a set of session WebSocket connections whose elements are WebSocket connections. This is initially empty.
A BiDi session session is associated with connection connection if session’s session WebSocket connections contains connection.
Note: Each WebSocket connection is associated with at most one BiDi session.
When a client establishes a WebSocket connection connection by connecting to one of the set of active listeners listener, the implementation must proceed according to the WebSocket server-side requirements, with the following steps run when deciding whether to accept the incoming connection:
-
Let resource name be the resource name from reading the client’s opening handshake. If resource name is not in listener’s list of WebSocket resources, then stop running these steps and act as if the requested service is not available.
-
If resource name is the byte string "
/session
", and the implementation supports BiDi-only sessions:-
Run any other implementation-defined steps to decide if the connection should be accepted, and if it is not stop running these steps and act as if the requested service is not available.
-
Add the connection to WebSocket connections not associated with a session.
-
Return.
-
-
Get a session ID for a WebSocket resource with resource name and let session id be that value. If session id is null then stop running these steps and act as if the requested service is not available.
-
If there is a session in the list of active sessions with session id as its session ID then let session be that session. Otherwise stop running these steps and act as if the requested service is not available.
-
Run any other implementation-defined steps to decide if the connection should be accepted, and if it is not stop running these steps and act as if the requested service is not available.
-
Otherwise append connection to session’s session WebSocket connections, and proceed with the WebSocket server-side requirements when a server chooses to accept an incoming connection.
When a WebSocket message has been received for a WebSocket connection connection with type type and data data, a remote end must handle an incoming message given connection, type and data.
When the WebSocket closing handshake is started or when the WebSocket connection is closed for a WebSocket connection connection, a remote end must handle a connection closing given connection.
Note: Both conditions are needed because it is possible for a WebSocket connection to be closed without a closing handshake.
To construct a WebSocket resource name given a session session:
-
If session is null, return "
/session
" -
Return the result of concatenating the string "
/session/
" with session’s session ID.
To construct a WebSocket URL given a WebSocket listener listener and session session:
-
Let resource name be the result of construct a WebSocket resource name with session.
-
Return a WebSocket URI constructed with host set to listener’s host, port set to listener’s port, path set to resource name, following the wss-URI construct if listener’s secure flag is set and the ws-URL construct otherwise.
To get a session ID for a WebSocket resource given resource name:
-
If resource name doesn’t begin with the byte string "
/session/
", return null. -
Let session id be the bytes in resource name following the "
/session/
" prefix. -
If session id is not the string representation of a UUID, return null.
-
Return session id.
-
If there is an existing WebSocket listener in active listeners which the remote end would like to reuse, let listener be that listener. Otherwise let listener be a new WebSocket listener with implementation-defined host, port, secure flag, and an empty list of WebSocket resources.
-
Let resource name be the result of construct a WebSocket resource name with session.
-
Append resource name to the list of WebSocket resources for listener.
-
Append listener to the remote end's active listeners.
-
Return listener.
Note: An intermediary node handling multiple sessions can use one or many WebSocket listeners. WebDriver defines that an endpoint node supports at most one session at a time, so it’s expected to only have a single listener.
Note: For an endpoint node the host in the above steps will
typically be "localhost
".
-
If type is not text, send an error response given connection, null, and invalid argument, and finally return.
-
Assert: data is a scalar value string, because the WebSocket handling errors in UTF-8-encoded data would already have failed the WebSocket connection otherwise.
Nothing seems to define what status code is used for UTF-8 errors.
-
If there is a BiDi Session associated with connection connection, let session be that session. Otherwise if connection is in WebSocket connections not associated with a session, let session be null. Otherwise, return.
-
Let parsed be the result of parsing JSON into Infra values given data. If this throws an exception, then send an error response given connection, null, and invalid argument, and finally return.
-
If session is not null and not in active sessions then return.
-
Match parsed against the remote end definition. If this results in a match:
-
Let matched be the map representing the matched data.
-
Assert: matched contains "
id
", "method
", and "params
". -
Let command id be matched["
id
"]. -
Let method be matched["
method
"] -
Let command be the command with command name method.
-
If session is null and command is not a static command, then send an error response given connection, command id, and invalid session id, and return.
-
Run the following steps in parallel:
-
Let result be the result of running the remote end steps for command given session and command parameters matched["
params
"] -
If result is an error, then send an error response given connection, command id, and result’s error code, and finally return.
-
Let value be result’s data.
-
Assert: value matches the definition for the result type corresponding to the command with command name method.
-
If method is "
session.new
", let session be the entry in the list of active sessions whose session ID is equal to the "sessionId
" property of value, append connection to session’s session WebSocket connections, and remove connection from the WebSocket connections not associated with a session. -
Let response be a new map matching the
CommandResponse
production in the local end definition with theid
field set to command id and thevalue
field set to value. -
Let serialized be the result of serialize an infra value to JSON bytes given response.
-
Send a WebSocket message comprised of serialized over connection.
-
-
-
Otherwise:
-
Let command id be null.
-
If parsed is a map and parsed["
id
"] exists and is an integer greater than or equal to zero, set command id to that integer. -
Let error code be invalid argument.
-
If parsed is a map and parsed["
method
"] exists and is a string, but parsed["method
"] is not in the set of all command names, set error code to unknown command. -
Send an error response given connection, command id, and error code.
-
To get related navigables given an settings object settings:
-
Let related navigables be an empty set.
-
Let navigable be null.
-
If settings’ relevant global object is a
Window
, set navigable to relevant global object's associatedDocument
’s node navigable.Otherwise if the global object specified by settings is a
WorkerGlobalScope
, for each owner in the global object's owner set, if owner is a Document, set navigable to owner’s node navigable. -
If navigable is not null, append navigable to related navigables.
-
Return related navigables.
-
Let serialized be the result of serialize an infra value to JSON bytes given body.
-
For each connection in session’s session WebSocket connections:
-
Send a WebSocket message comprised of serialized over connection.
-
-
Let error data be a new map matching the
ErrorResponse
production in the local end definition, with theid
field set to command id, theerror
field set to error code, themessage
field set to an implementation-defined string containing a human-readable definition of the error that occurred and thestacktrace
field optionally set to an implementation-defined string containing a stack trace report of the active stack frames at the time when the error occurred. -
Let response be the result of serialize an infra value to JSON bytes given error data.
Note: command id can be null, in which case the
id
field will also be set to null, not omitted from response. -
Send a WebSocket message comprised of response over connection.
To handle a connection closing given a WebSocket connection connection:
-
If there is a BiDi session associated with connection connection:
-
Let session be the BiDi session associated with connection connection.
-
Entfernen Sie connection from session’s session WebSocket connections.
-
-
Otherwise, if WebSocket connections not associated with a session contains connection, remove connection from that set.
Note: This does not end any session.
Need to hook in to the session ending to allow the UA to close the listener if it wants.
To close the WebSocket connections given session:
-
For each connection in session’s session WebSocket connections:
-
Start the WebSocket closing handshake with connection.
Note: this will result in the steps in handle a connection closing being run for connection, which will clean up resources associated with connection.
-
4.1. Establishing a Connection
WebDriver clients opt in to a bidirectional connection by requesting the WebSocket URL capability with value true.
-
If flags contains "
bidi
", return. -
Let webSocketUrl be the result of getting a property named "
webSocketUrl
" from capabilities. -
If webSocketUrl is undefined, return.
-
Assert: webSocketUrl is true.
-
Let listener be the result of start listening for a WebSocket connection given session.
-
Set webSocketUrl to the result of construct a WebSocket URL with listener and session.
-
Set a property on capabilities named "
webSocketUrl
" to webSocketUrl. -
Set session’s BiDi flag to true.
-
Append "
bidi
" to flags.
Implementations should also allow clients to establish a BiDi Session which is not a HTTP Session. In this case the URL to the WebSocket server is communicated out-of-band. An implementation that allows this supports BiDi-only sessions. At the time such an implementation is ready to accept requests to start a WebDriver session, it must:
-
Start listening for a WebSocket connection given null.
5. Sandboxed Script Execution
A common requirement for automation tools is to execute scripts which have access to the DOM of a document, but don’t have information about any changes to the DOM APIs made by scripts running in the navigable containing the document.
A BiDi session has a sandbox map which is a weak map in which the
keys are Window
objects, and the values are maps between strings and SandboxWindowProxy
objects.
Note: The definition of sandboxes here is an attempt to codify the behaviour of existing implementations. It exposes parts of the implementations that have previously been considered internal by specifications, in particular the distinction between the internal state of platform objects (which is typically implemented as native objects in the main implementation language of the browser engine) and the ECMAScript-visible state. Because existing sandbox implementations happen at a low level in the engine, implementations converging toward the specification in all details might be a slow process. In the meantime, implementers are encouraged to provide detailed documentation on any differences with the specification, and users of this feature are encouraged to explicitly test that scripts running in sandboxes work in all implementations.
5.1. Sandbox Realms
Each sandbox is a unique ECMAScript Realm. However the sandbox realm
provides access to platform objects in an existing Window
realm via SandboxProxy
objects.
-
If name is an empty string, then return error with error code invalid argument.
-
Let window be navigable’s active window.
-
If sandbox map does not contain window, set sandbox map[window] to a new map.
-
Let sandboxes be sandbox map[window].
-
If sandboxes does not contain name, set sandboxes[name] to create a sandbox realm with navigable.
-
Return success with data sandboxes[name].
Define creation of sandbox realm. This is going to return a SandboxWindowProxy
wrapping window.
To get a sandbox name given target realm:
-
Let realms maps be get the values of sandbox map.
-
For each realms map in realms maps:
-
For each name → realm in realms map:
-
If realm is target realm, return name.
-
-
-
Return null.
5.2. Sandbox Proxy Objects
A SandboxProxy
object is an exotic object that mediates sandboxed access to
objects from another realm. Sandbox proxy objects are designed to enforce the
following restrictions:
-
Platform objects are accessible, but property access returns only Web IDL-defined properties and not ECMAScript-defined properties (either "expando" properties that are not present in the underlying interface, or ECMAScript-defined properties that shadow a property in the underlying interface).
-
Setting a property either runs Web IDL-defined setter steps, or sets a property on the proxy object. This means that properties written outside the sandbox are not accessible, but interface members can be used as normal.
There is no SandboxProxy
interface object.
Define in detail how SandboxProxy
works
-
While object is
SandboxProxy
oderSandboxWindowProxy
, set object to it’s wrapped object. -
Return object.
5.3. SandboxWindowProxy
A SandboxWindowProxy
is an exotic object that represents a Window
object wrapped by a SandboxProxy
object. This provides sandboxed
access to that data in a Window
global.
6. User Contexts
A user context represents a collection of zero or more top-level traversables within a remote end. Each user context has an associated storage partition, so that remote end data is not shared between different user contexts.
Unclear that this is the best way to formally define the concept of a user context or the interaction with storage.
Note: The infra spec uses the term "user agent" to refer to the same concept as user contexts. However, this is not compatible with usage of the term "user agent" to mean the entire web client with multiple user contexts. Although this difference is not visible to web content, it is observed via WebDriver, so we avoid using this terminology.
A user context has a user context id, which is a unique string set upon the user context creation.
A navigable has an associated user context, which is a user context.
When a new top-level traversable is created its associated user context is set to a user context in the set of user contexts.
Note: In some cases the user context is set by specification when the top-level traversable is created, however in cases where no such requirements are present, the associated user context for a top-level traversable is implemenation-defined.
Should we specify that top-level traversables with a non-null opener have the same associated user context as their opener? Need to check if this is something existing implementations enforce.
A child navigable's associated user context is it’s parent's associated user context.
A user context which isn’t the associated user context for any top-level traversable is an empty user context.
The default user context is a user context with user context
id "default"
.
An implementation has a set of user contexts, which is a set of user contexts. Initially this contains the default user context.
Implementations may append new user contexts to the set of user contexts at any time, for example in response to user actions.
Note: "At any time" here includes during implementation startup, so a given implementation might always have multiple entries in the set of user contexts.
Implementations may remove any empty user context, with exception of the default user context, from the set of user contexts at any time. However they are not required to remove such user contexts. User contexts that are not empty user contexts must not be removed from the set of user contexts.
-
For each user context in the set of user contexts:
-
If user context’s user context id equals user context id:
-
Return user context.
-
-
Return null.
7. Modules
7.1. The session Module
The session module contains commands and events for monitoring the status of the remote end.
7.1.1. Definition
SessionCommand = ( session.End // session.New // session.Status // session.Subscribe // session.Unsubscribe )
SessionResult = ( session.NewResult / session.StatusResult )
-
Entfernen Sie session from active sessions.
-
If active sessions is empty, set the webdriver-active flag to false.
To cleanup the session given session:
-
Close the WebSocket connections with session.
-
Perform any implementation-specific cleanup steps.
-
Set the default cache behavior to "
default
". -
Perform implementation-defined steps to enable any implementation-specific resource caches that are usually enabled in the current remote end configuration.
Note: The return value of this algorithm is a map between event names and navigables. When the events are being enabled, the navigables in the return value are those for which the event are now enabled but were not previously. When events are disabled, the return value is always empty.
-
Let global event set be a clone of the global event set for session.
-
Let event map be a new map.
-
For each key → value of the navigable event map for session:
-
Set event map[key] to a clone of value.
-
-
Let event names be an empty set.
-
For each entry name in requested event names, let event names be the union of event names and the result of trying to obtain a set of event names with name.
-
Let enabled events be a new map.
-
If navigables is null:
-
If enabled is true:
-
For each event name of event names:
-
If global event set doesn’t contain event name:
-
Let already enabled navigables be the event enabled navigables given session and event name.
-
hinzufügen event name to global event set.
-
For each navigable of already enabled navigables, remove event name from event map[navigable].
-
Let newly enabled contexts be a list of all top-level traversable that are not contained in already enabled navigables,
-
Set enabled events[event name] to newly enabled contexts.
-
-
-
-
If enabled is false:
-
For each event name in event names:
-
If global event set contains event name, remove event name from global event set. Otherwise return error with error code invalid argument.
-
-
-
-
Otherwise, if navigables is not null:
-
Let targets be an empty map.
-
For each navigable id in navigables:
-
Let navigable be the result of trying to get a navigable with navigable id.
-
Let top-level traversable be the top-level traversable for navigable.
-
If event map does not contain top-level traversable, set event map[top-level traversable] to a new set.
-
Set targets[top-level traversable] to event map[top-level traversable].
-
-
For each event name in event names:
-
If enabled is true and global event set contains event name, continue.
-
For each navigable → target in targets:
-
If enabled is true and target does not contain event name:
-
hinzufügen event name to target.
-
If enabled events does not contain event name, set enabled events[event name] to a new set.
-
Append navigable to enabled events[event name].
-
-
If enabled is false:
-
If target contains event name, remove event name from target. Otherwise return error with error code invalid argument.
-
-
-
-
-
Set the global event set for session to global event set.
-
Set the navigable event map for session to event map.
-
Return success with data enabled events.
Note: Implementations that do additional work when an event is enabled, e.g. subscribing to the relevant engine-internal events, will likely perform those additional steps when updating the event map. This specification uses a model where hooks are always called and then the event map is used to filter only those that ought to be returned to the local end.
7.1.2. Types
7.1.2.1. The session.CapabilitiesRequest Type
session.CapabilitiesRequest = { ? alwaysMatch: session.CapabilityRequest, ? firstMatch: [*session.CapabilityRequest] }
The session.CapabilitiesRequest
type represents the capabilities requested
for a session.
7.1.2.2. The session.CapabilityRequest Type
remote end definition and local end definition
session.CapabilityRequest = { ? acceptInsecureCerts: bool, ? browserName: text, ? browserVersion: text, ? platformName: text, ? proxy: session.ProxyConfiguration, ? unhandledPromptBehavior: session.UserPromptHandler, Extensible };
The session.CapabilityRequest
type represents a specific set of
requested capabilities.
WebDriver BiDi defines additional WebDriver capabilities. The following tables enumerates the capabilities each implementation must support for WebDriver BiDi.
Capability | WebSocket URL |
---|---|
Key | "webSocketUrl "
|
Value type | boolean |
Description | Defines the current session’s support for bidirectional connection. |
webSocketUrl
" capability, with parameter value is:
-
If value is not a boolean, return error with code invalid argument.
-
Return success with data value.
webSocketUrl
" capability,
with parameter value is:
7.1.2.3. The session.ProxyConfiguration Type
remote end definition and local end definition
session.ProxyConfiguration = { session.AutodetectProxyConfiguration // session.DirectProxyConfiguration // session.ManualProxyConfiguration // session.PacProxyConfiguration // session.SystemProxyConfiguration // } session.AutodetectProxyConfiguration = ( proxyType: "autodetect", Extensible ) session.DirectProxyConfiguration = ( proxyType: "direct", Extensible ) session.ManualProxyConfiguration = ( proxyType: "manual", ? ftpProxy: text, ? httpProxy: text, ? sslProxy: text, ? session.SocksProxyConfiguration, ? noProxy: [*text], Extensible ) session.SocksProxyConfiguration = ( socksProxy: text, socksVersion: 0..255, ) session.PacProxyConfiguration = ( proxyType: "pac", proxyAutoconfigUrl: text, Extensible ) session.SystemProxyConfiguration = ( proxyType: "system" Extensible )
7.1.2.4. The session.UserPromptHandler Type
Remote end definition and local end definition
session.UserPromptHandler = { ? alert: session.UserPromptHandlerType, ? beforeUnload: session.UserPromptHandlerType, ? confirm: session.UserPromptHandlerType, ? default: session.UserPromptHandlerType, ? prompt: session.UserPromptHandlerType, };
The session.UserPromptHandler
type represents the configuration of
the user prompt handler.
7.1.2.5. The session.UserPromptHandlerType Type
Remote end definition and local end definition
session.UserPromptHandlerType = "accept" / "dismiss" / "ignore";
The session.UserPromptHandlerType
type represents the behavior
of the user prompt handler.
7.1.2.6. The session.SubscriptionRequest Type
session.SubscriptionRequest = { events: [+text], ? contexts: [+browsingContext.BrowsingContext], }
The session.SubscriptionRequest
type represents a request to
subscribe to or unsubscribe from a specific set of events.
7.1.3. Commands
7.1.3.1. The session.status Command
The session.status command returns information about whether a remote end is in a state in which it can create new sessions, but may additionally include arbitrary meta information that is specific to the implementation.
This is a static command.
- Command Type
-
session.Status = ( method: "session.status", params: EmptyParams, )
- Result Type
-
session.StatusResult = { ready: bool, message: text, }
The remote end steps given session, and command parameters are:
-
Let body be a new map with the following properties:
- "ready"
- The remote end’s readiness state.
- "message"
- An implementation-defined string explaining the remote end’s readiness state.
-
Return success with data body
7.1.3.2. The session.new Command
The session.new command allows creating a new BiDi session.
Note: A session created this way will not be accessible via HTTP.
This is a static command.
- Command Type
-
session.New = ( method: "session.new", params: session.NewParameters ) session.NewParameters = { capabilities: session.CapabilitiesRequest }
- Result Type
-
session.NewResult = { sessionId: text, capabilities: { acceptInsecureCerts: bool, browserName: text, browserVersion: text, platformName: text, setWindowRect: bool, userAgent: text, ? proxy: session.ProxyConfiguration, ? unhandledPromptBehavior: session.UserPromptHandler, ? webSocketUrl: text, Extensible } }
The remote end steps given session and command parameters are:
-
If session is not null, return an error with error code session not created.
-
If the implementation is unable to start a new session for any reason, return an error with error code session not created.
-
Let flags be a set containing "
bidi
". -
Let capabilities json be the result of trying to process capabilities with command parameters and flags.
-
Let capabilities be convert a JSON-derived JavaScript value to an Infra value with capabilities json.
-
Let session be the result of trying to create a session with capabilities and flags.
-
Set session’s BiDi flag to true.
Note: the connection for this session will be set to the current connection by the caller.
-
Let body be a new map matching the
session.NewResult
production, with thesessionId
field set to session’s session ID, and thecapabilities
field set to capabilities. -
Return success with data body.
7.1.3.3. The session.end Command
The session.end command ends the current session.
- Command Type
-
session.End = ( method: "session.end", params: EmptyParams )
- Result Type
-
EmptyResult
The remote end steps given session and command parameters are:
-
End the session with session.
-
Return success with data null, and in parallel run the following steps:
-
Wait until the Send a WebSocket message steps have been called with the response to this command.
this is rather imprecise language, but hopefully it’s clear that the intent is that we send the response to the command before starting shutdown of the connections.
-
Cleanup the session with session.
-
7.1.3.4. The session.subscribe Command
The session.subscribe command enables certain events either globally or for a set of navigables.
This needs to be generalized to work with realms too.
- Command Type
-
session.Subscribe = ( method: "session.subscribe", params: session.SubscriptionRequest )
- Result Type
-
EmptyResult
-
Let the list of event names be the value of the
Ereignisse
field of command parameters -
Let the list of navigables be the value of the
contexts
field of command parameters if it is present or null if it isn’t. -
Let enabled events be the result of trying to update the event map with session, list of event names , list of navigables and enabled true.
-
Let subscribe step events be a new map.
-
For each event name → navigables in enabled events:
-
If the event with event name event name defines remote end subscribe steps, set subscribe step events[event name] to navigables.
-
-
Sort in ascending order subscribe step events using the following less than algorithm given two entries with keys event name one and event name two:
-
Let event one be the event with name event name one
-
Let event two be the event with name event name two
-
Return true if event one’s subscribe priority is less than event two’s subscribe priority, or false otherwise.
-
-
If list of navigables is null, let include global be true, otherwise let include global be false.
-
For each event name → navigables in subscribe step events:
-
Run the remote end subscribe steps for the event with event name event name given session, navigables and include global.
-
-
Return success with data null.
7.1.3.5. The session.unsubscribe Command
The session.unsubscribe command disables events either globally or for a set of navigables.
This needs to be generalised to work with realms too.
- Command Type
-
session.Unsubscribe = ( method: "session.unsubscribe", params: session.SubscriptionRequest )
- Result Type
-
EmptyResult
-
Let the list of event names be the value of the
Ereignisse
field of command parameters. -
Let the list of contexts be the value of the
contexts
field of command parameters if it is present or null if it isn’t. -
Try to update the event map with session, list of event names, list of contexts and enabled false.
-
Return success with data null.
7.2. The browser Module
The browser module contains commands for managing the remote end browser process.
7.2.1. Definition
BrowserCommand = ( browser.Close // browser.CreateUserContext // browser.GetUserContexts // browser.RemoveUserContext )
BrowserResult = ( browser.CreateUserContextResult / browser.GetUserContextsResult )
7.2.2. Types
7.2.2.1. The browser.UserContext Type
browser.UserContext = text;
The browser.UserContext
unique identifies a user context.
7.2.2.2. The browser.UserContextInfo Type
browser.UserContextInfo = { userContext: browser.UserContext }
The browser.UserContextInfo
type represents properties of a user
context.
7.2.3. Commands
7.2.3.1. The browser.close Command
The browser.close command terminates all WebDriver sessions and cleans up automation state in the remote browser instance.
- Command Type
-
browser.Close = ( method: "browser.close", params: EmptyParams, )
- Return Type
-
EmptyResult
-
End the session with session.
-
If active sessions is not empty an implementation may return error with error code unable to close browser, and then run the following steps in parallel:
-
Wait until the Send a WebSocket message steps have been called with the response to this command.
-
Cleanup the session with session.
Note: The behaviour in cases where the browser has multiple automation sessions is currently unspecified. It might be that any session can close the browser, or that only the final open session can actually close the browser, or only the first session started can. This behaviour might be fully specified in a future version of this specification.
-
-
For each active session in active sessions:
-
End the session active session.
-
Cleanup the session with active session
-
-
Return success with data null, and run the following steps in parallel.
-
Wait until the Send a WebSocket message steps have been called with the response to this command.
-
Cleanup the session with session.
-
Close any top-level traversables without prompting to unload.
-
Perform implementation defined steps to clean up resources associated with the remote end under automation.
Note: For example this might include cleanly shutting down any OS-level processes associated with the browser under automation, removing temporary state, such as user profile data, created by the remote end while under automation, or shutting down the WebSocket Listener. Because of differences between browsers and operating systems it is not possible to specify in detail precise invariants local ends can depend on here.
-
7.2.3.2. The browser.createUserContext Command
The browser.createUserContext command creates a user context.
- Command Type
-
browser.CreateUserContext = ( method: "browser.createUserContext", params: EmptyParams, )
- Return Type
-
browser.CreateUserContextResult = browser.UserContextInfo
The remote end steps are:
-
Let user context be a new user context.
-
Append user context to the set of user contexts.
-
Let user context info be a map matching the
browser.UserContextInfo
production with theuserContext
field set to user context’s user context id. -
Return success with data user context info.
7.2.3.3. The browser.getUserContexts Command
The browser.getUserContexts command returns a list of user contexts.
- Command Type
-
browser.GetUserContexts = ( method: "browser.getUserContexts", params: EmptyParams, )
- Return Type
-
browser.GetUserContextsResult = { userContexts: [ + browser.UserContextInfo] }
The remote end steps are:
-
Let user contexts be an empty list.
-
For each user context in the set of user contexts:
-
Let user context info be a map matching the
browser.UserContextInfo
production with theuserContext
field set to user context’s user context id. -
Append user context info to user contexts.
-
-
Let result be a map matching the
browser.GetUserContextsResult
production with theuserContexts
field set to user contexts. -
Return success with data result.
7.2.3.4. The browser.removeUserContext Command
The browser.removeUserContext command closes a
user context and all navigables in it without running beforeunload
handlers.
- Command Type
-
browser.RemoveUserContext = ( method: "browser.removeUserContext", params: browser.RemoveUserContextParameters ) browser.RemoveUserContextParameters = { userContext: browser.UserContext }
- Return Type
-
EmptyResult
The remote end steps with command parameters are:
-
Let user context id be command parameters["
userContext
"]. -
If user context id is
"default"
, return error with error code invalid argument. -
Set user context to get user context with user context id.
-
If user context is null, return error with error code no such user context.
-
For each top-level traversable navigable:
-
If navigable’s associated user context is user context:
-
Schließen Sie navigable without prompting to unload.
-
-
-
Entfernen Sie user context for the set of user contexts.
-
Return success with data null.
7.3. The browsingContext Module
The browsingContext module contains commands and events relating to navigables.
Note: For historic reasons this module is called browsingContext
rather than navigable
, and the protocol uses the term context
to refer to navigables, particularly as a field in command
and response parameters.
The progress of navigation is communicated using an immutable WebDriver navigation status struct, which has the following items:
- id
- The navigation id for the navigation, or null when the navigation is canceled before making progress.
- status
- A status code that is either
"
canceled
", "pending
", or "complete
". - url
- The URL which is being loaded in the navigation
7.3.1. Definition
BrowsingContextCommand = ( browsingContext.Activate // browsingContext.CaptureScreenshot // browsingContext.Close // browsingContext.Create // browsingContext.GetTree // browsingContext.HandleUserPrompt // browsingContext.LocateNodes // browsingContext.Navigate // browsingContext.Print // browsingContext.Reload // browsingContext.SetViewport // browsingContext.TraverseHistory )
BrowsingContextResult = ( browsingContext.CaptureScreenshotResult / browsingContext.CreateResult / browsingContext.GetTreeResult / browsingContext.LocateNodesResult / browsingContext.NavigateResult / browsingContext.PrintResult / browsingContext.TraverseHistoryResult ) BrowsingContextEvent = ( browsingContext.ContextCreated // browsingContext.ContextDestroyed // browsingContext.DomContentLoaded // browsingContext.DownloadWillBegin // browsingContext.FragmentNavigated // browsingContext.Load // browsingContext.NavigationAborted // browsingContext.NavigationFailed // browsingContext.NavigationStarted // browsingContext.UserPromptClosed // browsingContext.UserPromptOpened )
A remote end has a device pixel ratio overrides which is a weak map between navigables and device pixel ratio overrides. It is initially empty.
Note: this map is not cleared when the final session ends i.e. device pixel ratio overrides outlive any WebDriver session.
7.3.2. Types
7.3.2.1. The browsingContext.BrowsingContext Type
remote end definition and local end definition
browsingContext.BrowsingContext = text;
Each navigable has an associated navigable id, which is a string uniquely identifying that navigable. This is implicitly set when the navigable is created. For navigables with an associated WebDriver window handle the navigable id must be the same as the window handle.
Each navigable also has an associated storage partition, which is the storage partition it uses to persist data.
Each navigable also has an associated original opener, which is a navigable that caused the navigable to open or null, initially set to null.
-
If navigable id is null, return success with data null.
-
If there is no navigable with navigable id navigable id return error with error code no such frame
-
Let navigable be the navigable with id navigable id.
-
Return success with data navigable.
7.3.2.2. The browsingContext.Info Type
browsingContext.InfoList = [*browsingContext.Info] browsingContext.Info = { children: browsingContext.InfoList / null, context: browsingContext.BrowsingContext, originalOpener: browsingContext.BrowsingContext / null, url: text, userContext: browser.UserContext, ? parent: browsingContext.BrowsingContext / null, }
The browsingContext.Info
type represents the properties of a
navigable.
-
Let parent navigable be navigable’s parent.
-
If parent navigable is null, then return null.
-
Return parent navigable.
TODO: make this return a list in document order
-
Let child navigables be a set containing all navigables that are a child navigable of navigable.
-
Return child navigables.
-
Let navigable id be the navigable id for navigable.
-
Let navigable be get the parent navigable given navigable.
-
If navigable is not null let parent id be the navigable id of navigable. Otherwise let parent id be null.
-
Let document be navigable’s active document.
-
Let url be the result of running the URL serializer, given document’s URL.
Note: This includes the fragment component of the URL.
-
Let child infos be null.
-
If max depth is null, or max depth is greater than 0:
-
Let child navigables be get the child navigables given navigable.
-
Let child depth be max depth - 1 if max depth is not null, or null otherwise.
-
Set child infos to an empty list.
-
For each child navigable of child navigables:
-
Let info be the result of get the navigable info given child navigable, child depth, and false.
-
Append info to child infos
-
-
-
Let user context be navigable’s associated user context.
-
Let opener id be the navigable id for navigable’s original opener, if navigable’s original opener is not null, and null otherwise.
-
Let context info be a map matching the
browsingContext.Info
production with thecontext
field set to navigable id, theparent
field set to parent id if include parent id istrue
, or unset otherwise, theurl
field set to url, theuserContext
field set to user context’s user context id,originalOpener
field set to opener id, and thechildren
field set to child infos. -
Return context info.
default
") and ignore cache (default: false):
-
Let navigation id be the string representation of a UUID based on truly random, or pseudo-random numbers.
-
Navigate navigable with resource request, and using navigable’s active document as the source
Document
, with navigation id navigation id, and history handling behavior history handling. If ignore cache is true, the navigation must not load resources from the HTTP cache.property specify how the ignore cache flag works. This needs to consider whether only the first load of a resource bypasses the cache (i.e. whether this is like initially clearing the cache and proceeding like normal), or whether resources not directly loaded by the HTML parser (e.g. loads initiated by scripts or stylesheets) also bypass the cache.
-
Let (event received, navigate status) be await given «"
navigation started
", "navigation failed
", "fragment navigated
"», and navigation id. -
Assert: navigate status’s id is navigation id.
-
If navigate status’s status is "
complete
":-
Let body be a map matching the
browsingContext.NavigateResult
production, with thenavigation
field set to navigation id, and theurl
field set to the result of the URL serializer given navigate status’s url. -
Return success with data body.
Note: this is the case if the navigation only caused the fragment to change.
-
-
If navigate status’s status is "
canceled
" return error with error code unknown error.TODO: is this the right way to handle errors here?
-
Assert: navigate status’s status is "
pending
" and navigation id is not null. -
If wait condition is "
none
":-
Let body be a map matching the
browsingContext.NavigateResult
production, with thenavigation
field set to navigation id, and theurl
field set to the result of the URL serializer given navigate status’s url. -
Return success with data body.
-
-
If wait condition is "
interactive
", let event name be "domContentLoaded
", otherwise let event name be "load
". -
Let (event received, status) be await given «event name, "
download started
", "navigation aborted
", "navigation failed
"» and navigation id. -
If event received is "
navigation failed
" return error with error code unknown error.Are we surfacing enough information about what failed and why with an error here? What error code do we want? Is there going to be a problem where local ends parse the implementation-defined strings to figure out what actually went wrong?
-
Let body be a map matching the
browsingContext.NavigateResult
production, with thenavigation
field set to status’s id, and theurl
field set to the result of the URL serializer given status’s url. -
Return success with data body.
7.3.2.3. The browsingContext.Locator Type
remote end definition and local end definition
browsingContext.Locator = ( browsingContext.AccessibilityLocator / browsingContext.CssLocator / browsingContext.InnerTextLocator / browsingContext.XPathLocator ) browsingContext.AccessibilityLocator = { type: "accessibility", value: { ? name: text, ? role: text, } } browsingContext.CssLocator = { type: "css", value: text } browsingContext.InnerTextLocator = { type: "innerText", value: text, ? ignoreCase: bool ? matchType: "full" / "partial", ? maxDepth: js-uint, } browsingContext.XPathLocator = { type: "xpath", value: text }
The browsingContext.Locator
type provides details on the strategy
for locating a node in a document.
7.3.2.4. The browsingContext.Navigation Type
remote end definition and local end definition
browsingContext.Navigation = text;
The browsingContext.Navigation
type is a unique string identifying an ongoing
navigation.
TODO: Link to the definition in the HTML spec.
7.3.2.5. The browsingContext.NavigationInfo Type
browsingContext.NavigationInfo = { context: browsingContext.BrowsingContext, navigation: browsingContext.Navigation / null, timestamp: js-uint, url: text, }
The browsingContext.NavigationInfo
type provides details of an ongoing navigation.
-
Let navigable id be the navigable id for navigable.
-
Let navigation id be navigation status’s id.
-
Let timestamp be a time value representing the current date and time in UTC.
-
Let url be navigation status’s url.
-
Return a map matching the
browsingContext.NavigationInfo
production, with thecontext
field set to navigable id, thenavigation
field set to navigation id, thetimestamp
field set to timestamp, and theurl
field set to the result of the URL serializer given url.
7.3.2.6. The browsingContext.ReadinessState Type
browsingContext.ReadinessState = "none" / "interactive" / "complete"
The browsingContext.ReadinessState
type represents the stage of
document loading at which a navigation command will return.
7.3.2.7. The browsingContext.UserPromptType Type
Remote end definition and local end definition
browsingContext.UserPromptType = "alert" / "beforeunload" / "confirm" / "prompt";
The browsingContext.UserPromptType
type represents the possible user
prompt types.
7.3.3. Commands
7.3.3.1. The browsingContext.activate Command
The browsingContext.activate command activates and focuses the given top-level traversable.
- Command Type
-
browsingContext.Activate = ( method: "browsingContext.activate", params: browsingContext.ActivateParameters ) browsingContext.ActivateParameters = { context: browsingContext.BrowsingContext }
- Result Type
-
EmptyResult
The remote end steps with command parameters are:
-
Let navigable id be the value of the command parameters["
context
"] field. -
Let navigable be the result of trying to get a navigable with navigable id.
-
If navigable is not a top-level traversable, return error with error code invalid argument.
-
Return activate a navigable with navigable.
-
Run implementation-specific steps so that navigable’s system visibility state becomes visible. If this is not possible return error with error code unsupported operation.
Note: This can have the side effect of making currently visible navigables hidden.
Note: This can change the underlying OS state by causing the window to become unminimized or by other side effects related to changing the system visibility state.
-
Run implementation-specific steps to set the system focus on the navigable if it is not focused.
Note: This does not change the focused area of the document except as mandated by other specifications.
-
Return success with data null.
7.3.3.2. The browsingContext.captureScreenshot Command
The browsingContext.captureScreenshot command captures an image of the given navigable, and returns it as a Base64-encoded string.
- Command Type
-
browsingContext.CaptureScreenshot = ( method: "browsingContext.captureScreenshot", params: browsingContext.CaptureScreenshotParameters ) browsingContext.CaptureScreenshotParameters = { context: browsingContext.BrowsingContext, ? origin: ("viewport" / "document") .default "viewport", ? format: browsingContext.ImageFormat, ? clip: browsingContext.ClipRectangle, } browsingContext.ImageFormat = { type: text, ? quality: 0.0..1.0, } browsingContext.ClipRectangle = ( browsingContext.BoxClipRectangle / browsingContext.ElementClipRectangle ) browsingContext.ElementClipRectangle = { type: "element", element: script.SharedReference } browsingContext.BoxClipRectangle = { type: "box", x: float, y: float, width: float, height: float }
- Result Type
-
browsingContext.CaptureScreenshotResult = { data: text }
Note: This ensures that the resulting rect has positive width dimension and height dimension.
-
Let x be rect’s x coordinate.
-
Let y be rect’s y coordinate.
-
Let width be rect’s width dimension.
-
Let height be rect’s height dimension.
-
If width is less than 0, set x to x + width and then set width to -width.
-
If height is less than 0, set y to y + height and then set height to -height.
-
Return a new
DOMRectReadOnly
with x coordinate x, y coordinate y, width dimension width and height dimension height.
-
Let rect1 be normalize rect with rect1.
-
Let rect2 be normalize rect with rect2.
-
Let x1_0 be rect1’s x coordinate.
-
Let x2_0 be rect2’s x coordinate.
-
Let x1_1 be rect1’s x coordinate plus rect1’s width dimension.
-
Let x2_1 be rect2’s x coordinate plus rect2’s width dimension.
-
Let x_0 be the maximum element of «x1_0, x2_0».
-
Let x_1 be the minimum element of «x1_1, x2_1».
-
Let y1_0 be rect1’s y coordinate.
-
Let y2_0 be rect2’s y coordinate.
-
Let y1_1 be rect1’s y coordinate plus rect1’s height dimension.
-
Let y2_1 be rect2’s y coordinate plus rect2’s height dimension.
-
Let y_0 be the maximum element of «y1_0, y2_0».
-
Let y_1 be the minimum element of «y1_1, y2_1».
-
If x_1 is less than x_0, let width be 0. Otherwise let width be x_1 - x_0.
-
If y_1 is less than y_0, let height be 0. Otherwise let height be y_1 - y_0.
-
Return a new
DOMRectReadOnly
with x coordinate x_0, y coordinate y_0, width dimension width and height dimension height.
-
Let ratio be determine the device pixel ratio given document’s default view.
-
Let paint width be rect’s width dimension multiplied by ratio, rounded to the nearest integer, so it matches the width of rect in device pixels.
-
Let paint height be rect’s height dimension multiplied by ratio, rounded to the nearest integer, so it matches the height of rect in device pixels.
-
Let canvas be a new
HTMLCanvasElement
withwidth
paint width andheight
paint height. -
Let canvas context be the result of running the 2D context creation algorithm with canvas and null.
-
Set canvas’s context mode to 2D.
-
Complete implementation specific steps equivalent to drawing the region of the framebuffer representing the region of document covered by rect to canvas context, such that each pixel in the framebuffer corresponds to a pixel in canvas context with (rect’s x coordinate, rect’s y coordinate) in viewport coordinates corresponding to (0,0) in canvas context and (rect’s x coordinate + rect’s width dimension, rect’s y coordinate + rect’s height dimension) corresponding to (paint width, paint height).
-
Return canvas.
-
If format is not null, let type be the
type
field of format, and let quality be thequality
field of format. -
Otherwise, let type be "image/png" and let quality be undefined.
-
Let file be a serialization of the bitmap as a file for canvas with type and quality.
-
Let encoded string be the forgiving-base64 encode of file.
-
Return success with data encoded string.
-
If origin is
"viewport"
:-
Let viewport be document’s visual viewport.
-
Let viewport rect be a
DOMRectReadOnly
with x coordinate viewport page left, y coordinate viewport page top, width dimension viewport width, and height dimension viewport height. -
Return success with data viewport rect.
-
-
Assert: origin is
"document"
. -
Let document element be the document element for document.
-
Let document rect be a
DOMRectReadOnly
with x coordinate 0, y coordinate 0, width dimension document element scroll height, and height dimension document element scroll width. -
Return success with data document rect.
The remote end steps with session and command parameters are:
-
Let navigable id be the value of the
context
field of command parameters if present, or null otherwise. -
Let navigable be the result of trying to get a navigable with navigable id.
-
If the implementation is unable to capture a screenshot of navigable for any reason then return error with error code unsupported operation.
-
Let document be navigable’s active document.
-
Immediately after the next invocation of the run the animation frame callbacks algorithm for document:
This ought to be integrated into the update rendering algorithm in some more explicit way.
-
Let origin be the value of the
context
field of command parameters if present, or "viewport" otherwise. -
Let origin rect be the result of trying to get the origin rectangle given origin and document.
-
Let clip rect be origin rect.
-
If command parameters contains "
clip
":-
Let clip be command parameters["
clip
"]. -
Run the steps under the first matching condition:
- clip matches the
browsingContext.ElementClipRectangle
production: -
-
Let environment settings be the environment settings object whose relevant global object's associated
Document
is document. -
Let realm be environment settings’ realm execution context's Realm component.
-
Let element be the result of trying to deserialize remote reference with clip["
element
"], realm, and session. -
If element doesn’t implement
Element
return error with error code no such element. -
If element’s node document is not document, return error with error code no such element.
-
Let viewport rect be get the origin rectangle given "
viewport
" and document. -
Let element rect be get the bounding box for element.
-
Let clip rect be a
DOMRectReadOnly
with x coordinate element rect["x
"] + viewport rect["x
"]|, y coordinate element rect["y
"] + viewport rect["y
"], width element rect["width
"], and height element rect["height
"].
-
- clip matches the
browsingContext.BoxClipRectangle
production: -
-
Let clip x be clip["
x
"] plus origin rect’s x coordinate. -
Let clip y be clip["
y
"] plus origin rect’s y coordinate. -
Let clip rect be a
DOMRectReadOnly
with x coordinate clip x, y coordinate clip y, width clip["width
"], and height clip["height
"].
-
- clip matches the
-
-
Note: All coordinates are now measured from the origin of the document.
-
Let rect be the rectangle intersection of origin rect and clip rect.
-
If rect’s width dimension is 0 or rect’s height dimension is 0, return error with error code unable to capture screen.
-
Let canvas be render document to a canvas with document and rect.
-
Let format be the
format
field of command parameters. -
Let encoding result be the result of trying to encode a canvas as Base64 with canvas and format.
-
Let body be a map matching the
browsingContext.CaptureScreenshotResult
production, with thedata
field set to encoding result. -
Return success with data body.
7.3.3.3. The browsingContext.close Command
The browsingContext.close command closes a top-level traversable.
- Command Type
-
browsingContext.Close = ( method: "browsingContext.close", params: browsingContext.CloseParameters ) browsingContext.CloseParameters = { context: browsingContext.BrowsingContext, ? promptUnload: bool .default false }
- Result Type
-
EmptyResult
-
Let navigable id be the value of the
context
field of command parameters. -
Let prompt unload be the value of the
promptUnload
field of command parameters. -
Let navigable be the result of trying to get a navigable with navigable id.
-
Assert: navigable is not null.
-
If navigable is not a top-level traversable, return error with error code invalid argument.
-
If prompt unload is true:
-
Schließen Sie navigable.
-
-
Otherwise:
-
Schließen Sie navigable without prompting to unload.
-
-
Return success with data null.
There is an open discussion about the behavior when closing the last top-level traversable. We could expect to close the browser, close the session or leave this up to the implementation. [Issue #w3c/webdriver-bidi#170]
7.3.3.4. The browsingContext.create Command
The browsingContext.create command creates a new navigable, either in a new tab or in a new window, and returns its navigable id.
- Command Type
-
browsingContext.Create = ( method: "browsingContext.create", params: browsingContext.CreateParameters ) browsingContext.CreateType = "tab" / "window" browsingContext.CreateParameters = { type: browsingContext.CreateType, ? referenceContext: browsingContext.BrowsingContext, ? background: bool .default false, ? userContext: browser.UserContext }
- Result Type
-
browsingContext.CreateResult = { context: browsingContext.BrowsingContext }
-
Let type be the value of the
type
field of command parameters. -
Let reference navigable id be the value of the
referenceContext
field of command parameters, if present, or null otherwise. -
If reference navigable id is not null, let reference navigable be the result of trying to get a navigable with reference navigable id. Otherwise let reference navigable be null.
-
If reference navigable is not null and is not a top-level traversable, return error with error code invalid argument.
-
If the implementation is unable to create a new top-level traversable for any reason then return error with error code unsupported operation.
-
Let user context be the default user context if reference navigable is null, and reference navigable’ associated user context otherwise.
-
Let user context id be the value of the
userContext
field of command parameters if present, or null otherwise. -
If user context id is not null, set user context to the result of trying to get user context with user context id.
-
If user context is null, return error with error code no such user context.
-
If the implementation is unable to create a new top-level traversable with associated user context user context for any reason, return error with error code unsupported operation.
-
Let traversable be the result of trying to create a new top-level traversable steps with null and empty string, and setting the associated user context for the newly created top-level traversable to user context. Which OS window the new top-level traversable is created in depends on type and reference navigable:
-
If type is "
tab
" and the implementation supports multiple top-level traversables in the same OS window:-
The new top-level traversable should reuse an existing OS window, if any.
-
If reference navigable is not null, the new top-level traversable should reuse the window containing reference navigable, if any. If the top-level traversables inside an OS window have a definite ordering, the new top-level traversable should be immediately after reference navigable’s top-level traversable in that ordering.
-
-
If type is "
window
", and the implementation supports multiple top-level traversable in separate OS windows, the created top-level traversable should be in a new OS window. -
Otherwise, the details of how the top-level traversable is presented to the user are implementation defined.
-
-
If the value of the command parameters’
background
field is false:-
Let activate result be the result of activate a navigable with the newly created navigable.
-
If activate result is an error, return activate result.
Note: Do not invoke the focusing steps for the created navigable if
background
is true. -
-
Let body be a map matching the
browsingContext.CreateResult
production, with thecontext
field set to traversable’s navigable id. -
Return success with data body.
7.3.3.5. The browsingContext.getTree Command
The browsingContext.getTree command returns a tree of all descendent navigables including the given parent itself, or all top-level contexts when no parent is provided.
- Command Type
-
browsingContext.GetTree = ( method: "browsingContext.getTree", params: browsingContext.GetTreeParameters ) browsingContext.GetTreeParameters = { ? maxDepth: js-uint, ? root: browsingContext.BrowsingContext, }
- Result Type
-
browsingContext.GetTreeResult = { contexts: browsingContext.InfoList }
-
Let root id be the value of the
root
field of command parameters if present, or null otherwise. -
Let max depth be the value of the
maxDepth
field of command parameters if present, or null otherwise. -
Let navigables be an empty list.
-
If root id is not null, append the result of trying to get a navigable given root id to navigables. Otherwise append all top-level traversables to navigables.
-
Let navigables infos be an empty list.
-
For each navigable of navigables:
-
Let info be the result of get the navigable info given navigable, max depth, and true.
-
Append info to navigables infos
-
-
Let body be a map matching the
browsingContext.GetTreeResult
production, with thecontexts
field set to navigables infos. -
Return success with data body.
7.3.3.6. The browsingContext.handleUserPrompt Command
The browsingContext.handleUserPrompt command allows closing an open prompt
- Command Type
-
browsingContext.HandleUserPrompt = ( method: "browsingContext.handleUserPrompt", params: browsingContext.HandleUserPromptParameters ) browsingContext.HandleUserPromptParameters = { context: browsingContext.BrowsingContext, ? accept: bool, ? userText: text, }
- Result Type
-
EmptyResult
The remote end steps with session and command parameters are:
-
Let navigable id be the value of the
context
field of command parameters. -
Let navigable be the result of trying to get a navigable with navigable id.
-
Let accept be the value of the
accept
field of command parameters if present, or true otherwise. -
Let userText be the value of the
userText
field of command parameters if present, or the empty string otherwise. -
If navigable is currently showing a simple dialog from a call to alert then acknowledge the prompt.
Otherwise if navigable is currently showing a simple dialog from a call to confirm, then respond positively if accept is true, or respond negatively if accept is false.
Otherwise if navigable is currently showing a simple dialog from a call to prompt, then respond with the string value userText if accept is true, or abort if accept is false.
Otherwise, if navigable is currently showing a prompt as part of the prompt to unload steps, then confirm the navigation if accept is true, otherwise refuse the navigation.
Otherwise return error with error code no such alert.
-
Return success with data null.
7.3.3.7. The browsingContext.locateNodes Command
The browsingContext.locateNodes command returns a list of all nodes matching the specified locator.
- Command Type
-
browsingContext.LocateNodes = ( method: "browsingContext.locateNodes", params: browsingContext.LocateNodesParameters ) browsingContext.LocateNodesParameters = { context: browsingContext.BrowsingContext, locator: browsingContext.Locator, ? maxNodeCount: (js-uint .ge 1), ? serializationOptions: script.SerializationOptions, ? startNodes: [ + script.SharedReference ] }
- Result Type
-
browsingContext.LocateNodesResult = { nodes: [ * script.NodeRemoteValue ] }
-
Let returned nodes be an empty list.
-
Let parse result be the result of parse a selector given selector.
-
If parse result is failure, return error with error code invalid selector.
-
For each context node of context nodes:
-
Let elements be the result of match a selector against a tree with parse result and navigable’s active document root using scoping root context node.
-
For each element in elements:
-
-
Return success with data returned nodes.
To locate nodes using XPath with given navigable, context nodes, selector, and maximum returned node count:
Note: Owing to the unmaintained state of the XPath specification, this algorithm is phrased as if making calls to the XPath DOM APIs. However this is to be understood as equivalent to spec-internal calls directly accessing the underlying algorithms, without going via the ECMAScript runtime.
-
Let returned nodes be an empty list.
-
For each context node of context nodes:
-
Let evaluate result be the result of calling evaluate on navigable’s active document, with arguments selector, context node, null, ORDERED_NODE_SNAPSHOT_TYPE, and null. If this throws a "SyntaxError" DOMException, return error with error code invalid selector; otherwise, if this throws any other exception return error with error code unknown error.
-
Let index be 0.
-
Let length be the result of getting the
snapshotLength
property from evaluate result. -
Repeat, while index is less than length:
-
Let node be the result of calling snapshotItem with evaluate result as this and index as the argument.
-
Append node to returned nodes.
-
If maximum returned node count not null and size of returned nodes is equal to maximum returned node count, return success with data returned nodes.
-
Set index to index + 1.
-
-
-
Return success with data returned nodes.
-
If selector is the empty string, return error with error code invalid selector.
-
Let returned nodes be an empty list.
-
If ignore case is false, let search text be selector. Otherwise, let search text be the result of toUppercase with selector according to the Unicode Default Case Conversion algorithm.
-
For each context node in context nodes:
-
If context node implements
Document
oderDocumentFragment
:Note: when traversing the document or document fragment,
max depth
is not decreased intentionally to make the search result withdocument
anddocument.documentElement
equivalent. -
If context node does not implement
HTMLElement
then continue. -
Let node inner text be the result of calling the innerText getter steps with context node as the this value.
-
If ignore case is false, let node text be node inner text. Otherwise, let node text be the result of toUppercase with node inner text according to the Unicode Default Case Conversion algorithm.
-
If search text is a code point substring of node text, perform the following steps:
-
Let child nodes be an empty list and, for each node child in the children of context node:
-
Append child to child nodes.
-
-
If size of child nodes is equal to 0 or max depth is equal to 0, perform the following steps:
-
Otherwise, perform the following steps:
-
Let child max depth be null if max depth is null, or max depth - 1 otherwise.
-
Let child node matches be the result of locate nodes using inner text with child nodes, selector, child max depth , match type, ignore case, and maximum returned node count.
-
If size of child node matches is equal to 0 and match type is
"partial"
, append context node to returned nodes. Otherwise, extend returned nodes with child node matches.
-
-
-
-
If maximum returned node count is not null, remove all entries in returned nodes with an index greater than or equal to maximum returned node count.
-
Return success with data returned nodes.
-
If returned nodes is null:
-
Set returned nodes to an empty list.
-
-
For each context node in context nodes:
-
Let match be true.
-
If context node implements
Element
:-
If selector contains "
role
":-
Let role be the computed role of context node.
-
If selector["
role
"] is not role:-
Set match to false.
-
-
-
If selector contains "
name
":-
Let name be the accessible name of context node.
-
If selector["
name
"] is not name:-
Set match to false.
-
-
-
-
Otherwise, set match to false.
-
If match is true:
-
Let child nodes be an empty list and, for each node child in the children of context node:
-
Try to collect nodes using accessibility attributes with child nodes, selector, maximum returned node count, and returned nodes.
-
-
Return returned nodes.
-
If selector does not contain "
role
" and selector does not contain "name
", return error with error code invalid selector. -
Return the result of collect nodes using accessibility attributes with context nodes, selector, maximum returned node count, and null.
-
Let navigable id be command parameters["
context
"]. -
Let navigable be the result of trying to get a navigable with navigable id.
-
Assert: navigable is not null.
-
Let realm be the result of trying to get a realm from a navigable with navigable id of navigable and null.
-
Let locator be command parameters["
locator
"]. -
If command parameters contains "
startNodes
", let start nodes parameter be command parameters["startNodes
"]. Otherwise let start nodes parameter be null. -
If command parameters contains "
maxNodeCount
", let maximum returned node count be command parameters["maxNodeCount
"]. Otherwise, let maximum returned node count be null. -
Let context nodes be an empty list.
-
If start nodes parameter is null, append the document element of navigable’s active document to context nodes. Otherwise, for each serialized start node in start nodes parameter:
-
Let start node be the result of trying to deserialize shared reference given serialized start node, realm and session.
-
Append start node to context nodes.
-
-
Assert size of context nodes is greater than 0.
-
Let type be locator["
type
"]. -
In the following list of conditions and associated steps, run the first set of steps for which the associated condition is true:
- type is the string "
css
" -
-
Let selector be locator["
value
"]. -
Let result nodes be a result of trying to locate nodes using css given navigable, context nodes, selector and maximum returned nodes.
-
- type is the string "
xpath
" -
-
Let selector be locator["
value
"]. -
Let result nodes be a result of trying to locate nodes using xpath given navigable, context nodes, selector and maximum returned nodes.
-
- type is the string "
innerText
" -
-
Let selector be locator["
value
"]. -
If locator contains
maxDepth
, let max depth be locator["maxDepth
"]. Otherwise, let max depth be null. -
If locator contains
ignoreCase
, let ignore case be locator["ignoreCase
"]. Otherwise, let ignore case be false. -
If locator contains
matchType
, let match type be locator["matchType
"]. Otherwise, let match type be "full". -
Let result nodes be a result of trying to locate nodes using inner text given context nodes, selector, max depth, match type, ignore case and maximum returned node count.
-
- type is the string "
accessibility
" -
-
Let selector be locator["
value
"]. -
Let result nodes be locate nodes using accessibility attributes given context nodes, selector, and maximum returned node count.
-
- type is the string "
-
Assert: maximum returned node count is null or size of result nodes is less than or equal to maximum returned node count.
-
If command parameters contains "
serializationOptions
", let serialization options be command parameters["serializationOptions
"]. Otherwise, let serialization options be a map matching thescript.SerializationOptions
production with the fields set to their default values. -
Let result ownership be "none".
-
Let serialized nodes be an empty list.
-
For each result node in result nodes:
-
Let serialized node be the result of serialize as a remote value with result node, serialization options, result ownership, a new map as serialization internal map, realm and session.
-
Append serialized node to serialized nodes.
-
-
Let result be a map matching the
browsingContext.LocateNodesResult
production, with thenodes
field set serialized nodes. -
Return success with data result.
7.3.3.8. The browsingContext.navigate Command
The browsingContext.navigate command navigates a navigable to the given URL.
- Command Type
-
browsingContext.Navigate = ( method: "browsingContext.navigate", params: browsingContext.NavigateParameters ) browsingContext.NavigateParameters = { context: browsingContext.BrowsingContext, url: text, ? wait: browsingContext.ReadinessState, }
- Result Type
-
browsingContext.NavigateResult = { navigation: browsingContext.Navigation / null, url: text, }
-
Let navigable id be the value of the
context
field of command parameters. -
Let navigable be the result of trying to get a navigable with navigable id.
-
Assert: navigable is not null.
-
Let wait condition be the value of the
wait
field of command parameters if present, or "none
" otherwise. -
Let url be the value of the
url
field of command parameters. -
Let document be navigable’s active document.
-
Let base be document’s base URL.
-
Let url record be the result of applying the URL parser to url, with base URL base.
-
If url record is failure, return error with error code invalid argument.
-
Let request be a new request whose URL is url record.
-
Return the result of await a navigation with navigable, request and wait condition.
7.3.3.9. The browsingContext.print Command
The browsingContext.print command creates a paginated representation of a document, and returns it as a PDF document represented as a Base64-encoded string.
- Command Type
-
browsingContext.Print = ( method: "browsingContext.print", params: browsingContext.PrintParameters ) browsingContext.PrintParameters = { context: browsingContext.BrowsingContext, ? background: bool .default false, ? margin: browsingContext.PrintMarginParameters, ? orientation: ("portrait" / "landscape") .default "portrait", ? page: browsingContext.PrintPageParameters, ? pageRanges: [*(js-uint / text)], ? scale: (0.1..2.0) .default 1.0, ? shrinkToFit: bool .default true, } browsingContext.PrintMarginParameters = { ? bottom: (float .ge 0.0) .default 1.0, ? left: (float .ge 0.0) .default 1.0, ? right: (float .ge 0.0) .default 1.0, ? top: (float .ge 0.0) .default 1.0, } ; Minimum size is 1pt x 1pt. Conversion follows from ; https://www.w3.org/TR/css3-values/#absolute-lengths browsingContext.PrintPageParameters = { ? height: (float .ge 0.0352) .default 27.94, ? width: (float .ge 0.0352) .default 21.59, }
- Result Type
-
browsingContext.PrintResult = { data: text }
The remote end steps with session and command parameters are:
-
Let navigable id be the value of the
context
field of command parameters. -
Let navigable be the result of trying to get a navigable with navigable id.
-
If the implementation is unable to provide a paginated representation of navigable for any reason then return error with error code unsupported operation.
-
Let margin be the value of the
margin
field of command parameters if present, or otherwise a map matching thebrowsingContext.PrintMarginParameters
with the fields set to their default values. -
Let page size be the value of the
page
field of command parameters if present, or otherwise a map matching thebrowsingContext.PrintPageParameters
with the fields set to their default values.
Note: The minimum page size is 1 point, which is (2.54 / 72) cm as per absolute lengths.
-
Let page ranges be the value of the
pageRanges
field of command parameters if present or an empty list otherwise. -
Let document be navigable’s active document.
-
Immediately after the next invocation of the run the animation frame callbacks algorithm for document:
This ought to be integrated into the update rendering algorithm in some more explicit way.
-
Let pdf data be the result taking UA-specific steps to generate a paginated representation of document, with the CSS media type set to
print
, encoded as a PDF, with the following paper settings:Property Value Width in cm page size[" width
"] if command parameters["orientation
"] is "portrait
" otherwise page size["height
"]Height in cm page size[" height
"] if command parameters["orientation
"] is "portrait
" otherwise page size["width
"]Top margin, in cm margin[" top
"]Bottom margin, in cm margin[" bottom
"]Left margin, in cm margin[" left
"]Right margin, in cm margin[" right
"]In addition, the following formatting hints should be applied by the UA:
- If command parameters["
scale
"] is not equal to1
: - Zoom the size of the content by a factor command parameters["
scale
"] - If command parameters["
background
"] is false: - Suppress output of background images
- If command parameters["
shrinkToFit
"] is true: - Resize the content to match the page width, overriding any page width specified in the content
- If command parameters["
-
If page ranges is not empty, let pages be the result of trying to parse a page range with page ranges and the number of pages contained in pdf data, then remove any pages from pdf data whose one-based index is not contained in pages.
-
Let encoding result be the result of calling Base64 Encode on pdf data.
-
Let encoded data be encoding result’s data.
-
Let body be a map matching the
browsingContext.PrintResult
production, with thedata
field set to encoded data. -
Return success with data body.
-
7.3.3.10. The browsingContext.reload Command
The browsingContext.reload command reloads a navigable.
- Command Type
-
browsingContext.Reload = ( method: "browsingContext.reload", params: browsingContext.ReloadParameters ) browsingContext.ReloadParameters = { context: browsingContext.BrowsingContext, ? ignoreCache: bool, ? wait: browsingContext.ReadinessState, }
- Return Type
-
browsingContext.NavigateResult
-
Let navigable id be the value of the
context
field of command parameters. -
Let navigable be the result of trying to get a navigable with navigable id.
-
Assert: navigable is not null.
-
Let ignore cache be the the value of the
ignoreCache
field of command parameters if present, or false otherwise. -
Let wait condition be the value of the
wait
field of command parameters if present, or "none
" otherwise. -
Let document be navigable’s active document.
-
Let url be document’s URL.
-
Let request be a new request whose URL is url.
-
Return the result of await a navigation with navigable, request, wait condition, history handling "
reload
", and ignore cache ignore cache.
7.3.3.11. The browsingContext.setViewport Command
The browsingContext.setViewport command modifies specific viewport characteristics (e.g. viewport width and viewport height) on the given top-level traversable.
- Command Type
-
browsingContext.SetViewport = ( method: "browsingContext.setViewport", params: browsingContext.SetViewportParameters ) browsingContext.SetViewportParameters = { context: browsingContext.BrowsingContext, ? viewport: browsingContext.Viewport / null, ? devicePixelRatio: (float .gt 0.0) / null, } browsingContext.Viewport = { width: js-uint, height: js-uint, }
- Result Type
-
EmptyResult
The remote end steps with command parameters are:
-
Let navigable id be the value of the
context
field of command parameters. -
Let navigable be the result of trying to get a navigable with navigable id.
-
If navigable is not a top-level traversable, return error with error code invalid argument.
-
If the implementation is unable to adjust the navigable’s layout viewport parameters with the given command parameters for any reason, return error with error code unsupported operation.
-
If command parameters contains the
viewport
field:-
Let viewport be the command parameters["
viewport
"]. -
If viewport is not null, set the width of navigable’s layout viewport to be the
width
of viewport in CSS pixels and set the height of the navigable’s layout viewport to be theheight
of viewport in CSS pixels. -
Otherwise, set the navigable’s layout viewport to the implementation-defined default.
-
-
Run the CSSOM View § 13.1 Resizing viewports steps.
-
If command parameters contains the
devicePixelRatio
field:-
Let device pixel ratio be the command parameters["
devicePixelRatio
"]. -
For the navigable and all descendant navigables:
-
Let navigable be the navigable whose active document is navigable’s active document.
-
If device pixel ratio is not null:
-
When the select an image source from a source set are run, act as if the implementation’s pixel density was set to device pixel ratio when selecting an image.
-
For the purposes of the resolution media feature, act as if the implementation’s resolution is device pixel ratio dppx scaled by the page zoom.
-
Set device pixel ratio overrides[navigable] to device pixel ratio.
Note: This will take an effect because of the patch of § 8.3.1 Determine the device pixel ratio.
-
-
Otherwise:
-
When the select an image source from a source set steps are run, use the implementation’s default behavior, without any changes made by previous invocations of these steps.
-
For the purposes of the resolution media feature, use the implementation’s default behavior, without any changes made by previous invocations of these steps.
-
Entfernen Sie navigable from device pixel ratio overrides.
-
-
Run evaluate media queries and report changes for document currently loaded in a specified navigable.
-
-
-
Return success with data null.
7.3.3.12. The browsingContext.traverseHistory Command
The browsingContext.traverseHistory command traverses the history of a given navigable by a delta.
- Command Type
-
browsingContext.TraverseHistory = ( method: "browsingContext.traverseHistory", params: browsingContext.TraverseHistoryParameters ) browsingContext.TraverseHistoryParameters = { context: browsingContext.BrowsingContext, delta: js-int, }
- Return Type
-
browsingContext.TraverseHistoryResult = { }
-
Let navigable be the result of trying to get a navigable with command parameters["
context
"]. -
Assert: navigable is not null.
-
Let delta be command parameters["
delta
"]. -
Let resume id be a unique string.
-
Queue a task on navigable’s session history traversal queue to run the following steps:
-
Let all steps be the result of getting all used history steps for navigable.
-
Let current index be the index of navigable’s current session history step within all steps.
-
Let target index be current index plus delta.
-
Let valid entry be false if all steps[target index] does not exist, or true otherwise.
-
Resume with "
check history
", resume id, and valid entry.
-
-
Let is valid entry be await with «"
check history
"», and resume id. -
If is valid entry is false, return error with error code no such history entry.
-
Traverse the history by a delta given delta and navigable.
There is a race condition in the algorithm as written because by the time we try to navigate the target session history entry might not exist. Once we support waiting for history to navigate we can handle this more robustly.
-
TODO: Support waiting for the history traversal to complete.
-
Let body be a map matching the
browsingContext.TraverseHistoryResult
production. -
Return success with data body.
The WebDriver BiDi page show steps given context and navigation status are:
Do we want to expose a `browsingContext.pageShow event? In that case we’d need to call this whenever `pageshow` is going to be emitted, not just on bfcache restore, and also add the persisted status to the data.
-
Let navigation id be navigation status’s id.
-
Resume with "
page show
", navigation id, and navigation status.
The WebDriver BiDi pop state steps given context and navigation status are:
-
Let navigation id be navigation status’s id.
-
Resume with "
pop state
", navigation id, and navigation status.
7.3.4. Events
7.3.4.1. The browsingContext.contextCreated Event
- Event Type
-
browsingContext.ContextCreated = ( method: "browsingContext.contextCreated", params: browsingContext.Info )
To Recursively emit context created events given session and navigable:
-
Emit a context created event with session and navigable.
-
For each child navigable, child, of navigable:
-
Recursively emit context created events given session and child.
-
To Emit a context created event given session and navigable:
-
Let params be the result of get the navigable info given navigable, 0, and true.
-
Let body be a map matching the
browsingContext.ContextCreated
production, with theparams
field set to params. -
Emit an event with session and body.
The remote end event trigger is the WebDriver BiDi navigable created steps given navigable and opener navigable:
-
Set navigable’s original opener to opener navigable, if opener navigable is provided.
-
If the navigable cache behavior with navigable is "
bypass
", then perform implementation-defined steps to disable any implementation-specific resource caches for network requests originating from navigable. -
Let related navigables be a set containing navigable.
-
For each session in the set of sessions for which an event is enabled given "
browsingContext.contextCreated
" and related navigables:-
Emit a context created event given session and navigable.
-
The remote end subscribe steps, with subscribe priority 1, given session, navigables and include global are:
-
For each navigable in navigables:
-
Recursively emit context created events given session and navigable.
-
7.3.4.2. The browsingContext.contextDestroyed Event
- Event Type
-
browsingContext.ContextDestroyed = ( method: "browsingContext.contextDestroyed", params: browsingContext.Info )
The remote end event trigger is the WebDriver BiDi navigable destroyed steps given navigable:
-
Let params be the result of get the navigable info, given navigable, null, and true.
-
Let body be a map matching the
browsingContext.ContextDestroyed
production, with theparams
field set to params. -
Let related navigables be a set containing the result of get the parent navigable with navigable, if that is not null, or an empty set otherwise.
-
For each session in the set of sessions for which an event is enabled given "
browsingContext.contextDestroyed
" and related navigables:-
Emit an event with session and body.
-
It’s unclear if we ought to only fire this event for browsing contexts that have active documents; navigation can also cause contexts to become inaccessible but not yet get discarded because bfcache.
7.3.4.3. The browsingContext.navigationStarted Event
- Event Type
-
browsingContext.NavigationStarted = ( method: "browsingContext.navigationStarted", params: browsingContext.NavigationInfo )
-
Let params be the result of get the navigation info given navigable and navigation status.
-
Let body be a map matching the
browsingContext.NavigationStarted
production, with theparams
field set to params. -
Let navigation id be navigation status’s id.
-
Let related navigables be a set containing navigable.
-
Resume with "
navigation started
", navigation id, and navigation status. -
For each session in the set of sessions for which an event is enabled given "
browsingContext.navigationStarted
" and related navigables:-
Emit an event with session and body.
-
7.3.4.4. The browsingContext.fragmentNavigated Event
- Event Type
-
browsingContext.FragmentNavigated = ( method: "browsingContext.fragmentNavigated", params: browsingContext.NavigationInfo )
-
Let params be the result of get the navigation info given navigable and navigation status.
-
Let body be a map matching the
browsingContext.FragmentNavigated
production, with theparams
field set to params. -
Let navigation id be navigation status’s id.
-
Let related navigable be a set containing navigable.
-
Resume with "
fragment navigated
", navigation id, and navigation status. -
For each session in the set of sessions for which an event is enabled given "
browsingContext.fragmentNavigated
" and related navigable:-
Emit an event with session and body.
-
7.3.4.5. The browsingContext.domContentLoaded Event
- Event Type
-
browsingContext.DomContentLoaded = ( method: "browsingContext.domContentLoaded", params: browsingContext.NavigationInfo )
-
Let params be the result of get the navigation info given navigable and navigation status.
-
Let body be a map matching the
browsingContext.DomContentLoaded
production, with theparams
field set to params. -
Let related navigables be a set containing navigable.
-
Let navigation id be navigation status’s id.
-
Resume with "
domContentLoaded
", navigation id, and navigation status. -
For each session in the set of sessions for which an event is enabled given "
browsingContext.domContentLoaded
" and related navigables:-
Emit an event with session and body.
-
7.3.4.6. The browsingContext.load Event
- Event Type
-
browsingContext.Load = ( method: "browsingContext.load", params: browsingContext.NavigationInfo )
-
Let params be the result of get the navigation info given navigable and navigation status.
-
Let body be a map matching the
browsingContext.Load
production, with theparams
field set to params. -
Let related navigables be a set containing navigable.
-
Let navigation id be navigation status’s id.
-
Resume with "
load
", navigation id and navigation status. -
For each session in the set of sessions for which an event is enabled given "
browsingContext.load
" and related navigables:-
Emit an event with session and body.
-
7.3.4.7. The browsingContext.downloadWillBegin Event
- Event Type
-
browsingContext.DownloadWillBegin = ( method: "browsingContext.downloadWillBegin", params: browsingContext.NavigationInfo )
-
Let params be the result of get the navigation info given navigable and navigation status.
-
Let body be a map matching the
browsingContext.DownloadWillBegin
production, with theparams
field set to params. -
Let navigation id be navigation status’s id.
-
Let related navigables be a set containing navigable.
-
Resume with "
download started
", navigation id, and navigation status. -
For each session in the set of sessions for which an event is enabled given "
browsingContext.downloadWillBegin
" and related navigables:-
Emit an event with session and body.
-
7.3.4.8. The browsingContext.navigationAborted Event
- Event Type
-
browsingContext.NavigationAborted = ( method: "browsingContext.navigationAborted", params: browsingContext.NavigationInfo )
-
Let params be the result of get the navigation info given navigable and navigation status.
-
Let body be a map matching the
browsingContext.NavigationAborted
production, with theparams
field set to params. -
Let navigation id be navigation status’s id.
-
Let related navigables be a set containing navigable.
-
Resume with "
navigation aborted
", navigation id, and navigation status. -
For each session in the set of sessions for which an event is enabled given "
browsingContext.navigationAborted
" and related navigables:-
Emit an event with session and body.
-
7.3.4.9. The browsingContext.navigationFailed Event
- Event Type
-
browsingContext.NavigationFailed = ( method: "browsingContext.navigationFailed", params: browsingContext.NavigationInfo )
-
Let params be the result of get the navigation info given navigable and navigation status.
-
Let body be a map matching the
browsingContext.NavigationFailed
production, with theparams
field set to params. -
Let navigation id be navigation status’s id.
-
Let related navigables be a set containing navigable.
-
Resume with "
navigation failed
", navigation id, and navigation status. -
For each session in the set of sessions for which an event is enabled given "
browsingContext.navigationFailed
" and related navigables:-
Emit an event with session and body.
-
7.3.4.10. The browsingContext.userPromptClosed Event
- Event Type
-
browsingContext.UserPromptClosed = ( method: "browsingContext.userPromptClosed", params: browsingContext.UserPromptClosedParameters ) browsingContext.UserPromptClosedParameters = { context: browsingContext.BrowsingContext, accepted: bool, type: browsingContext.UserPromptType, ? userText: text }
-
Let navigable be window’s navigable.
-
Let navigable id be the navigable id for navigable.
-
Let params be a map matching the
browsingContext.UserPromptClosedParameters
production with thecontext
field set to navigable id, theaccepted
field set to accepted, thetype
field set to type, and theuserText
field set to user text if user text is not null or omitted otherwise. -
Let body be a map matching the
BrowsingContextUserPromptClosedEvent
production, with theparams
field set to params. -
Let related navigables be a set containing navigable.
-
For each session in the set of sessions for which an event is enabled given "
browsingContext.userPromptClosed
" and related navigables:-
Emit an event with session and body.
-
7.3.4.11. The browsingContext.userPromptOpened Event
- Event Type
-
browsingContext.UserPromptOpened = ( method: "browsingContext.userPromptOpened", params: browsingContext.UserPromptOpenedParameters ) browsingContext.UserPromptOpenedParameters = { context: browsingContext.BrowsingContext, handler: session.UserPromptHandlerType, message: text, type: browsingContext.UserPromptType, ? defaultValue: text }
-
Let navigable be window’s navigable.
-
Let navigable id be the navigable id for navigable.
-
Let handler configuration be get the prompt handler with type.
-
Let handler be handler configuration’s handler.
-
Let params be a map matching the
browsingContext.UserPromptOpenedParameters
production with thecontext
field set to navigable id, thetype
field set to type, themessage
field set to message, thedefaultValue
field set to default value if default value is not null or omitted otherwise, and thehandler
field set to handler. -
Let body be a map matching the
browsingContext.UserPromptOpened
production, with theparams
field set to params. -
Let related navigables be a set containing navigable.
-
For each session in the set of sessions for which an event is enabled given "
browsingContext.userPromptOpened
" and related navigables:-
Emit an event with session and body.
-
-
If handler is "
ignore
", set handler to "none
". -
Return handler.
7.4. The network Module
The network module contains commands and events relating to network requests.
7.4.1. Definition
NetworkCommand = ( network.AddIntercept // network.ContinueRequest // network.ContinueResponse // network.ContinueWithAuth // network.FailRequest // network.ProvideResponse // network.RemoveIntercept // network.SetCacheBehavior )
NetworkResult = ( network.AddInterceptResult ) NetworkEvent = ( network.AuthRequired // network.BeforeRequestSent // network.FetchError // network.ResponseCompleted // network.ResponseStarted )
A remote end has a before request sent map which is initially an
empty map. It’s used to track the network events for which a network.beforeRequestSent
event has already been sent.
A remote end has a default cache behavior which is a string. It is
initially "default
".
A remote end has a navigable cache behavior map which is a weak map between top-level traversables and strings representing cache behavior. It is initially empty.
7.4.2. Network Intercepts
A network intercept is a mechanism to allow remote ends to intercept and modify network requests and responses.
A BiDi session has an intercept map which is a map between
intercept id and a struct with fields url patterns
, phases
, and browsingContexts
that define the properties
of active network intercepts. It is initially empty.
A BiDi session has a blocked request map, used to track the
requests which are actively being blocked. It is an map between request id and a struct with fields request
, phase
, and response
. It is initially empty.
To get the network intercepts given session, event, request, and navigable id:
-
Let session intercepts be session’s intercept map.
-
Let intercepts be an empty list.
-
Run the steps under the first matching condition:
- event is "
network.beforeRequestSent
" - Set phase to "
beforeRequestSent
". - event is "
network.responseStarted
" - Set phase to "
responseStarted
". - event is "
network.authRequired
" - Set phase to "
authRequired
". - event is "
network.responseCompleted
" - Return intercepts.
- event is "
-
Let url be the result of running the URL serializer with request’s URL.
-
For each intercept id → intercept of session intercepts:
-
If intercept’s
contexts
is not null:-
If intercept’s
contexts
does not contain navigable id:-
Continue.
-
-
-
If intercept’s
phases
contains phase:-
Let url patterns be intercept’s
url patterns
. -
If url patterns is empty:
-
Append intercept id to intercepts.
-
Continue.
-
-
For each url pattern in url patterns:
-
If match URL pattern with url pattern and url:
-
Append intercept id to intercepts.
-
Break.
-
-
-
-
-
Return intercepts.
-
Let blocked requests be session’s blocked request map.
-
Let request id be command parameters["
request
"]. -
If blocked requests does not contain request id then return error with error code no such request.
-
Let (request, phase, response) be blocked requests[request id].
-
If phase is "
beforeRequestSent
" and command is "continueResponse
", return error with error code "invalid argument
".TODO: Consider a different error
-
If response is null:
-
Assert: phase is "
beforeRequestSent
". -
Set response to a new response.
-
-
If command parameters contains "
statusCode
":-
Set responses’s status be command parameters["
statusCode
"].
-
-
If command parameters contains "
reasonPhrase
":-
Set responses’s status message be UTF-8 encode with command parameters["
reasonPhrase
"].
-
-
If command parameters contains "
headers
":-
Let headers be an empty header list.
-
For header in command parameters["
headers
"]:-
Let deserialized header be deserialize header with header.
-
If deserialized header’s name does not match the field-name token production, return error with error code "
invalid argument
". -
If deserialized header’s value does not match the header value production, return error with error code "
invalid argument
". -
Append deserialized header to headers.
-
-
Set response’s header list to headers.
-
-
If command parameters contains "
cookies
":-
If command parameters contains "
headers
", let headers be response’s header list.Otherwise:
-
Let headers be an empty header list.
-
For each header in response’s headers list:
-
Let name be header’s name.
-
If byte-lowercase name is not `
set-cookie
`:-
Append header to headers
-
-
-
-
For cookie in command parameters["
cookies
"]:-
Let header value be serialize set-cookie header with cookie.
-
Append (`
Set-Cookie
`, header value) to headers. -
Set response’s header list to headers.
-
-
-
If command parameters contains "
credentials
":This doesn’t have a way to cancel the auth.
-
Let credentials be command parameters["
credentials
"]. -
Assert: credentials["
type
"] is "password
". -
Set response’s authentication credentials to (credentials["
username
"], credentials["password
"])
-
-
Return response
7.4.3. Types
7.4.3.1. The network.AuthChallenge Type
network.AuthChallenge = { scheme: text, realm: text, }
To extract challenges given response:
Should we include parameters other than realm?
-
If response’s status is 401, let header name be `
WWW-Authenticate
`. Otherwise if response’s status is 407, let header name be `Proxy-Authenticate
`. Otherwise return null. -
Let challenges be a new list.
-
For each (name, value) in response’s header list:
as in Fetch it’s unclear if this is the right way to handle multiple headers, parsing issues, etc.
-
If name is a byte-case-insensitive match for header name:
-
Let header challenges be the result of parsing value into a list of challenges, each consisting of a scheme and a list of parameters, each of which is a tuple (name, value), according to the rules of [RFC9110].
-
For each header challenge in header challenges:
-
Let scheme be header challenge’s scheme.
-
Let realm be the empty string.
-
For each (param name, param value) in header challenge’s parameters:
-
If param name equals `
realm
` let realm be UTF-8 decode param value.
-
-
Let challenge be a new map matching the
network.AuthChallenge
production, with thescheme
field set to scheme and therealm
field set to realm.
-
-
Append challenge to challenges.
-
-
-
Return challenges.
7.4.3.2. The network.AuthCredentials Type
network.AuthCredentials = { type: "password", username: text, password: text, }
The network.AuthCredentials
type represents the response to a
request for authorization credentials.
7.4.3.3. The network.BaseParameters Type
network.BaseParameters = ( context: browsingContext.BrowsingContext / null, isBlocked: bool, navigation: browsingContext.Navigation / null, redirectCount: js-uint, request: network.RequestData, timestamp: js-uint, ? intercepts: [+network.Intercept] )
The network.BaseParameters
type is an abstract type representing
the data that’s common to all network events.
Consider including the `sharedId` of the document node that initiated the request in addition to the context.
-
Let request data be the result of get the request data with request.
-
Let navigation be request’s navigation id.
-
Let navigable id be null.
-
Let top-level navigable id be null.
-
If request’s window is an environment settings object:
-
Let environment settings be request’s window
-
If there is a navigable whose active window is environment settings’ global object, set navigable id to the navigable id for that navigable, and set top-level navigable id to be top-level traversable's navigable id for that context.
-
-
Let intercepts be the result of get the network intercepts with session, event, request, and top-level navigable id.
-
Let redirect count be request’s redirect count.
-
Let timestamp be a time value representing the current date and time in UTC.
-
If intercepts is not empty, let is blocked be true, otherwise let is blocked be false.
-
Let params be map matching the
network.BaseParameters
production, with therequest
field set to request data, the navigation field set tonavigation
, thecontext
field set to navigable id, thetimestamp
field set to timestamp, theredirectCount
field set to redirect count, theisBlocked
field set to is blocked, andintercepts
field set to intercepts if is blocked is true, or omitted otherwise. -
Return params
7.4.3.4. The network.BytesValue Type
network.BytesValue = network.StringValue / network.Base64Value; network.StringValue = { type: "string", value: text, } network.Base64Value = { type: "base64", value: text, }
The network.BytesValue
type represents binary data sent over the
network. Valid UTF-8 is represented with the network.StringValue
type, any other data is represented in Base64-encoded form as network.Base64Value
.
Note: this takes bytes encoded as a network.BytesValue
and returns
a byte sequence.
-
If protocol bytes matches the
network.StringValue
production, let bytes be UTF-8 encode protocol bytes["value
"]. -
Otherwise if protocol bytes matches the
network.Base64Value
production. Let bytes be forgiving-base64 decode protocol bytes["value
"]. -
Return bytes.
Note: this takes a byte sequence and returns a network.BytesValue
.
-
Let text be UTF-8 decode without BOM or fail bytes.
-
If text is failure, return a map matching the
network.Base64Value
production, with value set to forgiving-base64 encode bytes. -
Return a map matching the
network.StringValue
production, with value set to text.
7.4.3.5. The network.Cookie Type
Remote end definition and local end definition
network.SameSite = "strict" / "lax" / "none" network.Cookie = { name: text, value: network.BytesValue, domain: text, path: text, size: js-uint, httpOnly: bool, secure: bool, sameSite: network.SameSite, ? expiry: js-uint, Extensible, };
The network.Cookie
type represents a cookie.
Note: The definitions of stored cookie’s fields are from [COOKIES], except samesite-flag, which is from [SAME-SITE-COOKIES].
-
Let name be the result of UTF-8 decode with stored cookie’s name field.
-
Let value be serialize protocol bytes with stored cookie’s value.
-
Let domain be stored cookie’s domain field.
-
Let path be stored cookie’s path field.
-
Let expiry be stored cookie’s expiry-time field represented as a unix timestamp, if set, or null otherwise.
-
Let size be the byte length of the result of serializing stored cookie as it would be represented in a
Cookie
header. -
Let http only be true if stored cookie’s http-only-flag is true, or false otherwise.
-
Let secure be true if stored cookie’s secure-only-flag is true, or false otherwise.
-
Let same site be "
none
" if stored cookie’s samesite-flag is "None
", "lax
" if it is "Lax
", or "strict
" if it is "Strict
". -
Return a map matching the
network.Cookie
production, with thename
field set to name, thevalue
field set to value, thedomain
field set to domain, thepath
field set to path, theexpiry
field set to expiry if it’s not null, or omitted otherwise, thesize
field set to size, thehttpOnly
field set to http only, thesecure
field set to secure, and thesameSite
field set to same site.
7.4.3.6. The network.CookieHeader Type
network.CookieHeader = { name: text, value: network.BytesValue, };
The network.CookieHeader
type represents the subset of cookie data
that’s in a Cookie
request header.
-
Let name be UTF-8 encode protocol cookie["
name
"]. -
Let value be deserialize protocol bytes with protocol cookie["
value
"]. -
Let header value be the byte sequence formed by concatenating name, `
=
`, and value -
Return header value.
7.4.3.7. The network.FetchTimingInfo Type
Remote end definition and local end definition
network.FetchTimingInfo = { timeOrigin: float, requestTime: float, redirectStart: float, redirectEnd: float, fetchStart: float, dnsStart: float, dnsEnd: float, connectStart: float, connectEnd: float, tlsStart: float, requestStart: float, responseStart: float, responseEnd: float, };
The network.FetchTimingInfo
type represents the time of each part
of the request, relative to the time origin of the request's client.
-
Let global be request’s client.
-
If global is null, return a map matching the
network.FetchTimingInfo
production, with all fields set to 0. -
Let time origin be get time origin timestamp with global.
-
Let timings be request’s fetch timing info.
-
Let connection timing be timings’ final connection timing info if it’s not null, or a new connection timing info otherwise.
-
Let request time be convert fetch timestamp given timings’ start time and global.
-
Let redirect start be convert fetch timestamp given timings’ redirect start time and global.
-
Let redirect end be convert fetch timestamp given timings’ redirect end time and global.
-
Let fetch start be convert fetch timestamp given timings’ post-redirect start time and global.
-
Let DNS start be convert fetch timestamp given connection timing’s domain lookup start time and global.
-
Let DNS end be convert fetch timestamp given connection timing’s domain lookup end time and global.
-
Let TLS start be convert fetch timestamp given connection timing’s secure connection start time and global.
-
Let connect start be convert fetch timestamp given connection timing’s connection start time and global.
-
Let connect end be convert fetch timestamp given connection timing’s connection end time and global.
-
Let request start be convert fetch timestamp given timings’ final network-request start time and global.
-
Let response start be convert fetch timestamp given timings’ final network-response start time and global.
-
Let response end be convert fetch timestamp given timings’ end time and global.
-
Return a map matching the
network.FetchTimingInfo
production with thetimeOrigin
field set to time origin, therequestTime
field set to request time, theredirectStart
field set to redirect start, theredirectEnd
field set to redirect end, thefetchStart
field set to fetch start, thednsStart
field set to DNS start, thednsEnd
field set to DNS end, theconnectStart
field set to connect start, theconnectEnd
field set to connect end, thetlsStart
field set to TLS start, therequestStart
field set to request start, theresponseStart
field set to response start, and theresponseEnd
field set to response end.
TODO: Add service worker fields
7.4.3.8. The network.Header Type
Remote end definition and local end definition
network.Header = { name: text, value: network.BytesValue, }
The network.Header
type represents a single request header.
-
Let name be the result of UTF-8 decode with name bytes.
Assert: Since header names are constrained to be ASCII-only this cannot fail.
-
Let value be serialize protocol bytes with value bytes.
-
Return a map matching the
network.Header
production, with thename
field set to name, and thevalue
field set to value.
-
Let name be UTF-8 encode protocol header["
name
"]. -
Let value be deserialize protocol bytes with protocol header["
value
"]. -
Return a header (name, value).
7.4.3.9. The network.Initiator Type
Remote end definition and local end definition
network.Initiator = { type: "parser" / "script" / "preflight" / "other", ? columnNumber: js-uint, ? lineNumber: js-uint, ? stackTrace: script.StackTrace, ? request: network.Request };
The network.Initiator
type represents the source of a network
request.
-
Let request id be request’s request id.
-
Let type be "
other
". -
If request is a CORS-Preflight Request, set type to "
preflight
". -
TODO: Get the type. It’s not quite clear how this ought to work; the CDP data depends on whether the navigation was kicked off by the parser or by script (so e.g. inserting an image from script causes the initiator to be "
script
"), but that doesn’t correspond to anything in Fetch. -
If request’s initiator type is "
fetch
" or "xmlhttprequest
":-
Let stack trace be the current stack trace.
-
If stack trace has size of 1 or greater, let line number be value of the
lineNumber
field in stack trace[0], and let column number be the value of thecolumnNumber
field in stack trace[0]. Otherwise let line number and column number be 0.
Otherwise, let stack trace, column number, and line number all be null.
TODO: Chrome includes the current parser position as column number / line number for parser-inserted resources.
-
-
Return a map matching the
network.Initiator
production, with thetype
field set to type, thecolumnNumber
field set to column number if it’s not null, or omitted otherwise, thelineNumber
field set to line number if it’s not null, or omitted otherwise, thestackTrace
field set to stack trace if it’s not null, or omitted otherwise, and therequest
field set to request id.
7.4.3.10. The network.Intercept Type
Remote end definition and local end definition
network.Intercept = text
The network.Intercept
type represents the id of a network intercept.
7.4.3.11. The network.Request Type
Remote end definition and local end definition
network.Request = text;
Each network request has an associated request id, which is a string uniquely identifying that request. The identifier for a request resulting from a redirect matches that of the request that initiated it.
7.4.3.12. The network.RequestData Type
Remote end definition and local end definition
network.RequestData = { request: network.Request, url: text, method: text, headers: [*network.Header], cookies: [*network.Cookie], headersSize: js-uint, bodySize: js-uint / null, timings: network.FetchTimingInfo, };
The network.RequestData
type represents an ongoing network request.
To get the request data given request:
-
Let request id be request’s request id.
-
Let url be the result of running the URL serializer with request’s URL.
-
Let method be request’s method.
-
Let body size be null.
-
Let body be request’s body.
-
If body is a byte sequence, set body size to the length of that sequence. Otherwise, if body is a body then set body size to that body’s length.
-
Let headers size be the size in bytes of request’s headers list when serialized as mandated by [HTTP11].
Note: For protocols which allow header compression, this is the compressed size of the headers, as sent over the network.
-
Let headers be an empty list.
-
Let cookies be an empty list.
-
For each (name, value) in request’s headers list:
-
Append the result of serialize header with name and value to headers.
-
If name is a byte-case-insensitive match for "
Cookie
" then:-
For each cookie in the user agent’s cookie store that are included in request:
Note: [COOKIES] defines some baseline requirements for which cookies in the store can be included in a request, but user agents are free to impose additional constraints.
-
Append the result of serialize cookie given cookie to cookies.
-
-
-
-
Let timings be get the fetch timings with request.
-
Return a map matching the
network.RequestData
production, with therequest
field set to request id,url
field set to url, themethod
field set to method, theheaders
field set to headers, the cookies field set to cookies, and theheadersSize
field set to headers size, thebodySize
field set to body size, and thetimings
field set to timings.
7.4.3.13. The network.ResponseContent Type
Remote end definition and local end definition
network.ResponseContent = { size: js-uint };
The network.ResponseContent
type represents the decoded response to
a network request.
-
Return a new map matching the
network.ResponseContent
production, with thesize
field set to response’s response body info's decoded size
7.4.3.14. The network.ResponseData Type
Remote end definition and local end definition
network.ResponseData = { url: text, protocol: text, status: js-uint, statusText: text, fromCache: bool, headers: [*network.Header], mimeType: text, bytesReceived: js-uint, headersSize: js-uint / null, bodySize: js-uint / null, content: network.ResponseContent, ?authChallenges: [*network.AuthChallenge], };
The network.ResponseData
type represents the response to a network
request.
To get the protocol given response:
-
Let protocol be the empty string.
-
If response’s final connection timing info is not null, set protocol to response’s final connection timing info's ALPN negotiated protocol.
-
If protocol is the empty string, or is equal to "
unknown
":-
If protocol is equal to either "
http
" or "https
" and response has an associated HTTP Response.Note: [FETCH] isn’t clear about the relation between a HTTP network response and a response object.
-
Let http version be the HTTP Response’s Status line’s HTTP-version [HTTP11].
-
If http version starts with "
HTTP/
":-
Let version be the code unit substring of http version from 5 to http version’s length.
-
If version is "
0.9
", set protocol to "http/0.9
", otherwise if version is "1.0
", set protocol to "http/1.0
", otherwise if version is "1.1
", set protocol to "http/1.1
".
-
-
-
Return protocol.
-
Let url be the result of running the URL serializer with response’s URL.
-
Set protocol to get the protocol given response.
-
Let status be response’s status.
-
Let status text be response’s status message.
-
If response’s cache state is "
local
", let from cache be true, otherwise let it be false. -
Let headers be an empty list.
-
Let mime type be the essence of the computed mime type for response.
Note: this is whatever MIME type the browser is actually using, even if it isn’t following the exact algorithm in the [MIMESNIFF] specification.
-
For each (name, value) in response’s headers list:
-
Append the result of serialize header with name and value to headers.
-
-
Let bytes received be the total number of bytes transmitted as part of the HTTP response associated with response.
-
Let headers size be the number of bytes transmitted as part of the header fields section of the HTTP response.
-
Let body size be response’s response body info's encoded size.
-
Let content be the result of get the response content info with response.
-
Let auth challenges be the result of extract challenges with response.
-
Return a map matching the
network.ResponseData
production, with theurl
field set to url, theprotocol
field set to protocol, thestatus
field set to status, thestatusText
field set to status text, thefromCache
field set to from cache, theheaders
field set to headers, themimeType
field set to mime type, thebytesReceived
field set to bytes received, theheadersSize
field set to headers size, thebodySize
field set to body size,content
field set to content, and theauthChallenges
field set to auth challenges if it’s not null, or omitted otherwise.
7.4.3.15. The network.SetCookieHeader Type
network.SetCookieHeader = { name: text, value: network.BytesValue, ? domain: text, ? httpOnly: bool, ? expiry: text, ? maxAge: js-int, ? path: text, ? sameSite: network.SameSite, ? secure: bool, }
The network.SetCookieHeader
represents the data in a Set-Cookie
response header.
Note: This produces the shortest representation of input as a string of decimal digits.
-
Let serialized be an empty string.
-
Let value be input.
-
While value is greater than 0:
-
Let x be value divided by 10.
-
Let most significant digits be the integer part of x.
-
Let y be most significant digits multiplied by 10.
-
Let least significant digit be value - y.
-
Assert: least significant digit is an integer in the range 0 to 9, inclusive.
-
Let codepoint be the code point whose value is U+0030 DIGIT ZERO’s value + least significant digit.
-
Prepend codepoint to serialized.
-
Set value to most significant digits.
-
-
Return serialized.
-
Let name be UTF-8 encode protocol cookie["
name
"]. -
Let value be deserialize protocol bytes with protocol cookie["
value
"]. -
Let header value be the byte sequence formed by concatenating name, `
=
`, and value. -
If protocol cookie contains "
expiry
":-
Let attribute be `
;Expires=
` -
Append UTF-8 encode protocol cookie["
expiry
"] to attribute. -
Append attribute to header value.
-
-
If protocol cookie contains "
maxAge
":-
Let attribute be `
;Max-Age=
` -
Let max age string be serialize an integer protocol cookie["
maxAge
"]. -
Append UTF-8 encode max age string to attribute.
-
Append attribute to header value.
-
-
If protocol cookie contains "
domain
":-
Let attribute be `
;Domain=
` -
Append UTF-8 encode protocol cookie["
domain
"] to attribute. -
Append attribute to header value.
-
-
If protocol cookie contains "
path
":-
Let attribute be `
;Path=
` -
Append UTF-8 encode protocol cookie["
path
"] to attribute. -
Append attribute to header value.
-
-
If protocol cookie contains "
secure
" and protocol cookie["secure
"] is true:-
Append `
;Secure
` to header value.
-
-
If protocol cookie contains "
httpOnly
" and protocol cookie["httpOnly
"] is true:-
Append `
;HttpOnly
` to header value.
-
-
If protocol cookie contains "
sameSite
":-
Let attribute be `
;SameSite=
` -
Append UTF-8 encode protocol cookie["
sameSite
"] to attribute. -
Append attribute to header value.
-
-
Return header value.
7.4.3.16. The network.UrlPattern Type
network.UrlPattern = ( network.UrlPatternPattern / network.UrlPatternString ) network.UrlPatternPattern = { type: "pattern", ?protocol: text, ?hostname: text, ?port: text, ?pathname: text, ?search: text, } network.UrlPatternString = { type: "string", pattern: text, }
A network.UrlPattern
represents a pattern used for matching request
URLs for network intercepts.
When URLs are matched against a network.UrlPattern
the URL is
parsed, and each component is compared for equality with the corresponding field
in the pattern, if present. Missing fields from the pattern always match.
Note: This syntax is designed with future extensibility in mind. In particular the syntax forbids characters that are treated specially in the [URLPattern] specification. These can be escaped by prefixing them with a U+005C (\) character.
-
Let forbidden characters be the set of codepoints «U+0028 ((), U+0029 ()), U+002A (*), U+007B ({), U+007D (})»
-
Let result be the empty string.
-
Let is escaped character be false.
-
For each codepoint in pattern:
-
If is escaped character is false:
-
If forbidden characters contains codepoint, return error with error code invalid argument.
-
If codepoint is U+005C (\):
-
Set is escaped character to true.
-
Continue.
-
-
-
Append codepoint to result.
-
Set is escaped character to false.
-
-
Return success with data result.
-
Let has protocol be true.
-
Let has hostname be true.
-
Let has port be true.
-
Let has pathname be true.
-
Let has search be true.
-
If pattern matches the
network.UrlPatternPattern
production:-
Let pattern url be the empty string.
-
If pattern contains "
protocol
":-
If pattern["
protocol
"] is the empty string, return error with error code invalid argument. -
Let protocol be the result of trying to unescape URL Pattern with pattern["
protocol
"]. -
For each codepoint in protocol:
-
If codepoint is not ASCII alphanumeric and «U+002B (+), U+002D (-), U+002E (.)» does not contain codepoint:
-
Return error with error code invalid argument.
-
-
-
Append protocol to pattern url.
-
-
Otherwise:
-
Set has protocol to false.
-
Append "
http
" to pattern url.
-
-
Let scheme be ASCII lowercase with pattern url.
-
Append "
:
" to pattern url. -
If scheme is special, append "
//
" to pattern url. -
If pattern contains "
hostname
":-
If pattern["
hostname
"] is the empty string, return error with error code invalid argument. -
If scheme is "
file
" return error with error code invalid argument. -
Let hostname be the result of trying to unescape URL Pattern with pattern["
hostname
"]. -
Let inside brackets be false.
-
For each codepoint in hostname:
-
If «U+002F (/), U+003F (?), U+0023 (#)» contains codepoint:
-
Return error with error code invalid argument.
-
-
If inside brackets is false and codepoint is U+003A (:):
-
Return error with error code invalid argument.
-
-
If codepoint is U+005B ([), set inside brackets to true.
-
If codepoint is U+005D (]), set inside brackets to false.
-
-
Append hostname to pattern url.
-
-
Otherwise:
-
If scheme is not "
file
", append "placeholder
" to pattern url. -
Set has hostname to false.
-
-
If pattern contains "
port
":-
If pattern["
port
"] is the empty string, return error with error code invalid argument. -
Let port be the result of trying to unescape URL Pattern with pattern["
port
"]. -
Append "
:
" to pattern url. -
For each codepoint in port:
-
If codepoint is not an ASCII digit:
-
Return error with error code invalid argument.
-
-
-
Append port to pattern url.
-
-
Otherwise:
-
Set has port to false.
-
-
If pattern contains "
pathname
":-
Let pathname be the result of trying to unescape URL Pattern with pattern["
pathname
"]. -
If pathname does not start with U+002F (/), then append "
/
" to pattern url. -
For each codepoint in pathname:
-
If «U+003F (?), U+0023 (#)» contains codepoint:
-
Return error with error code invalid argument.
-
-
-
Append pathname to pattern url.
-
-
Otherwise:
-
Set has pathname to false.
-
-
If pattern contains "
search
":-
Let search be the result of trying to unescape URL pattern with pattern["
search
"]. -
If search does not start with U+003F (?), then append "
?
" to pattern url. -
For each codepoint in search:
-
If codepoint is U+0023 (#):
-
Return error with error code invalid argument.
-
-
-
Append search to pattern url.
-
-
Otherwise:
-
Set has search to false.
-
-
-
Otherwise, if pattern matches the
network.UrlPatternString
production:-
Let pattern url be the result of trying to unescape URL pattern with pattern["
pattern
"].
-
-
Let url be the result of parsing pattern url.
-
If url is failure, return error with error code invalid argument.
-
Let parsed be a struct with the following fields:
- protocol
- url’s scheme if has protocol is true, or null otherwise.
- hostname
- url’s host if has hostname is true, or null otherwise.
- port
-
-
If has port is false:
-
null.
-
-
Otherwise:
-
If url’s scheme is special and url’s scheme's default port is not null, and url’s port is null or is equal to scheme's default port:
-
The empty string.
-
-
Otherwise, if url’s port is not null:
-
Serialize an integer with url’s port.
-
-
Otherwise:
-
null.
-
-
-
- pathname
-
-
If has pathname is false:
-
null.
-
-
Otherwise:
-
The result of running the URL path serializer with url, if url’s path is not the empty string and is not empty, or null otherwise.
-
-
- search
-
Return success with data parsed.
-
Let url be the result of parsing url string.
-
If url pattern’s protocol is not null and is not equal to url’s scheme, return false.
-
If url pattern’s hostname is not null and is not equal to url’s host, return false.
-
If url pattern’s port is not null:
-
Let port be null.
-
If url’s scheme is special and url’s scheme's default port is not null, and url’s port is null or is equal to scheme's default port:
-
Set port to the empty string.
-
-
Otherwise, if url’s port, is not null:
-
Set port to serialize an integer with url’s port.
-
-
If url pattern’s port is not equal to port, return false.
-
-
If url pattern’s pathname is not null and is not equal to the result of running the URL path serializer with url, return false.
-
If url pattern’s search is not null:
-
Let url query be url’s query.
-
If url query is null, set url query to the empty string.
-
If url pattern’s search is not equal to url query, return false.
-
-
Return true.
7.4.4. Commands
7.4.4.1. The network.addIntercept Command
The network.addIntercept command adds a network intercept.
- Command Type
-
network.AddIntercept = ( method: "network.addIntercept", params: network.AddInterceptParameters ) network.AddInterceptParameters = { phases: [+network.InterceptPhase], ? contexts: [+browsingContext.BrowsingContext], ? urlPatterns: [*network.UrlPattern], } network.InterceptPhase = "beforeRequestSent" / "responseStarted" / "authRequired"
- Return Type
-
network.AddInterceptResult = { intercept: network.Intercept }
-
Let intercept be the string representation of a UUID.
-
Let url patterns be the
urlPatterns
field of command parameters if present, or an empty list otherwise. -
Let navigables be null.
-
If the
contexts
field of command parameters is present:-
Set navigables to an empty set.
-
For each navigable id of command parameters["
contexts
"]-
Let navigable be the result of trying to get a navigable with navigable id.
-
If navigable is not a top-level traversable, return error with error code invalid argument.
-
Append navigable to navigables.
-
-
If navigables is an empty set, return error with error code invalid argument.
-
-
Let intercept map be session’s intercept map.
-
Let parsed patterns be an empty list.
-
For each url pattern in url patterns:
-
Let parsed be the result of trying to parse url pattern with url pattern.
-
Append parsed to parsed patterns.
-
-
Set intercept map[intercept] to a struct with
url patterns
parsed patterns,phases
command parameters["phases
"] andbrowsingContexts
navigables. -
Return a new map matching the
network.AddInterceptResult
production with theintercept
field set to intercept.
7.4.4.2. The network.continueRequest Command
The network.continueRequest command continues a request that’s blocked by a network intercept.
- Command Type
-
network.ContinueRequest = ( method: "network.continueRequest", params: network.ContinueRequestParameters ) network.ContinueRequestParameters = { request: network.Request, ?body: network.BytesValue, ?cookies: [*network.CookieHeader], ?headers: [*network.Header], ?method: text, ?url: text, }
- Return Type
-
EmptyResult
-
Let blocked requests be session’s blocked request map.
-
Let request id be command parameters["
request
"]. -
If blocked requests does not contain request id then return error with error code no such request.
-
Let (request, phase, response) be blocked requests[request id].
-
If phase is not "
beforeRequestSent
", then return error with error code invalid argument. -
If command parameters contains "
url
":-
Let url record be the result of applying the URL parser to command parameters["
url
"], with base URL null. -
If url record is failure, return error with error code invalid argument.
TODO: Should we also resume here?
-
Let request’s url be url record.
-
-
If command parameters contains "
method
":-
Let method be command parameters["
method
"]. -
If method does not match the method token production, return error with error code "
invalid argument
". -
Let request’s method be method.
-
-
If command parameters contains "
headers
":-
Let headers be an empty header list.
-
For header in command parameters["
headers
"]:-
Let deserialized header be deserialize header with header.
-
If deserialized header’s name does not match the field-name token production, return error with error code "
invalid argument
". -
If deserialized header’s value does not match the header value production, return error with error code "
invalid argument
". -
Append deserialized header to headers.
-
-
Set request’s headers list to headers.
-
-
If command parameters contains "
cookies
":-
Let cookie header be an empty byte sequence.
-
For each cookie in command parameters["
cookies
"]:-
If cookie header is not empty, append `
;
` to cookie header. -
Append serialize cookie header with cookie to cookie header.
-
-
Let found cookie header be false.
-
For each header in request’s headers list:
-
Let name be header’s name.
-
If byte-lowercase name is `
cookie
`:-
Set header’s value to cookie header.
-
Set found cookie header to true.
-
Break.
-
-
-
If found cookie header is false:
-
Append the header (`
Cookie
`, cookie header) to request’s headers list.
-
-
-
If command parameters contains "
body
":-
Let body be deserialize protocol bytes with command parameters["
body
"]. -
Set request’s body to body.
-
-
Resume with "
continue request
", request id, and (null, "incomplete
"). -
Return success with data null.
7.4.4.3. The network.continueResponse Command
The network.continueResponse command continues a
response that’s blocked by a network intercept. It can be called in the responseStarted
phase, to modify the status and headers of the
response, but still provide the network response body.
- Command Type
-
network.ContinueResponse = ( method: "network.continueResponse", params: network.ContinueResponseParameters ) network.ContinueResponseParameters = { request: network.Request, ?cookies: [*network.SetCookieHeader] ?credentials: network.AuthCredentials, ?headers: [*network.Header], ?reasonPhrase: text, ?statusCode: js-uint, }
- Return Type
-
EmptyResult
-
Let request id be command parameters["
request
"]. -
Let response be the result of trying to update the response with session, "
continueResponse
" and command parameters. -
Resume with "
continue request
", request id, and (response, "incomplete
"). -
Return success with data null.
7.4.4.4. The network.continueWithAuth Command
The network.continueWithAuth command continues a
response that’s blocked by a network intercept at the authRequired
phase.
- Command Type
-
network.ContinueWithAuth = ( method: "network.continueWithAuth", params: network.ContinueWithAuthParameters ) network.ContinueWithAuthParameters = { request: network.Request, (network.ContinueWithAuthCredentials // network.ContinueWithAuthNoCredentials) } network.ContinueWithAuthCredentials = ( action: "provideCredentials", credentials: network.AuthCredentials ) network.ContinueWithAuthNoCredentials = ( action: "default" / "cancel" )
- Return Type
-
EmptyResult
-
Let blocked requests be session’s blocked request map.
-
Let request id be command parameters["
request
"]. -
If blocked requests does not contain request id then return error with error code no such request.
-
Let (request, phase, response) be blocked requests[request id].
-
If phase is not "
authRequired
", then return error with error code invalid argument. -
If command parameters "
action
" is "cancel
", set response’s authentication credentials to "cancelled
". -
If command parameters "
action
" is "provideCredentials
":-
Let credentials be command parameters["
credentials
"]. -
Assert: credentials["
type
"] is "password
". -
Set response’s authentication credentials to (credentials["
username
"], credentials["password
"])
-
-
Resume with "
continue request
", request id, and (response, "incomplete
"). -
Return success with data null.
7.4.4.5. The network.failRequest Command
The network.failRequest command fails a fetch that’s blocked by a network intercept.
- Command Type
-
network.FailRequest = ( method: "network.failRequest", params: network.FailRequestParameters ) network.FailRequestParameters = { request: network.Request, }
- Return Type
-
EmptyResult
-
Let blocked requests be session’s blocked request map.
-
Let request id be command parameters["
request
"]. -
If blocked requests does not contain request id then return error with error code no such request.
-
Let (request, phase, response) be blocked requests[request id].
-
If phase is "
authRequired
", then return error with error code invalid argument. -
Let response be a new network error.
Allow setting the precise kind of error [Issue #508]
-
Resume with "
continue request
", request id, and (response, "complete
"). -
Return success with data null.
7.4.4.6. The network.provideResponse Command
The network.provideResponse command continues a request that’s blocked by a network intercept, by providing a complete response.
Note: This will not prevent the request going through the normal request lifecycle, and therefore emitting other events as it progresses.
- Command Type
-
network.ProvideResponse = ( method: "network.provideResponse", params: network.ProvideResponseParameters ) network.ProvideResponseParameters = { request: network.Request, ?body: network.BytesValue, ?cookies: [*network.SetCookieHeader], ?headers: [*network.Header], ?reasonPhrase: text, ?statusCode: js-uint, }
- Return Type
-
EmptyResult
-
Let request id be command parameters["
request
"]. -
Let response be the result of trying to update the response with session, "
provideResponse
", and command parameters. -
If command parameters contains "
body
":-
Let body be deserialize protocol bytes with command parameters["
body
"].
-
-
Resume with "
continue request
", request id, and (response,"complete
"). -
Return success with data null.
7.4.4.7. The network.removeIntercept Command
The network.removeIntercept command removes a network intercept.
- Command Type
-
network.RemoveIntercept = ( method: "network.removeIntercept", params: network.RemoveInterceptParameters ) network.RemoveInterceptParameters = { intercept: network.Intercept }
- Return Type
-
EmptyResult
-
Let intercept be the value of the "
intercept
" field in command parameters. -
Let intercept map be session’s intercept map.
-
If intercept map does not contain intercept, return error with error code no such intercept.
-
Entfernen Sie intercept from intercept map.
Note: removal of an intercept does not affect requests that have been already blocked by this intercept. Only future requests or future phases of existing requests will be affected.
7.4.4.8. The network.setCacheBehavior Command
The network.setCacheBehavior command configures the network cache behavior for certain requests.
- Command Type
-
network.SetCacheBehavior = ( method: "network.setCacheBehavior", params: network.SetCacheBehaviorParameters ) network.SetCacheBehaviorParameters = { cacheBehavior: "default" / "bypass", ? contexts: [+browsingContext.BrowsingContext] }
- Return Type
-
EmptyResult
-
Let navigable be null.
-
If request’s window is an environment settings object:
-
Let environment settings be request’s window
-
If there is a navigable whose active window is environment settings’ global object, set navigable to the top-level browsing context for that browsing context.
-
-
If navigable is not null and navigable cache behavior map contains navigable, return navigable cache behavior map[navigable].
-
Return default cache behavior.
-
Let top-level navigable be navigable’s top-level traversable.
-
If navigable cache behavior map contains top-level navigable, return navigable cache behavior map[top-level navigable].
-
Return default cache behavior.
-
Let behavior be command parameters["
cacheBehavior
"]. -
If command parameters does not contain "
contexts
":-
Set the default cache behavior to behavior.
-
Switch on the value of behavior:
- "
bypass
" - Perform implementation-defined steps to disable any implementation-specific resource caches.
- "
default
" - Perform implementation-defined steps to enable any implementation-specific resource caches that are usually enabled in the current remote end configuration.
- "
-
Return success with data null.
-
-
Let navigables be an empty set.
-
For each navigable id of command parameters["
contexts
"]:-
Let context be the result of trying to get a navigable with navigable id.
-
If context is not a top-level browsing context, return error with error code invalid argument.
-
Append context to navigables.
-
-
For each navigable in navigables:
-
If navigable cache behavior map contains navigable, and navigable cache behavior map[navigable] is equal to behavior then continue.
-
Switch on the value of behavior:
- "
bypass
" - Perform implementation-defined steps to disable any implementation-specific resource caches for network requests originating from any browsing context for which navigable is the top-level browsing context.
- "
default
" - Perform implementation-defined steps to enable any implementation-specific resource caches that are usually enabled in the current remote end configuration for network requests originating from any browsing context for which navigable is the top-level browsing context.
- "
-
If behavior is equal to default cache behavior:
-
If navigable cache behavior map contains navigable, remove navigable cache behavior map[navigable].
-
-
Otherwise:
-
Set navigable cache behavior map[navigable] to behavior.
-
-
-
Return success with data null.
7.4.5. Events
7.4.5.1. The network.authRequired Event
- Event Type
-
network.AuthRequired = ( method: "network.authRequired", params: network.AuthRequiredParameters ) network.AuthRequiredParameters = { network.BaseParameters, response: network.ResponseData }
- Return Type
-
EmptyResult
This event is emitted when the user agent is going to prompt for authorization credentials.
-
Let redirect count be request’s redirect count.
-
Assert: before request sent map[request] is equal to redirect count.
Note: This implies that every caller needs to ensure that the WebDriver BiDi before request sent steps are invoked with request before these steps.
-
If request’s client is not null, let related navigables be the result of get related navigables with request’s client. Otherwise let related navigables be an empty set.
-
For each session in the set of sessions for which an event is enabled given "
network.authRequired
" and related navigables:-
Let params be the result of process a network event with session "
network.authRequired
", and request. -
Let response data be the result of get the response data with response.
-
Assert: response data contains "
authChallenge
". -
Set the
response
field of params to response data. -
Assert: params matches the
network.AuthRequiredParameters
production. -
Let body be a map matching the
network.AuthRequired
production, with theparams
field set to params. -
Emit an event with session and body.
-
If params["
isBlocked
"] is true:-
Let blocked requests be session’s blocked request map.
-
Let request id be request’s request id.
-
Set blocked requests[request id] to (request, "
authRequired
", response). -
Await with «"
continue request
"», and request id. -
Entfernen Sie blocked requests[request id].
-
-
7.4.5.2. The network.beforeRequestSent Event
- Event Type
-
network.BeforeRequestSent = ( method: "network.beforeRequestSent", params: network.BeforeRequestSentParameters ) network.BeforeRequestSentParameters = { network.BaseParameters, initiator: network.Initiator, }
This event is emitted before a request is sent (either over the network or before it’s handled by a serviceworker or a local cache).
-
If before request sent map does not contain request, set before request sent map[request] to a new set.
-
Let redirect count be request’s redirect count.
-
hinzufügen redirect count to before request sent map[request].
-
If request’s client is not null, let related navigables be the result of get related navigables with request’s client. Otherwise let related navigables be an empty set.
-
Let response be null.
-
Let response status be "
incomplete
". -
For each session in the set of sessions for which an event is enabled given "
network.beforeRequestSent
" and related navigables:-
Let params be the result of process a network event with session, "
network.beforeRequestSent
", and request. -
If params is null then continue.
-
Let initiator be the result of get the initiator with request.
-
Set the
initiator
field of params to initiator. -
Assert: params matches the
network.BeforeRequestSentParameters
production. -
Let body be a map matching the
network.BeforeRequestSent
production, with theparams
field set to params. -
Emit an event with session and body.
-
If params["
isBlocked
"] is true, then:-
Let blocked requests be session’s blocked request map.
-
Let request id be request’s request id.
-
Set blocked requests[request id] to (request, "
beforeRequestSent
", null). -
Let (response, status) be await with «"
continue request
"», and request’s request id. -
If status is "
complete
" set response status to status. -
Entfernen Sie blocked requests[request id].
Note: While waiting, no further processing of the request occurs.
-
-
-
Return (response, response status).
7.4.5.3. The network.fetchError Event
- Event Type
-
network.FetchError = ( method: "network.fetchError", params: network.FetchErrorParameters ) network.FetchErrorParameters = { network.BaseParameters, errorText: text, }
This event is emitted when a network request ends in an error.
-
If before request sent map[request] does not contain request’s redirect count, then run the WebDriver BiDi before request sent steps with request.
Note: This ensures that a
network.beforeRequestSent
can always be emitted before anetwork.fetchError
, without the caller needing to explicitly invoke the WebDriver BiDi before request sent steps on every error path. -
If request’s client is not null, let related navigables be the result of get related navigables with request’s client. Otherwise let related navigables be an empty set.
-
For each session in the set of sessions for which an event is enabled given "
network.fetchError
" and related navigables:-
Let params be the result of process a network event with session "
network.fetchError
", and request. -
TODO: Set the
errorText
field of params. -
Assert: params matches the
network.FetchErrorParameters
production. -
Let body be a map matching the
network.FetchError
production, with theparams
field set to params. -
Emit an event with session and body.
-
7.4.5.4. The network.responseCompleted Event
- Event Type
-
network.ResponseCompleted = ( method: "network.responseCompleted", params: network.ResponseCompletedParameters ) network.ResponseCompletedParameters = { network.BaseParameters, response: network.ResponseData, }
This event is emitted after the full response body is received.
-
Let redirect count be request’s redirect count.
-
Assert: before request sent map[request] contains redirect count.
Note: This implies that every caller needs to ensure that the WebDriver BiDi before request sent steps are invoked with request before these steps.
-
If request’s client is not null, let related navigables be the result of get related navigables with request’s client. Otherwise let related navigables be an empty set.
-
For each session in the set of sessions for which an event is enabled given "
network.responseCompleted
" and related navigables:-
Let params be the result of process a network event with session "
network.responseCompleted
", and request. -
Assert: params["
isBlocked
"] is false. -
Let response data be the result of get the response data with response.
-
Set the
response
field of params to response data. -
Assert: params matches the
network.ResponseCompletedParameters
production. -
Let body be a map matching the
network.ResponseCompleted
production, with theparams
field set to params. -
Emit an event with session and body.
-
7.4.5.5. The network.responseStarted Event
- Event Type
-
network.ResponseStarted = ( method: "network.responseStarted", params: network.ResponseStartedParameters ) network.ResponseStartedParameters = { network.BaseParameters, response: network.ResponseData, }
This event is emitted after the response headers are received but before the body is complete.
-
Let redirect count be request’s redirect count.
-
Assert: before request sent map[request] is equal to redirect count.
Note: This implies that every caller needs to ensure that the WebDriver BiDi before request sent steps are invoked with request before these steps.
-
If request’s client is not null, let related navigables be the result of get related navigables with request’s client. Otherwise let related navigables be an empty set.
-
Let response status be "
incomplete
". -
For each session in the set of sessions for which an event is enabled given "
network.responseStarted
" and related navigables:-
Let params be the result of process a network event with session "
network.responseStarted
", and request. -
Let response data be the result of get the response data with response.
-
Set the
response
field of params to response data. -
Assert: params matches the
network.ResponseStartedParameters
production. -
Let body be a map matching the
network.ResponseStarted
production, with theparams
field set to params. -
Emit an event with session and body.
-
If params["
isBlocked
"] is true:-
Let blocked requests be session’s blocked request map.
-
Let request id be request’s request id.
-
Set blocked requests[request id] to (request, "
beforeRequestSent
", response). -
Let (response, status) be await with «"
continue request
"», and request id. -
If status is "
complete
", set response status to status. -
Entfernen Sie blocked requests[request id].
-
-
-
Return (response, response status).
7.5. The script Module
The script module contains commands and events relating to script realms and execution.
7.5.1. Definition
ScriptCommand = ( script.AddPreloadScript // script.CallFunction // script.Disown // script.Evaluate // script.GetRealms // script.RemovePreloadScript )
ScriptResult = ( script.AddPreloadScriptResult / script.EvaluateResult / script.GetRealmsResult ) ScriptEvent = ( script.Message // script.RealmCreated // script.RealmDestroyed )
7.5.2. Preload Scripts
A Preload script is one which runs on creation of a new Window
,
before any author-defined script have run.
TODO: Extend this to scripts in other kinds of realms.
A BiDi session has a preload script map which is a map in
which the keys are UUIDs, and the values are structs with an item named function declaration
, which is a string, arguments
, contexts
, which is a list or null, and an item named sandbox
which is a string
or null.
Note: If executing a preload script fails, either due to a syntax error, or a runtime exception, an [ECMAScript] exception is reported in the realm in which it was being executed, and other preload scripts run as normal.
-
Let document be environment settings’ relevant global object's associated
Document
. -
Let navigable be document’s navigable.
-
For each session in active BiDi sessions:
-
For each preload script in session’s preload script map's values:
-
If preload script’s
contexts
is not null:-
Let navigable id be navigable’s top-level traversable's id.
-
If
contexts
does not contain navigable id, return.
-
-
If preload script’s
sandbox
is not null, let realm be get or create a sandbox realm with preload script’ssandbox
and navigable. Otherwise let realm be environment settings’ realm execution context's Realm component. -
Let exception reporting global be be environment settings’ realm execution context's Realm component’s global object.
-
Let arguments be preload script’s
arguments
. -
Let deserialized arguments be an empty list.
-
For each argument in arguments:
-
Let channel be create a channel with session, realm and argument.
-
Append channel to deserialized arguments.
-
-
Let base URL be the API base URL of environment settings.
-
Let options be the default classic script fetch options.
-
Let function declaration be preload script’s
function declaration
. -
Let (script, function body evaluation status) be the result of evaluate function body with function declaration, environment settings, base URL, and options.
-
If function body evaluation status is an abrupt completion, then report an exception given by function body evaluation status.[[Value]] for exception reporting global.
-
Let function object be function body evaluation status.[[Value]].
-
If IsCallable(function object) is
false
:-
Let error be a new TypeError object in realm.
-
Report an exception error for exception reporting global.
-
-
Prepare to run script with environment settings.
-
Set evaluation status to Call(function object, null, deserialized arguments).
-
Clean up after running script with environment settings.
-
If evaluation status is an abrupt completion, then report an exception given by evaluation status.[[Value]] for exception reporting global.
-
-
7.5.3. Types
7.5.3.1. The script.Channel Type
Remote end definition and local end definition
script.Channel = text;
The script.Channel
type represents the id of a specific channel
used to send custom messages from the remote end to the local end.
7.5.3.2. The script.ChannelValue Type
script.ChannelValue = { type: "channel", value: script.ChannelProperties, }; script.ChannelProperties = { channel: script.Channel, ? serializationOptions: script.SerializationOptions, ? ownership: script.ResultOwnership, }
The script.ChannelValue
type represents an ArgumentValue
that can be deserialized into a function that sends
messages from the remote end to the local end.
To create a channel given session, realm and protocol value:
-
Let channel properties be protocol value["
value
"]. -
Let steps be the following steps given the argument message:
-
Let current realm be the current Realm Record.
-
Emit a script message with session, current realm, channel properties and message.
-
-
Return CreateBuiltinFunction(steps, 1, "", « », realm).
7.5.3.3. The script.EvaluateResult Type
Remote end definition and local end definition
script.EvaluateResult = ( script.EvaluateResultSuccess / script.EvaluateResultException ) script.EvaluateResultSuccess = { type: "success", result: script.RemoteValue, realm: script.Realm } script.EvaluateResultException = { type: "exception", exceptionDetails: script.ExceptionDetails realm: script.Realm }
The script.EvaluateResult
type indicates the return value of a command
that executes script. The script.EvaluateResultSuccess
variant is used in
cases where the script completes normally and the script.EvaluateResultException
variant is used in cases where the script
completes with a thrown exception.
7.5.3.4. The script.ExceptionDetails Type
Remote end definition and local end definition
script.ExceptionDetails = { columnNumber: js-uint, exception: script.RemoteValue, lineNumber: js-uint, stackTrace: script.StackTrace, text: text, };
The script.ExceptionDetails
type represents a JavaScript exception.
To get exception details given a realm, a completion record record, an ownership type and a session:
-
Assert: record.[[Type]] is
throw
. -
Let text be an implementation-defined textual description of the error represented by record.
TODO: Tighten up the requirements here; people will probably try to parse this data with regex or something equally bad.
-
Let serialization options be a map matching the
script.SerializationOptions
production with the fields set to their default values. -
Let exception be the result of serialize as a remote value with record.[[Value]], serialization options, ownership type, a new map as serialization internal map, realm and session.
-
Let stack trace be the stack trace for an exception given record.
-
If stack trace has size of 1 or greater, let line number be value of the
lineNumber
field in stack trace[0], and let column number be the value of thecolumnNumber
field stack trace[0]. Otherwise let line number and column number be 0. -
Let exception details be a map matching the
script.ExceptionDetails
production, with thetext
field set to text, theexception
field set to exception, thelineNumber
field set to line number, thecolumnNumber
field set to column number, and thestackTrace
field set to stack trace. -
Return exception details.
7.5.3.5. The script.Handle Type
Remote end definition and local end definition
script.Handle = text;
The script.Handle
type represents a handle to an object owned by
the ECMAScript runtime. The handle is only valid in a specific Realm.
Each ECMAScript Realm has a corresponding handle object map. This is a strong map from handle ids to their corresponding objects.
7.5.3.6. The script.InternalId Type
Remote end definition and local end definition
script.InternalId = text;
The script.InternalId
type represents the id of
a previously serialized script.RemoteValue
during serialization.
7.5.3.7. The script.LocalValue Type
script.LocalValue = ( script.RemoteReference / script.PrimitiveProtocolValue / script.ChannelValue / script.ArrayLocalValue / script.DateLocalValue / script.MapLocalValue / script.ObjectLocalValue / script.RegExpLocalValue / script.SetLocalValue ) script.ListLocalValue = [*script.LocalValue]; script.ArrayLocalValue = { type: "array", value: script.ListLocalValue, } script.DateLocalValue = { type: "date", value: text } script.MappingLocalValue = [*[(script.LocalValue / text), script.LocalValue]]; script.MapLocalValue = { type: "map", value: script.MappingLocalValue, } script.ObjectLocalValue = { type: "object", value: script.MappingLocalValue, } script.RegExpValue = { pattern: text, ? flags: text, } script.RegExpLocalValue = { type: "regexp", value: script.RegExpValue, } script.SetLocalValue = { type: "set", value: script.ListLocalValue, }
The script.LocalValue
type represents values which can be
deserialized into ECMAScript. This includes both primitive and non-primitive
values as well as remote references and channels.
To deserialize key-value list given serialized key-value list, realm and session:
-
Let deserialized key-value list be a new list.
-
For each serialized key-value in the serialized key-value list:
-
If size of serialized key-value is not 2, return error with error code invalid argument.
-
Let serialized key be serialized key-value[0].
-
If serialized key is a
string
, let deserialized key be serialized key. -
Otherwise let deserialized key be result of trying to given deserialize local value with serialized key, realm and session.
-
Let serialized value be serialized key-value[1].
-
Let deserialized value be result of trying to deserialize local value given serialized value, realm and session.
-
Append CreateArrayFromList(«deserialized key, deserialized value») to deserialized key-value list.
-
-
Return success with data deserialized key-value list.
To deserialize value list given serialized value list, realm and session:
-
Let deserialized values be a new list.
-
For each serialized value in the serialized value list:
-
Let deserialized value be result of trying to deserialize local value given serialized value, realm and session.
-
Append deserialized value to deserialized values;
-
-
Return success with data deserialized values.
To deserialize local value given local protocol value, realm and session:
-
If local protocol value matches the script.RemoteReference production, return deserialize remote reference of given local protocol value, realm and session.
-
If local protocol value matches the script.PrimitiveProtocolValue production, return deserialize primitive protocol value with local protocol value.
-
If local protocol value matches the
script.ChannelValue
production, return create a channel with session, realm and local protocol value. -
Let type be the value of the
type
field of local protocol value or undefined if no such a field. -
Let value be the value of the
value
field of local protocol value or undefined if no such a field. -
In the following list of conditions and associated steps, run the first set of steps for which the associated condition is true:
- type is the string "
array
" -
-
Let deserialized value list be a result of trying to deserialize value list given value, realm and session.
-
Return success with data CreateArrayFromList(deserialized value list).
-
- type is the string "
date
" -
-
If value does not match Date Time String Format, return error with error code invalid argument.
-
Assert: date result is not an abrupt completion.
-
Return success with data date result.
-
- type is the string "
map
" -
-
Let deserialized key-value list be a result of trying to deserialize key-value list with value, realm and session.
-
Let iterable be CreateArrayFromList(deserialized key-value list)
-
- type is the string "
object
" -
-
Let deserialized key-value list be a result of trying to deserialize key-value list with value, realm and session.
-
Let iterable be CreateArrayFromList(deserialized key-value list)
-
Return success with data Object.fromEntries(iterable).
-
- type is the string "
regexp
" -
-
Let pattern be the value of the
pattern
field of local protocol value. -
Let flags be the value of the
flags
field of local protocol value or undefined if no such a field. -
Let regex_result be Regexp(pattern, flags). If this throws exception, return error with error code invalid argument.
-
Return success with data regex_result.
-
- type is the string "
set
" -
-
Let deserialized value list be a result of trying to deserialize value list given value, realm and session.
-
Let iterable be CreateArrayFromList(deserialized key-value list)
-
Return success with data Set object(iterable).
-
- otherwise
- Return error with error code invalid argument.
- type is the string "
7.5.3.8. The script.PreloadScript Type
Remote end definition and local end definition
script.PreloadScript = text;
The script.PreloadScript
type represents a handle to a script that will run
on realm creation.
7.5.3.9. The script.Realm Type
Remote end definition and local end definition
script.Realm = text;
Each realm has an associated realm id, which is a string uniquely identifying that realm. This is implicitly set when the realm is created.
The realm id for a realm is opaque and must not be derivable from the handle id of the corresponding global object in the handle object map or, where relevant, from the navigable id of any navigable.
Note: this is to ensure that users do not rely on implementation-specific relationships between different ids.
-
If realm id is null, return success with data null.
-
If there is no realm with id realm id return error with error code no such frame
-
Return success with data realm
7.5.3.10. The script.PrimitiveProtocolValue Type
Remote end definition and local end definition
script.PrimitiveProtocolValue = ( script.UndefinedValue / script.NullValue / script.StringValue / script.NumberValue / script.BooleanValue / script.BigIntValue ) script.UndefinedValue = { type: "undefined", } script.NullValue = { type: "null", } script.StringValue = { type: "string", value: text, } script.SpecialNumber = "NaN" / "-0" / "Infinity" / "-Infinity"; script.NumberValue = { type: "number", value: number / script.SpecialNumber, } script.BooleanValue = { type: "boolean", value: bool, } script.BigIntValue = { type: "bigint", value: text, }
The script.PrimitiveProtocolValue represents values which can only be represented by value, never by reference.
To serialize primitive protocol value given a value:
-
Let remote value be undefined.
-
In the following list of conditions and associated steps, run the first set of steps for which the associated condition is true, if any:
- Typ(value) is undefined
- Let remote value be a map matching the
script.UndefinedValue
production in the local end definition. - Typ(value) is Null
- Let remote value be a map matching the
script.NullValue
production in the local end definition. - Typ(value) is String
-
Let remote value be a map matching the
script.StringValue
production in the local end definition, with thevalue
property set to value. - Typ(value) is Number
-
-
Switch on the value of value:
- NaN
- Let serialized be
"NaN"
- -0
- Let serialized be
"-0"
- Infinity
- Let serialized be
"Infinity"
- -Infinity
- Let serialized be
"-Infinity"
- Otherwise:
- Let serialized be value
-
Let remote value be a map matching the
script.NumberValue
production in the local end definition, with thevalue
property set to serialized.
-
- Typ(value) is Boolean
- Let remote value be a map matching the
script.BooleanValue
production in the local end definition, with thevalue
property set to value. - Typ(value) is BigInt
- Let remote value be a map matching the
script.BigIntValue
production in the local end definition, with thevalue
property set to the result of running the ToString operation on value.
-
Return remote value
To deserialize primitive protocol value given a primitive protocol value:
-
Let type be the value of the
type
field of primitive protocol value. -
Let value be undefined.
-
If primitive protocol value has field
value
:-
Let value be the value of the
value
field of primitive protocol value.
-
-
In the following list of conditions and associated steps, run the first set of steps for which the associated condition is true:
- type is the string "
undefined
" - Return success with data undefined.
- type is the string "
null
" - Return success with data null.
- type is the string "
string
" - Return success with data value.
- type is the string "
number
" -
-
Assert: Typ(value) is String.
-
If value is the string "
NaN
", return success with data NaN. -
Let number_result be StringToNumber(value).
-
If number_result is NaN, return error with error code invalid argument
-
Return success with data number_result.
- type is the string "
boolean
" - Return success with data value.
- type is the string "
bigint
" -
-
Let bigint_result be StringToBigInt(value).
-
If bigint_result is undefined, return error with error code invalid argument
-
Return success with data bigint_result.
-
- type is the string "
-
Return error with error code invalid argument
7.5.3.11. The script.RealmInfo Type
script.RealmInfo = ( script.WindowRealmInfo / script.DedicatedWorkerRealmInfo / script.SharedWorkerRealmInfo / script.ServiceWorkerRealmInfo / script.WorkerRealmInfo / script.PaintWorkletRealmInfo / script.AudioWorkletRealmInfo / script.WorkletRealmInfo ) script.BaseRealmInfo = ( realm: script.Realm, origin: text ) script.WindowRealmInfo = { script.BaseRealmInfo, type: "window", context: browsingContext.BrowsingContext, ? sandbox: text } script.DedicatedWorkerRealmInfo = { script.BaseRealmInfo, type: "dedicated-worker", owners: [script.Realm] } script.SharedWorkerRealmInfo = { script.BaseRealmInfo, type: "shared-worker" } script.ServiceWorkerRealmInfo = { script.BaseRealmInfo, type: "service-worker" } script.WorkerRealmInfo = { script.BaseRealmInfo, type: "worker" } script.PaintWorkletRealmInfo = { script.BaseRealmInfo, type: "paint-worklet" } script.AudioWorkletRealmInfo = { script.BaseRealmInfo, type: "audio-worklet" } script.WorkletRealmInfo = { script.BaseRealmInfo, type: "worklet" }
Note: there’s a 1:1 relationship between the script.RealmInfo
variants and values of script.RealmType
.
The script.RealmInfo
type represents the properties of a realm.
-
Let global object be the global object of the realm.
-
Let global object be the unwrapped global object.
-
If global object is not a
Window
object, returnnull
. -
Let document be global object’s wrapped
Window
's associatedDocument
. -
Return document’s node navigable.
-
Assert: global object is a
WorkerGlobalScope
object. -
Let owners be an empty list.
-
For each owner in the global object’s associated owner set:
-
Let owner environment settings be owner’s relevant settings object.
-
Let owner realm info be the result of get the realm info given owner environment settings.
-
If owner realm info is null, continue.
-
Append owner realm info["
id
"] to owners.
-
-
Return owners.
-
Let realm be environment settings’ realm execution context's Realm component.
-
Let realm id be the realm id for realm.
-
Let origin be the serialization of an origin given environment settings’s origin.
-
Let global object be the global object specified by environment settings
-
Run the steps under the first matching condition:
- global object is a
Window
object -
-
Let document be environment settings’ relevant global object's associated
Document
. -
Let navigable be document’s node navigable.
-
If navigable is null, return null.
-
Let navigable id be the navigable id for navigable.
-
Let realm info be a map matching the
script.WindowRealmInfo
production, with therealm
field set to realm id, theorigin
field set to origin, and thecontext
field set to navigable id.
-
- global object is
SandboxWindowProxy
object -
TODO: Unclear if this is the right formulation for handling sandboxes.
-
Let document be global object’s wrapped
Window
's associatedDocument
. -
Let navigable be document’s node navigable.
-
If navigable is null, return null.
-
Let navigable id be the navigable id for navigable.
-
Let sandbox name be the result of get a sandbox name given realm.
-
Assert: sandbox name is not null.
-
Let realm info be a map matching the
script.WindowRealmInfo
production, with therealm
field set to realm id, theorigin
field set to origin, thecontext
field set to navigable id, and thesandbox
field set to sandbox name.
-
- global object is a
DedicatedWorkerGlobalScope
object -
-
Let owners be the result of get the worker’s owners given global object.
-
Assert: owners has precisely one item.
-
Let realm info be a map matching the
script.DedicatedWorkerRealmInfo
production, with therealm
field set to realm id, theorigin
field set to origin, and theowners
field set to owners.
-
- global object is a
SharedWorkerGlobalScope
object -
-
Let realm info be a map matching the
script.SharedWorkerRealmInfo
production, with therealm
field set to realm id, and theorigin
field set to origin.
-
- global object is a
ServiceWorkerGlobalScope
object -
-
Let realm info be a map matching the
script.ServiceWorkerRealmInfo
production, with therealm
field set to realm id, and theorigin
field set to origin.
-
- global object is a
WorkerGlobalScope
object -
-
Let realm info be a map matching the
script.WorkerRealmInfo
production, with therealm
field set to realm id, and theorigin
field set to origin.
-
- global object is a
PaintWorkletGlobalScope
object -
-
Let realm info be a map matching the
script.PaintWorkletRealmInfo
production, with therealm
field set to realm id, and theorigin
field set to origin.
-
- global object is a
AudioWorkletGlobalScope
object -
-
Let realm info be a map matching the
script.AudioWorkletRealmInfo
production, with therealm
field set to realm id, and theorigin
field set to origin.
-
- global object is a
WorkletGlobalScope
object -
-
Let realm info be a map matching the
script.WorkletRealmInfo
production, with therealm
field set to realm id, and theorigin
field set to origin.
-
- Otherwise:
-
-
Let realm info be null.
-
- global object is a
-
Return realm info
Note: Future variations of this specification will retain the invariant that
the last component of the type name after splitting on "-
"
will always be "worker
" for globals implementing WorkerGlobalScope
, and "worklet
" for globals
implementing WorkletGlobalScope
.
7.5.3.12. The script.RealmType Type
Remote end definition and local end definition
script.RealmType = "window" / "dedicated-worker" / "shared-worker" / "service-worker" / "worker" / "paint-worklet" / "audio-worklet" / "worklet"
The script.RealmType
type represents the different types of Realm.
7.5.3.13. The script.RemoteReference Type
script.RemoteReference = ( script.SharedReference / script.RemoteObjectReference ) script.SharedReference = { sharedId: script.SharedId ? handle: script.Handle, Extensible } script.RemoteObjectReference = { handle: script.Handle, ? sharedId: script.SharedId Extensible }
The script.RemoteReference
type is either a script.RemoteObjectReference
representing a remote reference to an
existing ECMAScript object in handle object map in the given Realm, or
is a script.SharedReference
representing a reference to a node.
handle "stale object reference" case.
Note: if the provided reference has both handle
and sharedId
, the algorithm will ignore handle
and respect
only sharedId
.
-
Assert remote reference matches the
script.RemoteReference
production. -
If remote reference matches the
script.SharedReference
production, return deserialize shared reference with remote reference, realm and session. -
Return deserialize remote object reference with remote reference and realm.
-
Let handle id be the value of the
handle
field of remote object reference. -
Let handle map be realm’s handle object map
-
If handle map does not contain handle id, then return error with error code no such handle.
-
Return success with data handle map[handle id].
-
Assert shared reference matches the
script.SharedReference
production. -
Let navigable be get the navigable with realm.
-
If navigable is
null
, return error with error code no such node.Note: This happens when the realm isn’t a Window global.
-
Let shared id be the value of the
sharedId
field of shared reference. -
Let node be result of trying to get a node with session, navigable and shared id.
-
If node is
null
, return error with error code no such node. -
Let environment settings be the environment settings object whose realm execution context's Realm component is realm.
-
If node’s node document's origin is not same origin domain with environment settings’s origin then return error with error code no such node.
Note: This ensures that WebDriver-BiDi can not be used to pass objects between realms that do not otherwise permit script access.
-
Let realm global object be the global object of the realm.
-
If the realm global object is
SandboxWindowProxy
object, set node to theSandboxProxy
wrapping node in the realm. -
Return success with data node.
7.5.3.14. The script.RemoteValue Type
Remote end definition and local end definition
script.RemoteValue = ( script.PrimitiveProtocolValue / script.SymbolRemoteValue / script.ArrayRemoteValue / script.ObjectRemoteValue / script.FunctionRemoteValue / script.RegExpRemoteValue / script.DateRemoteValue / script.MapRemoteValue / script.SetRemoteValue / script.WeakMapRemoteValue / script.WeakSetRemoteValue / script.GeneratorRemoteValue / script.ErrorRemoteValue / script.ProxyRemoteValue / script.PromiseRemoteValue / script.TypedArrayRemoteValue / script.ArrayBufferRemoteValue / script.NodeListRemoteValue / script.HTMLCollectionRemoteValue / script.NodeRemoteValue / script.WindowProxyRemoteValue ) script.ListRemoteValue = [*script.RemoteValue]; script.MappingRemoteValue = [*[(script.RemoteValue / text), script.RemoteValue]]; script.SymbolRemoteValue = { type: "symbol", ? handle: script.Handle, ? internalId: script.InternalId, } script.ArrayRemoteValue = { type: "array", ? handle: script.Handle, ? internalId: script.InternalId, ? value: script.ListRemoteValue, } script.ObjectRemoteValue = { type: "object", ? handle: script.Handle, ? internalId: script.InternalId, ? value: script.MappingRemoteValue, } script.FunctionRemoteValue = { type: "function", ? handle: script.Handle, ? internalId: script.InternalId, } script.RegExpRemoteValue = { ? handle: script.Handle, ? internalId: script.InternalId, } .and script.RegExpLocalValue script.DateRemoteValue = { ? handle: script.Handle, ? internalId: script.InternalId, } .and script.DateLocalValue script.MapRemoteValue = { type: "map", ? handle: script.Handle, ? internalId: script.InternalId, ? value: script.MappingRemoteValue, } script.SetRemoteValue = { type: "set", ? handle: script.Handle, ? internalId: script.InternalId, ? value: script.ListRemoteValue } script.WeakMapRemoteValue = { type: "weakmap", ? handle: script.Handle, ? internalId: script.InternalId, } script.WeakSetRemoteValue = { type: "weakset", ? handle: script.Handle, ? internalId: script.InternalId, } script.GeneratorRemoteValue = { type: "generator", ? handle: script.Handle, ? internalId: script.InternalId, } script.ErrorRemoteValue = { type: "error", ? handle: script.Handle, ? internalId: script.InternalId, } script.ProxyRemoteValue = { type: "proxy", ? handle: script.Handle, ? internalId: script.InternalId, } script.PromiseRemoteValue = { type: "promise", ? handle: script.Handle, ? internalId: script.InternalId, } script.TypedArrayRemoteValue = { type: "typedarray", ? handle: script.Handle, ? internalId: script.InternalId, } script.ArrayBufferRemoteValue = { type: "arraybuffer", ? handle: script.Handle, ? internalId: script.InternalId, } script.NodeListRemoteValue = { type: "nodelist", ? handle: script.Handle, ? internalId: script.InternalId, ? value: script.ListRemoteValue, } script.HTMLCollectionRemoteValue = { type: "htmlcollection", ? handle: script.Handle, ? internalId: script.InternalId, ? value: script.ListRemoteValue, } script.NodeRemoteValue = { type: "node", ? sharedId: script.SharedId, ? handle: script.Handle, ? internalId: script.InternalId, ? value: script.NodeProperties, } script.NodeProperties = { nodeType: js-uint, childNodeCount: js-uint, ? attributes: {*text => text}, ? children: [*script.NodeRemoteValue], ? localName: text, ? mode: "open" / "closed", ? namespaceURI: text, ? nodeValue: text, ? shadowRoot: script.NodeRemoteValue / null, } script.WindowProxyRemoteValue = { type: "window", value: script.WindowProxyProperties, ? handle: script.Handle, ? internalId: script.InternalId } script.WindowProxyProperties = { context: browsingContext.BrowsingContext }
Should WindowProxy get attributes in a similar style to Node?
handle String / Number / etc. wrapper objects specially?
Values accessible from the ECMAScript runtime are represented by a mirror
object, specified as script.RemoteValue
. The value’s type is
specified in the type
property. In the case of JSON-representable
primitive values, this contains the value in the value
property; in
the case of non-JSON-representable primitives, the value
property
contains a string representation of the value.
For non-primitive objects, the handle
property, when present,
contains a unique string handle to the object. The handle is unique for each
serialization. The remote end will keep objects with a corresponding handle
alive until such a time that script.disown
is called with that
handle, or the realm itself is to be discarded (e.g. due to navigation).
For some non-primitive types, the value
property contains a
representation of the data in the ECMAScript object; for container types this
can contain further script.RemoteValue
instances. The value
property can be null or omitted if there is a duplicate
object i.e. the object has already been serialized in the current script.RemoteValue
, perhaps as part of a cycle, or otherwise when
the maximum serialization depth is reached.
In case of duplicated objects in the same script.RemoteValue
, the
value is provided only for one of the remote values, while the
unique-per-ECMAScript-object internalId
is provided for all the
duplicated objects for a given serialization.
Nodes are also represented by script.RemoteValue
instances. These have a partial serialization of the node in the value property.
reconsider mirror objects' lifecycle.
Note: mirror objects do not keep the original object alive in the runtime. If an object is discarded in the runtime, subsequent attempts to access it via the protocol will result in an error.
-
If ownership type is equal "
none
", returnnull
. -
Let handle id be a new, unique, string handle for object.
-
Let handle map be realm’s handle object map
-
Set handle map[handle id] to object.
-
Return handle id as a result.
-
Let node be unwrapped node.
-
If node does not implement
Node
, return null. -
Let navigable be node’s node navigable.
-
If navigable is null, return null.
-
Return get or create a node reference with session, navigable and node.
-
If the serialization internal map does not contain object, set serialization internal map[object] to remote value.
-
Otherwise, run the following steps:
-
Let previously serialized remote value be serialization internal map[object].
-
If previously serialized remote value does not have a field
internalId
, run the following steps:-
Let internal id be the string representation of a UUID based on truly random, or pseudo-random numbers.
-
Set the
internalId
field of previously serialized remote value to internal id.
-
-
Set the
internalId
field of remote value to a fieldinternalId
in previously serialized remote value.
-
To serialize as a remote value given value, serialization options, an ownership type, a serialization internal map, a realm and a session:
-
Let remote value be a result of serialize primitive protocol value given a value.
-
If remote value is not undefined, return remote value.
-
In the following list of conditions and associated steps, run the first set of steps for which the associated condition is true:
-
Let handle id be the handle for an object with realm, ownership type and value.
-
Set ownership type to "
none
". -
Let known object be
true
, if value is in the serialization internal map, otherwisefalse
.- Typ(value) is Symbol
- Let remote value be a map matching the
script.SymbolRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - IsArray(value)
- Let remote value be serialize an Array-like with session,
script.ArrayRemoteValue
, handle id, known object, value, serialization options, ownership type, serialization internal map, realm, and session. - IsRegExp(value)
-
-
Let serialized be a map matching the
script.RegExpValue
production in the local end definition, with thepattern
property set to the pattern and the theflags
property set to the flags. -
Let remote value be a map matching the
script.RegExpRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise, and thevalue
property set to serialized.
- value has a [[DateValue]] internal slot.
-
-
Set serialized to Call(Date.prototype.toISOString, value).
-
Assert: serialized is not a throw completion.
-
Let remote value be a map matching the
script.DateRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise, and the value set to serialized.
-
- value has a [[MapData]] internal slot
-
-
Let remote value be a map matching the
script.MapRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. -
Set internal ids if needed with serialization internal map, remote value and value.
-
Let serialized be null.
-
If known object is
false
, and serialization options["maxObjectDepth
"] is not 0, run the following steps:-
Let serialized be the result of serialize as a mapping with CreateMapIterator(value, key+value), serialization options, ownership type, serialization internal map, realm, and session.
-
-
If serialized is not null, set field
value
of remote value to serialized.
-
- value has a [[SetData]] internal slot
-
-
Let remote value be a map matching the
script.SetRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. -
Set internal ids if needed with serialization internal map, remote value and value.
-
Let serialized be null.
-
If known object is
false
, and serialization options["maxObjectDepth
"] is not 0, run the following steps:-
Let serialized be the result of serialize as a list with CreateSetIterator(value, value), serialization options, ownership type, serialization internal map, realm, and session.
-
-
If serialized is not null, set field
value
of remote value to serialized.
-
- value has a [[WeakMapData]] internal slot
- Let remote value be a map matching the
script.WeakMapRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - value has a [[WeakSetData]] internal slot
- Let remote value be a map matching the
script.WeakSetRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - value has a [[GeneratorState]] internal slot or [[AsyncGeneratorState]] internal slot
- Let remote value be a map matching the
script.GeneratorRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - value has an [[ErrorData]] internal slot
- Let remote value be a map matching the
script.ErrorRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - value has a [[ProxyHandler]] internal slot and a [[ProxyTarget]] internal slot
- Let remote value be a map matching the
script.ProxyRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - IsPromise(value)
- Let remote value be a map matching the
script.PromiseRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - value has a [[TypedArrayName]] internal slot
- Let remote value be a map matching the
script.TypedArrayRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - value has an [[ArrayBufferData]] internal slot
- Let remote value be a map matching the
script.ArrayBufferRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - value is a platform object that implements
NodeList
- Let remote value be serialize an Array-like with
script.NodeListRemoteValue
,handle id, known object, value, serialization options, ownership type, serialization internal map, realm, and session. - value is a platform object that implements
HTMLCollection
- Let remote value be serialize an Array-like with
script.HTMLCollectionRemoteValue
, handle id, known object, value, serialization options, ownership type, known object, serialization internal map, realm, and session. - value is a platform object that implements
Node
-
-
Let shared id be get shared id for a node with value and session.
-
Let remote value be a map matching the
script.NodeRemoteValue
production in the local end definition, with thesharedId
property set to shared id if it’s not null, or omitted otherwise, and thehandle
property set to handle id if it’s not null, or omitted otherwise. -
Set internal ids if needed with serialization internal map, remote value and value.
-
Let serialized be null.
-
If known object is
false
, run the following steps:-
Let serialized be a map.
-
Set serialized["
nodeType
"] to Get(value, "nodeType"). -
Set node value to Get(value, "nodeValue").
-
If node value is not null set serialized["
nodeValue
"] to node value. -
Set serialized["
childNodeCount
"] to child node count. -
If serialization options["
maxDomDepth
"] is equal to 0, or if value implementsShadowRoot
and serialization options["includeShadowTree
"] is "none
", or if serialization options["includeShadowTree
"] is "open
" and value’s mode is "closed
", let children be null.Otherwise, let children be an empty list and, for each node child in the children of value:
-
Let child serialization options be a clone of serialization options.
-
If child serialization options["
maxDomDepth
"] is not null, set child serialization options["maxDomDepth
"] to child serialization options["maxDomDepth
"] - 1. -
Let serialized be the result of serialize as a remote value with child, child serialization options, ownership type, serialization internal map, realm, and session.
-
Append serialized to children.
-
-
If children is not null, set serialized["
children
"] to children. -
If value implements
Element
:-
Let attributes be a new map.
-
For each attribute in value’s attribute list:
-
Let name be attribute’s qualified name
-
Let value be attribute’s value.
-
Set attributes[name] to value
-
-
Set serialized["
attributes
"] to attributes. -
Let shadow root be value’s shadow root.
-
If shadow root is null, let serialized shadow be null. Otherwise run the following substeps:
-
Let serialized shadow be the result of serialize as a remote value with shadow root, serialization options, ownership type, serialization internal map, realm, and session.
-
-
Set serialized["
shadowRoot
"] to serialized shadow.
-
-
If value implements
ShadowRoot
, set serialized["mode
"] to value’s mode.
-
-
If serialized is not null, set field
value
of remote value to serialized.
-
- value is a platform object that implements
WindowProxy
-
-
Let window be the value of value’s [[WindowProxy]] internal slot.
-
Let navigable be window’s navigable.
-
Let navigable id be the navigable id for navigable.
-
Let serialized be a map matching the
script.WindowProxyProperties
production in the local end definition with thecontext
property set to navigable id. -
Let remote value be a map matching the
script.WindowProxyRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise, and thevalue
property set to serialized.
-
- value is a platform object
- 1. Let remote value be a map matching the
script.ObjectRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - IsCallable(value)
- Let remote value be a map matching the
script.FunctionRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. - Otherwise:
-
-
Let remote value be a map matching the
script.ObjectRemoteValue
production in the local end definition, with thehandle
property set to handle id if it’s not null, or omitted otherwise. -
Set internal ids if needed with serialization internal map, remote value and value.
-
Let serialized be null.
-
If known object is
false
, and serialization options["maxObjectDepth
"] is not 0, run the following steps:-
Let serialized be the result of serialize as a mapping with EnumerableOwnPropertyNames(value, key+value), serialization options, ownership type, serialization internal map, realm, and session.
-
-
If serialized is not null, set field
value
of remote value to serialized.
-
Return remote value
children and child nodes are different things. Either childNodeCount
should
reference to childNodes
, or it should be renamed to childrenCount
.
-
Let remote value be a map matching production, with the
handle
property set to handle id if it’s not null, or omitted otherwise. -
Set internal ids if needed with serialization internal map, remote value and value.
-
If known object is
false
, and serialization options["maxObjectDepth
"]| is not 0:-
Let serialized be the result of serialize as a list with CreateArrayIterator(value, value), serialization options, ownership type, serialization internal map, realm, and session.
-
If serialized is not null, set field
value
of remote value to serialized.
-
-
Return remote value
-
If serialization options["
maxObjectDepth
"] is not null, assert: serialization options["maxObjectDepth
"] is greater than 0. -
Let serialized be a new list.
-
For each child value in IteratorToList(GetIterator(iterable, sync)):
-
Let child serialization options be a clone of serialization options.
-
If child serialization options["
maxObjectDepth
"] is not null, set child serialization options["maxObjectDepth
"] to child serialization options["maxObjectDepth
"] - 1. -
Let serialized child be the result of serialize as a remote value with child value, child serialization options, ownership type, serialization internal map, realm, and session.
-
Append serialized child to serialized.
-
-
Return serialized
To serialize as a mapping given iterable, serialization options, ownership type, serialization internal map, realm, and session:
-
If serialization options["
maxObjectDepth
"] is not null, assert: serialization options["maxObjectDepth
"] is greater than 0. -
Let serialized be a new list.
-
For item in IteratorToList(GetIterator(iterable, sync)):
-
Assert: IsArray(item)
-
Let property be CreateListFromArrayLike(item)
-
Assert: property is a list of size 2
-
Let key be property[0] and let value be property[1]
-
Let child serialization options be a clone of serialization options.
-
If child serialization options["
maxObjectDepth
"] is not null, set child serialization options["maxObjectDepth
"] to child serialization options["maxObjectDepth
"] - 1. -
If Typ(key) is String, let serialized key be child key, otherwise let serialized key be the result of serialize as a remote value with child key, child serialization options, ownership type, serialization internal map, realm, and session.
-
Let serialized value be the result of serialize as a remote value with value, child serialization options, ownership type, serialization internal map, realm, and session.
-
Let serialized child be («serialized key, serialized value»).
-
Append serialized child to serialized.
-
-
Return serialized
7.5.3.15. The script.ResultOwnership Type
script.ResultOwnership = "root" / "none"
The script.ResultOwnership
specifies how the serialized value
ownership will be treated.
7.5.3.16. The script.SerializationOptions Type
script.SerializationOptions = { ? maxDomDepth: (js-uint / null) .default 0, ? maxObjectDepth: (js-uint / null) .default null, ? includeShadowTree: ("none" / "open" / "all") .default "none", }
The script.SerializationOptions
allows specifying how ECMAScript
objects will be serialized.
7.5.3.17. The script.SharedId Type
Remote end definition and local end definition
script.SharedId = text;
The script.SharedId
type represents a reference to a DOM Node
that
is usable in any realm (including Sandbox Realms).
7.5.3.18. The script.StackFrame Type
Remote end definition and local end definition
script.StackFrame = { columnNumber: js-uint, functionName: text, lineNumber: js-uint, url: text, }
A frame in a stack trace is represented by a StackFrame
object. This has a url
property, which represents the URL of the
script, a functionName
property which represents the name of the
executing function, and lineNumber
and columnNumber
properties, which represent the line and column number of the executed code.
7.5.3.19. The script.StackTrace Type
Remote end definition and local end definition
script.StackTrace = { callFrames: [*script.StackFrame], }
The script.StackTrace
type represents the javascript stack at a point in
script execution.
Note: The details of how to get a list of stack frames, and the properties of that list are underspecified, and therefore the details here are implementation defined.
It is assumed that an implementation is able to generate a list of stack frames, which is a list with one entry for each item in the javascript call stack, starting from the most recent. Each entry is a single stack frame corresponding to execution of a statement or expression in a script script, which contains the following fields:
- script url
- The url of the resource containing script
- function
- The name of the function being executed
- line number
- The zero-based line number of the executed code, relative to the top of the resource containing script.
- column number
- The zero-based column number of the executed code, relative to the start of the line in the resource containing script.
To construct a stack trace, with a list of stack frames stack:
-
Let call frames be a new list.
-
For each stack frame frame in stack, starting from the most recently executed frame, run the following steps:
-
Let url be the result of running the URL serializer, given the URL of frame’s script url.
-
Let frame info be a new map matching the
script.StackFrame
production, with theurl
field set to url, thefunctionName
field set to frame’s function, thelineNumber
field set to frame’s line number and thecolumnNumber
field set to frame’s column number.
-
-
Append frame info to call frames.
-
Let stack trace be a new map matching the
script.StackTrace
production, with thecallFrames
property set to call frames. -
Return stack trace.
The current stack trace is the result of construct a stack trace given a list of stack frames representing the callstack of the running execution context.
The stack trace for an exception with an exception, or a Completion
Record of type throw
, exception, is given by:
-
If exception is a value that has been thrown as an exception, let record be the Completion Record created to throw exception. Otherwise let record be exception.
-
Let stack be the list of stack frames corresponding to execution at the point record was created.
-
Return construct a stack trace given stack.
7.5.3.20. The script.Source Type
script.Source = { realm: script.Realm, ? context: browsingContext.BrowsingContext }
The script.Source
type represents a script.Realm
with
an optional browsingContext.BrowsingContext
in which a
script related event occurred.
-
Let realm be the realm id for source realm.
-
Let environment settings be the environment settings object whose realm execution context's Realm component is source realm.
-
If environment settings has a associated
Document
:-
Let document be environment settings’ associated
Document
. -
Let navigable be document’s node navigable.
-
Let navigable id be the navigable id for navigable if navigable is not null.
Otherwise let navigable be null.
-
-
Let source be a map matching the
script.Source
production with therealm
field set to realm, and thecontext
field set to navigable id if navigable is not null, or unset otherwise. -
Return source.
7.5.3.21. The script.Target Type
script.RealmTarget = { realm: script.Realm }; script.ContextTarget = { context: browsingContext.BrowsingContext, ? sandbox: text } script.Target = ( script.ContextTarget / script.RealmTarget );
The script.Target
type represents a value that is either a script.Realm
or a browsingContext.BrowsingContext
.
This is useful in cases where a navigable identifier can stand in for the realm
associated with the navigable’s active document.
-
Let navigable be the result of trying to get a navigable with navigable id.
-
If sandbox is null or is an empty string:
-
Let document be navigable’s active document.
-
Let environment settings be the environment settings object whose relevant global object's associated
Document
is document. -
Let realm be environment settings’ realm execution context's Realm component.
-
-
Otherwise: let realm be result of trying to get or create a sandbox realm given sandbox and navigable.
-
Return success with data realm
-
If target matches the
script.ContextTarget
production:-
Let sandbox be null.
-
If target contains "
sandbox
", set sandbox to target["sandbox
"]. -
Let realm be get a realm from a navigable with target["
context
"] and sandbox.
-
-
Otherwise:
-
Assert: target matches the
script.RealmTarget
production. -
Let realm id be the value of the
realm
field of target. -
Let realm be get a realm given realm id.
-
-
Return success with data realm
7.5.4. Commands
7.5.4.1. The script.addPreloadScript Command
The script.addPreloadScript command adds a preload script.
- Command Type
-
script.AddPreloadScript = ( method: "script.addPreloadScript", params: script.AddPreloadScriptParameters ) script.AddPreloadScriptParameters = { functionDeclaration: text, ? arguments: [*script.ChannelValue], ? contexts: [+browsingContext.BrowsingContext], ? sandbox: text }
- Return Type
-
script.AddPreloadScriptResult = { script: script.PreloadScript }
-
Let function declaration be the
functionDeclaration
field of command parameters. -
Let arguments be the
arguments
field of command parameters if present, or an empty list otherwise. -
Let navigables be null.
-
If the
contexts
field of command parameters is present:-
Set navigables to an empty set.
-
For each navigable id of command parameters["
contexts
"]-
Let navigable be the result of trying to get a navigable with navigable id.
-
If navigable is not a top-level traversable, return error with error code invalid argument.
-
Append navigable to navigables.
-
-
-
Let sandbox be the value of the "
sandbox
" field in command parameters, if present, or null otherwise. -
Let script be the string representation of a UUID.
-
Let preload script map be session’s preload script map.
-
Set preload script map[script] to a struct with
function declaration
function declaration,arguments
arguments,contexts
navigables, andsandbox
sandbox. -
Return a new map matching the
script.AddPreloadScriptResult
with thescript
field set to script.
7.5.4.2. The script.disown Command
The script.disown command disowns the given handles. This does not guarantee the handled object will be garbage collected, as there can be other handles or strong ECMAScript references.
- Command Type
-
script.Disown = ( method: "script.disown", params: script.DisownParameters ) script.DisownParameters = { handles: [*script.Handle] target: script.Target; }
- Return Type
-
EmptyResult
-
Let realm be the result of trying to get a realm from a target given the value of the
target
field of command parameters. -
Let handles the value of the
handles
field of command parameters. -
For each handle id of handles:
-
Let handle map be realm’s handle object map
-
If handle map contains handle id, remove handle id from the handle map.
-
-
Return success with data null.
7.5.4.3. The script.callFunction Command
The script.callFunction command calls a provided function with given arguments in a given realm.
RealmInfo
can be either a realm or a navigable.
Note: In case of an arrow function in functionDeclaration
, the this
argument doesn’t affect function’s this
binding.
- Command Type
-
script.CallFunction = ( method: "script.callFunction", params: script.CallFunctionParameters ) script.CallFunctionParameters = { functionDeclaration: text, awaitPromise: bool, target: script.Target, ? arguments: [*script.LocalValue], ? resultOwnership: script.ResultOwnership, ? serializationOptions: script.SerializationOptions, ? this: script.LocalValue, ? userActivation: bool .default false, }
- Result Type
-
script.EvaluateResult
TODO: Add timeout argument as described in the script.evaluate.
To deserialize arguments with given realm, serialized arguments list and session:
-
Let deserialized arguments list be an empty list.
-
For each serialized argument of serialized arguments list:
-
Let deserialized argument be the result of trying to deserialize local value given serialized argument, realm and session.
-
Append deserialized argument to the deserialized arguments list.
-
-
Return success with data deserialized arguments list.
Note: the function declaration is parenthesized and evaluated.
-
Let parenthesized function declaration be concatenate «"
(
", function declaration, ")
"» -
Let function script be the result of create a classic script with parenthesized function declaration, environment settings, base URL, and options.
-
Prepare to run script with environment settings.
-
Let function body evaluation status be ScriptEvaluation(function script’s record).
-
Clean up after running script with environment settings.
-
Return (function script, function body evaluation status).
The remote end steps with session and command parameters are:
-
Let realm be the result of trying to get a realm from a target given the value of the
target
field of command parameters. -
Let realm id be realm’s realm id.
-
Let environment settings be the environment settings object whose realm execution context's Realm component is realm.
-
Let command arguments be the value of the
arguments
field of command parameters. -
Let deserialized arguments be an empty list.
-
If command arguments is not null, set deserialized arguments to the result of trying to deserialize arguments given realm, command arguments and session.
-
Let this parameter be the value of the
this
field of command parameters. -
Let this object be null.
-
If this parameter is not null, set this object to the result of trying to deserialize local value given this parameter, realm and session.
-
Let function declaration be the value of the
functionDeclaration
field of command parameters. -
Let await promise be the value of the
awaitPromise
field of command parameters. -
Let serialization options be the value of the
serializationOptions
field of command parameters, if present, or otherwise a map matching thescript.SerializationOptions
production with the fields set to their default values. -
Let result ownership be the value of the
resultOwnership
field of command parameters, if present, ornone
otherwise. -
Let base URL be the API base URL of environment settings.
-
Let options be the default classic script fetch options.
-
Let (script, function body evaluation status) be the result of evaluate function body with function declaration, environment settings, base URL, and options.
-
If function body evaluation status.[[Type]] is
throw
:-
Let exception details be the result of get exception details given realm, function body evaluation status, result ownership and session.
-
Return a new map matching the
script.EvaluateResultException
production, with theexceptionDetails
field set to exception details.
-
-
Let function object be function body evaluation status.[[Value]].
-
If IsCallable(function object) is
false
:-
Return an error with error code invalid argument
-
-
If command parameters["
userActivation
"] is true, run activation notification steps. -
Prepare to run script with environment settings.
-
Set evaluation status to Call(function object, this object, deserialized arguments).
-
If evaluation status.[[Type]] is
normal
, and await promise istrue
, and IsPromise(evaluation status.[[Value]]):-
Set evaluation status to Await(evaluation status.[[Value]]).
-
-
Clean up after running script with environment settings.
-
If evaluation status.[[Type]] is
throw
:-
Let exception details be the result of get exception details given realm, evaluation status, result ownership and session.
-
Return a new map matching the
script.EvaluateResultException
production, with theexceptionDetails
field set to exception details.
-
-
Assert: evaluation status.[[Type]] is
normal
. -
Let result be the result of serialize as a remote value with evaluation status.[[Value]], serialization options, result ownership, a new map as serialization internal map, realm and session.
-
Return a new map matching the
script.EvaluateResultSuccess
production, with therealm
field set to realm id, and theresult
field set to result.
7.5.4.4. The script.evaluate Command
The script.evaluate command evaluates a provided script in a given realm. For convenience a navigable can be provided in place of a realm, in which case the realm used is the realm of the browsing context’s active document.
The method returns the value of executing the provided script, unless it returns
a promise and awaitPromise
is true, in which case the resolved value of
the promise is returned.
- Command Type
-
script.Evaluate = ( method: "script.evaluate", params: script.EvaluateParameters ) script.EvaluateParameters = { expression: text, target: script.Target, awaitPromise: bool, ? resultOwnership: script.ResultOwnership, ? serializationOptions: script.SerializationOptions, ? userActivation: bool .default false, }
- Result Type
-
script.EvaluateResult
TODO: Add timeout argument. It’s not totally clear how this ought to work; in Chrome it seems like the timeout doesn’t apply to the promise resolve step, but that likely isn’t what clients want.
The remote end steps given session and command parameters are:
-
Let realm be the result of trying to get a realm from a target given the value of the
target
field of command parameters. -
Let realm id be realm’s realm id.
-
Let environment settings be the environment settings object whose realm execution context's Realm component is realm.
-
Let source be the value of the
expression
field of command parameters. -
Let await promise be the value of the
awaitPromise
field of command parameters. -
Let serialization options be the value of the
serializationOptions
field of command parameters, if present, or otherwise a map matching thescript.SerializationOptions
production with the fields set to their default values. -
Let result ownership be the value of the
resultOwnership
field of command parameters, if present, ornone
otherwise. -
Let options be the default classic script fetch options.
-
Let base URL be the API base URL of environment settings.
-
Let script be the result of create a classic script with source, environment settings, base URL, and options.
-
If command parameters["
userActivation
"] is true, run activation notification steps. -
Prepare to run script with environment settings.
-
Set evaluation status to ScriptEvaluation(script’s record).
-
If evaluation status.[[Type]] is
normal
, await promise is true, and IsPromise(evaluation status.[[Value]]):-
Set evaluation status to Await(evaluation status.[[Value]]).
-
-
Clean up after running script with environment settings.
-
If evaluation status.[[Type]] is
throw
:-
Let exception details be the result of get exception details with realm, evaluation status, result ownership and session.
-
Return a new map matching the
script.EvaluateResultException
production, with therealm
field set to realm id, and theexceptionDetails
field set to exception details.
-
-
Assert: evaluation status.[[Type]] is
normal
. -
Let result be the result of serialize as a remote value with evaluation status.[[Value]], serialization options, result ownership, a new map as serialization internal map, realm and session.
-
Return a new map matching the
script.EvaluateResultSuccess
production, with the with therealm
field set to realm id, and theresult
field set to result.
7.5.4.5. The script.getRealms Command
The script.getRealms command returns a list of all realms, optionally filtered to realms of a specific type, or to the realm associated with a navigable's active document.
- Command Type
-
script.GetRealms = ( method: "script.getRealms", params: script.GetRealmsParameters ) script.GetRealmsParameters = { ? context: browsingContext.BrowsingContext, ? type: script.RealmType, }
- Result Type
-
script.GetRealmsResult = { realms: [*script.RealmInfo] }
-
Let environment settings be a list of all the environment settings objects that have their execution ready flag set.
-
If command parameters contains
context
:-
Let navigable be the result of trying to get a navigable with command parameters["
context
"]. -
Let document be navigable’s active document.
-
Let navigable environment settings be a list.
-
For each settings of environment settings:
-
If any of the following conditions hold:
-
The associated
Document
of settings’ relevant global object is document -
The global object specified by settings is a
WorkerGlobalScope
with document in its owner set
Append settings to navigable environment settings.
-
-
-
Set environment settings to navigable environment settings.
-
-
Let realms be a list.
-
For each settings of environment settings:
-
Let realm info be the result of get the realm info given settings.
-
If command parameters contains
type
and realm info["type
"] is not equal to command parameters["type
"] then continue. -
If realm info is not null, append realm info to realms.
-
-
Let body be a map matching the
script.GetRealmsResult
production, with therealms
field set to realms. -
Return success with data body.
Extend this to also allow realm parents e.g. for nested workers? Or get all ancestor workers.
We might want to have a more sophisticated filter system than just a literal match.
7.5.4.6. The script.removePreloadScript Command
The script.removePreloadScript command removes a preload script.
- Command Type
-
script.RemovePreloadScript = ( method: "script.removePreloadScript", params: script.RemovePreloadScriptParameters ) script.RemovePreloadScriptParameters = { script: script.PreloadScript }
- Return Type
-
EmptyResult
-
Let script be the value of the "
script
" field in command parameters. -
Let preload script map be session’s preload script map.
-
If preload script map does not contain script, return error with error code no such script.
-
Entfernen Sie script from preload script map.
-
Return null
7.5.5. Events
7.5.5.1. The script.message Event
- Event Type
-
script.Message = ( method: "script.message", params: script.MessageParameters ) script.MessageParameters = { channel: script.Channel, data: script.RemoteValue, source: script.Source, }
-
Let environment settings be the environment settings object whose realm execution context's Realm component is realm.
-
Let related navigables be the result of get related navigables given environment settings.
-
If event is enabled given session, "
script.message
" and related navigables:-
If channel properties contains "
serializationOptions
", let serialization options be the value of theserializationOptions
field of channel properties. Otherwise let serialization options be a map matching thescript.SerializationOptions
production with the fields set to their default values. -
Let if channel properties contains "
ownership
", let ownership type be channel properties["ownership
"]. Otherwise let ownership type be "none
". -
Let data be the result of serialize as a remote value given message, serialization options, ownership type, a new map as serialization internal map and realm.
-
Let source be the get the source with realm.
-
Let params be a map matching the
script.MessageParameters
production, with thechannel
field set to channel properties["channel
"], thedata
field set to data, and thesource
field set to source. -
Let body be a map matching the
script.Message
production, with theparams
field set to params. -
Emit an event with session and body.
-
7.5.5.2. The script.realmCreated Event
- Event Type
-
script.RealmCreated = ( method: "script.realmCreated", params: script.RealmInfo )
When any of the set up a window environment settings object, set up a worker environment settings object or set up a worklet environment settings object algorithms are invoked, immediately prior to returning the settings object:
-
Let environment settings be the newly created environment settings object.
-
Let realm info be the result of get the realm info given environment settings.
-
If realm info is null, return.
-
Let related navigables be the result of get related navigables given environment settings.
-
Let body be a map matching the
script.RealmCreated
production, with theparams
field set to realm info. -
For each session in the set of sessions for which an event is enabled given "
script.realmCreated
" and related navigables:-
Emit an event with session and body.
-
The remote end subscribe steps with subscribe priority 2, given session, navigables and include global are:
-
Let environment settings be a list of all the environment settings objects that have their execution ready flag set.
-
For each settings of environment settings:
-
Let related navigables be a new set.
-
If the associated
Document
of settings’ relevant global object is a Document:-
Let navigable be settings’s relevant global object's associated
Document
’s node navigable. -
If navigable is null, continue.
-
Let top-level traversible be navigable’s top-level traversable.
-
If top-level traversible is not in navigables, continue.
-
Append top-level traversible to related navigables.
Otherwise, if include global is false, continue.
-
-
Let realm info be the result of get the realm info given settings.
-
If realm info is null, continue.
-
Let body be a map matching the
script.RealmCreated
production, with theparams
field set to realm info. -
If event is enabled given session, "
script.realmCreated
" and related navigables:-
Emit an event with session and body.
-
-
7.5.5.3. The script.realmDestroyed Event
- Event Type
-
script.RealmDestroyed = ( method: "script.realmDestroyed", params: script.RealmDestroyedParameters ) script.RealmDestroyedParameters = { realm: script.Realm }
-
Let related navigables be an empty set.
-
Append document’s navigable to related navigables.
-
For each worklet global scope in document’s worklet global scopes:
-
Let realm be worklet global scope’s relevant Realm.
-
Let realm id be the realm id for realm.
-
Let params be a map matching the
script.RealmDestroyedParameters
production, with therealm
field set of realm id. -
Let body be a map matching the
script.RealmDestroyed
production, with theparams
field set to params. -
For each session in the set of sessions for which an event is enabled given "
script.realmDestroyed
" and related navigables:-
Emit an event with session and body.
-
-
-
Let environment settings be the environment settings object whose relevant global object's associated
Document
is document. -
Let realm be environment settings’ realm execution context's Realm component.
-
Let realm id be the realm id for realm.
-
Let params be a map matching the
script.RealmDestroyedParameters
production, with therealm
field set to realm id. -
Let body be a map matching the
script.RealmDestroyed
production, with theparams
field set to params. -
For each session in the set of sessions for which an event is enabled given "
script.realmDestroyed
" and related navigables:-
Emit an event with session and body.
-
Whenever a worker event loop event loop is destroyed, either because the worker comes to the end of its lifecycle, or prematurely via the terminate a worker algorithm:
-
Let environment settings be the environment settings object for which event loop is the responsible event loop.
-
Let related navigables be the result of get related navigables given environment settings.
-
Let realm be environment settings’s environment settings object’s Realm.
-
Let realm id be the realm id for realm.
-
Let params be a map matching the
script.RealmDestroyedParameters
production, with therealm
field set of realm id. -
Let body be a map matching the
script.RealmDestroyed
production, with theparams
field set to params.
7.6. The storage Module
The storage module contains functionality and events related to storage.
A storage partition is a namespace within which the user agent may organize persistent data such as cookies and local storage.
A storage partition key is a map which uniquely identifies a storage partition.
7.6.1. Definition
StorageCommand = ( storage.DeleteCookies // storage.GetCookies // storage.SetCookie )
StorageResult = ( storage.DeleteCookiesResult / storage.GetCookiesResult / storage.SetCookieResult )
7.6.2. Types
7.6.2.1. The storage.PartitionKey Type
storage.PartitionKey = { ? userContext: text, ? sourceOrigin: text, Extensible, }
The storage.PartitionKey
type represents a storage partition key.
The following table of standard storage partition key attributes enumerates attributes with well-known meanings which a remote end may choose to support. An implementation may define additional extension storage partition key attributes.
Attribute | Definition |
---|---|
"userContext "
| A user context id |
"sourceOrigin"
| The serialization of the origin of resources that can access the storage partition |
Remote ends may support any number of extension storage partition key attributes. In order to avoid conflicts with other implementations, these attributes must begin with a unique identifier for the vendor and user-agent followed by U+003A (:).
A remote end has a map of default values for storage partition key attributes which contains zero or more entries. Each key must be a member of the table of standard storage partition key attributes where the storage partition key corresponds to a standard storage partition, or an extension storage partition key attribute where it does not, and the values represent the default value of that partition key that will be used when the user doesn’t provide an explicit value. The precise entries are implementation-defined and are determined by the storage partitioning adopted by the implementation.
A remote end has a list of required partition key attributes which contains zero or more entries. Each key must be a member of the table of standard storage partition key attributes where the storage partition key corresponds to a standard storage partition, or an extension storage partition key attribute where it does not. The precise entries are implementation-defined and are determined by the storage partitioning adopted by the implementation. This list includes only partition keys for which no default is available. As such the list must not share any entries with the keys of default values for storage partition key attributes.
-
Let deserialized filter to be an empty map.
-
For each name → value in filter:
-
Let deserialized name be the field name corresponding to the JSON key name in the table for cookie conversion.
-
If name is "
value
", set deserialized value to deserialize protocol bytes with value, otherwise let deserialized value be value. -
Set deserialized filter[deserialized name] to deserialized value.
-
-
Return deserialized filter.
-
If partition spec is null:
-
Set partition spec to an empty map.
-
-
Otherwise, if partition spec["
type
"] is "context
":-
Let navigable be the result of trying to get a navigable given partition spec["
context
"]. -
Let partition key be the key of navigable’s associated storage partition.
-
Return success with data partition key.
-
-
Let partition key be an empty map.
-
For each name → default value in the default values for storage partition key attributes:
-
For each name in the remote end’s required partition key attributes:
-
If partition spec[name] exists:
-
Set partition key][name] to partition spec[name].
-
-
Otherwise:
-
Return error with error code underspecified storage partition.
-
-
-
Return success with data partition key.
-
If storage partition key uniquely identifies an extant storage partition:
-
Let store be the cookie store of that storage partition.
-
Return success with data store.
-
-
Return error with error code no such storage partition.
-
For each name → value in filter:
-
If stored cookie[name] does not equal value:
-
Return false.
-
-
-
Return true.
-
Let cookies be a new list.
-
Set deserialized filter to deserialize filter with filter.
-
For each stored cookie in cookie store:
-
If match cookie with stored cookie and deserialized filter is true:
-
Append stored cookie to cookies.
-
-
-
Return cookies.
7.6.3. Commands
7.6.3.1. The storage.getCookies Command
The storage.getCookies command retrieves zero or more cookies which match a set of provided parameters.
- Command Type
-
storage.GetCookies = ( method: "storage.getCookies", params: storage.GetCookiesParameters ) storage.CookieFilter = { ? name: text, ? value: network.BytesValue, ? domain: text, ? path: text, ? size: js-uint, ? httpOnly: bool, ? secure: bool, ? sameSite: network.SameSite, ? expiry: js-uint, Extensible, } storage.BrowsingContextPartitionDescriptor = { type: "context", context: browsingContext.BrowsingContext } storage.StorageKeyPartitionDescriptor = { type: "storageKey", ? userContext: text, ? sourceOrigin: text, Extensible, } storage.PartitionDescriptor = ( storage.BrowsingContextPartitionDescriptor / storage.StorageKeyPartitionDescriptor ) storage.GetCookiesParameters = { ? filter: storage.CookieFilter, ? partition: storage.PartitionDescriptor, }
- Result Type
-
storage.GetCookiesResult = { cookies: [*network.Cookie], partitionKey: storage.PartitionKey, }
-
Let filter be the value of the
filter
field of command parameters if it is present or an empty map if it isn’t. -
Let partition spec be the value of the
partition
field of command parameters if it is present or null if it isn’t. -
Let partition key be the result of trying to expand a storage partition spec with partition spec.
-
Let store be the result of trying to get the cookie store with partition key.
-
Let cookies be the result of get matching cookies with store and filter.
-
Let serialized cookies be a new list.
-
For each cookie in cookies:
-
Let serialized cookie be the result of serialize cookie given cookie.
-
Append serialized cookie to serialized cookies.
-
-
Let body be a map matching the
storage.GetCookiesResult
production, with thecookies
field set to serialized cookies and thepartitionKey
field set to partition key. -
Return success with data body.
7.6.3.2. The storage.setCookie Command
The storage.setCookie command creates a new cookie in a cookie store, replacing any cookie in that store which matches according to [COOKIES].
- Command Type
-
storage.SetCookie = ( method: "storage.setCookie", params: storage.SetCookieParameters, ) storage.PartialCookie = { name: text, value: network.BytesValue, domain: text, ? path: text, ? httpOnly: bool, ? secure: bool, ? sameSite: network.SameSite, ? expiry: js-uint, Extensible, } storage.SetCookieParameters = { cookie: storage.PartialCookie, ? partition: storage.PartitionDescriptor, }
- Result Type
-
storage.SetCookieResult = { partitionKey: storage.PartitionKey }
-
Let cookie spec be the value of the
cookie
field of command parameters. -
Let partition spec be the value of the
partition
field of command parameters if it is present or null if it isn’t. -
Let partition key be the result of trying to expand a storage partition spec with partition spec.
-
Let store be the result of trying to get the cookie store with partition key.
-
Let deserialized value be deserialize protocol bytes with cookie spec["
value
"]. -
Create a cookie in store using cookie name cookie spec["
name
"], cookie value deserialized value, cookie domain cookie spec["domain
"], and an attribute-value list of the following cookie concepts listed in the table for cookie conversion:- Cookie path
-
cookie spec["
path
"] if it exists, otherwise "/
". - Cookie secure only
-
cookie spec["
secure
"] if it exists, otherwise false. - Cookie HTTP only
-
cookie spec["
httpOnly
"] if it exists, otherwise false. - Cookie expiry time
-
cookie spec["
expiry
"] if it exists, otherwise leave unset to indicate that this is a session cookie. - Cookie same site
-
cookie spec["
sameSite
"] if it exists, otherwise leave unset to indicate that no same site policy is defined.
If this step is aborted without inserting a cookie into the cookie store, return error with error code unable to set cookie.
-
Let body be a map matching the
storage.SetCookieResult
production, with thepartitionKey
field set to partition key. -
Return success with data body.
7.6.3.3. The storage.deleteCookies Command
The storage.deleteCookies command removes zero or more cookies which match a set of provided parameters.
- Command Type
-
storage.DeleteCookies = ( method: "storage.deleteCookies", params: storage.DeleteCookiesParameters, ) storage.DeleteCookiesParameters = { ? filter: storage.CookieFilter, ? partition: storage.PartitionDescriptor, }
- Result Type
-
storage.DeleteCookiesResult = { partitionKey: storage.PartitionKey }
-
Let filter be the value of the
filter
field of command parameters if it is present or an empty map if it isn’t. -
Let partition spec be the value of the
partition
field of command parameters if it is present or null if it isn’t. -
Let partition key be the result of trying to expand a storage partition spec with partition spec.
-
Let store be the result of trying to get the cookie store with partition key.
-
Let cookies be the result of get matching cookies with store and filter.
-
For each cookie in cookies:
-
Entfernen Sie cookie from store.
-
-
Let body be a map matching the
storage.DeleteCookiesResult
production, with thepartitionKey
field set to partition key. -
Return success with data body.
7.7. The log Module
The log module contains functionality and events related to logging.
A BiDi Session has a log event buffer which is a map from navigable id to a list of log events for that context that have not been emitted. User agents may impose a maximum size on this buffer, subject to the condition that if events A and B happen in the same context with A occurring before B, and both are added to the buffer, the entry for B must not be removed before the entry for A.
To buffer a log event given session, navigables and event:
-
Let buffer be session’s log event buffer.
-
Let navigable ids be a new list.
-
For each navigable of navigables:
-
Append the navigable id for navigable to navigable ids.
-
-
For each navigable id in navigable ids:
-
Let other navigables be an empty list
-
For each other id in navigable ids:
-
If other id is not equal to navigable id, append other id to other navigables.
-
If buffer does not contain navigable id, let buffer[navigable id] be a new list.
-
Append (event, other navigables) to buffer[navigable id].
-
Note: we store the other navigables here so that each event is only emitted once. In practice this is only relevant for workers that can be associated with multiple navigables.
Do we want to key this on browsing context or top-level traversable? The difference is in what happens if an event occurs in a frame and that frame is then navigated before the local end subscribes to log events for the top level navigable.
7.7.1. Definition
LogEvent = ( log.EntryAdded )
7.7.2. Types
7.7.2.1. log.LogEntry
log.Level = "debug" / "info" / "warn" / "error" log.Entry = ( log.GenericLogEntry / log.ConsoleLogEntry / log.JavascriptLogEntry ) log.BaseLogEntry = ( level: log.Level, source: script.Source, text: text / null, timestamp: js-uint, ? stackTrace: script.StackTrace, ) log.GenericLogEntry = { log.BaseLogEntry, type: text, } log.ConsoleLogEntry = { log.BaseLogEntry, type: "console", method: text, args: [*script.RemoteValue], } log.JavascriptLogEntry = { log.BaseLogEntry, type: "javascript", }
Each log event is represented by a log.Entry
object. This has a type
property which represents the type of log entry added, a level
property representing severity, a source
property representing the origin of the log entry, a text
property
with the log message string itself, and a timestamp
property
corresponding to the time the log entry was generated. Specific variants of the log.Entry
are used to represent logs from different sources, and
provide additional fields specific to the entry type.
7.7.3. Events
7.7.3.1. The log.entryAdded Event
- Event Type
-
log.EntryAdded = ( method: "log.entryAdded", params: log.Entry, )
The remote end event trigger is:
Define the following console steps with method, args, and options:
-
For each session in active BiDI sessions:
-
If method is "
error
" or "assert
", let level be "error
". If method is "debug
" or "trace
" let level be "debug
". If method is "warn
", let level be "warn
". Otherwise let level be "info
". -
Let timestamp be a time value representing the current date and time in UTC.
-
Let text be an empty string.
-
If Typ(args[0]) is String, and args[0] contains a formatting specifier, let formatted args be Formatter(args). Otherwise let formatted args be args.
Note: The formatter operation is underdefined in the console specification, formatting can be inconsistent between different implementations.
-
For each arg in formatted args:
-
If arg is not the first entry in args, append a U+0020 SPACE to text.
-
If arg is a primitive ECMAScript value, append ToString(arg) to text. Otherwise append an implementation-defined string to text.
-
-
Let realm be the realm id of the current Realm Record.
-
Let serialized args be a new list.
-
Let serialization options be a map matching the
script.SerializationOptions
production with the fields set to their default values. -
For each arg of args:
-
Let serialized arg be the result of serialize as a remote value with arg as value, serialization options,
none
as ownership type, a new map as serialization internal map, realm and session. -
hinzufügen serialized arg to serialized args.
-
-
Let source be the result of get the source given current Realm Record.
-
If method is "
assert
", "error
", "trace
", or "warn
", let stack be the current stack trace. Otherwise let stack be null. -
Let entry be a map matching the
log.ConsoleLogEntry
production, with the thelevel
field set to level, thetext
field set to text, thetimestamp
field set to timestamp, thestackTrace
field set to stack if stack is not null, or omitted otherwise, the method field set to method, thesource
field set to source and theargs
field set to serialized args. -
Let body be a map matching the
log.EntryAdded
production, with theparams
field set to entry. -
Let settings be the current settings object
-
Let related navigables be the result of get related navigables given settings.
-
If event is enabled with session, "
log.entryAdded
" and related navigables, emit an event with session and body.Otherwise, buffer a log event with session, related browsing contexts, and body.
-
Define the following error reporting steps with arguments script, line number, column number, message and handled:
-
If handled is true return.
-
Let settings be script’s settings object.
-
Let stack be the stack trace for an exception with the exception corresponding to the error being reported.
-
Let source be the result of get the source given current Realm Record.
-
Let entry be a map matching the
log.JavascriptLogEntry
production, withlevel
set to "error
",text
set to message,source
set to source, and thetimestamp
field set to timestamp. -
Let related navigables be the result of get related navigables given settings.
-
For each session in active BiDi sessions:
-
If event is enabled with session, "
log.entryAdded
" and related navigables, emit an event with session and body.Otherwise, buffer a log event with session, related browsing contexts, and body.
-
Lots more things require logging. CDP has LogEntryAdded types xml, javascript, network, storage, appcache, rendering, security, deprecation, worker, violation, intervention, recommendation, other. These are in addition to the js exception and console API types that are represented by different methods.
The remote end subscribe steps, with subscribe priority 10, given session, navigables and include global are:
-
For each navigable id → Ereignisse in session’s log event buffer:
-
Let maybe context be the result of getting a navigable given navigable id.
-
If maybe context is an error, remove navigable id from log event buffer and continue.
-
Let navigable be maybe context’s data
-
Let top level navigable be navigable’s top-level traversable.
-
If include global is true and top level navigable is not in navigables, or if include global is false and top level navigable is in navigables:
-
For each (event, other navigables) in Ereignisse:
-
Emit an event with session and event.
-
For each other context id in other navigables:
-
If log event buffer contains other context id, remove event from log event buffer[other context id].
-
-
-
-
7.8. The input Module
The input module contains functionality for simulated user input.
7.8.1. Definition
InputCommand = ( input.PerformActions // input.ReleaseActions // input.SetFiles )
7.8.2. Types
7.8.2.1. input.ElementOrigin
The input.ElementOrigin
type represents an Element
that will
be used as a coordinate origin.
input.ElementOrigin = { type: "element", element: script.SharedReference }
input.ElementOrigin
steps given object are:
-
If object is a map matching the
input.ElementOrigin
production, return true. -
Return false.
input.ElementOrigin
steps given session:
-
Return the following steps, given origin and navigable:
-
Assert: origin matches
input.ElementOrigin
. -
Let document be navigable’s active document.
-
Let reference be origin["
element
"] -
Let environment settings be the environment settings object whose relevant global object's associated
Document
is document. -
Let realm be environment settings’ realm execution context's Realm component.
-
Let element be the result of trying to deserialize remote reference with reference, realm, and session.
-
If element doesn’t implement
Element
return error with error code no such element. -
Return success with data element.
-
7.8.3. Commands
7.8.3.1. The input.performActions Command
The input.performActions command performs a specified sequence of user input actions.
Note: for a detailed description of the behavior of this command, see the actions section of [WEBDRIVER].
- Command Type
-
input.PerformActions = ( method: "input.performActions", params: input.PerformActionsParameters ) input.PerformActionsParameters = { context: browsingContext.BrowsingContext, actions: [*input.SourceActions] } input.SourceActions = ( input.NoneSourceActions / input.KeySourceActions / input.PointerSourceActions / input.WheelSourceActions ) input.NoneSourceActions = { type: "none", id: text, actions: [*input.NoneSourceAction] } input.NoneSourceAction = input.PauseAction input.KeySourceActions = { type: "key", id: text, actions: [*input.KeySourceAction] } input.KeySourceAction = ( input.PauseAction / input.KeyDownAction / input.KeyUpAction ) input.PointerSourceActions = { type: "pointer", id: text, ? parameters: input.PointerParameters, actions: [*input.PointerSourceAction] } input.PointerType = "mouse" / "pen" / "touch" input.PointerParameters = { ? pointerType: input.PointerType .default "mouse" } input.PointerSourceAction = ( input.PauseAction / input.PointerDownAction / input.PointerUpAction / input.PointerMoveAction ) input.WheelSourceActions = { type: "wheel", id: text, actions: [*input.WheelSourceAction] } input.WheelSourceAction = ( input.PauseAction / input.WheelScrollAction ) input.PauseAction = { type: "pause", ? duration: js-uint } input.KeyDownAction = { type: "keyDown", value: text } input.KeyUpAction = { type: "keyUp", value: text } input.PointerUpAction = { type: "pointerUp", button: js-uint, } input.PointerDownAction = { type: "pointerDown", button: js-uint, input.PointerCommonProperties } input.PointerMoveAction = { type: "pointerMove", x: js-int, y: js-int, ? duration: js-uint, ? origin: input.Origin, input.PointerCommonProperties } input.WheelScrollAction = { type: "scroll", x: js-int, y: js-int, deltaX: js-int, deltaY: js-int, ? duration: js-uint, ? origin: input.Origin .default "viewport", } input.PointerCommonProperties = ( ? width: js-uint .default 1, ? height: js-uint .default 1, ? pressure: float .default 0.0, ? tangentialPressure: float .default 0.0, ? twist: (0..359) .default 0, ; 0 .. Math.PI / 2 ? altitudeAngle: (0.0..1.5707963267948966) .default 0.0, ; 0 .. 2 * Math.PI ? azimuthAngle: (0.0..6.283185307179586) .default 0.0, ) input.Origin = "viewport" / "pointer" / input.ElementOrigin
- Return Type
-
EmptyResult
The remote end steps with session and command parameters are:
-
Let navigable id be the value of the
context
field of command parameters. -
Let navigable be the result of trying to get a navigable with navigable id.
-
Let input state be get the input state with session and navigable’s top-level traversable.
-
Let actions options be a new actions options with the is element origin steps set to is input.ElementOrigin, and the get element origin steps set to the result of get Element from input.ElementOrigin steps given session.
-
Let actions by tick be the result of trying to extract an action sequence with input state, command parameters, and actions options.
-
Try to dispatch actions with input state, actions by tick, navigable, and actions options.
-
Return success with data null.
7.8.3.2. The input.releaseActions Command
The input.releaseActions command resets the input state associated with the current session.
- Command Type
-
input.ReleaseActions = ( method: "input.releaseActions", params: input.ReleaseActionsParameters ) input.ReleaseActionsParameters = { context: browsingContext.BrowsingContext, }
- Return Type
-
EmptyResult
The remote end steps given session, and command parameters are:
-
Let navigable id be the value of the
context
field of command parameters. -
Let navigable be the result of trying to get a navigable with navigable id.
-
Let top-level traversable be navigable’s top-level traversable.
-
Let input state be get the input state with session and top-level traversable.
-
Let actions options be a new actions options with the is element origin steps set to is input.ElementOrigin, and the get element origin steps set to get Element from input.ElementOrigin steps given session.
-
Let undo actions be input state’s input cancel list in reverse order.
-
Try to dispatch tick actions with undo actions, 0, navigable, and actions options.
-
Reset the input state with session and top-level traversable.
-
Return success with data null.
7.8.3.3. The input.setFiles Command
The input.setFiles command sets the files
property of a given input
element with type file
to a set of file paths.
- Command Type
-
input.SetFiles = ( method: "input.setFiles", params: input.SetFilesParameters ) input.SetFilesParameters = { context: browsingContext.BrowsingContext, element: script.SharedReference, files: [*text] }
- Return Type
-
EmptyResult
The remote end steps given session and command parameters are:
-
Let navigable id be the value of the command parameters["
context
"] field. -
Let navigable be the result of trying to get a navigable with navigable id.
-
Let document be navigable’s active document.
-
Let environment settings be the environment settings object whose relevant global object's associated
Document
is document. -
Let realm be environment settings’s realm execution context's Realm component.
-
Let element be the result of trying to deserialize remote reference with command parameters["
element
"], realm, and session. -
If element doesn’t implement
Element
, return error with error code no such element. -
If element doesn’t implement
HTMLInputElement
, element’stype
is not in the File Upload state, or element is disabled, return error with error code unable to set file input. -
If the size of files is greater than 1 and element’s
multiple
attribute is not set, return error with error code unable to set file input. -
Let files be the value of the command parameters["
files
"] field. -
Let selected files be element’s selected files.
-
If the size of the intersection of files and selected files is equal to the size of selected files and equal to the size of files, queue an element task on the user interaction task source given element to fire an event named
cancel
at element, with thebubbles
attribute initialized to true.Note: Cancellation in a browser is typically determined by changes in file selection. In other words, if there is no change, a "cancel" event is sent.
-
Otherwise, update the file selection for element with files as the user’s selection.
-
If, for any reason, the remote end is unable to set the selected files of element to the files with paths given in files, return error with error code unsupported operation.
Note: For example remote ends might be unable to set selected files to files that do not currently exist on the filesystem.
-
Return success with data null.
8. Patches to Other Specifications
This specification requires some changes to external specifications to provide the necessary integration points. It is assumed that these patches will be committed to the other specifications as part of the standards process.
8.1. HTML
The report an error algorithm is modified with an additional step at the end:
-
Call any error reporting steps defined in external specifications with script, line, col, message, and true if the error is handled, or false otherwise.
8.2. Console
Other specifications can define console steps.
-
At the point when the Printer operation is called with arguments name, printerArgs and options (which is undefined if the argument is not provided), call any console steps defined in external specification with arguments name, printerArgs, and options.
8.3. CSS
8.3.1. Determine the device pixel ratio
Insert the following steps at the start of the determine the device pixel ratio algorithm:
-
If device pixel ratio overrides contains window’s navigable, return device pixel ratio overrides[window’s navigable].
9. Appendices
This section is non-normative.
9.1. External specifications
Note: the list is not exhaustive and might not be up to date.
The following external specifications define additional WebDriver BiDi modules: