Update web-platform-tests to revision 719721f655102bcd24d45eba91339eb2d7dbc591

This commit is contained in:
WPT Sync Bot 2019-07-14 10:26:29 +00:00
parent 2b84348372
commit bc8af9cf87
70 changed files with 1271 additions and 294 deletions

View file

@ -27,6 +27,7 @@ test_computed_value("color", "#FEDCBA", "rgb(254, 220, 186)");
test_computed_value("color", "rgb(2, 3, 4)");
test_computed_value("color", "rgb(100%, 0%, 0%)", "rgb(255, 0, 0)");
test_computed_value("color", "rgba(2, 3, 4, 0.5)");
test_computed_value("color", "rgba(2, 3, 4, 50%)", "rgba(2, 3, 4, 0.5)");
test_computed_value("color", "hsl(120, 100%, 50%)", "rgb(0, 255, 0)");
test_computed_value("color", "hsla(120, 100%, 50%, 0.25)", "rgba(0, 255, 0, 0.25)");
test_computed_value("color", "rgb(-2, 3, 4)", "rgb(0, 3, 4)");

View file

@ -21,6 +21,7 @@ test_valid_value("color", "#FEDCBA", "rgb(254, 220, 186)");
test_valid_value("color", "rgb(2, 3, 4)");
test_valid_value("color", "rgb(100%, 0%, 0%)", "rgb(255, 0, 0)");
test_valid_value("color", "rgba(2, 3, 4, 0.5)"); // Safari serializes alpha-value 0.498039
test_valid_value("color", "rgba(2, 3, 4, 50%)", "rgba(2, 3, 4, 0.5)"); // Safari serializes alpha-value 0.498039
test_valid_value("color", "hsl(120, 100%, 50%)", ["rgb(0, 255, 0)", "hsl(120, 100%, 50%)"]);
test_valid_value("color", "hsla(120, 100%, 50%, 0.25)", ["rgba(0, 255, 0, 0.25)", "hsla(120, 100%, 50%, 0.25)"]); // Safari serializes alpha-value 0.247059
test_valid_value("color", "rgb(-2, 3, 4)", "rgb(0, 3, 4)");

View file

@ -16,6 +16,10 @@ test_computed_value("opacity", "0.5");
test_computed_value("opacity", "0");
test_computed_value("opacity", "-2", "0");
test_computed_value("opacity", "3", "1");
test_computed_value("opacity", "-100%", "0");
test_computed_value("opacity", "50%", "0.5");
test_computed_value("opacity", "300%", "1");
</script>
</body>
</html>

View file

@ -17,6 +17,10 @@ test_valid_value("opacity", "0.5");
test_valid_value("opacity", "0");
test_valid_value("opacity", "-2");
test_valid_value("opacity", "3");
test_valid_value("opacity", "-100%", "-1");
test_valid_value("opacity", "50%", "0.5");
test_valid_value("opacity", "300%", "3");
</script>
</body>
</html>

View file

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html class='reftest-wait'>
<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
<link rel="help" href="https://www.w3.org/TR/css-position-3/" />
<meta name="assert" content="This test checks that a dynamic change in constraints calculates the static position correctly."/>
<script src="/common/reftest-wait.js"></script>
<style>
#container {
position: relative;
background: red;
direction: rtl;
box-sizing: border-box;
border: solid green 10px;
width: 100px;
height: 100px;
}
#float {
float: right;
background: green;
width: 40px;
height: 80px;
}
#target {
position: absolute;
background: green;
display: inline;
width: 40px;
height: 80px;
top: -10px;
left: -10px;
}
</style>
<p>Test passes if there is a filled green square.</p>
<div id="container">
<div id="float"></div>
<div id="target"></div>
</div>
<script>
document.body.offsetTop;
const target = document.getElementById('target');
target.style.top = 'initial';
target.style.left = 'initial';
document.body.offsetTop;
takeScreenshot();
</script>

View file

@ -0,0 +1,38 @@
<!doctype html>
<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-tables-3/#row-layout">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
<link rel="bookmark" href="https://crbug.com/982312" />
<meta name="flags" content="" />
<meta name="assert" content="min-height is honored on a %height child of a table cell with an unresolvable %height and when the descendant has overflow:auto" />
<title>table cell percent height descendant with overflow:auto</title>
<!-- msft.html -->
<style>
.list-div {
overflow-y: auto;
height: 100%;
width: 100px;
min-height: 100px;
background: green;
}
#redSquare {
height: 100px;
width: 100px;
background-color: red;
position: absolute;
z-index: -1;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.
</p>
<div id="redSquare"></div>
<div style="display:table">
<div style="display:table-cell; height:100%">
<div class="list-div">
</div>
</div>
</div>

View file

@ -0,0 +1,38 @@
<!doctype html>
<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-tables-3/#row-layout">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
<link rel="bookmark" href="https://crbug.com/982312" />
<meta name="flags" content="" />
<meta name="assert" content="%height child of a table cell with a fixed height is positioned correctly when the min-height is greater than the cell's fixed height and when the descendant has overflow:auto." />
<title>table cell percent height descendant with overflow:auto</title>
<!-- msft_fixed_height.html -->
<style>
.list-div {
overflow-y: auto;
height: 100%;
width: 100px;
min-height: 100px;
background: green;
}
#redSquare {
height: 100px;
width: 100px;
background-color: red;
position: absolute;
z-index: -1;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.
</p>
<div id="redSquare"></div>
<div style="display:table">
<div style="display:table-cell; height:50px">
<div class="list-div">
</div>
</div>
</div>

View file

@ -0,0 +1,41 @@
<!doctype html>
<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-tables-3/#row-layout">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
<link rel="bookmark" href="https://crbug.com/982312" />
<meta name="flags" content="" />
<meta name="assert" content="intrinsic height of a table cell descendant is honored when the descendant and cell both have unresolvable percentage heights and when the descendant has overflow:auto" />
<title>table cell percent height descendant with overflow:auto</title>
<!-- other_msft.html -->
<style>
.list-div {
overflow-y: auto;
height: 100%;
}
.list-div-child {
width: 100px;
height: 100px;
background: green;
}
#redSquare {
height: 100px;
width: 100px;
background-color: red;
position: absolute;
z-index: -1;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.
</p>
<div id="redSquare"></div>
<div style="display:table">
<div style="display:table-cell; height:100%">
<div class="list-div">
<div class="list-div-child"></div>
</div>
</div>
</div>

View file

@ -0,0 +1,39 @@
<!doctype html>
<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-tables-3/#row-layout">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
<link rel="bookmark" href="https://crbug.com/982312" />
<meta name="flags" content="" />
<meta name="assert" content="table cell descendant retains its min-height when the descendant and cell both have unresolvable percentage heights and the descendant has overflow:auto, and the cell's sibling has a fixed height greater than the descendant's min-height." />
<title>table cell percent height descendant with overflow:auto</title>
<!-- msftsibling.html -->
<style>
.list-div {
overflow-y: auto;
height: 100%;
width: 100px;
min-height: 100px;
background: green;
}
#redSquare {
height: 100px;
width: 100px;
background-color: red;
position: absolute;
z-index: -1;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.
</p>
<div id="redSquare"></div>
<div style="display:table">
<!-- vertical-align:top because blink and ff do baseline differently here -->
<div style="display:table-cell; height:100%; vertical-align:top;">
<div class="list-div"></div>
</div>
<div style="display:table-cell; height:150px;"></div>
</div>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<title>CSS Text Test: Test when soft-hyphen overflows</title>
<link rel="match" href="reference/hyphens-overflow-001-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#hyphens-property">
<link rel="author" href="mailto:kojii@chromium.org">
<style>
div {
font-size: 10px;
font-family: Ahem;
width: 5.1ch;
}
</style>
<body>
<div>12 4&shy;xx</div>
<div>12 45&shy;xx</div>
<div>12 456&shy;xx</div>
<div>1234&shy;xx</div>
<div>12345&shy;xx</div>
<div>123456&shy;xx</div>
</body>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<style>
div {
font-size: 10px;
font-family: Ahem;
}
</style>
<body>
<div>12 4-<br>xx</div>
<div>12<br>45xx</div>
<div>12<br>456xx</div>
<div>1234-<br>xx</div>
<div>12345-<br>xx</div>
<div>123456-<br>xx</div>
</body>

View file

@ -59,7 +59,7 @@
{ property: "cursor", valuesToTest:["auto", "crosshair", "default", "pointer", "move", "e-resize", "ne-resize", "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "text", "wait", "help"], default: "auto" },
{ property: "direction", valuesToTest:["ltr", "rtl"], default: "ltr" },
{ property: "display", valuesToTest:["inline", "block", "list-item", "table", "inline-table", "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption", "none"], default: "inline" },
{ property: "dominant-baseline", valuesToTest:["auto", "use-script", "no-change", "reset-size", "ideographic", "alphabetic", "hanging", "mathematical", "central", "middle", "text-after-edge", "text-before-edge"], default: "auto" },
{ property: "dominant-baseline", valuesToTest:["auto", "ideographic", "alphabetic", "hanging", "mathematical", "central", "middle", "text-after-edge", "text-before-edge"], default: "auto" },
{ property: "fill", valuesToTest:["red", "url(#gradient) black"], default: "black" },
{ property: "fill-opacity", valuesToTest:["0.8"], default: "1" },
{ property: "fill-rule", valuesToTest:["nonzero", "evenodd"], default: "nonzero" },

View file

@ -16,6 +16,9 @@
test_computed_value("flood-opacity", "-1", "0");
test_computed_value("flood-opacity", "0.5");
test_computed_value("flood-opacity", "3", "1");
test_computed_value("flood-opacity", "-100%", "0");
test_computed_value("flood-opacity", "50%", "0.5");
test_computed_value("flood-opacity", "300%", "1");
]]></script>
</svg>

Before

Width:  |  Height:  |  Size: 819 B

After

Width:  |  Height:  |  Size: 974 B

Before After
Before After

View file

@ -16,9 +16,9 @@
test_valid_value("flood-opacity", "-1");
test_valid_value("flood-opacity", "0.5");
test_valid_value("flood-opacity", "3");
test_valid_value("flood-opacity", "-100%");
test_valid_value("flood-opacity", "50%");
test_valid_value("flood-opacity", "300%");
test_valid_value("flood-opacity", "-100%", "-1");
test_valid_value("flood-opacity", "50%", "0.5");
test_valid_value("flood-opacity", "300%", "3");
]]></script>
</svg>

Before

Width:  |  Height:  |  Size: 931 B

After

Width:  |  Height:  |  Size: 949 B

Before After
Before After

View file

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<script>
// Test that correct `Sec-Fetch-Site` (and other `Sec-Fetch-...` request
/// headers) are used in navigations triggered by |history.back()|.
function add_test(description, report_host, go_back_host, expectations) {
async_test(t => {
// STEP1: Navigate a new window to report_host/post-to-owner.py
const url_suffix = '/fetch/sec-metadata/resources/post-to-owner.py'
const url = `https://${report_host}${url_suffix}`;
const w = window.open(url, '_blank');
var msg_counter = 0;
window.addEventListener('message', t.step_func(e => {
if (e.source != w)
return;
msg_counter = msg_counter + 1;
if (msg_counter == 1) {
// STEP2: Verify the headers (this is a sanity check that the same
// headers are used here and in STEP5).
assert_header_equals(e.data, expectations);
// STEP3: Go to go_back_host/go-back.html (postponing this via
// step_timeout ensures that go-back.html will get a separate
// history entry - otherwise it might be treated as a client-side
// redirect and we might end up with nowhere to go back to).
t.step_timeout(() => {
const url_suffix = '/fetch/sec-metadata/resources/go-back.html'
const url = `https://${go_back_host}${url_suffix}`;
w.location = url;
});
// STEP4 (elsewhere - inside go-back.html): Call history.back().
} else if (msg_counter == 2) {
// STEP5: Verify the headers (this is the main verification and focus
// of the test).
assert_header_equals(e.data, expectations);
// STEP6: Finish the test.
t.done();
}
}));
}, description);
}
const same_origin_host = "{{host}}:{{ports[https][0]}}";
const same_site_host = "{{hosts[][www]}}:{{ports[https][0]}}";
const cross_site_host = "{{hosts[alt][www]}}:{{ports[https][0]}}";
add_test(
"back to same-origin-initiated navigation",
same_origin_host, // report_host
cross_site_host, // go_back_host
{ "dest": "document",
"site": "same-origin",
"user": "",
"mode": "navigate" });
add_test(
"back to same-site-initiated navigation",
same_site_host, // report_host
cross_site_host, // go_back_host
{ "dest": "document",
"site": "same-site",
"user": "",
"mode": "navigate" });
add_test(
"back to cross-site-initiated navigation",
cross_site_host, // report_host
cross_site_host, // go_back_host
{ "dest": "document",
"site": "cross-site",
"user": "",
"mode": "navigate" });
</script>

View file

@ -0,0 +1,3 @@
<!DOCTYPE html>
<body onload="history.back()">
</body>

View file

@ -1,7 +1,10 @@
import json
def main(request, response):
headers = [("Content-Type", "text/html")]
headers = [
("Content-Type", "text/html"),
("Cache-Control", "no-cache, no-store, must-revalidate")
]
body = """
<!DOCTYPE html>

View file

@ -10,8 +10,8 @@
}
</style>
<img src=broken width=100 height=125>
<img src="/images/green.png" width=100 height=125>
<img src="/images/green.png">
<img src="/images/green.png" width=100 height=125>
<script>
let t = async_test("Image width and height attributes are used to infer aspect-ratio");
function assert_ratio(img, expected) {
@ -21,7 +21,7 @@ function assert_ratio(img, expected) {
onload = t.step_func_done(function() {
let images = document.querySelectorAll("img");
assert_ratio(images[0], 0.8);
assert_ratio(images[1], 0.8);
assert_ratio(images[2], 2.0); // 2.0 is the original aspect ratio of green.png
assert_ratio(images[1], 2.0); // Loaded image's aspect ratio, at least by default, overrides width / height ratio.
});
</script>

View file

@ -6,6 +6,9 @@
<link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<!-- Additional helper script for common checks across event types -->
<script type="text/javascript" src="pointerevent_support.js"></script>
<script>
@ -95,6 +98,7 @@
var innerFrame = document.getElementById('innerFrame');
var square2 = innerFrame.contentDocument.getElementById('square2');
var rectSquare2 = square2.getBoundingClientRect();
var actions_promise;
eventList.forEach(function(eventName) {
on_event(square1, eventName, function (event) {
@ -112,10 +116,32 @@
checkPointerEventAttributes(event, rectSquare2, "Inner frame ");
if (Object.keys(detected_eventTypes).length == eventList.length) {
square2.style.visibility = 'hidden';
test_pointerEvent.done();
// Make sure the test finishes after all the input actions are completed.
actions_promise.then( () => {
test_pointerEvent.done();
});
}
});
});
// Inject mouse and pen inputs.
actions_promise = clickInTarget("mouse", square1).then(function() {
return moveToDocument("mouse");
}).then(function() {
return clickInTarget("mouse", square2);
}).then(function() {
return moveToDocument("mouse");
}).then(function() {
test_pointerEvent.done();
}).then(function() {
return clickInTarget("pen", square1);
}).then(function() {
return moveToDocument("pen");
}).then(function() {
return clickInTarget("pen", square2);
}).then(function() {
return moveToDocument("pen");
});
}
</script>
</head>

View file

@ -6,6 +6,9 @@
<link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<!-- Additional helper script for common checks across event types -->
<script type="text/javascript" src="pointerevent_support.js"></script>
<script>
@ -76,6 +79,7 @@
var innerFrame = document.getElementById('innerFrame');
var square2 = innerFrame.contentDocument.getElementById('square2');
var rectSquare2 = square2.getBoundingClientRect();
var actions_promise;
eventList.forEach(function(eventName) {
on_event(square1, eventName, function (event) {
@ -93,10 +97,18 @@
checkPointerEventAttributes(event, rectSquare2, "Inner frame ");
if (Object.keys(detected_eventTypes).length == eventList.length) {
square2.style.visibility = 'hidden';
test_pointerEvent.done();
// Make sure the test finishes after all the input actions are completed.
actions_promise.then( () => {
test_pointerEvent.done();
});
}
});
});
// Inject touch inputs.
actions_promise = clickInTarget("touch", square1).then(function() {
return clickInTarget("touch", square2);
});
}
</script>
</head>

View file

@ -353,3 +353,11 @@ function pointerHoverInTarget(pointerType, target, direction) {
.pointerMove(3 * x_delta, 3 * y_delta, {origin: target})
.send();
}
function moveToDocument(pointerType) {
var pointerId = pointerType + "Pointer1";
return new test_driver.Actions()
.addPointer(pointerId, pointerType)
.pointerMove(0, 0)
.send();
}

View file

@ -16,6 +16,35 @@ const default_stage_parameters = {
bounds: null
};
function getMatrixFromTransform(transform) {
let x = transform.orientation[0];
let y = transform.orientation[1];
let z = transform.orientation[2];
let w = transform.orientation[3];
let m11 = 1.0 - 2.0 * (y * y + z * z);
let m21 = 2.0 * (x * y + z * w);
let m31 = 2.0 * (x * z - y * w);
let m12 = 2.0 * (x * y - z * w);
let m22 = 1.0 - 2.0 * (x * x + z * z);
let m32 = 2.0 * (y * z + x * w);
let m13 = 2.0 * (x * z + y * w);
let m23 = 2.0 * (y * z - x * w);
let m33 = 1.0 - 2.0 * (x * x + y * y);
let m14 = transform.position[0];
let m24 = transform.position[1];
let m34 = transform.position[2];
// Column-major linearized order is expected.
return [m11, m21, m31, 0,
m12, m22, m32, 0,
m13, m23, m33, 0,
m14, m24, m34, 1];
}
class ChromeXRTest {
constructor() {
this.mockVRService_ = new MockVRService(mojo.frameInterfaces);
@ -178,6 +207,9 @@ class MockRuntime {
this.framesOfReference = {};
this.input_sources_ = [];
this.next_input_source_index_ = 1;
// Initialize DisplayInfo first to set the defaults, then override with
// anything from the deviceInit
if (fakeDeviceInit.supportsImmersive) {
@ -194,8 +226,8 @@ class MockRuntime {
this.setViewerOrigin(fakeDeviceInit.viewerOrigin);
}
if (fakeDeviceInit.localToFloorLevelTransform != null) {
this.setLocalToFloorLevelTransform(fakeDeviceInit.localToFloorLevelTransform);
if (fakeDeviceInit.floorOrigin != null) {
this.setFloorOrigin(fakeDeviceInit.floorOrigin);
}
// This appropriately handles if the coordinates are null
@ -280,7 +312,7 @@ class MockRuntime {
}
}
setLocalToFloorLevelTransform(transform) {
setFloorOrigin(floorOrigin) {
if (!this.displayInfo_.stageParameters) {
this.displayInfo_.stageParameters = default_stage_parameters;
this.displayInfo_.stageParameters.bounds = this.bounds_;
@ -288,14 +320,14 @@ class MockRuntime {
this.displayInfo_.stageParameters.standingTransform = new gfx.mojom.Transform();
this.displayInfo_.stageParameters.standingTransform.matrix =
this.getMatrixFromTransform(transform);
getMatrixFromTransform(floorOrigin);
if (this.sessionClient_.ptr.isBound()) {
this.sessionClient_.onChanged(this.displayInfo_);
}
}
clearLocalToFloorLevelTransform() {
clearFloorOrigin() {
if (this.displayInfo_.stageParameters) {
this.displayInfo_.stageParameters = null;
@ -309,35 +341,16 @@ class MockRuntime {
this.send_pose_reset_ = true;
}
// Helper methods
getMatrixFromTransform(transform) {
let x = transform.orientation[0];
let y = transform.orientation[1];
let z = transform.orientation[2];
let w = transform.orientation[3];
simulateInputSourceConnection(fakeInputSourceInit) {
let index = this.next_input_source_index_;
this.next_input_source_index_++;
let m11 = 1.0 - 2.0 * (y * y + z * z);
let m21 = 2.0 * (x * y + z * w);
let m31 = 2.0 * (x * z - y * w);
let m12 = 2.0 * (x * y - z * w);
let m22 = 1.0 - 2.0 * (x * x + z * z);
let m32 = 2.0 * (y * z + x * w);
let m13 = 2.0 * (x * z + y * w);
let m23 = 2.0 * (y * z - x * w);
let m33 = 1.0 - 2.0 * (x * x + y * y);
let m14 = transform.position[0];
let m24 = transform.position[1];
let m34 = transform.position[2];
// Column-major linearized order is expected.
return [m11, m21, m31, 0,
m12, m22, m32, 0,
m13, m23, m33, 0,
m14, m24, m34, 1];
let source = new MockXRInputSource(fakeInputSourceInit, index, this);
this.input_sources_.push(source);
return source;
}
// Helper methods
getNonImmersiveDisplayInfo() {
let displayInfo = this.getImmersiveDisplayInfo();
@ -418,6 +431,21 @@ class MockRuntime {
};
}
// These methods are intended to be used by MockXRInputSource only.
addInputSource(source) {
let index = this.input_sources_.indexOf(source);
if (index == -1) {
this.input_sources_.push(source);
}
}
removeInputSource(source) {
let index = this.input_sources_.indexOf(source);
if (index >= 0) {
this.input_sources_.splice(index, 1);
}
}
// Mojo function implementations.
// XRFrameDataProvider implementation.
@ -426,6 +454,19 @@ class MockRuntime {
this.pose_.poseIndex++;
this.pose_.poseReset = this.send_pose_reset_;
this.send_pose_reset_ = false;
// Setting the input_state to null tests a slightly different path than
// the browser tests where if the last input source is removed, the device
// code always sends up an empty array, but it's also valid mojom to send
// up a null array.
if (this.input_sources_.length > 0) {
this.pose_.inputState = [];
for (let i = 0; i < this.input_sources_.length; i++) {
this.pose_.inputState.push(this.input_sources_[i].getInputSourceState());
}
} else {
this.pose_.inputState = null;
}
}
// Convert current document time to monotonic time.
@ -516,6 +557,147 @@ class MockRuntime {
};
}
class MockXRInputSource {
constructor(fakeInputSourceInit, id, pairedDevice) {
this.source_id_ = id;
this.pairedDevice_ = pairedDevice;
this.handedness_ = fakeInputSourceInit.handedness;
this.target_ray_mode_ = fakeInputSourceInit.targetRayMode;
this.setPointerOrigin(fakeInputSourceInit.pointerOrigin);
this.primary_input_pressed_ = false;
if (fakeInputSourceInit.selectionStarted != null) {
this.primary_input_pressed_ = fakeInputSourceInit.selectionStarted;
}
this.primary_input_clicked_ = false;
if (fakeInputSourceInit.selectionClicked != null) {
this.primary_input_clicked_ = fakeInputSourceInit.selectionClicked;
}
this.grip_ = null;
if (fakeInputSourceInit.gripOrigin != null) {
this.setGripOrigin(fakeInputSourceInit.gripOrigin);
}
this.gamepad_ = null;
this.emulated_position_ = false;
this.desc_dirty_ = true;
}
// Webxr-test-api
setHandedness(handedness) {
if (this.handedness_ != handedness) {
this.desc_dirty_ = true;
this.handedness_ = handedness;
}
}
setTargetRayMode(targetRayMode) {
if (this.target_ray_mode_ != targetRayMode) {
this.desc_dirty_ = true;
this.target_ray_mode_ = targetRayMode;
}
}
setProfiles(profiles) {
// Profiles are not yet implemented by chromium
}
setGripOrigin(transform, emulatedPosition = false) {
this.grip_ = new gfx.mojom.Transform();
this.grip_.matrix = getMatrixFromTransform(transform);
this.emulated_position_ = emulatedPosition;
}
clearGripOrigin() {
if (this.grip_ != null) {
this.grip_ = null;
this.emulated_position_ = false;
}
}
setPointerOrigin(transform, emulatedPosition = false) {
this.desc_dirty_ = true;
this.pointer_offset_ = new gfx.mojom.Transform();
this.pointer_offset_.matrix = getMatrixFromTransform(transform);
}
disconnect() {
this.pairedDevice_.removeInputSource(this);
}
reconnect() {
this.pairedDevice_.addInputSource(this);
}
startSelection() {
this.primary_input_pressed_ = true;
}
endSelection() {
if (!this.primary_input_pressed_) {
throw new Error("Attempted to end selection which was not started");
}
this.primary_input_pressed_ = false;
this.primary_input_clicked_ = true;
}
simulateSelect() {
this.primary_input_clicked_ = true;
}
// Helpers for Mojom
getInputSourceState() {
let input_state = new device.mojom.XRInputSourceState();
input_state.sourceId = this.source_id_;
input_state.primaryInputPressed = this.primary_input_pressed_;
input_state.primaryInputClicked = this.primary_input_clicked_;
input_state.grip = this.grip_;
input_state.gamepad = this.gamepad_;
if (this.desc_dirty_) {
let input_desc = new device.mojom.XRInputSourceDescription();
input_desc.emulatedPosition = this.emulated_position_;
switch (this.target_ray_mode_) {
case 'gaze':
input_desc.targetRayMode = device.mojom.XRTargetRayMode.GAZING;
break;
case 'tracked-pointer':
input_desc.targetRayMode = device.mojom.XRTargetRayMode.POINTING;
break;
}
switch (this.handedness_) {
case 'left':
input_desc.handedness = device.mojom.XRHandedness.LEFT;
break;
case 'right':
input_desc.handedness = device.mojom.XRHandedness.RIGHT;
break;
default:
input_desc.handedness = device.mojom.XRHandedness.NONE;
break;
}
input_desc.pointerOffset = this.pointer_offset_;
input_state.description = input_desc;
this.desc_dirty_ = false;
}
return input_state;
}
}
// Mojo helper classes
class MockXRPresentationProvider {
constructor() {

View file

@ -16,6 +16,9 @@
test_computed_value("fill-opacity", "-1", "0");
test_computed_value("fill-opacity", "0.5");
test_computed_value("fill-opacity", "3", "1");
test_computed_value("fill-opacity", "-100%", "0");
test_computed_value("fill-opacity", "50%", "0.5");
test_computed_value("fill-opacity", "300%", "1");
]]></script>
</svg>

Before

Width:  |  Height:  |  Size: 790 B

After

Width:  |  Height:  |  Size: 942 B

Before After
Before After

View file

@ -16,9 +16,9 @@
test_valid_value("fill-opacity", "-1");
test_valid_value("fill-opacity", "0.5");
test_valid_value("fill-opacity", "3");
test_valid_value("fill-opacity", "-100%");
test_valid_value("fill-opacity", "50%");
test_valid_value("fill-opacity", "300%");
test_valid_value("fill-opacity", "-100%", "-1");
test_valid_value("fill-opacity", "50%", "0.5");
test_valid_value("fill-opacity", "300%", "3");
]]></script>
</svg>

Before

Width:  |  Height:  |  Size: 907 B

After

Width:  |  Height:  |  Size: 925 B

Before After
Before After

View file

@ -16,6 +16,9 @@
test_computed_value("stroke-opacity", "-1", "0");
test_computed_value("stroke-opacity", "0.5");
test_computed_value("stroke-opacity", "3", "1");
test_computed_value("stroke-opacity", "-100%", "0");
test_computed_value("stroke-opacity", "50%", "0.5");
test_computed_value("stroke-opacity", "300%", "1");
]]></script>
</svg>

Before

Width:  |  Height:  |  Size: 810 B

After

Width:  |  Height:  |  Size: 968 B

Before After
Before After

View file

@ -16,9 +16,9 @@
test_valid_value("stroke-opacity", "-1");
test_valid_value("stroke-opacity", "0.5");
test_valid_value("stroke-opacity", "3");
test_valid_value("stroke-opacity", "-100%");
test_valid_value("stroke-opacity", "50%");
test_valid_value("stroke-opacity", "300%");
test_valid_value("stroke-opacity", "-100%", "-1");
test_valid_value("stroke-opacity", "50%", "0.5");
test_valid_value("stroke-opacity", "300%", "3");
]]></script>
</svg>

Before

Width:  |  Height:  |  Size: 925 B

After

Width:  |  Height:  |  Size: 943 B

Before After
Before After

View file

@ -16,6 +16,9 @@
test_computed_value("stop-opacity", "-1", "0");
test_computed_value("stop-opacity", "0.5");
test_computed_value("stop-opacity", "3", "1");
test_computed_value("stop-opacity", "-100%", "0");
test_computed_value("stop-opacity", "50%", "0.5");
test_computed_value("stop-opacity", "300%", "1");
]]></script>
</svg>

Before

Width:  |  Height:  |  Size: 803 B

After

Width:  |  Height:  |  Size: 955 B

Before After
Before After

View file

@ -16,9 +16,9 @@
test_valid_value("stop-opacity", "-1");
test_valid_value("stop-opacity", "0.5");
test_valid_value("stop-opacity", "3");
test_valid_value("stop-opacity", "-100%");
test_valid_value("stop-opacity", "50%");
test_valid_value("stop-opacity", "300%");
test_valid_value("stop-opacity", "-100%", "-1");
test_valid_value("stop-opacity", "50%", "0.5");
test_valid_value("stop-opacity", "300%", "3");
]]></script>
</svg>

Before

Width:  |  Height:  |  Size: 912 B

After

Width:  |  Height:  |  Size: 930 B

Before After
Before After

View file

@ -95,11 +95,11 @@ class FontInstaller(object):
from ctypes import wintypes
wparam = 0
lparam = 0
SendMessageW = ctypes.windll.user32.SendMessageW
SendMessageW.argtypes = [wintypes.HANDLE, wintypes.UINT,
wintypes.WPARAM, wintypes.LPARAM]
return bool(SendMessageW(hwnd_broadcast, wm_fontchange,
wparam, lparam))
SendNotifyMessageW = ctypes.windll.user32.SendNotifyMessageW
SendNotifyMessageW.argtypes = [wintypes.HANDLE, wintypes.UINT,
wintypes.WPARAM, wintypes.LPARAM]
return bool(SendNotifyMessageW(hwnd_broadcast, wm_fontchange,
wparam, lparam))
def remove_linux_font(self, font_name, _):
if self.created_dir:
@ -129,8 +129,8 @@ class FontInstaller(object):
from ctypes import wintypes
wparam = 0
lparam = 0
SendMessageW = ctypes.windll.user32.SendMessageW
SendMessageW.argtypes = [wintypes.HANDLE, wintypes.UINT,
wintypes.WPARAM, wintypes.LPARAM]
return bool(SendMessageW(hwnd_broadcast, wm_fontchange,
wparam, lparam))
SendNotifyMessageW = ctypes.windll.user32.SendNotifyMessageW
SendNotifyMessageW.argtypes = [wintypes.HANDLE, wintypes.UINT,
wintypes.WPARAM, wintypes.LPARAM]
return bool(SendNotifyMessageW(hwnd_broadcast, wm_fontchange,
wparam, lparam))

View file

@ -35,7 +35,7 @@
`context.sampleRate (${context.sampleRate} Hz)`).beGreaterThan(0);
defaultLatency = context.baseLatency;
should(defaultLatency, 'default baseLatency').beGreaterThan(0);
should(defaultLatency, 'default baseLatency').beGreaterThanOrEqualTo(0);
// Verify that an AudioContext can be created with the expected
// latency types.
@ -130,7 +130,7 @@
should(context1.baseLatency, 'high latency context baseLatency')
.beEqualTo(context2.baseLatency);
should(context1.baseLatency, 'high latency context baseLatency')
.beGreaterThan(interactiveLatency);
.beGreaterThanOrEqualTo(interactiveLatency);
closingPromises.push(context1.close());
closingPromises.push(context2.close());

View file

@ -0,0 +1,54 @@
/**
* @class ActiveProcessingTester
* @extends AudioWorkletProcessor
*
* This processor class sends a message to its AudioWorkletNodew whenever the
* number of channels on the input changes. The message includes the actual
* number of channels, the context time at which this occurred, and whether
* we're done processing or not.
*/
class ActiveProcessingTester extends AudioWorkletProcessor {
constructor(options) {
super(options);
this._lastChannelCount = 0;
// See if user specified a value for test duration.
if (options.hasOwnProperty('processorOptions') &&
options.processorOptions.hasOwnProperty('testDuration')) {
this._testDuration = options.processorOptions.testDuration;
} else {
this._testDuration = 5;
}
// Time at which we'll signal we're done, based on the requested
// |testDuration|
this._endTime = currentTime + this._testDuration;
}
process(inputs, outputs) {
const input = inputs[0];
const output = outputs[0];
const inputChannelCount = input.length;
const isFinished = currentTime > this._endTime;
// Send a message if we're done or the count changed.
if (isFinished || (inputChannelCount != this._lastChannelCount)) {
this.port.postMessage({
channelCount: inputChannelCount,
finished: isFinished,
time: currentTime
});
this._lastChannelCount = inputChannelCount;
}
// Just copy the input to the output for no particular reason.
for (let channel = 0; channel < input.length; ++channel) {
output[channel].set(input[channel]);
}
// When we're finished, this method no longer needs to be called.
return !isFinished;
}
}
registerProcessor('active-processing-tester', ActiveProcessingTester);

View file

@ -6,101 +6,86 @@
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webaudio/resources/audit-util.js"></script>
<script src="/webaudio/resources/audit.js"></script>
</head>
<body>
<script id="layout-test-code">
let audit = Audit.createTaskRunner();
// The sample rate MUST be a power of two to eliminate round-off when
// computing render boundaries but is otherwise arbitrary. And we only new
// a few blocks for rendering to see if things are working.
let sampleRate = 8192;
let renderLength = 10 * RENDER_QUANTUM_FRAMES;
// Number of inputs for the ChannelMergerNode. Pretty arbitrary, but
// should not be 1.
let numberOfInputs = 7;
// How many frames the source should run. Arbitrary but should be more
// than a render quantum.
let sourceDurationFrames = 131;
// Frame at which to connect the source to the merger
let connectFrame = 2 * RENDER_QUANTUM_FRAMES;
// AudioProcessor that counts the number of channels on its single input.
// AudioProcessor that sends a message to its AudioWorkletNode whenver the
// number of channels on its input changes.
let filePath =
'../the-audioworklet-interface/processors/input-count-processor.js';
'../the-audioworklet-interface/processors/active-processing.js';
audit.define(
{
label: 'Test',
description: 'Active processing for ChannelMergerNode'
},
async (task, should) => {
const context = new OfflineAudioContext({
numberOfChannels: numberOfInputs,
length: renderLength,
sampleRate: sampleRate
const audit = Audit.createTaskRunner();
let context;
audit.define('initialize', (task, should) => {
// Create context and load the module
context = new AudioContext();
should(
context.audioWorklet.addModule(filePath),
'AudioWorklet module loading')
.beResolved()
.then(() => task.done());
});
audit.define('test', (task, should) => {
const src = new OscillatorNode(context);
// Number of inputs for the ChannelMergerNode. Pretty arbitrary, but
// should not be 1.
const numberOfInputs = 7;
const merger =
new ChannelMergerNode(context, {numberOfInputs: numberOfInputs});
const testerNode =
new AudioWorkletNode(context, 'active-processing-tester', {
// Use as short a duration as possible to keep the test from
// taking too much time.
processorOptions: {testDuration: .5},
});
// Don't mix the inputs to the destination!
context.destination.channelInterpretation = 'discrete';
// Expected number of output channels from the merger node. We should
// start with the number of inputs, because the source (oscillator) is
// actively processing. When the source stops, the number of channels
// should change to 1.
const expectedValues = [numberOfInputs, 1];
let index = 0;
await context.audioWorklet.addModule(filePath);
testerNode.port.onmessage = event => {
let count = event.data.channelCount;
let finished = event.data.finished;
let src = new ConstantSourceNode(context);
let merger = new ChannelMergerNode(
context, {numberOfInputs: numberOfInputs});
let counter = new AudioWorkletNode(context, 'counter');
// Just to print a message that we created the graph with a
// convolver in it.
should(
() => {
merger.connect(counter).connect(context.destination);
},
`Construction of graph with ChannelMergerNode with ${
merger.numberOfInputs} inputs`)
.notThrow()
// Connect the source now and start it and let it run for
// |sourceDurationFrames| frames.
context.suspend(connectFrame / context.sampleRate)
.then(() => {
src.connect(merger, 0, 0);
src.start();
src.stop(
context.currentTime +
sourceDurationFrames / context.sampleRate);
})
.then(() => context.resume());
const renderedBuffer = await context.startRendering();
// The expected output is something like:
//
// 1, 1, 1,..., 7, 7, 7.,,,, 1, 1, 1
//
// When the merger has no inputs, it's not actively processing
// so it must output mono silence. After connecting a source,
// the number of channels of the output should be the same as
// the number of inputs to the merger. Finally, when the
// source stops, the merger is not actively processing anymore
// and should output mono silence again. For this test, we
// don't care too much how many different values there are.
// There just has to be at least one of each value, in the
// order given.
const output = renderedBuffer.getChannelData(0);
should(output, 'Number of output channels').containValues([
1, numberOfInputs, 1
]);
// If we're finished, end testing.
if (finished) {
// Verify that we got the expected number of changes.
should(index, 'Number of distinct values')
.beEqualTo(expectedValues.length);
task.done();
});
return;
}
if (index < expectedValues.length) {
// Verify that the number of channels matches the expected number of
// channels.
should(count, `Test ${index}: Number of convolver output channels`)
.beEqualTo(expectedValues[index]);
}
++index;
};
// Create the graph and go
src.connect(merger).connect(testerNode).connect(context.destination);
src.start();
// Stop the source after a short time so we can test that the channel
// merger changes to not actively processing and thus produces a single
// channel of silence.
src.stop(context.currentTime + .1);
});
audit.run();
</script>

View file

@ -40,4 +40,6 @@ def test_file_protocol(session, server_config):
response = navigate_to(session, url)
assert_success(response)
if session.url.endswith('/'):
url += '/'
assert session.url == url

View file

@ -29,22 +29,38 @@ const VALID_PROJECTION_MATRIX =
[1, 0, 0, 0, 0, 1, 0, 0, 3, 2, -1, -1, 0, 0, -0.2, 0];
// A valid input grip matrix for when we don't care about specific values
const VALID_GRIP = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 4, 3, 2, 1];
const VALID_GRIP = [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
4, 3, 2, 1];
const VALID_GRIP_TRANSFORM = {
position: [4, 3, 2],
orientation: [0, 0, 0, 1]
};
// A valid input pointer offset for when we don't care about specific values
const VALID_POINTER_OFFSET = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1];
const VALID_POINTER_OFFSET = [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 1, 1];
const VALID_POINTER_TRANSFORM = {
position: [0, 0, 1],
orientation: [0, 0, 0, 1]
};
const VALID_GRIP_WITH_POINTER_OFFSET =
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 4, 3, 3, 1];
// A Valid Local to floor matrix/transform for when we don't care about specific
// values. Note that these should be identical, just different representations.
const VALID_LOCAL_TO_FLOOR_MATRIX = [1, 0, 0, 0,
const VALID_FLOOR_ORIGIN_MATRIX = [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
1, 1.65, -1, 1];
const VALID_LOCAL_TO_FLOOR_TRANSFORM = {
const VALID_FLOOR_ORIGIN = {
position: [1.0, 1.65, -1.0],
orientation: [0, 0, 0, 1]
};
@ -105,3 +121,17 @@ const VALID_NON_IMMERSIVE_DEVICE = {
views: NON_IMMERSIVE_VIEWS,
viewerOrigin: IDENTITY_TRANSFORM
};
const VALID_CONTROLLER = {
handedness: "none",
targetRayMode: "tracked-pointer",
pointerOrigin: VALID_POINTER_TRANSFORM,
profiles: []
};
const RIGHT_CONTROLLER = {
handedness: "right",
targetRayMode: "tracked-pointer",
pointerOrigin: VALID_POINTER_TRANSFORM,
profiles: []
}

View file

@ -14,7 +14,7 @@ let fakeDeviceInitParams = {
supportsImmersive: true,
views: VALID_VIEWS,
viewerOrigin: IDENTITY_TRANSFORM,
localToFloorLevelTransform: VALID_LOCAL_TO_FLOOR_TRANSFORM
floorOrigin: VALID_FLOOR_ORIGIN
};
let testFunction = function(session, fakeDeviceController, t) {

View file

@ -32,7 +32,7 @@ let testFunction = function(session, fakeDeviceController, t) {
assert_greater_than(poseMatrix[13], 1.0);
assert_approx_equals(poseMatrix[14], 0.0, FLOAT_EPSILON);
fakeDeviceController.setLocalToFloorLevelTransform(VALID_LOCAL_TO_FLOOR_TRANSFORM);
fakeDeviceController.setFloorOrigin(VALID_FLOOR_ORIGIN);
// Need to request one animation frame for the new stage transform to
// propagate before we check that it's what we expect.
@ -49,7 +49,7 @@ let testFunction = function(session, fakeDeviceController, t) {
assert_not_equals(pose, null);
let poseMatrix = pose.transform.matrix;
assert_matrix_approx_equals(poseMatrix, VALID_LOCAL_TO_FLOOR_MATRIX, FLOAT_EPSILON);
assert_matrix_approx_equals(poseMatrix, VALID_FLOOR_ORIGIN_MATRIX, FLOAT_EPSILON);
});
// Finished.