mirror of
https://github.com/servo/servo.git
synced 2025-10-04 02:29:12 +01:00
Update web-platform-tests to revision 2c89bbecfab9a69190906abd7610c3bc62303dd4
This commit is contained in:
parent
48bb94ded8
commit
b33912a5ce
87 changed files with 1442 additions and 452 deletions
|
@ -1,14 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child can navigate the parent because the relevant policy belongs to the navigation initiator (in this case the child)");
|
||||
var t = async_test("Test that the child can navigate the parent because the relevant policy belongs to the navigation initiator (in this case the child, which has the policy `navigate-to 'self'`)");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'success');
|
||||
});
|
||||
|
|
|
@ -6,7 +6,14 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child can't navigate the parent because the relevant policy belongs to the navigation initiator (in this case the child which has the policy `navigate-to 'none'`)");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
</script>
|
||||
<iframe srcdoc="<iframe src='support/navigate_parent.sub.html?csp=navigate-to%20%27none%27&report_id={{$id:uuid()}}'>"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27none%27&reportID={{$id}}'></script>
|
||||
</body>
|
||||
</body>
|
||||
|
|
|
@ -12,5 +12,5 @@
|
|||
assert_equals(e.data.result, 'success');
|
||||
});
|
||||
</script>
|
||||
<iframe src="../support/form_action_navigation.sub.html?csp=navigate-to%20%27self%27%3B%20form-action%20%27self%27%3B&action=post_message_to_frame_owner.html">
|
||||
<iframe src="../support/form_action_navigation.sub.html?csp=navigate-to%20%27self%27%3B%20form-action%20%27self%27%3B&action=post_message_to_frame_owner.html&report_id=dummy">
|
||||
</body>
|
|
@ -12,5 +12,5 @@
|
|||
assert_equals(e.data.result, 'success');
|
||||
});
|
||||
</script>
|
||||
<iframe src="../support/form_action_navigation.sub.html?csp=navigate-to%20%27none%27%3B%20form-action%20%27self%27%3B&action=post_message_to_frame_owner.html">
|
||||
<iframe src="../support/form_action_navigation.sub.html?csp=navigate-to%20%27none%27%3B%20form-action%20%27self%27%3B&action=post_message_to_frame_owner.html&report_id=dummy">
|
||||
</body>
|
|
@ -13,5 +13,5 @@
|
|||
assert_equals(e.data.violatedDirective, 'form-action');
|
||||
});
|
||||
</script>
|
||||
<iframe src="../support/form_action_navigation.sub.html?csp=navigate-to%20%27self%27%3B%20form-action%20%27none%27%3B&action=post_message_to_frame_owner.html">
|
||||
<iframe src="../support/form_action_navigation.sub.html?csp=navigate-to%20%27self%27%3B%20form-action%20%27none%27%3B&action=post_message_to_frame_owner.html&report_id=dummy">
|
||||
</body>
|
|
@ -13,5 +13,5 @@
|
|||
assert_equals(e.data.violatedDirective, 'form-action');
|
||||
});
|
||||
</script>
|
||||
<iframe src="../support/form_action_navigation.sub.html?csp=navigate-to%20%27none%27%3B%20form-action%20%27none%27%3B&action=post_message_to_frame_owner.html">
|
||||
<iframe src="../support/form_action_navigation.sub.html?csp=navigate-to%20%27none%27%3B%20form-action%20%27none%27%3B&action=post_message_to_frame_owner.html&report_id=dummy">
|
||||
</body>
|
|
@ -6,6 +6,13 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
</script>
|
||||
<iframe src="support/form_action_navigation.sub.html?csp=navigate-to%20%27none%27&report_id={{$id:uuid()}}&action=post_message_to_frame_owner.html"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27none%27&reportID={{$id}}'></script>
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
</script>
|
||||
<iframe src="support/form_action_navigation.sub.html?csp=navigate-to%20%27self%27&report_id={{$id:uuid()}}&action=http%3A%2F%2F{{domains[www1]}}:{{ports[http][0]}}%2Fcontent-security-policy%2Fnavigate-to%2Fsupport%2Fpost_message_to_frame_owner.html"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27self%27&reportID={{$id}}'></script>
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
</script>
|
||||
|
||||
<iframe src="support/form_action_navigation.sub.html?csp=navigate-to%20%27self%27&report_id={{$id:uuid()}}&action=redirect_to_post_message_to_frame_owner.py%3Flocation%3Dhttp%3A%2F%2F{{domains[www1]}}%3A{{ports[http][0]}}%2Fcontent-security-policy%2Fnavigate-to%2Fsupport%2Fpost_message_to_frame_owner.html"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27self%27&reportID={{$id}}'></script>
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
|
||||
window.open("support/href_location_navigation.sub.html?csp=navigate-to%20%27none%27&report_id={{$id:uuid()}}&target=post_message_to_frame_owner.html", "_blank");
|
||||
</script>
|
||||
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
|
||||
window.open("support/href_location_navigation.sub.html?csp=navigate-to%20%27self%27&report_id={{$id:uuid()}}&target=http%3A%2F%2F{{domains[www1]}}:{{ports[http][0]}}%2Fcontent-security-policy%2Fnavigate-to%2Fsupport%2Fpost_message_to_frame_owner.html", "_blank");
|
||||
</script>
|
||||
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
|
||||
window.open("support/href_location_navigation.sub.html?csp=navigate-to%20%27self%27&report_id={{$id:uuid()}}&target=redirect_to_post_message_to_frame_owner.py%3Flocation%3Dhttp%3A%2F%2F{{domains[www1]}}%3A{{ports[http][0]}}%2Fcontent-security-policy%2Fnavigate-to%2Fsupport%2Fpost_message_to_frame_owner.html", "_blank");
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
|
|
@ -6,7 +6,14 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
</script>
|
||||
<iframe src="support/link_click_navigation.sub.html?csp=navigate-to%20%27none%27&report_id={{$id:uuid()}}&target=post_message_to_frame_owner.html"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27none%27&reportID={{$id}}'></script>
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27self%27&reportID={{$id}}'></script>
|
||||
</body>
|
|
@ -1,7 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
</script>
|
||||
|
||||
<iframe src="support/link_click_navigation.sub.html?csp=navigate-to%20%27self%27&report_id={{$id:uuid()}}&target=http%3A%2F%2F{{domains[www1]}}:{{ports[http][0]}}%2Fcontent-security-policy%2Fnavigate-to%2Fsupport%2Fpost_message_to_frame_owner.html"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27self%27&reportID={{$id}}'></script>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
</script>
|
||||
<iframe src="support/link_click_navigation.sub.html?csp=navigate-to%20%27self%27&report_id={{$id:uuid()}}&target=redirect_to_post_message_to_frame_owner.py%3Flocation%3Dhttp%3A%2F%2F{{domains[www1]}}%3A{{ports[http][0]}}%2Fcontent-security-policy%2Fnavigate-to%2Fsupport%2Fpost_message_to_frame_owner.html"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27self%27&reportID={{$id}}'></script>
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
</script>
|
||||
|
||||
<iframe src="support/meta_refresh_navigation.sub.html?csp=navigate-to%20%27none%27&report_id={{$id:uuid()}}&target=post_message_to_frame_owner.html"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27none%27&reportID={{$id}}'></script>
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
</script>
|
||||
|
||||
<iframe src="support/meta_refresh_navigation.sub.html?csp=navigate-to%20%27self%27&report_id={{$id:uuid()}}&target=http%3A%2F%2F{{domains[www1]}}:{{ports[http][0]}}%2Fcontent-security-policy%2Fnavigate-to%2Fsupport%2Fpost_message_to_frame_owner.html"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27self%27&reportID={{$id}}'></script>
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is not allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
</script>
|
||||
|
||||
<iframe src="support/meta_refresh_navigation.sub.html?csp=navigate-to%20%27self%27&report_id={{$id:uuid()}}&target=redirect_to_post_message_to_frame_owner.py%3Flocation%3Dhttp%3A%2F%2F{{domains[www1]}}%3A{{ports[http][0]}}%2Fcontent-security-policy%2Fnavigate-to%2Fsupport%2Fpost_message_to_frame_owner.html"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20%27self%27&reportID={{$id}}'></script>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the parent can navigate the child because the relevant policy belongs to the navigation initiator (in this case the parent)");
|
||||
var t = async_test("Test that the parent can navigate the child because the relevant policy belongs to the navigation initiator (in this case the parent, which has the policy `navigate-to 'self'`)");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'success');
|
||||
});
|
||||
|
@ -23,4 +23,4 @@
|
|||
i.src = "support/wait_for_navigation.html?csp=navigate-to%20%none%27";
|
||||
document.body.appendChild(i);
|
||||
</script>
|
||||
</body>
|
||||
</body>
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the parent can't navigate the child because the relevant policy belongs to the navigation initiator (in this case the parent, which has the policy `navigate-to support/wait_for_navigation.html;`)");
|
||||
window.onmessage = t.unreached_func("Should not have received a message as the navigation should not have been successful");
|
||||
window.addEventListener('securitypolicyviolation', t.step_func_done(function(e) {
|
||||
assert_equals(e.violatedDirective, 'navigate-to');
|
||||
}));
|
||||
|
||||
var i = document.createElement('iframe');
|
||||
var src_changed = false;
|
||||
i.onload = function() {
|
||||
|
@ -17,5 +23,6 @@
|
|||
i.src = "support/wait_for_navigation.html?csp=navigate-to%20%27self%27";
|
||||
document.body.appendChild(i);
|
||||
</script>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=navigate-to%20support%2Fwait_for_navigation.html'></script>
|
||||
</body>
|
||||
</body>
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- This tests that a navigation initiator that has been replaced by the time
|
||||
the navigation it initiates is blocked, will not receive the SPV event.
|
||||
|
||||
An iframe will navigate another iframe and the navigate itself.
|
||||
The second iframe's navigation response will be delayed by the server but will
|
||||
eventually be blocked by the CSP of the first iframe.
|
||||
By the time this happens the first iframe should be an entirely different
|
||||
document and it should not receive a SPV event -->
|
||||
<script>
|
||||
var t = async_test("Test that no spv event is raised");
|
||||
window.onmessage = t.step_func(function(e) {
|
||||
if (e.data == "end_test") t.done();
|
||||
else assert_unreached("Should not have raised a spv event");
|
||||
});
|
||||
|
||||
var frames_loaded_count = 0;
|
||||
var frame_loaded = function() {
|
||||
if (++frames_loaded_count == 2) {
|
||||
// both child frame have loaded we can start the
|
||||
// test now, send a message to iframe1 so it knows to start
|
||||
document.getElementById('iframe1').contentWindow.postMessage('start_test', '*');
|
||||
}
|
||||
}
|
||||
var i1 = document.createElement('iframe');
|
||||
i1.src = "support/spv-test-iframe1.sub.html?report_id={{$id:uuid()}}";
|
||||
i1.id = "iframe1";
|
||||
i1.name = "iframe1";
|
||||
i1.onload = frame_loaded;
|
||||
document.body.appendChild(i1);
|
||||
|
||||
var i2 = document.createElement('iframe');
|
||||
i2.src = "support/spv-test-iframe2.sub.html";
|
||||
i2.id = "iframe2";
|
||||
i2.name = "iframe2";
|
||||
i2.onload = frame_loaded;
|
||||
document.body.appendChild(i2);
|
||||
</script>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportExists=false&reportID={{$id}}'></script>
|
||||
|
||||
</body>
|
|
@ -0,0 +1,12 @@
|
|||
import time
|
||||
def main(request, response):
|
||||
time.sleep(1)
|
||||
headers = [("Content-Type", "text/html")]
|
||||
return headers, '''
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
DELAYED FRAME
|
||||
</body
|
||||
'''
|
|
@ -6,6 +6,10 @@
|
|||
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener('securitypolicyviolation', function(e) {
|
||||
opener.postMessage({result: 'fail', violatedDirective: e.violatedDirective}, '*');
|
||||
});
|
||||
|
||||
try {
|
||||
location.href = "{{GET[target]}}";
|
||||
} catch(ex) {}
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
<body>
|
||||
<a href="{{GET[target]}}" id="link">dummy link</a>
|
||||
<script>
|
||||
window.addEventListener('securitypolicyviolation', function(e) {
|
||||
top.postMessage({result: 'fail', violatedDirective: e.violatedDirective}, '*');
|
||||
});
|
||||
|
||||
document.getElementById('link').click();
|
||||
</script>
|
||||
</body>
|
|
@ -3,4 +3,4 @@ def main(request, response):
|
|||
if "location" in request.GET:
|
||||
response.headers.set("Location", request.GET["location"])
|
||||
else:
|
||||
response.headers.set("Location", "post_message_to_frame_owner.html")
|
||||
response.headers.set("Location", "post_message_to_frame_owner.html")
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<script>
|
||||
window.onmessage = function(e) {
|
||||
if (e.data == "start_test") {
|
||||
document.getElementById('link').click();
|
||||
location.href = "{{location[server]}}/content-security-policy/navigate-to/support/spv-test-iframe3.sub.html";
|
||||
}
|
||||
}
|
||||
window.addEventListener('securitypolicyviolation', function(e) {
|
||||
top.postMessage({iframe: 'iframe1', violatedDirective: e.violatedDirective}, '*');
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a href="{{location[server]}}/content-security-policy/navigate-to/support/delayed_frame.py" id="link" target="iframe2">dummy link</a>
|
||||
IFRAME 1
|
||||
</body>
|
|
@ -0,0 +1,4 @@
|
|||
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Pragma: no-cache
|
||||
Content-Security-Policy: navigate-to {{location[server]}}/content-security-policy/navigate-to/support/spv-test-iframe3.sub.html 'unsafe-allow-redirects'; report-uri /content-security-policy/support/report.py?op=put&reportID={{GET[report_id]}}
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener('securitypolicyviolation', function(e) {
|
||||
top.postMessage({iframe: 'iframe1', violatedDirective: e.violatedDirective}, '*');
|
||||
});
|
||||
setTimeout(function() {
|
||||
top.postMessage("end_test", "*");
|
||||
}, 4000);
|
||||
</script>
|
||||
IFRAME 2
|
||||
</body>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<script>
|
||||
window.addEventListener('securitypolicyviolation', function(e) {
|
||||
top.postMessage({iframe: 'iframe3', violatedDirective: e.violatedDirective}, '*');
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
IFRAME 3
|
||||
</body>
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'success');
|
||||
});
|
||||
|
||||
// the iframe will navigate to:
|
||||
// [www2]/..../redirect.py (which is not in the navigate-to source list) which will in turn navigate to
|
||||
// [www1]/..../post_message_to_frame_owner.html which is not exactly in
|
||||
// the list but the check should be reduced to an origin check since there has been a redirect.
|
||||
// Because of 'unsafe-allow-redirects' only the second one is checked since the first is a redirect
|
||||
|
||||
var i = document.createElement('iframe');
|
||||
i.src = "../support/link_click_navigation.sub.html" +
|
||||
"?csp=" + encodeURIComponent("navigate-to {{location[scheme]}}://{{domains[www1]}}:{{location[port]}}/some-path/ 'unsafe-allow-redirects'") +
|
||||
"&target=" + encodeURIComponent("{{location[scheme]}}://{{domains[www2]}}:{{location[port]}}/common/redirect.py?location=" +
|
||||
encodeURIComponent("{{location[scheme]}}://{{domains[www1]}}:{{location[port]}}/content-security-policy/navigate-to/support/post_message_to_frame_owner.html"));
|
||||
document.body.appendChild(i);
|
||||
</script>
|
||||
|
||||
</body>
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is allowed");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'success');
|
||||
});
|
||||
|
||||
// the iframe will navigate to:
|
||||
// [www2]/..../redirect.py (which is not in the navigate-to source list) which will in turn navigate to
|
||||
// [www1]/..../post_message_to_frame_owner.html which is in the list
|
||||
// because of 'unsafe-allow-redirects' only the second one is checked since the first is a redirect
|
||||
|
||||
var i = document.createElement('iframe');
|
||||
i.src = "../support/link_click_navigation.sub.html" +
|
||||
"?csp=" + encodeURIComponent("navigate-to {{location[scheme]}}://{{domains[www1]}}:{{location[port]}} 'unsafe-allow-redirects'") +
|
||||
"&target=" + encodeURIComponent("{{location[scheme]}}://{{domains[www2]}}:{{location[port]}}/common/redirect.py?location=" +
|
||||
encodeURIComponent("{{location[scheme]}}://{{domains[www1]}}:{{location[port]}}/content-security-policy/navigate-to/support/post_message_to_frame_owner.html"));
|
||||
document.body.appendChild(i);
|
||||
</script>
|
||||
|
||||
</body>
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test("Test that the child iframe navigation is blocked");
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data.result, 'fail');
|
||||
assert_equals(e.data.violatedDirective, 'navigate-to');
|
||||
});
|
||||
|
||||
// the iframe will navigate to:
|
||||
// [www2]/..../redirect.py (which is not in the navigate-to source list) which will in turn navigate to
|
||||
// [www2]/..../post_message_to_frame_owner.html which is also not in the list
|
||||
// because of 'unsafe-allow-redirects' only the second one is checked since the first is a redirect
|
||||
|
||||
var i = document.createElement('iframe');
|
||||
i.src = "../support/link_click_navigation.sub.html" +
|
||||
"?csp=" + encodeURIComponent("navigate-to {{location[scheme]}}://{{domains[www1]}}:{{location[port]}} 'unsafe-allow-redirects'") +
|
||||
"&target=" + encodeURIComponent("{{location[scheme]}}://{{domains[www2]}}:{{location[port]}}/common/redirect.py?location=" +
|
||||
encodeURIComponent("{{location[scheme]}}://{{domains[www2]}}:{{location[port]}}/content-security-policy/navigate-to/support/post_message_to_frame_owner.html"));
|
||||
document.body.appendChild(i);
|
||||
</script>
|
||||
|
||||
</body>
|
|
@ -27,16 +27,42 @@
|
|||
paint(ctx, geom, styleMap) {
|
||||
ctx.strokeStyle = 'green';
|
||||
for (let prop of props) {
|
||||
let first = styleMap.get(prop.name);
|
||||
let all = styleMap.getAll(prop.name);
|
||||
// Read values using get, getAll and iterator:
|
||||
let valueFromGet = styleMap.get(prop.name);
|
||||
let valueFromGetAll = styleMap.getAll(prop.name);
|
||||
let valueFromIterator = Array.from(styleMap).filter(e => e[0] == prop.name)[0][1];
|
||||
|
||||
// Serialize 'actual'-values for all three cases:
|
||||
let serialize = v => v.constructor.name + '=' + v.toString()
|
||||
let actual = all.map(serialize).join(',');
|
||||
let expected = prop.expected.join(',');
|
||||
let pass = actual === expected
|
||||
&& serialize(first) === prop.expected[0];
|
||||
let actualFromGet = serialize(valueFromGet);
|
||||
let actualFromGetAll = valueFromGetAll.map(serialize).join(',');
|
||||
let actualFromIterator = valueFromIterator.map(serialize).join(',');
|
||||
|
||||
// Create 'expected'-values for all three cases:
|
||||
let expectedForGet = prop.expected[0];
|
||||
let expectedForGetAll = prop.expected.join(',');
|
||||
let expectedForIterator = expectedForGetAll;
|
||||
|
||||
let pass = true;
|
||||
|
||||
// Assertions:
|
||||
if (actualFromGet !== expectedForGet) {
|
||||
debugLog(`FAIL: StylePropertyMap.get: actual: ${actualFromGet} expected: ${expectedForGet}`);
|
||||
pass = false;
|
||||
}
|
||||
if (actualFromGetAll !== expectedForGetAll) {
|
||||
debugLog(`FAIL: StylePropertyMap.getAll: actual: ${actualFromGetAll} expected: ${expectedForGetAll}`);
|
||||
pass = false;
|
||||
}
|
||||
if (actualFromIterator !== expectedForIterator) {
|
||||
debugLog(`FAIL: StylePropertyMap iterator: actual: ${actualFromIterator} expected: ${expectedForIterator}`);
|
||||
pass = false;
|
||||
}
|
||||
|
||||
if (!pass)
|
||||
ctx.strokeStyle = 'red';
|
||||
debugLog(pass ? 'PASS' : 'FAIL', prop.syntax, actual, expected);
|
||||
else
|
||||
debugLog('PASS', prop.syntax, actualFromGetAll, expectedForGetAll);
|
||||
}
|
||||
ctx.lineWidth = 4;
|
||||
ctx.strokeRect(0, 0, geom.width, geom.height);
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Reference for multicolumn under position:sticky should be positioned correctly</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
#scroller {
|
||||
overflow-y: scroll;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#relative {
|
||||
position: relative;
|
||||
top: 100px;
|
||||
margin: 10px;
|
||||
}
|
||||
#child {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: green;
|
||||
}
|
||||
#contents {
|
||||
position: relative;
|
||||
top: 10%;
|
||||
left: 10%;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
background: lightgreen;
|
||||
}
|
||||
#spacer {
|
||||
height: 400px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="scroller">
|
||||
<div id="relative">
|
||||
<div id="child">
|
||||
<div id="contents"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="spacer"></div>
|
||||
</div>
|
||||
|
||||
<div>You should see a light green box above with a dark green border.</div>
|
||||
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
scroller.scrollTop = 100;
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Multicolumn under position:sticky should be positioned correctly</title>
|
||||
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
|
||||
<link rel="match" href="position-sticky-child-multicolumn-ref.html" />
|
||||
<link rel="author" title="Philip Rogers" href="mailto:pdr@chromium.org" />
|
||||
<meta name="assert" content="This test checks that a multicolumn element is positioned relative to a sticky position" />
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
#scroller {
|
||||
overflow-y: scroll;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#sticky {
|
||||
position: sticky;
|
||||
top: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
#multicolumn {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: green;
|
||||
columns: 1;
|
||||
}
|
||||
#contents {
|
||||
margin-left: 10%;
|
||||
margin-top: 10%;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
background: lightgreen;
|
||||
}
|
||||
#spacer {
|
||||
height: 400px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="scroller">
|
||||
<div id="sticky">
|
||||
<div id="multicolumn">
|
||||
<div id="contents"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="spacer"></div>
|
||||
</div>
|
||||
|
||||
<div>You should see a light green box above with a dark green border.</div>
|
||||
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
scroller.scrollTop = 100;
|
||||
});
|
||||
</script>
|
|
@ -33,6 +33,13 @@ function gen_prop(syntax, initialValue) {
|
|||
return name;
|
||||
}
|
||||
|
||||
// Cleans style rules used for testing between every test.
|
||||
add_result_callback(function(){
|
||||
target.attributeStyleMap.clear();
|
||||
// Clears 'div' rule in #style:
|
||||
style.sheet.rules[0].styleMap.clear();
|
||||
});
|
||||
|
||||
// On the target element, verify that computed value of 'name' is an instance
|
||||
// of 'expected' and not an instance of CSSUnparsedValue.
|
||||
//
|
||||
|
@ -594,4 +601,124 @@ test(function(){
|
|||
}
|
||||
}, 'Direct CSSStyleValue instances are tied to their associated property');
|
||||
|
||||
// StylePropertyMapReadOnly iteration
|
||||
|
||||
test(function(){
|
||||
let name = gen_prop('<length>', '10px');
|
||||
let result = Array.from(target.computedStyleMap()).filter(e => e[0] == name)[0];
|
||||
assert_true(typeof(result) !== 'undefined');
|
||||
}, 'Registered property with initial value show up on iteration of computedStyleMap');
|
||||
|
||||
// Verifies that iterating a StylePropertyMap[ReadOnly] yields correctly
|
||||
// typed objects for a given syntax/value.
|
||||
function test_iteration_type_for_property_map(propertyMapName, propertyMap, options) {
|
||||
test(function(){
|
||||
let name = gen_prop(options.syntax, options.initialValue);
|
||||
if (propertyMap instanceof StylePropertyMap) {
|
||||
// Only set the value if the propertyMap is mutable.
|
||||
propertyMap.set(name, options.value);
|
||||
}
|
||||
let result = Array.from(propertyMap).filter(e => e[0] == name)[0];
|
||||
let value = result[1];
|
||||
assert_true(options.expect(value));
|
||||
}, `Iteration on ${propertyMapName} produces correct type for ${options.syntax}`);
|
||||
}
|
||||
|
||||
function test_iteration_type(options) {
|
||||
test_iteration_type_for_property_map('computedStyleMap', target.computedStyleMap(), options);
|
||||
test_iteration_type_for_property_map('attributeStyleMap', target.attributeStyleMap, options);
|
||||
test_iteration_type_for_property_map('styleMap', style.sheet.rules[0].styleMap, options);
|
||||
}
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '*',
|
||||
initialValue: 'none',
|
||||
value: 'thing',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSUnparsedValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<angle>',
|
||||
initialValue: '0deg',
|
||||
value: '42deg',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<custom-ident>',
|
||||
initialValue: 'none',
|
||||
value: 'thing',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSKeywordValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<image>',
|
||||
initialValue: 'url(a)',
|
||||
value: 'url(b)',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSImageValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<integer>',
|
||||
initialValue: '0',
|
||||
value: '100',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<length>',
|
||||
initialValue: '0px',
|
||||
value: '10px',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<number>',
|
||||
initialValue: '0',
|
||||
value: '42',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<percentage>',
|
||||
initialValue: '0%',
|
||||
value: '10%',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<resolution>',
|
||||
initialValue: '0dpi',
|
||||
value: '300dpi',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<time>',
|
||||
initialValue: '0s',
|
||||
value: '10s',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<url>',
|
||||
initialValue: 'url(a)',
|
||||
value: 'url(b)',
|
||||
expect: v => v.length == 1 && v[0].constructor === CSSStyleValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: 'none | thing | THING',
|
||||
initialValue: 'none',
|
||||
value: 'THING',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSKeywordValue,
|
||||
});
|
||||
|
||||
test_iteration_type({
|
||||
syntax: '<angle> | <length>',
|
||||
initialValue: '0deg',
|
||||
value: '10px',
|
||||
expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<style>
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
/* The boxes should stack in the order that I've listed their CSS classes
|
||||
here. The class names' first word (outside/before/inside/after) refers
|
||||
to the boxes' DOM position, and "background"/"midground"/"foreground"
|
||||
refers to their z-index values. */
|
||||
|
||||
.before-IB-background {
|
||||
background: darkmagenta;
|
||||
z-index: -1;
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
}
|
||||
.after-IB-background {
|
||||
background: magenta;
|
||||
z-index: -1;
|
||||
top: 70px;
|
||||
left: 70px;
|
||||
}
|
||||
.outside-span-midground {
|
||||
background: darkkhaki;
|
||||
top: 90px;
|
||||
left: 90px;
|
||||
}
|
||||
.inside-IB-midground {
|
||||
background: khaki;
|
||||
top: 110px;
|
||||
left: 110px;
|
||||
}
|
||||
.before-IB-foreground {
|
||||
background: darkcyan;
|
||||
z-index: 1;
|
||||
top: 130px;
|
||||
left: 130px;
|
||||
}
|
||||
.after-IB-foreground {
|
||||
background: cyan;
|
||||
z-index: 1;
|
||||
top: 150px;
|
||||
left: 150px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- The expectation here is that 'abspos-box' elements will all interact in
|
||||
the same top-level stacking context. That means the box ordering should
|
||||
be (back to front): darkmagenta/magenta/darkkhaki/khaki/darkcyan/cyan,
|
||||
with the boxes stacked (visually) from top-left to bottom-right. -->
|
||||
|
||||
<div class="abspos-box outside-span-midground"></div>
|
||||
|
||||
<!-- Note: this file is identical to the testcase,
|
||||
except for the lack of "contain: layout" on this span. -->
|
||||
<span>
|
||||
<div class="abspos-box before-IB-background"></div>
|
||||
<div class="abspos-box before-IB-foreground"></div>
|
||||
<!-- This unstyled div crates the IB split: -->
|
||||
<div>
|
||||
<div class="abspos-box inside-IB-midground"></div>
|
||||
</div>
|
||||
<div class="abspos-box after-IB-background"></div>
|
||||
<div class="abspos-box after-IB-foreground"></div>
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: 'contain: layout' should have no effect on non-atomic inline
|
||||
(including its block part, if there's a block-in-inline split)</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#containment-layout">
|
||||
<link rel="match" href="contain-layout-ignored-cases-ib-split-001-ref.html">
|
||||
<style>
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
/* The boxes should stack in the order that I've listed their CSS classes
|
||||
here. The class names' first word (outside/before/inside/after) refers
|
||||
to the boxes' DOM position, and "background"/"midground"/"foreground"
|
||||
refers to their z-index values. */
|
||||
|
||||
.before-IB-background {
|
||||
background: darkmagenta;
|
||||
z-index: -1;
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
}
|
||||
.after-IB-background {
|
||||
background: magenta;
|
||||
z-index: -1;
|
||||
top: 70px;
|
||||
left: 70px;
|
||||
}
|
||||
.outside-span-midground {
|
||||
background: darkkhaki;
|
||||
top: 90px;
|
||||
left: 90px;
|
||||
}
|
||||
.inside-IB-midground {
|
||||
background: khaki;
|
||||
top: 110px;
|
||||
left: 110px;
|
||||
}
|
||||
.before-IB-foreground {
|
||||
background: darkcyan;
|
||||
z-index: 1;
|
||||
top: 130px;
|
||||
left: 130px;
|
||||
}
|
||||
.after-IB-foreground {
|
||||
background: cyan;
|
||||
z-index: 1;
|
||||
top: 150px;
|
||||
left: 150px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- The expectation here is that 'abspos-box' elements will all interact in
|
||||
the same top-level stacking context. That means the box ordering should
|
||||
be (back to front): darkmagenta/magenta/darkkhaki/khaki/darkcyan/cyan,
|
||||
with the boxes stacked (visually) from top-left to bottom-right. -->
|
||||
|
||||
<div class="abspos-box outside-span-midground"></div>
|
||||
|
||||
<span style="contain: layout">
|
||||
<div class="abspos-box before-IB-background"></div>
|
||||
<div class="abspos-box before-IB-foreground"></div>
|
||||
<!-- This unstyled div crates the IB split: -->
|
||||
<div>
|
||||
<div class="abspos-box inside-IB-midground"></div>
|
||||
</div>
|
||||
<div class="abspos-box after-IB-background"></div>
|
||||
<div class="abspos-box after-IB-foreground"></div>
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<style>
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
/* The boxes should stack in the order that I've listed their CSS classes
|
||||
here. The class names' first word (outside/before/inside/after) refers
|
||||
to the boxes' DOM position, and "background"/"midground"/"foreground"
|
||||
refers to their z-index values. */
|
||||
|
||||
.before-IB-background {
|
||||
background: darkmagenta;
|
||||
z-index: -1;
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
}
|
||||
.after-IB-background {
|
||||
background: magenta;
|
||||
z-index: -1;
|
||||
top: 70px;
|
||||
left: 70px;
|
||||
}
|
||||
.outside-span-midground {
|
||||
background: darkkhaki;
|
||||
top: 90px;
|
||||
left: 90px;
|
||||
}
|
||||
.inside-IB-midground {
|
||||
background: khaki;
|
||||
top: 110px;
|
||||
left: 110px;
|
||||
}
|
||||
.before-IB-foreground {
|
||||
background: darkcyan;
|
||||
z-index: 1;
|
||||
top: 130px;
|
||||
left: 130px;
|
||||
}
|
||||
.after-IB-foreground {
|
||||
background: cyan;
|
||||
z-index: 1;
|
||||
top: 150px;
|
||||
left: 150px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- The expectation here is that 'abspos-box' elements will all interact in
|
||||
the same top-level stacking context. That means the box ordering should
|
||||
be (back to front): darkmagenta/magenta/darkkhaki/khaki/darkcyan/cyan,
|
||||
with the boxes stacked (visually) from top-left to bottom-right. -->
|
||||
|
||||
<div class="abspos-box outside-span-midground"></div>
|
||||
|
||||
<!-- Note: this file is identical to the testcase,
|
||||
except for the lack of "contain: paint" on this span. -->
|
||||
<span>
|
||||
<div class="abspos-box before-IB-background"></div>
|
||||
<div class="abspos-box before-IB-foreground"></div>
|
||||
<!-- This unstyled div crates the IB split: -->
|
||||
<div>
|
||||
<div class="abspos-box inside-IB-midground"></div>
|
||||
</div>
|
||||
<div class="abspos-box after-IB-background"></div>
|
||||
<div class="abspos-box after-IB-foreground"></div>
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: 'contain: paint' should have no effect on non-atomic inline
|
||||
(including its block part, if there's a block-in-inline split)</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#containment-paint">
|
||||
<link rel="match" href="contain-paint-ignored-cases-ib-split-001-ref.html">
|
||||
<style>
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
/* The boxes should stack in the order that I've listed their CSS classes
|
||||
here. The class names' first word (outside/before/inside/after) refers
|
||||
to the boxes' DOM position, and "background"/"midground"/"foreground"
|
||||
refers to their z-index values. */
|
||||
|
||||
.before-IB-background {
|
||||
background: darkmagenta;
|
||||
z-index: -1;
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
}
|
||||
.after-IB-background {
|
||||
background: magenta;
|
||||
z-index: -1;
|
||||
top: 70px;
|
||||
left: 70px;
|
||||
}
|
||||
.outside-span-midground {
|
||||
background: darkkhaki;
|
||||
top: 90px;
|
||||
left: 90px;
|
||||
}
|
||||
.inside-IB-midground {
|
||||
background: khaki;
|
||||
top: 110px;
|
||||
left: 110px;
|
||||
}
|
||||
.before-IB-foreground {
|
||||
background: darkcyan;
|
||||
z-index: 1;
|
||||
top: 130px;
|
||||
left: 130px;
|
||||
}
|
||||
.after-IB-foreground {
|
||||
background: cyan;
|
||||
z-index: 1;
|
||||
top: 150px;
|
||||
left: 150px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- The expectation here is that 'abspos-box' elements will all interact in
|
||||
the same top-level stacking context. That means the box ordering should
|
||||
be (back to front): darkmagenta/magenta/darkkhaki/khaki/darkcyan/cyan,
|
||||
with the boxes stacked (visually) from top-left to bottom-right. -->
|
||||
|
||||
<div class="abspos-box outside-span-midground"></div>
|
||||
|
||||
<span style="contain: paint">
|
||||
<div class="abspos-box before-IB-background"></div>
|
||||
<div class="abspos-box before-IB-foreground"></div>
|
||||
<!-- This unstyled div crates the IB split: -->
|
||||
<div>
|
||||
<div class="abspos-box inside-IB-midground"></div>
|
||||
</div>
|
||||
<div class="abspos-box after-IB-background"></div>
|
||||
<div class="abspos-box after-IB-foreground"></div>
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
|
@ -26,6 +26,11 @@
|
|||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
.innerContents {
|
||||
color: transparent;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -51,7 +56,7 @@
|
|||
<br>
|
||||
|
||||
<div class="flexBaselineCheck">
|
||||
outside before<div class="basic"></div>outside after
|
||||
outside before<div class="basic innerContents">i</div>outside after
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<div class="contain floatLWidth"><div class="innerContents">inner</div></div>
|
||||
<br>
|
||||
|
||||
<!--CSS Test: A size-contained block element should perform baseline alignment as if the container were empty.-->
|
||||
<!--CSS Test: A size-contained block element should perform baseline alignment regularly.-->
|
||||
<div class="flexBaselineCheck">
|
||||
outside before<div class="contain"><div class="innerContents">inner</div></div>outside after
|
||||
</div>
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
.container {
|
||||
border: 10px solid green;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
.height {
|
||||
height: 30px;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
.container {
|
||||
border: 10px solid green;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
.innerContents {
|
||||
height: 50px;
|
||||
|
|
|
@ -24,11 +24,23 @@
|
|||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
fieldset {
|
||||
border: none;
|
||||
color: transparent;
|
||||
}
|
||||
legend, .innerContents {
|
||||
width: 0;
|
||||
height: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexBaselineCheck">
|
||||
outside before<fieldset class="basic"></fieldset>outside after
|
||||
outside before<fieldset class="basc">
|
||||
<legend>l</legend>
|
||||
<div class="innerContents">i</div>
|
||||
</fieldset>outside after
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: 'contain: size' on fieldset elements should cause them to be baseline-aligned as if they had no contents.</title>
|
||||
<title>CSS Test: 'contain: size' on fieldset elements shouldn't prevent them from being baseline-aligned regularly.</title>
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#containment-size">
|
||||
<link rel="match" href="contain-size-fieldset-002-ref.html">
|
||||
|
@ -24,7 +24,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!--CSS Test: A size-contained fieldset element should perform baseline alignment as if the container were empty.-->
|
||||
<!--CSS Test: A size-contained fieldset element should perform baseline alignment regularly.-->
|
||||
<div class="flexBaselineCheck">
|
||||
outside before<fieldset class="contain">
|
||||
<legend>legend</legend>
|
||||
|
|
|
@ -15,24 +15,29 @@
|
|||
.width-ref {
|
||||
width: 50px;
|
||||
}
|
||||
.innerContents {
|
||||
color: transparent;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="basic"></div>
|
||||
<div class="basic"><div class="innerContents">i</div></div>
|
||||
<br>
|
||||
|
||||
outside before<div class="basic"></div>outside after
|
||||
outside before<div class="basic"><div class="innerContents">i</div></div>outside after
|
||||
<br>
|
||||
|
||||
<div class="basic height-ref"></div>
|
||||
<div class="basic height-ref"><div class="innerContents">i</div></div>
|
||||
<br>
|
||||
|
||||
<div class="basic height-ref"></div>
|
||||
<div class="basic height-ref"><div class="innerContents">i</div></div>
|
||||
<br>
|
||||
|
||||
<div class="basic width-ref"></div>
|
||||
<div class="basic width-ref"><div class="innerContents">i</div></div>
|
||||
<br>
|
||||
|
||||
<div class="basic width-ref"></div>
|
||||
<div class="basic width-ref"><div class="innerContents">i</div></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: 'contain: size' on inline-block elements should cause them to be sized and baseline-aligned as if they had no contents.</title>
|
||||
<title>CSS Test: 'contain: size' on inline-block elements should cause them to be sized as if they had no contents and baseline-aligned regularly.</title>
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#containment-size">
|
||||
<link rel="match" href="contain-size-inline-block-001-ref.html">
|
||||
|
@ -37,7 +37,7 @@
|
|||
<div class="contain"><div class="innerContents">inner</div></div>
|
||||
<br>
|
||||
|
||||
<!--CSS Test: A size-contained inline-block element should perform baseline alignment as if the container were empty.-->
|
||||
<!--CSS Test: A size-contained inline-block element should perform baseline alignment regularly.-->
|
||||
outside before<div class="contain"><div class="innerContents">inner</div></div>outside after
|
||||
<br>
|
||||
|
||||
|
|
|
@ -12,12 +12,17 @@
|
|||
.width-ref {
|
||||
width: 50px;
|
||||
}
|
||||
.innerContents {
|
||||
color: transparent;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
aa<div class="basic"></div>bb
|
||||
aa<div class="basic"><div class="innerContents">i</div></div>bb
|
||||
<br>
|
||||
|
||||
aa<div class="basic width-ref"></div>bb
|
||||
aa<div class="basic width-ref"><div class="innerContents">i</div></div>bb
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: 'contain: size' on inline-flex elements should cause them to be sized and baseline-aligned as if they had no contents.</title>
|
||||
<title>CSS Test: 'contain: size' on inline-flex elements should cause them to be sized as if they had no contents and baseline-aligned regularly.</title>
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#containment-size">
|
||||
<link rel="match" href="contain-size-inline-flex-001-ref.html">
|
||||
|
@ -24,11 +24,11 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!--CSS Test: A size-contained inline-flex element without dimensions should ensure baseline alignment behaviour matches that of an empty object of the same type.-->
|
||||
<!--CSS Test: A size-contained inline-flex element without dimensions should ensure baseline alignment behaves regularly.-->
|
||||
aa<div class="contain"><div class="innerContents">inner</div></div>bb
|
||||
<br>
|
||||
|
||||
<!--CSS Test: A size-contained inline-flex element with specified width should ensure baseline alignment behaviour matches that of an empty object of the same type.-->
|
||||
<!--CSS Test: A size-contained inline-flex element with specified width should ensure baseline alignment behaves regularly.-->
|
||||
aa<div class="contain width"><div class="innerContents">inner</div></div>bb
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
== contain-paint-containing-block-fixed-001.html contain-paint-containing-block-fixed-001-ref.html
|
||||
== contain-paint-formatting-context-float-001.html contain-paint-formatting-context-float-001-ref.html
|
||||
== contain-paint-formatting-context-margin-001.html contain-paint-formatting-context-margin-001-ref.html
|
||||
== contain-paint-ignored-cases-ib-split-001.html contain-paint-ignored-cases-ib-split-001-ref.html
|
||||
== contain-paint-ignored-cases-internal-table-001a.html contain-paint-ignored-cases-internal-table-001-ref.html
|
||||
== contain-paint-ignored-cases-internal-table-001b.html contain-paint-ignored-cases-internal-table-001-ref.html
|
||||
== contain-paint-ignored-cases-no-principal-box-001.html contain-paint-ignored-cases-no-principal-box-001-ref.html
|
||||
|
@ -35,6 +36,7 @@
|
|||
== contain-layout-formatting-context-margin-001.html contain-layout-formatting-context-margin-001-ref.html
|
||||
== contain-layout-containing-block-fixed-001.html contain-paint-containing-block-fixed-001-ref.html
|
||||
== contain-layout-containing-block-absolute-001.html contain-paint-containing-block-absolute-001-ref.html
|
||||
== contain-layout-ignored-cases-ib-split-001.html contain-layout-ignored-cases-ib-split-001-ref.html
|
||||
== contain-layout-ignored-cases-no-principal-box-001.html contain-paint-ignored-cases-no-principal-box-001-ref.html
|
||||
== contain-layout-ignored-cases-no-principal-box-002.html contain-layout-ignored-cases-no-principal-box-002-ref.html
|
||||
== contain-layout-ignored-cases-no-principal-box-003.html contain-layout-ignored-cases-no-principal-box-003-ref.html
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script src=/common/media.js></script>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/resources/testdriver.js></script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script src=/common/media.js></script>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/resources/testdriver.js></script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script src=/common/media.js></script>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/resources/testdriver.js></script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script src=/common/media.js></script>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/resources/testdriver.js></script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script src=/common/media.js></script>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/resources/testdriver.js></script>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src='/common/media.js'></script>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
|
@ -21,7 +22,7 @@ const check_report_format = (reports, observer) => {
|
|||
|
||||
const loadVideo = () => new Promise(resolve => {
|
||||
const video = document.createElement('video');
|
||||
video.src = '/media/movie_5.ogv';
|
||||
video.src = getVideoURI('/media/movie_5');
|
||||
video.addEventListener('loadedmetadata', () => {
|
||||
resolve(video);
|
||||
}, { once: true });
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<script src=/common/media.js></script>
|
||||
<script src=/feature-policy/resources/picture-in-picture.js></script>
|
||||
<script>
|
||||
'use strict';
|
||||
|
|
|
@ -4,7 +4,7 @@ function isPictureInPictureAllowed() {
|
|||
|
||||
return new Promise(resolve => {
|
||||
let video = document.createElement('video');
|
||||
video.src = '/media/movie_5.ogv';
|
||||
video.src = getVideoURI('/media/movie_5');
|
||||
video.onloadedmetadata = () => {
|
||||
video.requestPictureInPicture()
|
||||
.then(() => resolve(document.pictureInPictureEnabled))
|
||||
|
|
|
@ -28,15 +28,26 @@ promise_test(async t => {
|
|||
|
||||
const stream = await timeout(navigator.mediaDevices.getUserMedia({video: true}), 10000, "getUserMedia timeout");
|
||||
t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
|
||||
vid.defaultPlaybackRate = 0.4;
|
||||
vid.playbackRate = 0.4;
|
||||
vid.preload = "metadata";
|
||||
vid.srcObject = stream;
|
||||
vid.onratechange = t.unreached_func('ratechange event must not be fired');
|
||||
vid.play();
|
||||
assert_true(!vid.seeking, "A MediaStream is not seekable");
|
||||
assert_equals(vid.seekable.length, 0, "A MediaStream is not seekable");
|
||||
assert_equals(vid.defaultPlaybackRate, 1, "playback rate is always 1");
|
||||
vid.defaultPlaybackRate = 0.5;
|
||||
assert_equals(vid.defaultPlaybackRate, 1, "Setting defaultPlaybackRate must be ignored");
|
||||
assert_equals(vid.playbackRate, 1, "playback rate is always 1");
|
||||
vid.playbackRate = 0.5;
|
||||
assert_equals(vid.playbackRate, 1, "Setting playbackRate must be ignored");
|
||||
assert_equals(vid.buffered.length, 0, "A MediaStream cannot be preloaded. Therefore, there is no buffered timeranges");
|
||||
assert_equals(vid.readyState, vid.HAVE_NOTHING, "readyState is HAVE_NOTHING initially");
|
||||
assert_equals(vid.duration, NaN, "A MediaStream does not have any duration initially.");
|
||||
assert_equals(vid.preload, "none", "preload must always be none");
|
||||
vid.preload = "metadata";
|
||||
assert_equals(vid.preload, "none", "Setting preload must be ignored");
|
||||
|
||||
const haveLoadedData = new Promise(r => vid.addEventListener("loadeddata", r, {once: true}));
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test disable Picture-in-Picture</title>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
|
@ -33,12 +34,11 @@ promise_test(async t => {
|
|||
|
||||
promise_test(async t => {
|
||||
const video = await loadVideo();
|
||||
return test_driver.bless('request Picture-in-Picture', async () => {
|
||||
const promise = video.requestPictureInPicture();
|
||||
video.disablePictureInPicture = true;
|
||||
await promise_rejects(t, 'InvalidStateError', promise);
|
||||
assert_equals(document.pictureInPictureElement, null);
|
||||
});
|
||||
await test_driver.bless('request Picture-in-Picture');
|
||||
const promise = video.requestPictureInPicture();
|
||||
video.disablePictureInPicture = true;
|
||||
await promise_rejects(t, 'InvalidStateError', promise);
|
||||
assert_equals(document.pictureInPictureElement, null);
|
||||
}, 'Request Picture-in-Picture rejects if disablePictureInPicture becomes ' +
|
||||
'true before promise resolves.');
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test enterpictureinpicture event</title>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test exit Picture-in-Picture</title>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// META: script=/common/media.js
|
||||
// META: script=/resources/WebIDLParser.js
|
||||
// META: script=/resources/idlharness.js
|
||||
// META: script=/resources/testdriver.js
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test leavepictureinpicture event</title>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test Picture-in-Picture element</title>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test Picture-in-Picture window</title>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test request Picture-in-Picture on two videos</title>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
|
@ -10,12 +11,9 @@
|
|||
promise_test(async t => {
|
||||
const video1 = await loadVideo();
|
||||
const video2 = await loadVideo();
|
||||
return test_driver.bless(
|
||||
'request Picture-in-Picture',
|
||||
async () => {
|
||||
video1.requestPictureInPicture();
|
||||
promise_rejects(t, 'NotAllowedError', video2.requestPictureInPicture());
|
||||
}
|
||||
);
|
||||
await test_driver.bless('request Picture-in-Picture');
|
||||
const promise = video1.requestPictureInPicture();
|
||||
await promise_rejects(t, 'NotAllowedError', video2.requestPictureInPicture());
|
||||
return promise;
|
||||
}, 'request Picture-in-Picture consumes user gesture');
|
||||
</script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test request Picture-in-Picture</title>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
|
@ -21,7 +22,7 @@ promise_test(t => {
|
|||
promise_test(async t => {
|
||||
const video = document.createElement('video');
|
||||
await new Promise(resolve => {
|
||||
video.src = '/media/sound_5.oga';
|
||||
video.src = getAudioURI('/media/sound_5');
|
||||
video.onloadeddata = resolve;
|
||||
}).then(() => {
|
||||
return promise_rejects(t, 'InvalidStateError',
|
||||
|
|
|
@ -8,15 +8,14 @@ function loadVideo(activeDocument, sourceUrl) {
|
|||
return new Promise((resolve, reject) => {
|
||||
const document = activeDocument || window.document;
|
||||
const video = document.createElement('video');
|
||||
video.src = sourceUrl || '/media/movie_5.ogv';
|
||||
video.src = sourceUrl || getVideoURI('/media/movie_5');
|
||||
video.onloadedmetadata = () => { resolve(video); };
|
||||
video.onerror = error => { reject(error); };
|
||||
});
|
||||
}
|
||||
|
||||
// Calls requestPictureInPicture() in a context that's 'allowed to request PiP'.
|
||||
function requestPictureInPictureWithTrustedClick(videoElement) {
|
||||
return test_driver.bless(
|
||||
'request Picture-in-Picture',
|
||||
() => videoElement.requestPictureInPicture());
|
||||
async function requestPictureInPictureWithTrustedClick(videoElement) {
|
||||
await test_driver.bless('request Picture-in-Picture');
|
||||
return videoElement.requestPictureInPicture();
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test for pictureInPictureElement adjustment for Shadow DOM</title>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="resources/picture-in-picture-helpers.js"></script>
|
||||
<script src='../shadow-dom/resources/shadow-dom.js'></script>
|
||||
<script src="../shadow-dom/resources/shadow-dom.js"></script>
|
||||
<body>
|
||||
<div id='host'>
|
||||
<template data-mode='open' id='root'>
|
||||
|
@ -45,7 +46,7 @@ promise_test(async t => {
|
|||
assert_equals(ids.root5.pictureInPictureElement, null);
|
||||
|
||||
await new Promise(resolve => {
|
||||
ids.video.src = '/media/movie_5.ogv';
|
||||
ids.video.src = getVideoURI('/media/movie_5');
|
||||
ids.video.onloadeddata = resolve;
|
||||
})
|
||||
.then(() => requestPictureInPictureWithTrustedClick(ids.video))
|
||||
|
@ -58,4 +59,4 @@ promise_test(async t => {
|
|||
assert_equals(ids.root5.pictureInPictureElement, null);
|
||||
})
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<!doctype html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<script>
|
||||
promise_test(async (t) => {
|
||||
const SCOPE = 'resources/empty.html';
|
||||
const SCRIPT = 'resources/fetch-rewrite-worker.js';
|
||||
const host_info = get_host_info();
|
||||
const REMOTE_ORIGIN = host_info.HTTPS_REMOTE_ORIGIN;
|
||||
|
||||
const reg = await service_worker_unregister_and_register(t, SCRIPT, SCOPE);
|
||||
await wait_for_state(t, reg.installing, 'activated');
|
||||
const frame = await with_iframe(SCOPE);
|
||||
|
||||
const doc = frame.contentDocument;
|
||||
const win = frame.contentWindow;
|
||||
|
||||
const context = new win.AudioContext();
|
||||
try {
|
||||
context.suspend();
|
||||
const audio = doc.createElement('audio');
|
||||
audio.autoplay = true;
|
||||
const source = context.createMediaElementSource(audio);
|
||||
const spn = context.createScriptProcessor(16384, 1, 1);
|
||||
source.connect(spn).connect(context.destination);
|
||||
const url = `${REMOTE_ORIGIN}/webaudio/resources/sin_440Hz_-6dBFS_1s.wav`;
|
||||
audio.src = '/test?url=' + encodeURIComponent(url);
|
||||
doc.body.appendChild(audio);
|
||||
|
||||
await new Promise((resolve) => {
|
||||
audio.addEventListener('playing', resolve);
|
||||
});
|
||||
await context.resume();
|
||||
const event = await new Promise((resolve) => {
|
||||
spn.addEventListener('audioprocess', resolve);
|
||||
});
|
||||
const data = event.inputBuffer.getChannelData(0);
|
||||
for (const e of data) {
|
||||
assert_equals(e, 0);
|
||||
}
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
}, 'Verify CORS XHR of fetch() in a Service Worker');
|
||||
</script>
|
|
@ -693,7 +693,16 @@ class TestRunnerManager(threading.Thread):
|
|||
# This might leak a file handle from the queue
|
||||
self.logger.warning("Forcibly terminating runner process")
|
||||
self.test_runner_proc.terminate()
|
||||
self.test_runner_proc.join(10)
|
||||
|
||||
# Multiprocessing queues are backed by operating system pipes. If
|
||||
# the pipe in the child process had buffered data at the time of
|
||||
# forced termination, the queue is no longer in a usable state
|
||||
# (subsequent attempts to retrieve items may block indefinitely).
|
||||
# Discard the potentially-corrupted queue and create a new one.
|
||||
self.command_queue.close()
|
||||
self.command_queue = Queue()
|
||||
self.remote_queue.close()
|
||||
self.remote_queue = Queue()
|
||||
else:
|
||||
self.logger.debug("Runner process exited with code %i" % self.test_runner_proc.exitcode)
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
Test passing SharedArrayBuffer to an AudioWorklet
|
||||
</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/webaudio/resources/audit.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script id="layout-test-code">
|
||||
let audit = Audit.createTaskRunner();
|
||||
|
||||
let context = new AudioContext();
|
||||
|
||||
let filePath = 'processors/sharedarraybuffer-processor.js';
|
||||
|
||||
if (window.SharedArrayBuffer) {
|
||||
audit.define(
|
||||
'Test postMessage from AudioWorkletProcessor to AudioWorkletNode',
|
||||
(task, should) => {
|
||||
let workletNode =
|
||||
new AudioWorkletNode(context, 'sharedarraybuffer-processor');
|
||||
|
||||
// After it is created, the worklet will send a new
|
||||
// SharedArrayBuffer to the main thread.
|
||||
//
|
||||
// The worklet will then wait to receive a message from the main
|
||||
// thread.
|
||||
//
|
||||
// When it receives the message, it will check whether it is a
|
||||
// SharedArrayBuffer, and send this information back to the main
|
||||
// thread.
|
||||
|
||||
workletNode.port.onmessage = (event) => {
|
||||
let data = event.data;
|
||||
switch (data.state) {
|
||||
case 'created':
|
||||
should(
|
||||
data.sab instanceof SharedArrayBuffer,
|
||||
'event.data.sab from worklet is an instance of SharedArrayBuffer')
|
||||
.beTrue();
|
||||
|
||||
// Send a SharedArrayBuffer back to the worklet.
|
||||
let sab = new SharedArrayBuffer(8);
|
||||
workletNode.port.postMessage(sab);
|
||||
break;
|
||||
|
||||
case 'received message':
|
||||
should(data.isSab, 'event.data from main thread is an instance of SharedArrayBuffer')
|
||||
.beTrue();
|
||||
task.done();
|
||||
break;
|
||||
|
||||
default:
|
||||
should(false,
|
||||
`Got unexpected message from worklet: ${data.state}`)
|
||||
.beTrue();
|
||||
task.done();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
workletNode.port.onmessageerror = (event) => {
|
||||
should(false, 'Got messageerror from worklet').beTrue();
|
||||
task.done();
|
||||
};
|
||||
});
|
||||
} else {
|
||||
// NOTE(binji): SharedArrayBuffer is only enabled where we have site
|
||||
// isolation.
|
||||
audit.define('Skipping test because SharedArrayBuffer is not defined',
|
||||
(task, should) => {
|
||||
task.done();
|
||||
});
|
||||
}
|
||||
|
||||
context.audioWorklet.addModule(filePath).then(() => {
|
||||
audit.run();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* @class SharedArrayBufferProcessor
|
||||
* @extends AudioWorkletProcessor
|
||||
*
|
||||
* This processor class demonstrates passing SharedArrayBuffers to and from
|
||||
* workers.
|
||||
*/
|
||||
class SharedArrayBufferProcessor extends AudioWorkletProcessor {
|
||||
constructor() {
|
||||
super();
|
||||
this.port.onmessage = this.handleMessage.bind(this);
|
||||
this.port.onmessageerror = this.handleMessageError.bind(this);
|
||||
let sab = new SharedArrayBuffer(8);
|
||||
this.port.postMessage({state: 'created', sab});
|
||||
}
|
||||
|
||||
handleMessage(event) {
|
||||
this.port.postMessage({
|
||||
state: 'received message',
|
||||
isSab: event.data instanceof SharedArrayBuffer
|
||||
});
|
||||
}
|
||||
|
||||
handleMessageError(event) {
|
||||
this.port.postMessage({
|
||||
state: 'received messageerror'
|
||||
});
|
||||
}
|
||||
|
||||
process() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
registerProcessor('sharedarraybuffer-processor', SharedArrayBufferProcessor);
|
Loading…
Add table
Add a link
Reference in a new issue