Skip to content

Commit

Permalink
Screen orientation type should be counter-clockwise
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=255388
rdar://107976966

Reviewed by Chris Dumez.

Now reports "landscape-primary" when the device is turned to the left and
"landscape-secondary" when the device is turned to the right. This matches
the behavior of the other platforms and aligns with the updated W3C Spec:
w3c/screen-orientation#248

* LayoutTests/imported/w3c/web-platform-tests/screen-orientation/orientation-reading-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/screen-orientation/orientation-reading.html:
* LayoutTests/platform/ios/imported/w3c/web-platform-tests/screen-orientation/orientation-reading-expected.txt:
* Source/WebCore/platform/ios/ScreenOrientationProviderIOS.mm:
(WebCore::ScreenOrientationProvider::platformCurrentOrientation):
* Tools/WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::TestController::lockScreenOrientation):

* LayoutTests/imported/w3c/web-platform-tests/screen-orientation/orientation-reading-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/screen-orientation/orientation-reading.html:
* LayoutTests/platform/ios/imported/w3c/web-platform-tests/screen-orientation/orientation-reading-expected.txt:
* Source/WebCore/platform/ios/ScreenOrientationProviderIOS.mm:
(WebCore::ScreenOrientationProvider::platformCurrentOrientation):
* Source/WebKit/UIProcess/ios/PageClientImplIOS.mm:
(WebKit::toUIInterfaceOrientationMask):
* Tools/WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::TestController::lockScreenOrientation):

Canonical link: https://commits.webkit.org/262940@main
  • Loading branch information
marcoscaceres committed Apr 14, 2023
1 parent aefb617 commit 9a0e886
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 108 deletions.
@@ -1,10 +1,10 @@

Harness Error (FAIL), message = Test named 'Test the orientations and associated angles' specified 1 'cleanup' function, and 1 failed.
Harness Error (FAIL), message = Test named 'Test the orientations and associated angles when the natural orientation is 'portrait'' specified 1 'cleanup' function, and 1 failed.

PASS Test screen.orientation properties
PASS Test screen.orientation default values.
PASS Test the orientations and associated angles
PASS Test that screen.orientation properties are not writable
PASS Test that screen.orientation is always the same object
NOTRUN Test that screen.orientation values change if the orientation changes
PASS screen.orientation attributes are present
PASS Test the orientations and associated angles when the natural orientation is 'portrait'
NOTRUN Test the orientations and associated angles when the natural orientation is 'landscape'
PASS Test that ScreenOrientation properties are not writable
PASS Test that ScreenOrientation is always the same object
NOTRUN Test that ScreenOrientation's attribute values change after 'change' event fires

Expand Up @@ -6,110 +6,91 @@
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script type="module">

import { makeCleanup, getOppositeOrientation } from "./resources/orientation-utils.js";

test(() => {
assert_true("type" in screen.orientation);
assert_true("angle" in screen.orientation);
}, "Test screen.orientation properties");
"use strict";
import {
makeCleanup,
getOppositeOrientation,
} from "./resources/orientation-utils.js";

test(() => {
const type = screen.orientation.type;
const angle = screen.orientation.angle;
assert_true("type" in screen.orientation, ".type must be present");
assert_true("angle" in screen.orientation, ".angle must be present");
}, "screen.orientation attributes are present");

if (screen.width > screen.height) {
assert_true(type == "landscape-primary" || type == "landscape-secondary");
} else if (screen.width < screen.height) {
assert_true(type == "portrait-primary" || type == "portrait-secondary");
async function testExpectedOrientationAngles(expectedAngles) {
for (const [orientation, expectedAngle] of Object.entries(expectedAngles)) {
try {
if (screen.orientation.type !== orientation) {
await screen.orientation.lock(orientation);
}
assert_equals(
screen.orientation.angle,
expectedAngle,
`Orientation angle for '${orientation}' must be ${expectedAngle} degrees`
);
} catch (err) {
// implementation might not support locking to this orientation
}
}
}

promise_test(async (t) => {
t.add_cleanup(makeCleanup());
await test_driver.bless("request full screen");
await document.documentElement.requestFullscreen();

assert_true(angle == 0 || angle == 90 || angle == 180 || angle == 270);
}, "Test screen.orientation default values.");
const expectedAnglesPortrait = {
"portrait-primary": 0,
"landscape-primary": 90,
"portrait-secondary": 180,
"landscape-secondary": 270,
};

promise_test(async t => {
await testExpectedOrientationAngles(expectedAnglesPortrait);
}, "Test the orientations and associated angles when the natural orientation is 'portrait'");

promise_test(async (t) => {
t.add_cleanup(makeCleanup());
await test_driver.bless("request full screen");
await document.documentElement.requestFullscreen();
try {
await screen.orientation.lock("portrait-primary");
} catch (err) {
// implementation might not support locking to portrait-primary
return;
}
const orientations =
screen.orientation.angle === 0
? {
secondaryOrientation1: "portrait-secondary",
primaryOrientation2: "landscape-primary",
secondaryOrientation2: "landscape-secondary",
}
: {
secondaryOrientation1: "landscape-secondary",
primaryOrientation2: "portrait-primary",
secondaryOrientation2: "portrait-secondary",
};
try {
await screen.orientation.lock(orientations.secondaryOrientation1);
} catch (err) {
// implementation might not support locking to this orientation
return;
}
assert_equals(
screen.orientation.angle,
180,
"Secondary orientation 1 angle must be 180"
);
try {
await screen.orientation.lock(orientations.primaryOrientation2);
} catch (err) {
// implementation might not support locking to this orientation
return;
}
assert_true(
screen.orientation.angle == 90 || screen.orientation.angle == 270,
"Primary orientation 2 angle must be either 90 or 270"
);
const primaryOrientation2Angle = screen.orientation.angle;
const secondaryOrientation2Angle = primaryOrientation2Angle === 90 ? 270 : 90;
try {
await screen.orientation.lock(orientations.secondaryOrientation2);
} catch (err) {
// implementation might not support locking to this orientation
return;
}
assert_equals(
screen.orientation.angle,
secondaryOrientation2Angle,
"Secondary orientation 2 angle must be the opposite angle to primary orientation 2"
);
screen.orientation.unlock();
}, "Test the orientations and associated angles");

const expectedAnglesLandscape = {
"landscape-primary": 0,
"portrait-primary": 90,
"landscape-secondary": 180,
"portrait-secondary": 270,
};

await testExpectedOrientationAngles(expectedAnglesLandscape);
}, "Test the orientations and associated angles when the natural orientation is 'landscape'");

test(() => {
const type = screen.orientation.type;
const angle = screen.orientation.angle;
const { angle, type } = screen.orientation;

try {
screen.orientation.type = "foo";
} catch (err) {
// implementation might throw an exception due to readonly
}
try {
screen.orientation.angle = 42;
} catch (err) {
// implementation might throw an exception due to readonly
}
assert_throws_js(
TypeError,
() => {
screen.orientation.type = "foo";
},
"throws when setting ScreenOrientation.type to a string in strict mode"
);
assert_throws_js(
TypeError,
() => {
screen.orientation.angle = 42;
},
"throws when setting ScreenOrientation.angle to a number in strict mode"
);

assert_equals(screen.orientation.type, type);
assert_equals(screen.orientation.angle, angle);
}, "Test that screen.orientation properties are not writable");
}, "Test that ScreenOrientation properties are not writable");

test(() => {
assert_equals(screen.orientation, screen.orientation);
}, "Test that screen.orientation is always the same object");
}, "Test that ScreenOrientation is always the same object");

promise_test(async t => {
promise_test(async (t) => {
t.add_cleanup(makeCleanup());
await test_driver.bless("request full screen");
await document.documentElement.requestFullscreen();
Expand All @@ -121,10 +102,18 @@
// change event is fired before resolving promise by lock.
const event = await Promise.race([
orientationWatcher.wait_for("change"),
screen.orientation.lock(newOrientationType)
screen.orientation.lock(newOrientationType),
]);
assert_true(event instanceof Event, "expected event");
assert_not_equals(screen.orientation.type, initialType, "type should have changed");
assert_not_equals(screen.orientation.angle, initialAngle, "angle should have changed");
}, "Test that screen.orientation values change if the orientation changes");
assert_not_equals(
screen.orientation.type,
initialType,
".type must change"
);
assert_not_equals(
screen.orientation.angle,
initialAngle,
".angle must change"
);
}, "Test that ScreenOrientation's attribute values change after 'change' event fires");
</script>
@@ -1,8 +1,8 @@

PASS Test screen.orientation properties
PASS Test screen.orientation default values.
PASS Test the orientations and associated angles
FAIL Test that screen.orientation properties are not writable Attempted to assign to readonly property.
PASS Test that screen.orientation is always the same object
PASS Test that screen.orientation values change if the orientation changes
PASS screen.orientation attributes are present
PASS Test the orientations and associated angles when the natural orientation is 'portrait'
PASS Test the orientations and associated angles when the natural orientation is 'landscape'
PASS Test that ScreenOrientation properties are not writable
PASS Test that ScreenOrientation is always the same object
PASS Test that ScreenOrientation's attribute values change after 'change' event fires

4 changes: 2 additions & 2 deletions Source/WebCore/platform/ios/ScreenOrientationProviderIOS.mm
Expand Up @@ -81,9 +81,9 @@ - (void)_screenOrientationDidChange
case UIInterfaceOrientationPortraitUpsideDown:
return WebCore::ScreenOrientationType::PortraitSecondary;
case UIInterfaceOrientationLandscapeLeft:
return WebCore::ScreenOrientationType::LandscapePrimary;
case UIInterfaceOrientationLandscapeRight:
return WebCore::ScreenOrientationType::LandscapeSecondary;
case UIInterfaceOrientationLandscapeRight:
return WebCore::ScreenOrientationType::LandscapePrimary;
}
return WebCore::ScreenOrientationType::PortraitPrimary;
}
Expand Down
4 changes: 2 additions & 2 deletions Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
Expand Up @@ -744,9 +744,9 @@ static UIInterfaceOrientationMask toUIInterfaceOrientationMask(WebCore::ScreenOr
case WebCore::ScreenOrientationType::PortraitSecondary:
return UIInterfaceOrientationMaskPortraitUpsideDown;
case WebCore::ScreenOrientationType::LandscapePrimary:
return UIInterfaceOrientationMaskLandscapeLeft;
case WebCore::ScreenOrientationType::LandscapeSecondary:
return UIInterfaceOrientationMaskLandscapeRight;
case WebCore::ScreenOrientationType::LandscapeSecondary:
return UIInterfaceOrientationMaskLandscapeLeft;
}
ASSERT_NOT_REACHED();
return UIInterfaceOrientationMaskPortrait;
Expand Down
4 changes: 2 additions & 2 deletions Tools/WebKitTestRunner/ios/TestControllerIOS.mm
Expand Up @@ -527,10 +527,10 @@ static _WKFocusStartsInputSessionPolicy focusStartsInputSessionPolicy(const Test
webView.supportedInterfaceOrientations = UIInterfaceOrientationMaskPortraitUpsideDown;
break;
case kWKScreenOrientationTypeLandscapePrimary:
webView.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscapeLeft;
webView.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscapeRight;
break;
case kWKScreenOrientationTypeLandscapeSecondary:
webView.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscapeRight;
webView.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscapeLeft;
break;
}
[UIView performWithoutAnimation:^{
Expand Down

0 comments on commit 9a0e886

Please sign in to comment.