Skip to content
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

Add support for "userContexts" argument to "browsingContext.setViewport" command. #876

Open
wants to merge 3 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
174 changes: 134 additions & 40 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -2966,6 +2966,16 @@ 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.

A <dfn for="viewport-configuration">viewport dimensions</dfn> is a [=struct=] with an [=struct/item=] named
<dfn attribute for="viewport-dimensions">height</dfn> which is an integer and
a [=struct/item=] named <dfn attribute for="viewport-dimensions">width</dfn> which is an integer.

A <dfn>viewport configuration</dfn> is a [=struct=] with an [=struct/item=] named
<dfn attribute for="viewport-configuration">viewport</dfn> which is a [=viewport-configuration/viewport dimensions=]
or null and an [=struct/item=] named <dfn attribute for="viewport-configuration">devicePixelRatio</dfn> which is a float or null.

A [=remote end=] has a <dfn>viewport overrides map</dfn> which is a weak map between [=user contexts=] and [=viewport configuration=].

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

#### The browsingContext.BrowsingContext Type #### {#type-browsingContext-Browsingcontext}
Expand Down Expand Up @@ -4629,9 +4639,10 @@ The <dfn export for=commands>browsingContext.setViewport</dfn> command modifies
)

browsingContext.SetViewportParameters = {
context: browsingContext.BrowsingContext,
? context: browsingContext.BrowsingContext,
? viewport: browsingContext.Viewport / null,
? devicePixelRatio: (float .gt 0.0) / null,
? userContexts: [+browser.UserContext],
}

browsingContext.Viewport = {
Expand All @@ -4648,71 +4659,154 @@ The <dfn export for=commands>browsingContext.setViewport</dfn> command modifies
</dd>
</dl>

<div algorithm="remote end steps for browsingContext.setViewport">
<div algorithm>
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this helper algorithms could be moved outside of the command section so that remote end steps follow the CDDL type definitions for the command.

To <dfn>set device pixel ratio override</dfn> given |navigable| and |device pixel ratio|:

The [=remote end steps=] with |command parameters| are:
1. Let |navigable| be the [=/navigable=] whose [=navigable/active document=] is
Copy link
Member

Choose a reason for hiding this comment

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

Is there a case where this isn't a no-op?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess now it should be handled in the command algorithm?

Copy link
Contributor

Choose a reason for hiding this comment

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

to me it read as Let |navigable| be |navigable|

|navigable|'s [=navigable/active document=].

1. Let |navigable id| be the value of the <code>context</code> field of |command
parameters|.
1. If |device pixel ratio| is not null:

1. Let |navigable| be the result of [=trying=] to [=get a navigable=] with
|navigable id|.
1. When the [=select an image source from a source set=] steps are run, act as if
the implementation's pixel density was set to |device pixel ratio| when selecting an image.

1. If |navigable| is not a [=/top-level traversable=], return [=error=] with
[=error code=] [=invalid argument=].
1. 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.

1. [=map/Set=] [=device pixel ratio overrides=][|navigable|] to |device pixel ratio|.

Note: This will take an effect because of the patch of [[#patchs-determine-the-device-pixel-ratio]].

1. Otherwise:

1. 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.

1. For the purposes of the [=resolution media feature=], use the implementation's default behavior,
without any changes made by previous invocations of these steps.

1. [=map/Remove=] |navigable| from [=device pixel ratio overrides=].

1. Run [=evaluate media queries and report changes=] for [=/document=] currently loaded
in a specified |navigable|.

</div>


<div algorithm>
To <dfn>set viewport</dfn> given |navigable| and |viewport|:

1. If |viewport| is not null, set the width of |navigable|'s [=layout
viewport=] to be the <code>width</code> of |viewport| in CSS pixels and
set the height of the |navigable|'s [=layout viewport=] to be the
<code>height</code> of |viewport| in CSS pixels.

1. Otherwise, set the |navigable|'s [=layout viewport=] to the
implementation-defined default.

</div>

<div algorithm="set viewport when a top-level traversable is created">

After creating a document in a new [=navigable/top-level traversable=] |navigable| and
before the [=run WebDriver BiDi preload scripts=] algorithm is invoked:

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

1. If [=viewport overrides map=] [=map/contains=] |user context|:

1. If |viewport overrides map|[|user context|] [=map/contains=] the <code>viewport</code> field:
Copy link
Contributor

@OrKoN OrKoN Feb 20, 2025

Choose a reason for hiding this comment

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

I think this should be [=viewport overrides map=] (here and below)

Copy link
Contributor

Choose a reason for hiding this comment

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

I think [=map/contains=] cannot be used here since |viewport overrides map|[|user context|] is a struct


1. If the implementation is unable to adjust the |navigable|'s [=layout viewport=]
1. [=Set viewport=] with |navigable| and |viewport overrides map|[|user context|]["<code>viewport</code>"].

1. If |viewport overrides map|[|user context|] [=map/contains=] the <code>devicePixelRatio</code> field:

1. For the |navigable| and all [=descendant navigables=]:

1. [=Set device pixel ratio override=] with |navigable| and |viewport overrides map|[|user context|]["<code>devicePixelRatio</code>""].

</div>

<div algorithm="remote end steps for browsingContext.setViewport">

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

1. If the implementation is unable to adjust the [=layout viewport=]
parameters with the given |command parameters| for any reason, return
[=error=] with [=error code=] [=unsupported operation=].

1. If |command parameters| [=map/contains=] the <code>viewport</code> field:
1. If |command parameters| [=map/contains=] "<code>userContexts</code>"
and |command parameters| [=map/contains=] "<code>context</code>",
return [=error=] with [=error code=] [=invalid argument=].
Comment on lines +4738 to +4740
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably also raise an error if both parameters are missing? It will effectively be a noop and won't crash or anything, but the user should know about it. Otherwise they might assume it just applied setViewport to all navigables?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that's true, added ✅


1. Let |viewport| be the |command parameters|["<code>viewport</code>"].
1. Let |navigables| be a [=/set=].

1. If |viewport| is not null, set the width of |navigable|'s [=layout
viewport=] to be the <code>width</code> of |viewport| in CSS pixels and
set the height of the |navigable|'s [=layout viewport=] to be the
<code>height</code> of |viewport| in CSS pixels.
1. If the <code>context</code> field of |command parameters| is present:
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we could use [=map/contains=] instead of "is present"


1. Otherwise, set the |navigable|'s [=layout viewport=] to the
implementation-defined default.
1. Let |navigable id| be the value of the <code>context</code> field of |command
parameters|.

1. Run the [[cssom-view-1#resizing-viewports]] steps.
1. Let |navigable| be the result of [=trying=] to [=get a navigable=] with
|navigable id|.

1. If |command parameters| [=map/contains=] the <code>devicePixelRatio</code> field:
1. If |navigable| is not a [=/top-level traversable=], return [=error=] with
[=error code=] [=invalid argument=].

1. Let |device pixel ratio| be the |command
parameters|["<code>devicePixelRatio</code>"].
1. [=set/Append=] |navigable| to |navigables|.

1. For the |navigable| and all [=descendant navigables=]:
1. Otherwise, if the <code>userContexts</code> field of |command parameters| is present:

1. Let |navigable| be the [=/navigable=] whose [=navigable/active document=] is
|navigable|'s [=navigable/active document=].
1. Let |user contexts| be a [=/set=].

1. If |device pixel ratio| is not null:
1. For each |user context id| of |command parameters|["<code>userContexts</code>"]:

1. 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.
1. Set |user context| to [=get user context=] with |user context id|.

1. 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.
1. If |user context| is null, return [=error=] with [=error code=] [=no such user context=].
Copy link
Member

Choose a reason for hiding this comment

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

This failure inside the loop means that we'd partially apply the command to any user contexts before the one that doesn't exist; we should probably fail if any don't exist.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, made the validation loop first.


1. [=map/Set=] [=device pixel ratio overrides=][|navigable|] to |device pixel ratio|.
1. [=set/Append=] |user context| to |user contexts|.

Note: This will take an effect because of the patch of [[#patchs-determine-the-device-pixel-ratio]].
1. For each |user context| of |user contexts|:

1. Otherwise:
1. [=map/Set=] [=viewport overrides map=][|user context|] to a new [=/map=].
Copy link
Contributor

Choose a reason for hiding this comment

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

isn't [=viewport overrides map=][|user context|] defined as a struct?


1. 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.
1. If |command parameters| [=map/contains=] the <code>viewport</code> field:

1. Set |viewport overrides map|[|user context|]["<code>viewport</code>"]
to |command parameters|["<code>viewport</code>"].

1. If |command parameters| [=map/contains=] the <code>devicePixelRatio</code> field:

1. Set |viewport overrides map|[|user context|]["<code>devicePixelRatio</code>"]
to |command parameters|["<code>devicePixelRatio</code>"].

1. [=list/For each=] |top-level traversable| in the list of all [=/top-level traversables=]
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
1. [=list/For each=] |top-level traversable| in the list of all [=/top-level traversables=]
1. [=list/For each=] |top-level traversable| of the list of all [=/top-level traversables=]

I think the infra standard recommends for each |item| of |list|.

whose [=associated user context=] is |user context|:

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

1. Otherwise, return [=error=] with [=error code=] [=invalid argument=].

1. If |command parameters| [=map/contains=] the <code>viewport</code> field:

1. Let |viewport| be the |command parameters|["<code>viewport</code>"].

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

1. [=Set viewport=] with |navigable| and |viewport|.

1. Run the [[cssom-view-1#resizing-viewports]] steps with |navigable|'s [=active document=].

1. If |command parameters| [=map/contains=] the <code>devicePixelRatio</code> field:

1. Let |device pixel ratio| be the |command
parameters|["<code>devicePixelRatio</code>"].

1. For the purposes of the [=resolution media feature=], use the implementation's default behavior,
without any changes made by previous invocations of these steps.
1. For each |navigable| of |navigables|:

1. [=map/Remove=] |navigable| from [=device pixel ratio overrides=].
1. For the |navigable| and all [=descendant navigables=]:

1. Run [=evaluate media queries and report changes=] for [=/document=] currently loaded
in a specified |navigable|.
1. [=Set device pixel ratio override=] with |navigable| and |device pixel ratio|.

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

Expand Down