Update web-platform-tests to revision 687b6cba3385c4c2ca85f44fe072961e651621b5

This commit is contained in:
WPT Sync Bot 2019-04-08 21:47:49 -04:00
parent cd579f6746
commit 1a4444a557
45 changed files with 594 additions and 259 deletions

View file

@ -130291,6 +130291,18 @@
{} {}
] ]
], ],
"css/css-multicol/multicol-overflow-clip-positioned.html": [
[
"css/css-multicol/multicol-overflow-clip-positioned.html",
[
[
"/css/css-multicol/multicol-overflow-clip-positioned-ref.html",
"=="
]
],
{}
]
],
"css/css-multicol/multicol-overflowing-001.xht": [ "css/css-multicol/multicol-overflowing-001.xht": [
[ [
"css/css-multicol/multicol-overflowing-001.xht", "css/css-multicol/multicol-overflowing-001.xht",
@ -201726,6 +201738,18 @@
], ],
{} {}
] ]
],
"xhtml/adopt-while-parsing-001.html": [
[
"xhtml/adopt-while-parsing-001.html",
[
[
"/xhtml/adopt-while-parsing-001-ref.html",
"=="
]
],
{}
]
] ]
}, },
"reftest_node": { "reftest_node": {
@ -270360,6 +270384,11 @@
{} {}
] ]
], ],
"css/css-multicol/multicol-overflow-clip-positioned-ref.html": [
[
{}
]
],
"css/css-multicol/multicol-overflowing-001-ref.xht": [ "css/css-multicol/multicol-overflowing-001-ref.xht": [
[ [
{} {}
@ -292215,6 +292244,31 @@
{} {}
] ]
], ],
"feature-policy/parameters/feature-parameters-inf.html": [
[
{}
]
],
"feature-policy/parameters/feature-parameters-inf.html.headers": [
[
{}
]
],
"feature-policy/parameters/feature-parameters.html.headers": [
[
{}
]
],
"feature-policy/parameters/resources/feature-parameters-frame.html": [
[
{}
]
],
"feature-policy/parameters/resources/sample-1.png": [
[
{}
]
],
"feature-policy/payment-allowed-by-feature-policy.https.sub.html.headers": [ "feature-policy/payment-allowed-by-feature-policy.https.sub.html.headers": [
[ [
{} {}
@ -308850,6 +308904,11 @@
{} {}
] ]
], ],
"portals/resources/portal-create-orphaned.html": [
[
{}
]
],
"portals/resources/portal-cross-origin.sub.html": [ "portals/resources/portal-cross-origin.sub.html": [
[ [
{} {}
@ -326485,21 +326544,6 @@
{} {}
] ]
], ],
"upgrade-insecure-requests/support/pass.png": [
[
{}
]
],
"upgrade-insecure-requests/support/pass.png.headers": [
[
{}
]
],
"upgrade-insecure-requests/support/post-origin-to-parent.html": [
[
{}
]
],
"upgrade-insecure-requests/support/redirect-cors.py": [ "upgrade-insecure-requests/support/redirect-cors.py": [
[ [
{} {}
@ -326510,16 +326554,6 @@
{} {}
] ]
], ],
"upgrade-insecure-requests/support/worker.js": [
[
{}
]
],
"upgrade-insecure-requests/support/worker.js.headers": [
[
{}
]
],
"url/META.yml": [ "url/META.yml": [
[ [
{} {}
@ -331954,6 +331988,16 @@
[ [
{} {}
] ]
],
"xhtml/adopt-while-parsing-001-ref.html": [
[
{}
]
],
"xhtml/adopt-while-parsing.xhtml": [
[
{}
]
] ]
}, },
"testharness": { "testharness": {
@ -380797,6 +380841,18 @@
} }
] ]
], ],
"feature-policy/parameters/feature-parameters-with-frames.html": [
[
"feature-policy/parameters/feature-parameters-with-frames.html",
{}
]
],
"feature-policy/parameters/feature-parameters.html": [
[
"feature-policy/parameters/feature-parameters.html",
{}
]
],
"feature-policy/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html": [ "feature-policy/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html": [
[ [
"feature-policy/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html", "feature-policy/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html",
@ -416046,6 +416102,12 @@
{} {}
] ]
], ],
"portals/portals-create-orphaned.html": [
[
"portals/portals-create-orphaned.html",
{}
]
],
"portals/portals-cross-origin-load.sub.html": [ "portals/portals-cross-origin-load.sub.html": [
[ [
"portals/portals-cross-origin-load.sub.html", "portals/portals-cross-origin-load.sub.html",
@ -485890,7 +485952,7 @@
"support" "support"
], ],
"common/security-features/resources/common.js": [ "common/security-features/resources/common.js": [
"678d2a0d8fa7001e5dcd2204b6f2b548d0b913c1", "8b9bd0d0372a0814a6e5785abc64a26763d35edc",
"support" "support"
], ],
"common/security-features/subresource/__init__.py": [ "common/security-features/subresource/__init__.py": [
@ -485914,7 +485976,7 @@
"support" "support"
], ],
"common/security-features/subresource/image.py": [ "common/security-features/subresource/image.py": [
"d132889412372e7f764fe98159897fcacc009bbb", "42ebc0767bbea9d3d50f4a3f23c7863748e6908d",
"support" "support"
], ],
"common/security-features/subresource/script.py": [ "common/security-features/subresource/script.py": [
@ -505870,7 +505932,7 @@
"testharness" "testharness"
], ],
"content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html": [ "content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html": [
"692db02b6fc5392b08cfcfeb98b88553cb6f72bd", "bf655a2e1b9512065fe19bd0e8f099b70c13eb5c",
"testharness" "testharness"
], ],
"content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html.headers": [ "content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html.headers": [
@ -594141,6 +594203,14 @@
"3fa9ed51fbb0141534d82e62b0f14fd6cf2efa13", "3fa9ed51fbb0141534d82e62b0f14fd6cf2efa13",
"reftest" "reftest"
], ],
"css/css-multicol/multicol-overflow-clip-positioned-ref.html": [
"58f1d57bc39beed37d14eea0dc9c1cbc47c33717",
"support"
],
"css/css-multicol/multicol-overflow-clip-positioned.html": [
"184bfc7f18dadbade32192b777c6b21f345882af",
"reftest"
],
"css/css-multicol/multicol-overflowing-001-ref.xht": [ "css/css-multicol/multicol-overflowing-001-ref.xht": [
"d3a6c6e03c58c17f0dfa4f2e6d9b945e352216af", "d3a6c6e03c58c17f0dfa4f2e6d9b945e352216af",
"support" "support"
@ -626446,7 +626516,7 @@
"testharness" "testharness"
], ],
"css/cssom-view/scrollintoview.html": [ "css/cssom-view/scrollintoview.html": [
"c69025b4943accd4c0b34e74dbd7862af2521849", "584ab4b60329d7cd1081edac93a375b7069634ea",
"testharness" "testharness"
], ],
"css/cssom-view/support/1x1-green.png": [ "css/cssom-view/support/1x1-green.png": [
@ -645722,11 +645792,11 @@
"support" "support"
], ],
"feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html": [ "feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html": [
"e277d9e8ad42307e9ab47038b534f8fc974c492b", "a9e2b295d5034d37c518cf0609590ec3065df70c",
"testharness" "testharness"
], ],
"feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html": [ "feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html": [
"ebed07bab5abdd15dc95a84eddd03bc4907386be", "3a2f469b25046629113cb2b97df09fa1e56e849e",
"testharness" "testharness"
], ],
"feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html.headers": [ "feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html.headers": [
@ -645997,6 +646067,34 @@
"33bbe3c14ffe28d961cc4c71c0b367028ff8d2df", "33bbe3c14ffe28d961cc4c71c0b367028ff8d2df",
"testharness" "testharness"
], ],
"feature-policy/parameters/feature-parameters-inf.html": [
"db21427c8ed9f3c2f8e8b8ba9d91d4fd230fc2ff",
"support"
],
"feature-policy/parameters/feature-parameters-inf.html.headers": [
"1ec003431b3f090dbb596f6973b84f81de27ace0",
"support"
],
"feature-policy/parameters/feature-parameters-with-frames.html": [
"de0a3ab1e3963e3e7c8da1e6bec35d454b1a9fdb",
"testharness"
],
"feature-policy/parameters/feature-parameters.html": [
"9830f93eb4dcac9aaa2dfe6d209c452df5f94701",
"testharness"
],
"feature-policy/parameters/feature-parameters.html.headers": [
"b4fa805c5696ab5ef8171508aeccf200e9d95df3",
"support"
],
"feature-policy/parameters/resources/feature-parameters-frame.html": [
"4f01f85795da8114e762cb0ddc271cefdd02da1f",
"support"
],
"feature-policy/parameters/resources/sample-1.png": [
"92901925c6082b7fb01fade09f87356308218a47",
"support"
],
"feature-policy/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html": [ "feature-policy/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html": [
"daa2aa182daed73bd51bf32cf7981a805e3956c8", "daa2aa182daed73bd51bf32cf7981a805e3956c8",
"testharness" "testharness"
@ -646410,7 +646508,7 @@
"support" "support"
], ],
"feature-policy/resources/featurepolicy.js": [ "feature-policy/resources/featurepolicy.js": [
"e2577f35c3fb53abda3934274c3e6a281ba617d9", "744c4c62069508061567d8ac758920beab8e1335",
"support" "support"
], ],
"feature-policy/resources/picture-in-picture.js": [ "feature-policy/resources/picture-in-picture.js": [
@ -683037,6 +683135,10 @@
"63a6d75dc42ef552c237a5c092e3a8c702bd27a8", "63a6d75dc42ef552c237a5c092e3a8c702bd27a8",
"testharness" "testharness"
], ],
"portals/portals-create-orphaned.html": [
"903186ff6c69b12f888286cd8dbca8cbfa0568dc",
"testharness"
],
"portals/portals-cross-origin-load.sub.html": [ "portals/portals-cross-origin-load.sub.html": [
"f860ac54dc9dc6578fa1a66c25da70bc3262d995", "f860ac54dc9dc6578fa1a66c25da70bc3262d995",
"testharness" "testharness"
@ -683093,6 +683195,10 @@
"dc161c0e0b82da493aba1cb8fbefb4262b203a48", "dc161c0e0b82da493aba1cb8fbefb4262b203a48",
"support" "support"
], ],
"portals/resources/portal-create-orphaned.html": [
"89b927f649b9db28fdbbb1ed8d023c33203595ce",
"support"
],
"portals/resources/portal-cross-origin.sub.html": [ "portals/resources/portal-cross-origin.sub.html": [
"145ab5a2d21295f615d3ecd5d36f9e3034a4202a", "145ab5a2d21295f615d3ecd5d36f9e3034a4202a",
"support" "support"
@ -710798,19 +710904,7 @@
"testharness" "testharness"
], ],
"upgrade-insecure-requests/support/generate.py": [ "upgrade-insecure-requests/support/generate.py": [
"8c8cca21273013693d94ecdae3bc401f08dc1241", "4fb7078e7709bd1541df8cc61bbcfa449bc14b37",
"support"
],
"upgrade-insecure-requests/support/pass.png": [
"2fa1e0ac0663a65deae6602621521cc2844b93de",
"support"
],
"upgrade-insecure-requests/support/pass.png.headers": [
"cb762eff806849df46dc758ef7b98b63f27f54c9",
"support"
],
"upgrade-insecure-requests/support/post-origin-to-parent.html": [
"4f596ef4dce2b8a76e92b4d7a267547ee28c43a7",
"support" "support"
], ],
"upgrade-insecure-requests/support/redirect-cors.py": [ "upgrade-insecure-requests/support/redirect-cors.py": [
@ -710818,15 +710912,7 @@
"support" "support"
], ],
"upgrade-insecure-requests/support/testharness-helper.sub.js": [ "upgrade-insecure-requests/support/testharness-helper.sub.js": [
"70378edd15e6a9423c91ca6d301f4e66e195e998", "2c854534d56f5cf3d17660b582156c7f8de4e1cd",
"support"
],
"upgrade-insecure-requests/support/worker.js": [
"7e2168bcc06e0dd0832f42c28ef9ba3f7c2d84bf",
"support"
],
"upgrade-insecure-requests/support/worker.js.headers": [
"cb762eff806849df46dc758ef7b98b63f27f54c9",
"support" "support"
], ],
"upgrade-insecure-requests/websocket-upgrade.https.html": [ "upgrade-insecure-requests/websocket-upgrade.https.html": [
@ -710838,11 +710924,11 @@
"testharness" "testharness"
], ],
"upgrade-insecure-requests/worker-subresource-fetch-redirect-upgrade.https.html": [ "upgrade-insecure-requests/worker-subresource-fetch-redirect-upgrade.https.html": [
"b2ce2cfe4043d2d022a775c77244144b4dfdb5d2", "948dd6566c2a1fae7b015c3bf15a4a43fdb3c06d",
"testharness" "testharness"
], ],
"upgrade-insecure-requests/worker-subresource-fetch-upgrade.https.html": [ "upgrade-insecure-requests/worker-subresource-fetch-upgrade.https.html": [
"1639363e898b8faae7cb4fed0014696e6147d8f5", "bc98b9f2d0680047d4808c5c22872246a8496dbb",
"testharness" "testharness"
], ],
"upgrade-insecure-requests/worker-upgrade.https.html": [ "upgrade-insecure-requests/worker-upgrade.https.html": [
@ -715938,7 +716024,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCDataChannel-id.html": [ "webrtc/RTCDataChannel-id.html": [
"4c16547ca780c5285fbb2a264bfaf7b10b43eab6", "0cf01976ff0eeb66c51ded321e777123f063b02c",
"testharness" "testharness"
], ],
"webrtc/RTCDataChannel-send.html": [ "webrtc/RTCDataChannel-send.html": [
@ -716014,7 +716100,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-createDataChannel.html": [ "webrtc/RTCPeerConnection-createDataChannel.html": [
"ae74b62d42c3de9254c62a6e974e578416fc7c92", "8a13155358de3dab22a77f50172aae5bf0789b43",
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-createOffer.html": [ "webrtc/RTCPeerConnection-createOffer.html": [
@ -716054,7 +716140,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-ondatachannel.html": [ "webrtc/RTCPeerConnection-ondatachannel.html": [
"711027439b3ab4b38a18d91a2c9a1eaee7e4b3af", "2fd33ca541148ca6a7be5f5624e303795c7c458d",
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-onnegotiationneeded.html": [ "webrtc/RTCPeerConnection-onnegotiationneeded.html": [
@ -720814,7 +720900,7 @@
"testharness" "testharness"
], ],
"webxr/xrRigidTransform_inverse.https.html": [ "webxr/xrRigidTransform_inverse.https.html": [
"ddae2af6469034e67dc579dfd6cfb53b86f28d6a", "e795a99538e27d7a85a75c652b9b972d119e91d6",
"testharness" "testharness"
], ],
"webxr/xrRigidTransform_matrix.https.html": [ "webxr/xrRigidTransform_matrix.https.html": [
@ -720850,7 +720936,7 @@
"testharness" "testharness"
], ],
"webxr/xrSession_requestAnimationFrame_data_valid.https.html": [ "webxr/xrSession_requestAnimationFrame_data_valid.https.html": [
"6c567d2fda6888ee0b30e4f4716e75ee4763516d", "2278666a1d7cfc43362b5e09ddf0df25fef42681",
"testharness" "testharness"
], ],
"webxr/xrSession_requestAnimationFrame_getViewerPose.https.html": [ "webxr/xrSession_requestAnimationFrame_getViewerPose.https.html": [
@ -724272,6 +724358,18 @@
"xhr/xmlhttprequest-unsent.htm": [ "xhr/xmlhttprequest-unsent.htm": [
"eb52d63eef971895f69f1b0151baa457250dd452", "eb52d63eef971895f69f1b0151baa457250dd452",
"testharness" "testharness"
],
"xhtml/adopt-while-parsing-001-ref.html": [
"5b512e72f5a1f3780c9c38be79968b095c277a39",
"support"
],
"xhtml/adopt-while-parsing-001.html": [
"74018b4ad0f342aa5b38ad337ce9329e6d92545d",
"reftest"
],
"xhtml/adopt-while-parsing.xhtml": [
"2d85d21558b1778e17376d12424f81c703c0c262",
"support"
] ]
}, },
"url_base": "/", "url_base": "/",

View file

@ -140,12 +140,6 @@
[Matching font-stretch: '90%' should prefer '50% 80%' over '60% 70%'] [Matching font-stretch: '90%' should prefer '50% 80%' over '60% 70%']
expected: FAIL expected: FAIL
[Matching font-stretch: '90%' should prefer '110% 140%' over '120% 130%']
expected: FAIL
[Matching font-style: 'normal' should prefer 'normal' over 'oblique 0deg']
expected: FAIL
[Matching font-style: 'normal' should prefer 'oblique 0deg' over 'oblique 10deg 40deg'] [Matching font-style: 'normal' should prefer 'oblique 0deg' over 'oblique 10deg 40deg']
expected: FAIL expected: FAIL
@ -176,9 +170,6 @@
[Matching font-style: 'oblique -10deg' should prefer 'oblique -5deg' over 'oblique -1deg 0deg'] [Matching font-style: 'oblique -10deg' should prefer 'oblique -5deg' over 'oblique -1deg 0deg']
expected: FAIL expected: FAIL
[Matching font-weight: '399' should prefer '350 399' over '340 360']
expected: FAIL
[Matching font-weight: '500' should prefer '450 460' over '400'] [Matching font-weight: '500' should prefer '450 460' over '400']
expected: FAIL expected: FAIL
@ -314,9 +305,6 @@
[Matching font-style: 'oblique -20deg' should prefer 'oblique 30deg 60deg' over 'oblique 40deg 50deg'] [Matching font-style: 'oblique -20deg' should prefer 'oblique 30deg 60deg' over 'oblique 40deg 50deg']
expected: FAIL expected: FAIL
[Matching font-weight: '400' should prefer '450 460' over '500']
expected: FAIL
[Matching font-weight: '399' should prefer '450 460' over '500 501'] [Matching font-weight: '399' should prefer '450 460' over '500 501']
expected: FAIL expected: FAIL
@ -332,6 +320,3 @@
[Matching font-stretch: '90%' should prefer '90% 100%' over '50% 80%'] [Matching font-stretch: '90%' should prefer '90% 100%' over '50% 80%']
expected: FAIL expected: FAIL
[Matching font-weight: '400' should prefer '400' over '450 460']
expected: FAIL

View file

@ -163,7 +163,7 @@
expected: NOTRUN expected: NOTRUN
[<iframe>: combined response Content-Type: text/html;" " text/plain] [<iframe>: combined response Content-Type: text/html;" " text/plain]
expected: TIMEOUT expected: FAIL
[Request: combined response Content-Type: text/plain;charset=gbk;x=foo text/plain] [Request: combined response Content-Type: text/plain;charset=gbk;x=foo text/plain]
expected: NOTRUN expected: NOTRUN
@ -202,7 +202,7 @@
expected: NOTRUN expected: NOTRUN
[<iframe>: separate response Content-Type: text/html;" " text/plain] [<iframe>: separate response Content-Type: text/html;" " text/plain]
expected: TIMEOUT expected: FAIL
[fetch(): separate response Content-Type: text/plain */*;charset=gbk] [fetch(): separate response Content-Type: text/plain */*;charset=gbk]
expected: NOTRUN expected: NOTRUN
@ -312,15 +312,3 @@
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk] [<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain;charset=gbk text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
expected: FAIL

View file

@ -11,6 +11,3 @@
[X-Content-Type-Options%3A%20nosniff%0C] [X-Content-Type-Options%3A%20nosniff%0C]
expected: FAIL expected: FAIL
[X-Content-Type-Options%3A%20%2Cnosniff]
expected: FAIL

View file

@ -0,0 +1,5 @@
[javascript-url-abort-return-value-undefined.tentative.html]
expected: TIMEOUT
[Not aborting fetch for javascript:undefined navigation]
expected: TIMEOUT

View file

@ -1,4 +1,4 @@
[traverse_the_history_2.html] [traverse_the_history_5.html]
[Multiple history traversals, last would be aborted] [Multiple history traversals, last would be aborted]
expected: FAIL expected: FAIL

View file

@ -1,10 +0,0 @@
[non-active-document.html]
[DOMParser]
expected: FAIL
[createHTMLDocument]
expected: FAIL
[<template>]
expected: FAIL

View file

@ -0,0 +1,2 @@
[script-onerror-insertion-point-2.html]
expected: TIMEOUT

View file

@ -1,5 +1,4 @@
[realtimeanalyser-fft-scaling.html] [realtimeanalyser-fft-scaling.html]
expected: TIMEOUT
[X 2048-point FFT peak position is not equal to 64. Got 0.] [X 2048-point FFT peak position is not equal to 64. Got 0.]
expected: FAIL expected: FAIL

View file

@ -0,0 +1,10 @@
[Secure-Send-binary-65K-arraybuffer.any.html]
[Secure-Send-binary-65K-arraybuffer.any.worker.html]
expected: TIMEOUT
[Send 65K binary data on a Secure WebSocket - ArrayBuffer - Connection should be closed]
expected: NOTRUN
[Send 65K binary data on a Secure WebSocket - ArrayBuffer - Message should be received]
expected: NOTRUN

View file

@ -263,25 +263,43 @@ function extractImageData(img) {
} }
function decodeImageData(rgba) { function decodeImageData(rgba) {
var rgb = new Uint8ClampedArray(rgba.length); let decodedBytes = new Uint8ClampedArray(rgba.length);
let decodedLength = 0;
// RGBA -> RGB. for (var i = 0; i + 12 <= rgba.length; i += 12) {
var rgb_length = 0; // A single byte is encoded in three pixels. 8 pixel octets (among
for (var i = 0; i < rgba.length; ++i) { // 9 octets = 3 pixels * 3 channels) are used to encode 8 bits,
// Skip alpha component. // the most significant bit first, where `0` and `255` in pixel values
if (i % 4 == 3) // represent `0` and `1` in bits, respectively.
continue; // This encoding is used to avoid errors due to different color spaces.
const bits = [];
for (let j = 0; j < 3; ++j) {
bits.push(rgba[i + j * 4 + 0]);
bits.push(rgba[i + j * 4 + 1]);
bits.push(rgba[i + j * 4 + 2]);
// rgba[i + j * 4 + 3]: Skip alpha channel.
}
// The last one element is not used.
bits.pop();
// Decode a single byte.
let byte = 0;
for (let j = 0; j < 8; ++j) {
byte <<= 1;
if (bits[j] >= 128)
byte |= 1;
}
// Zero is the string terminator. // Zero is the string terminator.
if (rgba[i] == 0) if (byte == 0)
break; break;
rgb[rgb_length++] = rgba[i]; decodedBytes[decodedLength++] = byte;
} }
// Remove trailing nulls from data. // Remove trailing nulls from data.
rgb = rgb.subarray(0, rgb_length); decodedBytes = decodedBytes.subarray(0, decodedLength);
var string_data = (new TextDecoder("ascii")).decode(rgb); var string_data = (new TextDecoder("ascii")).decode(decodedBytes);
return JSON.parse(string_data); return JSON.parse(string_data);
} }

View file

@ -60,20 +60,17 @@ class Image:
def encode_string_as_bmp_image(string_data): def encode_string_as_bmp_image(string_data):
data_bytes = array.array("B", string_data) data_bytes = array.array("B", string_data)
num_bytes = len(data_bytes) num_bytes = len(data_bytes)
# Convert data bytes to color data (RGB). # Encode data bytes to color data (RGB), one bit per channel.
# This is to avoid errors due to different color spaces used in decoding.
color_data = [] color_data = []
num_components = 3
rgb = [0] * num_components
i = 0
for byte in data_bytes: for byte in data_bytes:
component_index = i % num_components p = [int(x) * 255 for x in '{0:08b}'.format(byte)]
rgb[component_index] = byte color_data.append((p[0], p[1], p[2]))
if component_index == (num_components - 1) or i == (num_bytes - 1): color_data.append((p[3], p[4], p[5]))
color_data.append(tuple(rgb)) color_data.append((p[6], p[7], 0))
rgb = [0] * num_components
i += 1
# Render image. # Render image.
num_pixels = len(color_data) num_pixels = len(color_data)

View file

@ -70,7 +70,7 @@
window.addEventListener("message", t.step_func(e => { window.addEventListener("message", t.step_func(e => {
if (e.source == i.contentWindow) { if (e.source == i.contentWindow) {
if (e.data == (new URL(url)).origin) { if (e.data.location == url) {
waitForViolation(window, "frame-src") waitForViolation(window, "frame-src")
.then(t.step_func(e => { .then(t.step_func(e => {
reported = true; reported = true;
@ -78,7 +78,7 @@
t.done(); t.done();
})); }));
i.contentWindow.location.href = navigate_to; i.contentWindow.location.href = navigate_to;
} else if (e.data == (new URL(upgraded)).origin) { } else if (e.data.location == upgraded) {
loaded = true; loaded = true;
if (reported) if (reported)
t.done(); t.done();

View file

@ -0,0 +1,6 @@
<!DOCTYPE html>
<div style="columns: 2">
<div style="height: 200px; background: blue"></div>
<div style="height: 200px"></div>
</div>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<title>CSS Multi-column Layout Test: multicol with overflow-clipped positioned content</title>
<link rel="help" href="https://www.w3.org/TR/css-multicol-1/">
<link rel="match" href="multicol-overflow-clip-positioned-ref.html">
<meta name="assert" content="Overflow clip for positioned content should work under multicol.">
<div style="columns: 2">
<div style="height: 200px; overflow: hidden">
<div style="height: 800px; background: blue; position: relative"></div>
</div>
<div style="height: 200px"></div>
</div>

View file

@ -1,6 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<title>CSSOM View - scrollIntoView</title> <title>CSSOM View - scrollIntoView</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="initial-scale=1">
<link rel="author" title="Chris Wu" href="mailto:pwx.frontend@gmail.com"> <link rel="author" title="Chris Wu" href="mailto:pwx.frontend@gmail.com">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview"> <link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
<link rel="help" href="https://heycam.github.io/webidl/#es-operations"> <link rel="help" href="https://heycam.github.io/webidl/#es-operations">

View file

@ -26,7 +26,7 @@ img {
<body> <body>
<p>Image inserted further below.</p> <p>Image inserted further below.</p>
<div id="image-container"> <div id="image-container">
<img id="off" load="eager" src="http://{{hosts[alt][www1]}}:{{ports[http][0]}}/feature-policy/experimental-features/resources/lazyload.png"></img> <img id="off" loading="eager" src="http://{{hosts[alt][www1]}}:{{ports[http][0]}}/feature-policy/experimental-features/resources/lazyload.png"></img>
</div> </div>
<script> <script>
var img = document.querySelector("img"); var img = document.querySelector("img");
@ -35,11 +35,11 @@ img {
target.load_complete = wait_for_load(target).then(() => target.did_load = true ); target.load_complete = wait_for_load(target).then(() => target.did_load = true );
}); });
// Sanity-check: Verify that when feature-policy 'lazyload' is enabled, the lazyload attribute // Sanity-check: Verify that when feature-policy 'lazyload' is enabled, the attribute
// value 'OFF' works as expected (images load immediately). // loading='eager' works as expected (images load immediately).
promise_test( async(t) => { promise_test( async(t) => {
await window.load_complete; await window.load_complete;
assert_true(img.did_load, "Image should have loaded."); assert_true(img.did_load, "Image should have loaded.");
}, "When feature is enabled, load=eager works as expected."); }, "When feature is enabled, loading=eager works as expected.");
</script> </script>
</body> </body>

View file

@ -31,12 +31,12 @@ iframe {
window.scrollTo(0, 0); window.scrollTo(0, 0);
// Sanity-check: Make sure load='lazy' works as intended. // Sanity-check: Make sure loading='lazy' works as intended.
promise_test(async(t) => { promise_test(async(t) => {
// Add a frame with load="lazy". // Add a frame with loading="lazy".
let frame_on = createIframe(document.body, { let frame_on = createIframe(document.body, {
id: "ON", id: "ON",
load: "lazy", loading: "lazy",
src: `${cross_origin_url}?id=ON` src: `${cross_origin_url}?id=ON`
}); });
// Sanity-check: The frame is not visible. // Sanity-check: The frame is not visible.
@ -48,17 +48,17 @@ iframe {
await waitForMessageOrTimeout(t, "ON", load_timeout); await waitForMessageOrTimeout(t, "ON", load_timeout);
assert_equals(msg_or_timeout_attr_on, assert_equals(msg_or_timeout_attr_on,
expected_timeout_msg, expected_timeout_msg,
"With load='lazy', the frame should not load."); "With loading='lazy', the frame should not load.");
}, "Sanity-check: Contents do not load immediately (no eager-loading) " + }, "Sanity-check: Contents do not load immediately (no eager-loading) " +
"when the load attribute is 'lazy' and frame is in viewport."); "when the loading attribute is 'lazy' and frame is in viewport.");
// When feature is enabled, a frame can turn off lazy loading by setting the // When feature is enabled, a frame can turn off lazy loading by setting the
// attribute to 'off'. // attribute to 'off'.
promise_test(async(t) => { promise_test(async(t) => {
// Add a frame with load="eager". // Add a frame with loading="eager".
let frame_off = createIframe(document.body, { let frame_off = createIframe(document.body, {
id: "OFF", id: "OFF",
load: "eager", loading: "eager",
src: `${cross_origin_url}?id=OFF` src: `${cross_origin_url}?id=OFF`
}); });
// Sanity-check: The frame is not visible. // Sanity-check: The frame is not visible.
@ -71,7 +71,7 @@ iframe {
assert_equals(msg_or_timeout_attr_off, assert_equals(msg_or_timeout_attr_off,
expected_load_msg, expected_load_msg,
"With load='eager', the frame should load."); "With loading='eager', the frame should load.");
}, "When 'lazyload' feature is enabled, a frame can avoid lazyloading by " + }, "When 'lazyload' feature is enabled, a frame can avoid lazyloading by " +
"setting 'load' attribute to 'eager'"); "setting 'loading' attribute to 'eager'");
</script> </script>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test oversized-images policy with threshold 'inf'</title>
</head>
<body>
<!-- The sample image has an intrinsic image size of 200x200px -->
<img src="resources/sample-1.png" width="200" height="200">
<img src="resources/sample-1.png" width="100" height="200">
<img src="resources/sample-1.png" width="50" height="200">
<br>
<img src="resources/sample-1.png" width="200" height="100">
<img src="resources/sample-1.png" width="100" height="100">
<img src="resources/sample-1.png" width="50" height="100">
<br>
<img src="resources/sample-1.png" width="200" height="50">
<img src="resources/sample-1.png" width="100" height="50">
<img src="resources/sample-1.png" width="50" height="50">
</body>
</html>

View file

@ -0,0 +1 @@
Feature-Policy: oversized-images (inf)

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/feature-policy/resources/featurepolicy.js"></script>
<title>Test oversized-images policy with threshold 1.5</title>
</head>
<body>
<iframe scrolling="no" name="a" style="overflow:hidden" width="380" height="220"></iframe>
<iframe scrolling="no" name="b" style="overflow:hidden" width="380" height="220"></iframe>
<iframe scrolling="no" name="c" style="overflow:hidden" width="380" height="220"></iframe>
<iframe scrolling="no" name="d" style="overflow:hidden" width="380" height="220"></iframe>
<iframe scrolling="no" name="e" style="overflow:hidden" width="380" height="220"></iframe>
<script>
const frame_to_test_map = {};
window.addEventListener('message', ev => {
if (ev.data.type == "finished") {
if (frame_to_test_map.hasOwnProperty(ev.data.name)) {
frame_to_test_map[ev.data.name].done();
}
}
});
const config = {
a: {threshold: 0.0, blocked: 3},
b: {threshold: 1.0, blocked: 2},
c: {threshold: 2.5, blocked: 1},
d: {threshold: 4.0, blocked: 0},
e: {threshold: "inf", blocked: 0}
};
const iframes = document.querySelectorAll('iframe');
const total_iframes = iframes.length;
iframes.forEach(iframe => {
const frame_config = config[iframe.name]
async_test(t => {
frame_to_test_map[iframe.name] = t;
iframe.src = "resources/feature-parameters-frame.html?name="+iframe.name+"&n="+frame_config.blocked+"&pipe=header(Feature-Policy,oversized-images%20("+frame_config.threshold+"\\);)";
}, "Test frame with threshold " + frame_config.threshold + " should block " + frame_config.blocked + " images.");
});
</script>
</body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/feature-policy/resources/featurepolicy.js"></script>
<title>Test oversized-images policy with threshold 1.5</title>
</head>
<body>
<!-- The sample image has an intrinsic image size of 200x200px -->
<img src="resources/sample-1.png" width="200" height="200">
<img src="resources/sample-1.png" width="100" height="200">
<img src="resources/sample-1.png" width="50" height="200">
<br>
<img src="resources/sample-1.png" width="200" height="100">
<img src="resources/sample-1.png" width="100" height="100">
<img src="resources/sample-1.png" width="50" height="100">
<br>
<img src="resources/sample-1.png" width="200" height="50">
<img src="resources/sample-1.png" width="100" height="50">
<img src="resources/sample-1.png" width="50" height="50">
<script>
expect_reports(8, "oversized-images", "8 images should be blocked by policy");
</script>
</body>
</html>

View file

@ -0,0 +1 @@
Feature-Policy: oversized-images (1.5)

View file

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/feature-policy/resources/featurepolicy.js"></script>
<title>Test oversized-images policy in subframe</title>
</head>
<body>
<!-- The sample image has an intrinsic image size of 200x200px -->
<img width="200" height="200">
<img width="100" height="200">
<img width="50" height="200">
<script>
const policy_name = "oversized-images";
const params = new URLSearchParams(document.location.search);
const frame_name = params.get('name');
const expected_report_count = +params.get('n');
var num_received_reports = 0;
const images = document.querySelectorAll('img');
const total_images = images.length;
var images_loaded = 0;
const notifyIfDone = () => {
if (num_received_reports >= expected_report_count &&
images_loaded == total_images) {
parent.postMessage({
"type": "finished",
"name": frame_name
},"*");
}
};
images.forEach(image => {
image.addEventListener('load', () => { images_loaded++; notifyIfDone(); });
image.src = "sample-1.png";
});
new ReportingObserver((reports, observer) => {
const relevant_reports = reports.filter(r => (r.body.featureId === policy_name));
num_received_reports += relevant_reports.length;
notifyIfDone();
}, {types: ['feature-policy-violation'], buffered: true}).observe();
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

View file

@ -433,3 +433,16 @@ function test_frame_policy(
assert_false(frame_policy.allowedFeatures().includes(feature)); assert_false(frame_policy.allowedFeatures().includes(feature));
} }
} }
function expect_reports(report_count, policy_name, description) {
async_test(t => {
var num_received_reports = 0;
new ReportingObserver(t.step_func((reports, observer) => {
const relevant_reports = reports.filter(r => (r.body.featureId === policy_name));
num_received_reports += relevant_reports.length;
if (num_received_reports >= report_count) {
t.done();
}
}), {types: ['feature-policy-violation'], buffered: true}).observe();
}, description);
}

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
promise_test(async () => {
let waitForMessage = new Promise((resolve, reject) => {
var bc = new BroadcastChannel("portals-create-orphaned");
bc.onmessage = e => {
bc.close();
resolve(e.data);
}
});
window.open("resources/portal-create-orphaned.html");
let message = await waitForMessage;
assert_equals(message, "portal loaded");
}, "creating a portal from an orphaned portal should succeed");
</script>
</body>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<body>
<script>
var portal = document.createElement("portal");
portal.src = "simple-portal.html";
let waitForMessage = new Promise((resolve, reject) => {
var bc_portal = new BroadcastChannel("simple-portal");
bc_portal.onmessage = e => {
bc_portal.close();
portal.activate();
var portal2 = document.createElement("portal");
portal2.src = "simple-portal.html";
document.body.appendChild(portal2);
var bc2 = new BroadcastChannel("simple-portal");
bc2.onmessage = e => {
bc2.close();
resolve("portal loaded");
}
}
});
document.body.appendChild(portal);
waitForMessage.then(message => {
var bc = new BroadcastChannel("portals-create-orphaned");
bc.postMessage(message);
bc.close();
});
</script>
</body>

View file

@ -33,8 +33,8 @@ for name, resourceType in [
('layout-worklet', 'WORKLET'), ('paint-worklet', 'WORKLET'), ('layout-worklet', 'WORKLET'), ('paint-worklet', 'WORKLET'),
('worker', 'WORKER'), ('worker', 'WORKER'),
('module-worker', 'WORKER'), ('module-worker', 'WORKER'),
('worker-subresource-xhr', 'IMAGE'), ('worker-subresource-xhr', 'FETCH'),
('worker-subresource-fetch', 'IMAGE')]: ('worker-subresource-fetch', 'FETCH')]:
sameOriginOnly = 'true' if resourceType == 'WORKER' else 'false' sameOriginOnly = 'true' if resourceType == 'WORKER' else 'false'
types = [('', 'generateTests'), ('-redirect', 'generateRedirectTests')] types = [('', 'generateTests'), ('-redirect', 'generateRedirectTests')]
if name == 'module-worker' or resourceType == 'WORKLET': if name == 'module-worker' or resourceType == 'WORKLET':

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -1 +0,0 @@
Access-Control-Allow-Origin: *

View file

@ -1,3 +0,0 @@
<script>
parent.postMessage(window.location.origin, '*');
</script>

View file

@ -20,6 +20,7 @@ const ResourceType = {
WORKER: "worker", WORKER: "worker",
WORKLET: "worklet", WORKLET: "worklet",
WEBSOCKET: "websocket", WEBSOCKET: "websocket",
FETCH: "fetch",
}; };
// These tests rely on some unintuitive cleverness due to WPT's test setup: // These tests rely on some unintuitive cleverness due to WPT's test setup:
@ -27,22 +28,24 @@ const ResourceType = {
// in the form `http://[domain]:[https-port]`. If the upgrade fails, the load will fail, // in the form `http://[domain]:[https-port]`. If the upgrade fails, the load will fail,
// as we don't serve HTTP over the secure port. // as we don't serve HTTP over the secure port.
function generateURL(host, protocol, resourceType) { function generateURL(host, protocol, resourceType) {
var url = new URL("http://{{host}}:{{ports[https][0]}}/upgrade-insecure-requests/support/"); var url = new URL("http://{{host}}:{{ports[https][0]}}/common/security-features/subresource/");
url.protocol = protocol == Protocol.INSECURE ? "http" : "https"; url.protocol = protocol == Protocol.INSECURE ? "http" : "https";
url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}"; url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}";
if (resourceType == ResourceType.IMAGE) { if (resourceType == ResourceType.IMAGE) {
url.pathname += "pass.png"; url.pathname += "image.py";
} else if (resourceType == ResourceType.FRAME) { } else if (resourceType == ResourceType.FRAME) {
url.pathname += "post-origin-to-parent.html"; url.pathname += "document.py";
} else if (resourceType == ResourceType.WEBSOCKET) { } else if (resourceType == ResourceType.WEBSOCKET) {
url.port = {{ports[wss][0]}}; url.port = {{ports[wss][0]}};
url.protocol = protocol == Protocol.INSECURE ? "ws" : "wss"; url.protocol = protocol == Protocol.INSECURE ? "ws" : "wss";
url.pathname = "echo"; url.pathname = "echo";
} else if (resourceType == ResourceType.WORKER) { } else if (resourceType == ResourceType.WORKER) {
url.pathname += "worker.js"; url.pathname += "worker.py";
} else if (resourceType == ResourceType.WORKLET) { } else if (resourceType == ResourceType.WORKLET) {
url.pathname = "/worklets/resources/empty-worklet-script-with-cors-header.js"; url.pathname += "worker.py";
} else if (resourceType == ResourceType.FETCH) {
url.pathname += "xhr.py";
} }
return { return {
name: protocol + "/" + host + " " + resourceType, name: protocol + "/" + host + " " + resourceType,
@ -110,24 +113,24 @@ function generateModuleImportTests(target, sameOriginOnly) {
return tests; return tests;
} }
function assert_image_loads(test, url, height, width) { function assert_image_loads(test, url) {
var i = document.createElement('img'); var i = document.createElement('img');
i.onload = test.step_func_done(_ => { i.onload = test.step_func_done(_ => {
assert_equals(i.naturalHeight, height, "Height."); assert_greater_than(i.naturalHeight, 0, "Height.");
assert_equals(i.naturalWidth, width, "Width."); assert_greater_than(i.naturalWidth, 0, "Width.");
}); });
i.onerror = test.unreached_func(url + " should load successfully."); i.onerror = test.unreached_func(url + " should load successfully.");
i.src = url; i.src = url;
} }
function assert_image_loads_in_srcdoc(test, url, height, width) { function assert_image_loads_in_srcdoc(test, url) {
var frame = document.createElement('iframe'); var frame = document.createElement('iframe');
frame.srcdoc = "yay!"; frame.srcdoc = "yay!";
frame.onload = _ => { frame.onload = _ => {
var i = frame.contentDocument.createElement('img'); var i = frame.contentDocument.createElement('img');
i.onload = test.step_func_done(_ => { i.onload = test.step_func_done(_ => {
assert_equals(i.naturalHeight, height, "Height."); assert_greater_than(i.naturalHeight, 0, "Height.");
assert_equals(i.naturalWidth, width, "Width."); assert_greater_than(i.naturalWidth, 0, "Width.");
frame.remove(); frame.remove();
}); });
i.onerror = test.unreached_func(url + " should load successfully."); i.onerror = test.unreached_func(url + " should load successfully.");
@ -137,13 +140,13 @@ function assert_image_loads_in_srcdoc(test, url, height, width) {
document.body.appendChild(frame); document.body.appendChild(frame);
} }
function assert_image_loads_in_blank(test, url, height, width) { function assert_image_loads_in_blank(test, url) {
var frame = document.createElement('iframe'); var frame = document.createElement('iframe');
frame.onload = _ => { frame.onload = _ => {
var i = frame.contentDocument.createElement('img'); var i = frame.contentDocument.createElement('img');
i.onload = test.step_func_done(_ => { i.onload = test.step_func_done(_ => {
assert_equals(i.naturalHeight, height, "Height."); assert_greater_than(i.naturalHeight, 0, "Height.");
assert_equals(i.naturalWidth, width, "Width."); assert_greater_than(i.naturalWidth, 0, "Width.");
frame.remove(); frame.remove();
}); });
i.onerror = test.unreached_func(url + " should load successfully."); i.onerror = test.unreached_func(url + " should load successfully.");
@ -153,20 +156,6 @@ function assert_image_loads_in_blank(test, url, height, width) {
document.body.appendChild(frame); document.body.appendChild(frame);
} }
function assert_frame_loads(test, url) {
var i = document.createElement('iframe');
window.addEventListener('message', test.step_func(e => {
if (e.source == i.contentWindow) {
i.remove();
test.done();
}
}));
i.src = url;
document.body.appendChild(i);
}
function assert_websocket_loads(test, url) { function assert_websocket_loads(test, url) {
var w = new WebSocket(url, "echo"); var w = new WebSocket(url, "echo");
w.onopen = test.step_func(_ => { w.onopen = test.step_func(_ => {
@ -178,12 +167,12 @@ function assert_websocket_loads(test, url) {
const testMap = { const testMap = {
"image": test => { "image": test => {
async_test(t => assert_image_loads(t, test.url, 64, 168), test.name); async_test(t => assert_image_loads(t, test.url), test.name);
async_test(t => assert_image_loads_in_srcdoc(t, test.url, 64, 168), test.name + " in <iframe srcdoc>"); async_test(t => assert_image_loads_in_srcdoc(t, test.url), test.name + " in <iframe srcdoc>");
async_test(t => assert_image_loads_in_blank(t, test.url, 64, 168), test.name + " in <iframe>"); async_test(t => assert_image_loads_in_blank(t, test.url), test.name + " in <iframe>");
}, },
"iframe": "iframe":
test => async_test(t => assert_frame_loads(t, test.url), test.name), test => promise_test(t => requestViaIframe(test.url), test.name),
"worker": "worker":
test => promise_test( test => promise_test(

View file

@ -1 +0,0 @@
postMessage('done');

View file

@ -1 +0,0 @@
Access-Control-Allow-Origin: *

View file

@ -12,7 +12,7 @@
</head> </head>
<body> <body>
<script> <script>
const tests = generateRedirectTests(ResourceType.IMAGE, false); const tests = generateRedirectTests(ResourceType.FETCH, false);
tests.forEach(test => testMap['worker-subresource-fetch'](test)); tests.forEach(test => testMap['worker-subresource-fetch'](test));
</script> </script>
</body> </body>

View file

@ -12,7 +12,7 @@
</head> </head>
<body> <body>
<script> <script>
const tests = generateTests(ResourceType.IMAGE, false); const tests = generateTests(ResourceType.FETCH, false);
tests.forEach(test => testMap['worker-subresource-fetch'](test)); tests.forEach(test => testMap['worker-subresource-fetch'](test));
</script> </script>
</body> </body>

View file

@ -82,11 +82,10 @@ promise_test(async (t) => {
}, 'DTLS server uses even data channel IDs'); }, 'DTLS server uses even data channel IDs');
/* /*
Check if the implementation allows using in-band negotiated channels with a specific ID (which Checks that the id is ignored if "negotiated" is false.
is now a spec violation). See section 6.1, createDataChannel step 13.
*/ */
promise_test(async (t) => { promise_test(async (t) => {
const resolver = new Resolver();
const pc1 = new RTCPeerConnection(); const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection(); const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close()); t.add_cleanup(() => pc1.close());
@ -104,17 +103,18 @@ promise_test(async (t) => {
negotiated: false, negotiated: false,
id: 42 id: 42
}); });
dc2.onmessage = t.step_func(() => { // ID should be null prior to negotiation.
assert_unreached('Channel established with same ID using negotiated=false'); assert_equals(dc1.id, null);
}); assert_equals(dc2.id, null);
exchangeIceCandidates(pc1, pc2); exchangeIceCandidates(pc1, pc2);
await doSignalingHandshake(pc1, pc2); await doSignalingHandshake(pc1, pc2);
// We should now have 2 datachannels with different IDs.
// Wait a bit to ensure the 'message' event does NOT fire // At least one of the datachannels should not be 42.
t.step_timeout(() => resolver.resolve(), 500); // If one has the value 42, it's an accident; if both have,
await resolver; // they are the same datachannel, and it's a bug.
}, 'In-band negotiation with a specific ID should not be allowed'); assert_false(dc1.id == 42 && dc2.id == 42);
}, 'In-band negotiation with a specific ID should not work');
/* /*
Check if the implementation still follows the odd/even role correctly if we annoy it with Check if the implementation still follows the odd/even role correctly if we annoy it with
@ -149,7 +149,7 @@ promise_test(async (t) => {
negotiated: true, negotiated: true,
id: id, id: id,
}); });
assert_equals(dc.id, null, 'Channel id must be null before DTLS role has been determined'); assert_equals(dc.id, id, 'Channel id must be set before DTLS role has been determined when negotiated is true');
negotiatedDcs.push([dc, id]); negotiatedDcs.push([dc, id]);
ids.add(dc.id, `Channel ID ${dc.id} should be unique`); ids.add(dc.id, `Channel ID ${dc.id} should be unique`);
} }

View file

@ -60,7 +60,7 @@
}; };
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -72,7 +72,7 @@ test((t) => {
6.2. createDataChannel 6.2. createDataChannel
2. If connection's [[isClosed]] slot is true, throw an InvalidStateError. 2. If connection's [[isClosed]] slot is true, throw an InvalidStateError.
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
pc.close(); pc.close();
assert_equals(pc.signalingState, 'closed', 'signaling state'); assert_equals(pc.signalingState, 'closed', 'signaling state');
@ -128,7 +128,7 @@ test((t) => {
[...] When a RTCDataChannel object is created, the binaryType attribute MUST [...] When a RTCDataChannel object is created, the binaryType attribute MUST
be initialized to the string "blob". be initialized to the string "blob".
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -151,14 +151,14 @@ test((t) => {
assert_equals(dc.binaryType, 'blob'); assert_equals(dc.binaryType, 'blob');
}, 'createDataChannel attribute default values'); }, 'createDataChannel attribute default values');
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
const dc = pc.createDataChannel('test', { const dc = pc.createDataChannel('test', {
ordered: false, ordered: false,
maxPacketLifeTime: null,
maxRetransmits: 1, maxRetransmits: 1,
// Note: maxPacketLifeTime is not set in this test.
protocol: 'custom', protocol: 'custom',
negotiated: true, negotiated: true,
id: 3, id: 3,
@ -178,6 +178,14 @@ test((t) => {
assert_equals(dc.bufferedAmount, 0); assert_equals(dc.bufferedAmount, 0);
assert_equals(dc.bufferedAmountLowThreshold, 0); assert_equals(dc.bufferedAmountLowThreshold, 0);
assert_equals(dc.binaryType, 'blob'); assert_equals(dc.binaryType, 'blob');
const dc2 = pc.createDataChannel('test2', {
ordered: false,
maxPacketLifeTime: 42
});
assert_equals(dc2.label, 'test2');
assert_equals(dc2.maxPacketLifeTime, 42);
assert_equals(dc.maxRetransmits, null);
}, 'createDataChannel with provided parameters should initialize attributes to provided values'); }, 'createDataChannel with provided parameters should initialize attributes to provided values');
/* /*
@ -198,7 +206,7 @@ const labels = [
['lone surrogate', '\uD800', '\uFFFD'], ['lone surrogate', '\uD800', '\uFFFD'],
]; ];
for (const [description, label, expected] of labels) { for (const [description, label, expected] of labels) {
test((t) => { test(t => {
const pc = new RTCPeerConnection; const pc = new RTCPeerConnection;
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -213,7 +221,7 @@ for (const [description, label, expected] of labels) {
11. Let channel have an [[Ordered]] internal slot initialized to option's 11. Let channel have an [[Ordered]] internal slot initialized to option's
ordered member. ordered member.
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -223,7 +231,7 @@ test((t) => {
// true as the default value of a boolean is confusing because null is converted // true as the default value of a boolean is confusing because null is converted
// to false while undefined is converted to true. // to false while undefined is converted to true.
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -239,7 +247,7 @@ test((t) => {
7. Let channel have an [[MaxPacketLifeTime]] internal slot initialized to 7. Let channel have an [[MaxPacketLifeTime]] internal slot initialized to
option's maxPacketLifeTime member, if present, otherwise null. option's maxPacketLifeTime member, if present, otherwise null.
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection; const pc = new RTCPeerConnection;
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -253,7 +261,7 @@ test((t) => {
10. Let channel have an [[MaxRetransmits]] internal slot initialized to 10. Let channel have an [[MaxRetransmits]] internal slot initialized to
option's maxRetransmits member, if present, otherwise null. option's maxRetransmits member, if present, otherwise null.
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection; const pc = new RTCPeerConnection;
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -266,17 +274,17 @@ test((t) => {
18. If both [[MaxPacketLifeTime]] and [[MaxRetransmits]] attributes are set (not null), 18. If both [[MaxPacketLifeTime]] and [[MaxRetransmits]] attributes are set (not null),
throw a TypeError. throw a TypeError.
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection; const pc = new RTCPeerConnection;
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
pc.createDataChannel('', { pc.createDataChannel('', {
maxPacketLifeTime: null, maxPacketLifeTime: undefined,
maxRetransmits: null maxRetransmits: undefined
}); });
}, 'createDataChannel with both maxPacketLifeTime and maxRetransmits null should succeed'); }, 'createDataChannel with both maxPacketLifeTime and maxRetransmits undefined should succeed');
test((t) => { test(t => {
const pc = new RTCPeerConnection; const pc = new RTCPeerConnection;
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -303,7 +311,7 @@ const protocols = [
['lone surrogate', '\uD800', '\uFFFD'], ['lone surrogate', '\uD800', '\uFFFD'],
]; ];
for (const [description, protocol, expected] of protocols) { for (const [description, protocol, expected] of protocols) {
test((t) => { test(t => {
const pc = new RTCPeerConnection; const pc = new RTCPeerConnection;
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -319,21 +327,22 @@ for (const [description, protocol, expected] of protocols) {
ID of 65534 but still qualifies as an unsigned short, throw a TypeError. ID of 65534 but still qualifies as an unsigned short, throw a TypeError.
*/ */
for (const id of [0, 1, 65534]) { for (const id of [0, 1, 65534]) {
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
const dc = pc.createDataChannel('', { id }); const dc = pc.createDataChannel('', { 'negotiated': true, 'id': id });
assert_equals(dc.id, id); assert_equals(dc.id, id);
}, `createDataChannel with id ${id} should succeed`); }, `createDataChannel with id ${id} should succeed`);
} }
for (const id of [-1, 65535, 65536]) { for (const id of [-1, 65535, 65536]) {
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
assert_throws(new TypeError(), () => pc.createDataChannel('', { id })); assert_throws(new TypeError(), () => pc.createDataChannel('',
{ 'negotiated': true, 'id': id }));
}, `createDataChannel with id ${id} should throw TypeError`); }, `createDataChannel with id ${id} should throw TypeError`);
} }
@ -343,7 +352,7 @@ for (const id of [-1, 65535, 65536]) {
17. Let channel have an [[DataChannelPriority]] internal slot initialized to option's 17. Let channel have an [[DataChannelPriority]] internal slot initialized to option's
priority member. priority member.
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -351,7 +360,7 @@ test((t) => {
assert_equals(dc.priority, 'high'); assert_equals(dc.priority, 'high');
}, 'createDataChannel with priority "high" should succeed'); }, 'createDataChannel with priority "high" should succeed');
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -363,7 +372,7 @@ test((t) => {
6.2. createDataChannel 6.2. createDataChannel
5. If [[DataChannelLabel]] is longer than 65535 bytes, throw a TypeError. 5. If [[DataChannelLabel]] is longer than 65535 bytes, throw a TypeError.
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -377,7 +386,7 @@ test((t) => {
})); }));
}, 'createDataChannel with too long label should throw TypeError'); }, 'createDataChannel with too long label should throw TypeError');
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -411,13 +420,14 @@ test(t => {
13. If [[DataChannelProtocol]] is longer than 65535 bytes long, throw a TypeError. 13. If [[DataChannelProtocol]] is longer than 65535 bytes long, throw a TypeError.
*/ */
test(() => { test(t => {
const pc = new RTCPeerConnection; const pc = new RTCPeerConnection;
const channel = pc.createDataChannel('', { negotiated: true }); t.add_cleanup(() => pc.close());
const channel = pc.createDataChannel('', { negotiated: true, id: 42 });
assert_equals(channel.negotiated, true); assert_equals(channel.negotiated, true);
}, 'createDataChannel with negotiated true should succeed'); }, 'createDataChannel with negotiated true and id should succeed');
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -434,7 +444,7 @@ test((t) => {
})); }));
}, 'createDataChannel with too long protocol should throw TypeError'); }, 'createDataChannel with too long protocol should throw TypeError');
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -451,7 +461,7 @@ test((t) => {
})); }));
}, 'createDataChannel with too long protocol (2 byte unicode) should throw TypeError'); }, 'createDataChannel with too long protocol (2 byte unicode) should throw TypeError');
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -476,7 +486,7 @@ test((t) => {
is intentional. Data channels negotiated in-band should have IDs selected based on the is intentional. Data channels negotiated in-band should have IDs selected based on the
DTLS role, as specified in [RTCWEB-DATA-PROTOCOL]. DTLS role, as specified in [RTCWEB-DATA-PROTOCOL].
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection; const pc = new RTCPeerConnection;
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -486,7 +496,7 @@ test((t) => {
assert_equals(dc.negotiated, false, 'Expect dc.negotiated to be false'); assert_equals(dc.negotiated, false, 'Expect dc.negotiated to be false');
}, 'createDataChannel with negotiated false should succeed'); }, 'createDataChannel with negotiated false should succeed');
test((t) => { test(t => {
const pc = new RTCPeerConnection; const pc = new RTCPeerConnection;
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -502,7 +512,7 @@ test((t) => {
6.2. createDataChannel 6.2. createDataChannel
16. If [[Negotiated]] is true and [[DataChannelId]] is null, throw a TypeError. 16. If [[Negotiated]] is true and [[DataChannelId]] is null, throw a TypeError.
*/ */
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -512,17 +522,6 @@ test((t) => {
})); }));
}, 'createDataChannel with negotiated true and id not defined should throw TypeError'); }, 'createDataChannel with negotiated true and id not defined should throw TypeError');
test((t) => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
assert_throws(new TypeError(), () =>
pc.createDataChannel('test', {
negotiated: true,
id: null
}));
}, 'createDataChannel with negotiated true and id null should throw TypeError');
/* /*
4.4.1.6. Set the RTCSessionSessionDescription 4.4.1.6. Set the RTCSessionSessionDescription
2.2.6. If description is of type "answer" or "pranswer", then run the 2.2.6. If description is of type "answer" or "pranswer", then run the
@ -544,7 +543,7 @@ test((t) => {
If the [[DataChannelId]] slot is null after this step, it will be populated once If the [[DataChannelId]] slot is null after this step, it will be populated once
the DTLS role is determined during the process of setting an RTCSessionDescription. the DTLS role is determined during the process of setting an RTCSessionDescription.
*/ */
promise_test(async (t) => { promise_test(async t => {
const pc1 = new RTCPeerConnection(); const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection(); const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close()); t.add_cleanup(() => pc1.close());
@ -597,7 +596,7 @@ promise_test(async (t) => {
'Expect negotiatedDc.id to be 42 after remote description has been set'); 'Expect negotiatedDc.id to be 42 after remote description has been set');
}, 'Channels created (after setRemoteDescription) should have id assigned'); }, 'Channels created (after setRemoteDescription) should have id assigned');
test((t) => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());
@ -625,7 +624,7 @@ test((t) => {
// We've seen implementations behaving differently before and after the connection has been // We've seen implementations behaving differently before and after the connection has been
// established. // established.
promise_test(async (t) => { promise_test(async t => {
const pc1 = new RTCPeerConnection(); const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection(); const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close()); t.add_cleanup(() => pc1.close());
@ -660,7 +659,7 @@ promise_test(async (t) => {
}, 'Reusing a data channel id that is in use (after setRemoteDescription) should throw ' + }, 'Reusing a data channel id that is in use (after setRemoteDescription) should throw ' +
'OperationError'); 'OperationError');
promise_test(async (t) => { promise_test(async t => {
const pc1 = new RTCPeerConnection(); const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection(); const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close()); t.add_cleanup(() => pc1.close());
@ -685,7 +684,7 @@ promise_test(async (t) => {
'should throw OperationError'); 'should throw OperationError');
// Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1441723 // Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1441723
promise_test(async (t) => { promise_test(async t => {
const pc1 = new RTCPeerConnection(); const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection(); const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close()); t.add_cleanup(() => pc1.close());

View file

@ -355,7 +355,8 @@ promise_test(async (t) => {
pc2.ondatachannel = t.unreached_func('datachannel event should not be fired'); pc2.ondatachannel = t.unreached_func('datachannel event should not be fired');
pc1.createDataChannel('test', { pc1.createDataChannel('test', {
negotiated: true negotiated: true,
id: 42
}); });
exchangeIceCandidates(pc1, pc2); exchangeIceCandidates(pc1, pc2);

View file

@ -29,14 +29,14 @@ let testFunction =
// An identity transform should be equal to it's inverse. // An identity transform should be equal to it's inverse.
let identity_transform = new XRRigidTransform(); let identity_transform = new XRRigidTransform();
t.step(() => { t.step(() => {
assert_transform_approx_equals(identity_transform, identity_transform.inverse()); assert_transform_approx_equals(identity_transform, identity_transform.inverse);
}); });
// Inversed transforms should yield the expected results // Inversed transforms should yield the expected results
let transform = new XRRigidTransform( let transform = new XRRigidTransform(
{ x: 1.0, y: 2.0, z: 3.0 }, { x: 1.0, y: 2.0, z: 3.0 },
{ x: 0.0, y: 0.0, z: 0.0, w: 1.0 }); { x: 0.0, y: 0.0, z: 0.0, w: 1.0 });
let inverse_transform = transform.inverse(); let inverse_transform = transform.inverse;
let expected_inverse = new XRRigidTransform( let expected_inverse = new XRRigidTransform(
{ x: -1.0, y: -2.0, z: -3.0 }, { x: -1.0, y: -2.0, z: -3.0 },
{ x: 0.0, y: 0.0, z: 0.0, w: 1.0 }); { x: 0.0, y: 0.0, z: 0.0, w: 1.0 });
@ -47,7 +47,7 @@ let testFunction =
transform = new XRRigidTransform( transform = new XRRigidTransform(
{ x: 0.0, y: 0.0, z: 0.0 }, { x: 0.0, y: 0.0, z: 0.0 },
{ x: 1.0, y: 0.0, z: 0.0, w: 1.0 }); { x: 1.0, y: 0.0, z: 0.0, w: 1.0 });
inverse_transform = transform.inverse(); inverse_transform = transform.inverse;
expected_inverse = new XRRigidTransform( expected_inverse = new XRRigidTransform(
{ x: 0.0, y: 0.0, z: 0.0 }, { x: 0.0, y: 0.0, z: 0.0 },
{ x: -1.0, y: 0.0, z: 0.0, w: 1.0 }); { x: -1.0, y: 0.0, z: 0.0, w: 1.0 });
@ -58,7 +58,7 @@ let testFunction =
transform = new XRRigidTransform( transform = new XRRigidTransform(
{ x: 1.0, y: 2.0, z: 3.0 }, { x: 1.0, y: 2.0, z: 3.0 },
{ x: 0.0, y: 1.0, z: 0.0, w: 1.0 }); { x: 0.0, y: 1.0, z: 0.0, w: 1.0 });
inverse_transform = transform.inverse(); inverse_transform = transform.inverse;
expected_inverse = new XRRigidTransform( expected_inverse = new XRRigidTransform(
{ x: 3.0, y: -2.0, z: -1.0 }, { x: 3.0, y: -2.0, z: -1.0 },
{ x: 0.0, y: -1.0, z: 0.0, w: 1.0 }); { x: 0.0, y: -1.0, z: 0.0, w: 1.0 });
@ -70,33 +70,33 @@ let testFunction =
transform = new XRRigidTransform( transform = new XRRigidTransform(
{ x: 1.0, y: 2.0, z: 3.0 }, { x: 1.0, y: 2.0, z: 3.0 },
{ x: 1.0, y: 2.0, z: 3.0, w: 4.0 }); { x: 1.0, y: 2.0, z: 3.0, w: 4.0 });
inverse_transform = transform.inverse(); inverse_transform = transform.inverse;
t.step(() => { t.step(() => {
assert_transform_approx_equals(transform, inverse_transform.inverse()); assert_transform_approx_equals(transform, inverse_transform.inverse);
}); });
transform = new XRRigidTransform( transform = new XRRigidTransform(
{ x: -9.0, y: 8.0, z: -7.0 }, { x: -9.0, y: 8.0, z: -7.0 },
{ x: 6.0, y: -5.0, z: 4.0, w: 3.0 }); { x: 6.0, y: -5.0, z: 4.0, w: 3.0 });
inverse_transform = transform.inverse(); inverse_transform = transform.inverse;
t.step(() => { t.step(() => {
assert_transform_approx_equals(transform, inverse_transform.inverse()); assert_transform_approx_equals(transform, inverse_transform.inverse);
}); });
transform = new XRRigidTransform( transform = new XRRigidTransform(
{ x: -2.0, y: 1.0, z: -4.0 }, { x: -2.0, y: 1.0, z: -4.0 },
{ x: 0.0, y: 1.0, z: 0.0, w: 1.0 }); { x: 0.0, y: 1.0, z: 0.0, w: 1.0 });
inverse_transform = transform.inverse(); inverse_transform = transform.inverse;
t.step(() => { t.step(() => {
assert_transform_approx_equals(transform, inverse_transform.inverse()); assert_transform_approx_equals(transform, inverse_transform.inverse);
}); });
transform = new XRRigidTransform( transform = new XRRigidTransform(
{ x: 2.0, y: -1.0, z: 4.0 }, { x: 2.0, y: -1.0, z: 4.0 },
{ x: 1.0, y: 0.0, z: 0.0, w: 1.0 }); { x: 1.0, y: 0.0, z: 0.0, w: 1.0 });
inverse_transform = transform.inverse(); inverse_transform = transform.inverse;
t.step(() => { t.step(() => {
assert_transform_approx_equals(transform, inverse_transform.inverse()); assert_transform_approx_equals(transform, inverse_transform.inverse);
}); });
resolve(); resolve();

View file

@ -36,7 +36,7 @@
assert_not_equals(view, null); assert_not_equals(view, null);
assert_not_equals(view.transform, null); assert_not_equals(view.transform, null);
let inv_view_transform = view.transform.inverse(); let inv_view_transform = view.transform.inverse;
assert_not_equals(inv_view_transform, null); assert_not_equals(inv_view_transform, null);
assert_not_equals(inv_view_transform.matrix, null); assert_not_equals(inv_view_transform.matrix, null);
assert_equals(inv_view_transform.matrix.length, 16); assert_equals(inv_view_transform.matrix.length, 16);

View file

@ -0,0 +1,9 @@
<!doctype html>
<title>Test reference</title>
<style>
html, body { margin: 0 }
</style>
<iframe src="about:blank"></iframe>
<div>
PASS
</div>

View file

@ -0,0 +1,19 @@
<!doctype html>
<title>Appending from the parser after adopting in an XML document doesn't miss notifications</title>
<link rel="match" href="adopt-while-parsing-001-ref.html">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1511329">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<style>
html, body { margin: 0 }
</style>
<script>
// If we don't get notified of the <div> insertion, the PASS text will never appear.
function parsingInterrupted() {
let frameDoc = document.querySelector("iframe").contentDocument;
let root = frameDoc.documentElement;
document.documentElement.appendChild(root);
root.offsetTop;
}
</script>
<iframe src="adopt-while-parsing.xhtml"></iframe>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<script>
window.parent.parsingInterrupted();
</script>
<div>
PASS
</div>
</body>
</html>