Skip to content

emulation.setUserAgentOverride #947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ spec: SCREEN-ORIENTATION; urlPrefix: https://www.w3.org/TR/screen-orientation
text: screen orientation; url: #dom-screenorientation
text: screen orientation change steps; url: #dfn-screen-orientation-change-steps
text: screen orientation values lists; url: #dfn-screen-orientation-values-lists
spec: FETCH; urlPrefix: https://fetch.spec.whatwg.org/
type: dfn
text: default User-Agent value; url: #default-user-agent-value
text: HTTP-network-or-cache fetch; url: #concept-http-network-or-cache-fetch
text: request; url: #fetch-params-request
spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/
type: dfn
text: 2D context creation algorithm; url: canvas.html#2d-context-creation-algorithm
Expand Down Expand Up @@ -235,6 +240,7 @@ spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/
text: navigable; for:window; url: nav-history-apis.html#window-navigable
text: navigables; url: document-sequences.html#navigables
text: navigation id; url: browsing-the-web.html#navigation-id
text: NavigatorID; url: system-state.html#navigatorid
text: ongoing-navigation; url: browsing-the-web.html#ongoing-navigation
text: origin-clean; url: canvas.html#concept-canvas-origin-clean
text: parent; for:navigable; url: document-sequences.html#nav-parent
Expand Down Expand Up @@ -3143,6 +3149,9 @@ A [=remote end=] has a <dfn>timezone overrides map</dfn> which is a weak map bet
A [=remote end=] has an <dfn>unhandled prompt behavior overrides map</dfn> which is a
weak map between [=user contexts=] and [=unhandled prompt behavior struct=].

A [=remote end=] has a <dfn>user agent overrides map</dfn> which is a weak map
between [=navigables=] or [=user contexts=] and string or null.

### Types ### {#module-browsingcontext-types}

#### The browsingContext.BrowsingContext Type #### {#type-browsingContext-Browsingcontext}
Expand Down Expand Up @@ -5817,6 +5826,8 @@ EmulationCommand = (
emulation.SetLocaleOverride //
emulation.SetScreenOrientationOverride //
emulation.SetTimezoneOverride
emulation.SetScreenOrientationOverride //
emulation.SetUserAgentOverride
)
</pre>

Expand Down Expand Up @@ -6188,6 +6199,142 @@ The [=remote end steps=] with |command parameters| are:

</div>

#### The emulation.setUserAgentOverride Command #### {#command-emulation-setUserAgentOverride}

The <dfn export for=commands>emulation.setUserAgentOverride</dfn> command modifies
User-Agent on the given top-level traversables or user contexts.

<dl>
<dt>Command Type</dt>
<dd>
<pre class="cddl" data-cddl-module="remote-cddl">
emulation.SetUserAgentOverride = (
method: "emulation.setUserAgentOverride",
params: emulation.SetUserAgentOverrideParameters
)

emulation.SetUserAgentOverrideParameters = {
userAgent: text / null,
? contexts: [+browsingContext.BrowsingContext],
? userContexts: [+browser.UserContext],
}
</pre>
</dd>
<dt>Result Type</dt>
<dd>
<code>
EmptyResult
</code>
</dd>
</dl>

<div algorithm="updated `User-Agent` getter steps">
The [=default User-Agent value=] getter steps is implementation defined. A
WebDriver-BiDi [=remote end=] must have an implementation that runs the following
steps:

1. Let |related navigables| be an empty list.

1. If [=default User-Agent value=] was accessed during execution of the
[=HTTP-network-or-cache fetch=] algorithm with |fetchParams|:

1. Let |request| be |fetchParams|’s [=request=].

1. If |request|'s [=request/client=] is not null, let |related navigables|
be the result of [=get related navigables=] with |request|'s
[=request/client=].

1. If [=default User-Agent value=] was accessed from [=NavigatorID=] interface:

1. Let |realm| be [=current Realm Record=].

1. Let |environment settings| be the [=environment settings object=] whose
[=realm execution context=]'s Realm component is |realm|.

1. Let |related navigables| be the result of [=get related navigables=] given
|environment settings|.
Comment on lines +6238 to +6255
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about this approach? @OrKoN @juliandescottes @jgraham ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@juliandescottes @jgraham WDYT about this approach?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a maintenance perspective, I prefer adding hooks in the relevant specs because otherwise the other specs might change and break the relationship with BiDi unintentionally.

From the point of view of someone trying to read and implement the specification, you still need to jump between the two specifications to understand the behavior. Possibly even harder to follow because you need to identify all the spots in the other spec which access [=default User-Agent value=], which sounds painful.

The main added value of this approach is that we don't have to update other specs, but apart from that hooks seem preferable to me. Is there something which makes it more difficult for the NavigatorID case? For fetch we already have pending hooks in whatwg/fetch#1540 so for consistency it also seems better to stick to hooks.


1. Let |emulated user agent| be the result of [=get emulated user agent=] given
|related navigables|.

1. If |emulated user agent| is not null, return |emulated user agent|.

1. Return the result of implementation-defined steps in accordance with the
requirements of the [=default User-Agent value=] specification.

</div>

<div algorithm>
To <dfn>get emulated user agent</dfn> given |navigables|:

1. For each |navigable| or |navigables|:

1. Let |top-level navigable| be |navigable|'s [=navigable/top-level traversable=].

1. If [=user agent overrides map=] contains |top-level navigable|, return
[=user agent overrides map=][|top-level navigable|].

1. Let |user context| be |top-level navigable|'s [=associated user context=].

1. If [=user agent overrides map=] contains |user context|, return
[=user agent overrides map=][|user context|].

1. Return null.

</div>

<div algorithm="remote end steps for emulation.setUserAgentOverride">

The [=remote end steps=] with |command parameters| are:

1. If |command parameters| [=map/contains=] "<code>userContexts</code>"
and |command parameters| [=map/contains=] "<code>context</code>",
return [=error=] with [=error code=] [=invalid argument=].

1. If |command parameters| doesn't [=map/contain=] "<code>userContexts</code>"
and |command parameters| doesn't [=map/contain=] "<code>context</code>",
return [=error=] with [=error code=] [=invalid argument=].

1. Let |emulated user agent| be null.

1. If |command parameters| [=map/contains=] "<code>userAgent</code>":

1. Set |emulated user agent| to |command parameters|["<code>userAgent</code>"].

1. Let |navigables| be a [=/set=].

1. If the <code>contexts</code> field of |command parameters| is present:

1. Let |navigables| be the result of [=trying=] to
[=get valid top-level traversables by ids=] with
|command parameters|["<code>contexts</code>"].

1. Otherwise:

1. Assert the <code>userContexts</code> field of |command parameters| is present.

1. Let |user contexts| be the result of [=trying=] to [=get valid user contexts=]
with |command parameters|["<code>userContexts</code>"].

1. For each |user context| of |user contexts|:

1. [=map/Set=] [=user agent overrides map=][|user context|] to
|emulated user agent|.

1. [=list/For each=] |top-level traversable| of the list of all
[=/top-level traversables=] whose [=associated user context=] is
|user context|:

1. [=list/Append=] |top-level traversable| to |navigables|.

1. For each |navigable| of |navigables|:

1. [=map/Set=] [=user agent overrides map=][|navigable|] to |emulated user agent|.

1. Return [=success=] with data null.

</div>

#### The emulation.setTimezoneOverride Command #### {#command-emulation-setTimezoneOverride}

The <dfn export for=commands>emulation.setTimezoneOverride</dfn> command modifies
Expand Down