From 9f414a04b0f33e0ff8034bb0a7917d853e7b648b Mon Sep 17 00:00:00 2001 From: "Menard, Alexis" Date: Tue, 29 Oct 2024 10:36:31 -0400 Subject: [PATCH] [css-viewport-1] Add automation support for viewport segments This commits define ways to emulate display features of a device. A display feature is a hardware feature that acts as a divider and creates logically separate regions of the viewport. Using WebDriver developers and user agents will have the opportunity to test or emulate several types of devices. --- css-viewport-1/Overview.bs | 213 ++++++++++- css-viewport-1/display_features.svg | 379 +++++++++++++++++++ css-viewport-1/display_features_general.svg | 391 ++++++++++++++++++++ 3 files changed, 979 insertions(+), 4 deletions(-) create mode 100644 css-viewport-1/display_features.svg create mode 100644 css-viewport-1/display_features_general.svg diff --git a/css-viewport-1/Overview.bs b/css-viewport-1/Overview.bs index af172a9b73e..5bfa18b1cc9 100644 --- a/css-viewport-1/Overview.bs +++ b/css-viewport-1/Overview.bs @@ -32,6 +32,11 @@ spec: fenced-frames; urlPrefix: https://wicg.github.io/fenced-frame/ type: interface; text: FencedFrames + +

Introduction

@@ -119,6 +124,22 @@ property for the first <BODY> element of an HTML or XHTML document. For other document types, it is the computed 'direction' for the root element. +

Display feature definition

+A display feature is a hardware feature that acts as a divider +and creates logically separate region of the viewport called {{segments}}. +It can be a fold area of a device with a foldable screen or a physical +split occupying a logical space within the viewport for example some dual +screen models. + +Below is an illustration describing the concept of display features and how +they divide the viewport in {{segments}}: + +Two images,
+showing two display feature configurations and the respective segments.
+One image is showing an vertical display feature, the other is showing
+an horizontal display feature + +

Viewport <meta> element

@@ -541,7 +562,7 @@ partial interface Window {
 [Exposed=Window]
 interface Viewport {
-  readonly attribute FrozenArray<DOMRect>? segments;
+	readonly attribute FrozenArray<DOMRect>? segments;
 };
 
@@ -554,10 +575,12 @@ Each {{DOMRect}} contains the geometry of the segment (x, y, width, height) in C Additonal details about the definition of a viewport segment can be found here: [[css-env-1#viewport-segments]]. -The {{segments}} attribute must run these steps: +The {{segments}} attribute getter steps are: 1. If the {{Viewport}}'s associated {{Document}} is not fully active, return null. -2. Returns null if there is only a single viewport segment and abort these steps. -3. Otherwise, return the {{Viewport}}'s [[css-env-1#viewport-segments|segments]] array. +2. Let |topLevelTraversable| be |document|'s [=relevant global object=]'s [=/navigable=]'s [=browsing context/top-level traversable=]. +3. If |topLevelTraversable|.[=[[DisplayFeaturesOverride]]=] is non-null, return {{Viewport}}'s [[css-env-1#viewport-segments|segments]] array calculated from |topLevelTraversable|.[=[[DisplayFeaturesOverride]]=]. +4. Returns null if there is only a single viewport segment and abort these steps. +5. Otherwise, return the {{Viewport}}'s [[css-env-1#viewport-segments|segments]] array calculated from the hardware features.
This section is not normative. @@ -572,6 +595,188 @@ If a viewport of 400px by 400px is split horizontally into two side-by-side segm
+

Automation

+The {{segments}} property poses a challenge to test authors, as exercising this property +requires access to specific hardware devices. To address this challenge this document defines +[[WEBDRIVER2]] [=extension commands=] that allow users to control how the viewport is split by +one or more [=display feature| display features=] (such as a fold or a hinge between two separate displays). + +A display feature override is a [=struct=] encapsulating the result of a single display feature. +It has a orientation (a string that is either "vertical" or "horizontal"), +a mask length (a positive number describing the length of the feature), and +an offset (which describe the distance from the origin of the viewport). + +

Internal slots

+To support the [=extension commands=] below and their integration with +the {{segments}} attribute getter steps, [=browsing context/top-level traversables=] must have the following +internal slots: + + + + + + + + + + + + + +
+ Internal slot + + Description +
+ \[[DisplayFeaturesOverride]] + + List of [=display feature override=] that overrides those provided by the hardware, or null. +
+ +

Extensions Commands

+ +
Set display features
+ + + + + + + + + +
+ HTTP Method + + [=extension command URI Template|URI Template=] +
+ POST + + /session/{session id}/displayfeatures +
+ +This [=extension command=] creates a setup that emulates a set of [=display feature override=] by taking a list of display features as +parameter. + +
+ This section is not normative. + + This section exists because the input format is not trivial. Here is a pseudo IDL example on + how a [=display feature override=] is defined: +
+		enum OrientationType {
+			"vertical",
+			"horizontal"
+		};
+
+		interface DisplayFeature {
+			readonly attribute OrientationType orientation;
+			readonly attribute double offset;
+			readonly attribute double maskLength;
+		};
+	
+ + Below is an illustration showing the various properties of a display feature: + + Two images,
+	showing the meaning of each display feature attributes. One image is showing an
+	vertical display feature, the other is showing an horizontal display feature +
+ +
+ To create a [=[[DisplayFeaturesOverride]]=] in the current browsing context of the [=session=] with ID 23, + the [=local end=] would POST to `/session/23/displayfeatures` with the body: +
+		{
+			"features": [
+				{
+					"orientation": "horizontal",
+					"offset": 190,
+					"maskLength": 20
+				}
+			]
+		}
+		
+ Considering a viewport of 400px by 400px the command will result of a {{segments}} property with the following content: + [DOMRect(0, 0, 400, 190), DOMRect(0, 210, 400, 190)] +
+ + +
+The [=remote end steps=] are: +
+
    +
  1. Let |features| be the result of invoking getting a property "features" from + |parameters|. +
  2. +
  3. If |features| is not a {{Array}}, return [=error=] with [=error + code|WebDriver error code=] [=invalid argument=]. +
  4. +
  5. Let |parsedFeatures| be a new list of [=display feature override=].
  6. +
  7. For each |feature item| in |features|: +
      +
    1. If |feature item| is not an {{Object}}, return [=error=] with [=error code|WebDriver error code=] [=invalid argument=].
    2. +
    3. Let |mask length| be the result of invoking getting a property "maskLength" from |feature item|.
    4. +
    5. If |mask length| is not a {{Number}} or its value is {{Number/NaN}}, +∞, −∞, or negative return [=error=] with [=error code|WebDriver error code=] [=invalid argument=]. +
    6. Let |offset| be the result of invoking getting a property "offset" from |feature item|.
    7. +
    8. If |offset| is not a {{Number}} or its value is {{Number/NaN}}, +∞, −∞, or negative return [=error=] with [=error code|WebDriver error code=] [=invalid argument=]. +
    9. Let |orientation| be the result of invoking getting a property "orientation" from |feature item|.
    10. +
    11. If |orientation| is not a {{string}}, return [=error=] with [=error code|WebDriver error code=] [=invalid argument=].
    12. +
    13. If |orientation| is neither "vertical" or "vertical", return [=error=] with [=error code|WebDriver error code=] [=invalid argument=]. +
    14. If |orientation| is "vertical" and |mask length| + |offset| is greater than viewport width including the size of the rendered scrollbar, return [=error=] with [=error code|WebDriver error code=] [=invalid argument=].
    15. +
    16. If |orientation| is "vertical" and |mask length| + |offset| is greater than viewport height including the size of the rendered scrollbar, return [=error=] with [=error code|WebDriver error code=] [=invalid argument=].
    17. +
    18. Let |override| be a new [=display feature override=].
    19. +
    20. Set |override|'s [=mask length=] to |mask length|.
    21. +
    22. Set |override|'s [=orientation=] to |orientation|.
    23. +
    24. Set |override|'s [=offset=] to |offset|.
    25. +
    26. [=list/Append=] |override| to |parsedFeatures|.
    27. +
    +
  8. +
  9. Let |topLevelTraversable| be the current browsing context's + [=browsing context/top-level traversable=]. +
  10. +
  11. Set |topLevelTraversable|.[=[[DisplayFeaturesOverride]]=] to |parsedFeatures|. +
  12. +
  13. Return [=success=] with data null. +
  14. +
+ +
Clear display features
+ + + + + + + + + +
+ HTTP Method + + [=extension command URI Template|URI Template=] +
+ DELETE + + /session/{session id}/displayfeatures +
+
+ This [=extension command=] removes the display features override and returns + control back to hardware. +
+
+ The [=remote end steps=] are: +
+
    +
  1. Let |topLevelTraversable| be the current browsing context's + [=browsing context/top-level traversable=]. +
  2. +
  3. Set |topLevelTraversable|. [=[[DisplayFeaturesOverride]]=] to null. +
  4. +
  5. Return [=success=] with data null. +
  6. +
+

Appendix A. Changes

This appendix is informative. diff --git a/css-viewport-1/display_features.svg b/css-viewport-1/display_features.svg new file mode 100644 index 00000000000..a88e94c87e1 --- /dev/null +++ b/css-viewport-1/display_features.svg @@ -0,0 +1,379 @@ + +http://http://Horizontal Display FeatureVertical Display FeatureOffsetmaskLengthmaskLengthOffset diff --git a/css-viewport-1/display_features_general.svg b/css-viewport-1/display_features_general.svg new file mode 100644 index 00000000000..a85dd8c8885 --- /dev/null +++ b/css-viewport-1/display_features_general.svg @@ -0,0 +1,391 @@ + +http://http://Horizontal Display FeatureVertical Display FeatureSegment 1Segment 2Segment 2Segment 1Display FeatureDisplay Feature