Update web-platform-tests to revision 8fde342d6e62e9820f2c19db634b99b78df796fa

This commit is contained in:
WPT Sync Bot 2019-03-08 20:43:08 -05:00
parent db29cb01b0
commit e9a369631b
48 changed files with 1012 additions and 283 deletions

View file

@ -14,6 +14,9 @@
[Revoke blob URL after creating Request, will fetch] [Revoke blob URL after creating Request, will fetch]
expected: FAIL expected: FAIL
[Revoke blob URL after calling fetch, fetch should succeed]
expected: FAIL
[url-with-fetch.any.html] [url-with-fetch.any.html]
[Untitled] [Untitled]
@ -34,3 +37,6 @@
[Revoke blob URL after creating Request, will fetch] [Revoke blob URL after creating Request, will fetch]
expected: FAIL expected: FAIL
[Revoke blob URL after calling fetch, fetch should succeed]
expected: FAIL

View file

@ -1219,6 +1219,12 @@
{} {}
] ]
], ],
"clipboard-apis/async-write-blobs-read-blobs-manual.https.html": [
[
"clipboard-apis/async-write-blobs-read-blobs-manual.https.html",
{}
]
],
"clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [ "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [
[ [
"clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html", "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html",
@ -1231,6 +1237,12 @@
{} {}
] ]
], ],
"clipboard-apis/async-write-duplicate-mime-type-manual.https.html": [
[
"clipboard-apis/async-write-duplicate-mime-type-manual.https.html",
{}
]
],
"clipboard-apis/async-write-image-read-image-manual.https.html": [ "clipboard-apis/async-write-image-read-image-manual.https.html": [
[ [
"clipboard-apis/async-write-image-read-image-manual.https.html", "clipboard-apis/async-write-image-read-image-manual.https.html",
@ -306720,6 +306732,11 @@
{} {}
] ]
], ],
"portals/resources/portal-inside-iframe.html": [
[
{}
]
],
"portals/resources/portals-rendering-portal.html": [ "portals/resources/portals-rendering-portal.html": [
[ [
{} {}
@ -334858,9 +334875,21 @@
{} {}
] ]
], ],
"IndexedDB/bindings-inject-key.html": [ "IndexedDB/bindings-inject-keys-bypass-setters.html": [
[ [
"IndexedDB/bindings-inject-key.html", "IndexedDB/bindings-inject-keys-bypass-setters.html",
{}
]
],
"IndexedDB/bindings-inject-values-bypass-chain.html": [
[
"IndexedDB/bindings-inject-values-bypass-chain.html",
{}
]
],
"IndexedDB/bindings-inject-values-bypass-setters.html": [
[
"IndexedDB/bindings-inject-values-bypass-setters.html",
{} {}
] ]
], ],
@ -364982,6 +365011,12 @@
{} {}
] ]
], ],
"custom-elements/reactions/HTMLMeterElement.html": [
[
"custom-elements/reactions/HTMLMeterElement.html",
{}
]
],
"custom-elements/reactions/HTMLModElement.html": [ "custom-elements/reactions/HTMLModElement.html": [
[ [
"custom-elements/reactions/HTMLModElement.html", "custom-elements/reactions/HTMLModElement.html",
@ -364994,6 +365029,12 @@
{} {}
] ]
], ],
"custom-elements/reactions/HTMLOptGroupElement.html": [
[
"custom-elements/reactions/HTMLOptGroupElement.html",
{}
]
],
"custom-elements/reactions/HTMLOptionElement.html": [ "custom-elements/reactions/HTMLOptionElement.html": [
[ [
"custom-elements/reactions/HTMLOptionElement.html", "custom-elements/reactions/HTMLOptionElement.html",
@ -365012,6 +365053,18 @@
{} {}
] ]
], ],
"custom-elements/reactions/HTMLParamElement.html": [
[
"custom-elements/reactions/HTMLParamElement.html",
{}
]
],
"custom-elements/reactions/HTMLProgressElement.html": [
[
"custom-elements/reactions/HTMLProgressElement.html",
{}
]
],
"custom-elements/reactions/HTMLQuoteElement.html": [ "custom-elements/reactions/HTMLQuoteElement.html": [
[ [
"custom-elements/reactions/HTMLQuoteElement.html", "custom-elements/reactions/HTMLQuoteElement.html",
@ -383796,6 +383849,14 @@
} }
] ]
], ],
"html/browsers/the-window-object/close-method.window.js": [
[
"html/browsers/the-window-object/close-method.window.html",
{
"script_metadata": []
}
]
],
"html/browsers/the-window-object/closed-attribute.window.js": [ "html/browsers/the-window-object/closed-attribute.window.js": [
[ [
"html/browsers/the-window-object/closed-attribute.window.html", "html/browsers/the-window-object/closed-attribute.window.html",
@ -414528,6 +414589,12 @@
{} {}
] ]
], ],
"portals/portals-activate-inside-iframe.html": [
[
"portals/portals-activate-inside-iframe.html",
{}
]
],
"portals/portals-activate-no-browsing-context.html": [ "portals/portals-activate-no-browsing-context.html": [
[ [
"portals/portals-activate-no-browsing-context.html", "portals/portals-activate-no-browsing-context.html",
@ -477217,8 +477284,16 @@
"589eeabe6c6e6798406759e2d40fd28be2645473", "589eeabe6c6e6798406759e2d40fd28be2645473",
"testharness" "testharness"
], ],
"IndexedDB/bindings-inject-key.html": [ "IndexedDB/bindings-inject-keys-bypass-setters.html": [
"2fbe95ec8fc41878babd2ce1705787c8c4f4aa5f", "91d586bde35dcfc89da49068b1a3b63295552bb1",
"testharness"
],
"IndexedDB/bindings-inject-values-bypass-chain.html": [
"02fdb8a64ca1774ee8b3a2db40650141149dc684",
"testharness"
],
"IndexedDB/bindings-inject-values-bypass-setters.html": [
"c16c0a4e010f9805796cd93f9cbd1f141e6c91e5",
"testharness" "testharness"
], ],
"IndexedDB/clone-before-keypath-eval.html": [ "IndexedDB/clone-before-keypath-eval.html": [
@ -480474,7 +480549,7 @@
"testharness" "testharness"
], ],
"animation-worklet/playback-rate.https.html": [ "animation-worklet/playback-rate.https.html": [
"9c975814f1ed09b3e78493df177c3c0eddf74cdd", "5367497b831d87741bb4aca67d4e0efcee6389e2",
"testharness" "testharness"
], ],
"animation-worklet/references/translated-box-ref.html": [ "animation-worklet/references/translated-box-ref.html": [
@ -480542,11 +480617,11 @@
"testharness" "testharness"
], ],
"animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html": [ "animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html": [
"9841c575d1d76f9601f8c229c9c527618083fd21", "6f981854d38877d42b1c7b63afdb9ec989a32d42",
"reftest" "reftest"
], ],
"animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden-ref.html": [ "animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden-ref.html": [
"2004e6df905177a6165c66647e271938f6255685", "c6d7314e396e85225f245905f5afa17fb848b469",
"support" "support"
], ],
"animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden.https.html": [ "animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden.https.html": [
@ -480554,11 +480629,11 @@
"reftest" "reftest"
], ],
"animation-worklet/worklet-animation-with-scroll-timeline-ref.html": [ "animation-worklet/worklet-animation-with-scroll-timeline-ref.html": [
"f30c861fb9a49b5c2691be0aa2f82297be17de41", "fe92232d9afa24f78e9cc7cc3bae341ba2a471bc",
"support" "support"
], ],
"animation-worklet/worklet-animation-with-scroll-timeline-root-scroller-ref.html": [ "animation-worklet/worklet-animation-with-scroll-timeline-root-scroller-ref.html": [
"3b527dced72ee63fba3d5538d679b517ed583a26", "5810e1738c1d5927223037e97a7a14a52c405a5e",
"support" "support"
], ],
"animation-worklet/worklet-animation-with-scroll-timeline-root-scroller.https.html": [ "animation-worklet/worklet-animation-with-scroll-timeline-root-scroller.https.html": [
@ -483818,23 +483893,31 @@
"testharness" "testharness"
], ],
"clipboard-apis/async-navigator-clipboard-basics.https.html": [ "clipboard-apis/async-navigator-clipboard-basics.https.html": [
"3c1a0af76c2674960a871f82c908b9044240f967", "2d2ebf6c6c2667e1e2e465baa3dd78b657b97a7c",
"testharness" "testharness"
], ],
"clipboard-apis/async-write-blobs-read-blobs-manual.https.html": [
"e616b5ed794bfd38dbd2199685c622e7ee01ec15",
"manual"
],
"clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [ "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [
"ea6e9369517976642cf158d3273a56f321249813", "bc8511efa72c6c7db097f2a35d1b864d92359039",
"manual" "manual"
], ],
"clipboard-apis/async-write-blobtext-read-text-manual.https.html": [ "clipboard-apis/async-write-blobtext-read-text-manual.https.html": [
"ecb744a65704a2ff449391f84d6c20e1474a52d5", "b1b85de65e8b3bdef5a462152946617082041d79",
"manual"
],
"clipboard-apis/async-write-duplicate-mime-type-manual.https.html": [
"8e249fc993a810ff1bec41c4ecbccdac8c2982c4",
"manual" "manual"
], ],
"clipboard-apis/async-write-image-read-image-manual.https.html": [ "clipboard-apis/async-write-image-read-image-manual.https.html": [
"a8e2956b7e14784d917a2dcf3f5b7e571b81c042", "76d3d872c980447d46da093800dff8e1116b215d",
"manual" "manual"
], ],
"clipboard-apis/async-write-text-read-blobtext-manual.https.html": [ "clipboard-apis/async-write-text-read-blobtext-manual.https.html": [
"7e682f1dbdd4f02de5a00addf9be1fbdcc4ca8f0", "b54fa609b655d08083bfddd382cd76bb6447392f",
"manual" "manual"
], ],
"clipboard-apis/async-write-text-read-text-manual.https.html": [ "clipboard-apis/async-write-text-read-text-manual.https.html": [
@ -637493,6 +637576,10 @@
"1010aa7367cdada919acf1e22857e4404a681212", "1010aa7367cdada919acf1e22857e4404a681212",
"testharness" "testharness"
], ],
"custom-elements/reactions/HTMLMeterElement.html": [
"a152eb0f5a00f778906751cea58a187756e685f3",
"testharness"
],
"custom-elements/reactions/HTMLModElement.html": [ "custom-elements/reactions/HTMLModElement.html": [
"850fe170a50d21c1a5cb5a042f05bd2fb062d3fd", "850fe170a50d21c1a5cb5a042f05bd2fb062d3fd",
"testharness" "testharness"
@ -637501,6 +637588,10 @@
"4e53cdb0a510453960feccd2104109610f23e665", "4e53cdb0a510453960feccd2104109610f23e665",
"testharness" "testharness"
], ],
"custom-elements/reactions/HTMLOptGroupElement.html": [
"afa31bb465f33debae79cbc0cbef4de0db382680",
"testharness"
],
"custom-elements/reactions/HTMLOptionElement.html": [ "custom-elements/reactions/HTMLOptionElement.html": [
"418ef282b32fd5e7c29f21a0a9eb17b6c4796167", "418ef282b32fd5e7c29f21a0a9eb17b6c4796167",
"testharness" "testharness"
@ -637513,6 +637604,14 @@
"02e669bc7a75558686dd56b4ab8fc5918892de2e", "02e669bc7a75558686dd56b4ab8fc5918892de2e",
"testharness" "testharness"
], ],
"custom-elements/reactions/HTMLParamElement.html": [
"a3f24ddb54ed5026f093f916adb54c8508e1f6e8",
"testharness"
],
"custom-elements/reactions/HTMLProgressElement.html": [
"1be45f8d395b9f4ab6911c04151bd3d1cb45f28a",
"testharness"
],
"custom-elements/reactions/HTMLQuoteElement.html": [ "custom-elements/reactions/HTMLQuoteElement.html": [
"97ab10a170e66eba7e036321111e99dbba8bcff8", "97ab10a170e66eba7e036321111e99dbba8bcff8",
"testharness" "testharness"
@ -637814,7 +637913,7 @@
"support" "support"
], ],
"docs/_writing-tests/testdriver-tutorial.md": [ "docs/_writing-tests/testdriver-tutorial.md": [
"33c4fe31a40da2464b934e09ca711089d1f917aa", "56a2abdb60d024ee6ac221bd296c5bc5a701386e",
"support" "support"
], ],
"docs/_writing-tests/testdriver.md": [ "docs/_writing-tests/testdriver.md": [
@ -640206,7 +640305,7 @@
"testharness" "testharness"
], ],
"element-timing/cross-origin-element.sub.html": [ "element-timing/cross-origin-element.sub.html": [
"ed820d0e66558d1db01109a6c4227c960f15644b", "a122819fc499bde272daf1f8ccf086d856e69a62",
"testharness" "testharness"
], ],
"element-timing/cross-origin-iframe-element.sub.html": [ "element-timing/cross-origin-iframe-element.sub.html": [
@ -640226,7 +640325,7 @@
"testharness" "testharness"
], ],
"element-timing/observe-child-element.html": [ "element-timing/observe-child-element.html": [
"83cc2ef94b3fe929ffd87b6c4a49f7424e6be29b", "9166a4b0e6d129c356d74da2b81a6e02c08105b6",
"testharness" "testharness"
], ],
"element-timing/observe-elementtiming.html": [ "element-timing/observe-elementtiming.html": [
@ -648537,6 +648636,10 @@
"a9d42e26dea16afa9743d31aa7b72f3f09e46e68", "a9d42e26dea16afa9743d31aa7b72f3f09e46e68",
"support" "support"
], ],
"html/browsers/the-window-object/close-method.window.js": [
"0288f9cab8e1cc54eec5f51d295be771d566ff78",
"testharness"
],
"html/browsers/the-window-object/closed-attribute.window.js": [ "html/browsers/the-window-object/closed-attribute.window.js": [
"88a3beba6f10b80b0b90acdc0b0f957e1a17cefc", "88a3beba6f10b80b0b90acdc0b0f957e1a17cefc",
"testharness" "testharness"
@ -666778,7 +666881,7 @@
"support" "support"
], ],
"interfaces/webxr.idl": [ "interfaces/webxr.idl": [
"e91a50c28ee7acbcc5e04ed9e7b929def64afee3", "1bbe7efd2da4c5f17967257cb52d1c6139624ddf",
"support" "support"
], ],
"interfaces/worklets.idl": [ "interfaces/worklets.idl": [
@ -679909,6 +680012,10 @@
"33d91e37d9d9ac77c5243a60b42ce841645d248e", "33d91e37d9d9ac77c5243a60b42ce841645d248e",
"testharness" "testharness"
], ],
"portals/portals-activate-inside-iframe.html": [
"3c9149f485d1ac44b8d2303a4448a78ea7525243",
"testharness"
],
"portals/portals-activate-no-browsing-context.html": [ "portals/portals-activate-no-browsing-context.html": [
"6eebca9f9d982ffd38a96bb72ff0173bcfb07903", "6eebca9f9d982ffd38a96bb72ff0173bcfb07903",
"testharness" "testharness"
@ -679973,6 +680080,10 @@
"5043a158ea74ef173f166c0580f9c1a27242bd14", "5043a158ea74ef173f166c0580f9c1a27242bd14",
"support" "support"
], ],
"portals/resources/portal-inside-iframe.html": [
"5db75d5b5fd5c12d5a77181ee1cac48f76657a57",
"support"
],
"portals/resources/portals-rendering-portal.html": [ "portals/resources/portals-rendering-portal.html": [
"1b6f23f512da5bb7d1c7b5b85e48277470d2e146", "1b6f23f512da5bb7d1c7b5b85e48277470d2e146",
"support" "support"
@ -690230,7 +690341,7 @@
"support" "support"
], ],
"resources/chromium/webxr-test.js": [ "resources/chromium/webxr-test.js": [
"c6c21a6fed6c05a1981b9241d233a1b501fdf3ab", "8816273705806dd8efb9c33a52a61689f802ecf2",
"support" "support"
], ],
"resources/chromium/webxr-test.js.headers": [ "resources/chromium/webxr-test.js.headers": [
@ -699570,7 +699681,7 @@
"testharness" "testharness"
], ],
"svg/painting/parsing/stroke-dashoffset-valid.svg": [ "svg/painting/parsing/stroke-dashoffset-valid.svg": [
"ff913e06e4f849b5b14fac050986f697df9c81d8", "f34774e68d7afa7a336ed7cbd30b44695451d74d",
"testharness" "testharness"
], ],
"svg/painting/parsing/stroke-invalid.svg": [ "svg/painting/parsing/stroke-invalid.svg": [
@ -699630,7 +699741,7 @@
"testharness" "testharness"
], ],
"svg/painting/parsing/stroke-width-computed.svg": [ "svg/painting/parsing/stroke-width-computed.svg": [
"71dead0942fc2e660f6ffe239f00ef502c1a8728", "0d14a6651482baff1b9168f304306b28d6edc910",
"testharness" "testharness"
], ],
"svg/painting/parsing/stroke-width-invalid.svg": [ "svg/painting/parsing/stroke-width-invalid.svg": [
@ -699638,7 +699749,7 @@
"testharness" "testharness"
], ],
"svg/painting/parsing/stroke-width-valid.svg": [ "svg/painting/parsing/stroke-width-valid.svg": [
"02bca189f74fe91088ebe913f848b80dfc24868c", "f90781284dcf54b2e864e0607ae3e880a40531e1",
"testharness" "testharness"
], ],
"svg/painting/parsing/text-rendering-computed.svg": [ "svg/painting/parsing/text-rendering-computed.svg": [
@ -709230,11 +709341,11 @@
"testharness" "testharness"
], ],
"web-animations/animation-model/animation-types/property-list.js": [ "web-animations/animation-model/animation-types/property-list.js": [
"2d45574a61fcb5d44147ba78dd2b9a79c09762ac", "8d9b296ff74fdd907f94da417bfce1d9021eca48",
"support" "support"
], ],
"web-animations/animation-model/animation-types/property-types.js": [ "web-animations/animation-model/animation-types/property-types.js": [
"64a7eb4762754adf693074ee1bc7780c81ffbe3e", "80d3b8f77ff5589f2f4dc5ee69b4fa102786f85a",
"support" "support"
], ],
"web-animations/animation-model/animation-types/visibility.html": [ "web-animations/animation-model/animation-types/visibility.html": [

View file

@ -3,6 +3,3 @@
[scroll-behavior: smooth on DIV element] [scroll-behavior: smooth on DIV element]
expected: FAIL expected: FAIL
[Instant scrolling while doing history navigation.]
expected: FAIL

View file

@ -0,0 +1,37 @@
[HTMLMeterElement.html]
[max on HTMLMeterElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[high on HTMLMeterElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[min on HTMLMeterElement must enqueue an attributeChanged reaction when adding a new attribute]
expected: FAIL
[optimum on HTMLMeterElement must enqueue an attributeChanged reaction when adding a new attribute]
expected: FAIL
[low on HTMLMeterElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[low on HTMLMeterElement must enqueue an attributeChanged reaction when adding a new attribute]
expected: FAIL
[min on HTMLMeterElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[high on HTMLMeterElement must enqueue an attributeChanged reaction when adding a new attribute]
expected: FAIL
[value on HTMLMeterElement must enqueue an attributeChanged reaction when adding value content attribute]
expected: FAIL
[value on HTMLMeterElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[max on HTMLMeterElement must enqueue an attributeChanged reaction when adding a new attribute]
expected: FAIL
[optimum on HTMLMeterElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL

View file

@ -0,0 +1,7 @@
[HTMLOptGroupElement.html]
[label on HTMLOptGroupElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[label on HTMLOptGroupElement must enqueue an attributeChanged reaction when adding a new attribute]
expected: FAIL

View file

@ -0,0 +1,13 @@
[HTMLParamElement.html]
[value on HTMLParamElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[value on HTMLParamElement must enqueue an attributeChanged reaction when adding a new attribute]
expected: FAIL
[name on HTMLParamElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[name on HTMLParamElement must enqueue an attributeChanged reaction when adding a new attribute]
expected: FAIL

View file

@ -0,0 +1,13 @@
[HTMLProgressElement.html]
[max on HTMLProgressElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[max on HTMLProgressElement must enqueue an attributeChanged reaction when adding max content attribute]
expected: FAIL
[value on HTMLProgressElement must enqueue an attributeChanged reaction when adding value content attribute]
expected: FAIL
[value on HTMLProgressElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL

View file

@ -32,7 +32,7 @@
[single-byte-decoder.html?XMLHttpRequest] [single-byte-decoder.html?XMLHttpRequest]
expected: TIMEOUT expected: CRASH
[ISO-8859-2: iso_8859-2:1987 (XMLHttpRequest)] [ISO-8859-2: iso_8859-2:1987 (XMLHttpRequest)]
expected: FAIL expected: FAIL

View file

@ -312,9 +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>: separate response Content-Type: */* text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL

View file

@ -11,9 +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'NosniFF']
expected: FAIL
[Content-Type-Options%3A%20nosniff]
expected: FAIL

View file

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

View file

@ -0,0 +1,7 @@
[close-method.window.html]
[window.close() affects name targeting immediately]
expected: FAIL
[window.close() queues a task to discard, but window.closed knows immediately]
expected: FAIL

View file

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

View file

@ -0,0 +1,7 @@
[toggleEvent.html]
[Calling open twice on 'details' fires only one toggle event]
expected: FAIL
[Setting open=true to opened 'details' element should not fire a toggle event at the 'details' element]
expected: FAIL

View file

@ -1,4 +0,0 @@
[iframe_005.html]
[document.write external script into iframe write back into parent]
expected: FAIL

View file

@ -1,82 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>IndexedDB: ES bindings - Inject a key into a value</title>
<meta name="help" href="https://w3c.github.io/IndexedDB/#inject-key-into-value">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support-promises.js"></script>
<script>
promise_test(async t => {
const db = await createDatabase(t, db => {
db.createObjectStore('store');
});
let setter_called = false;
Object.defineProperty(Object.prototype, '10', {
configurable: true,
set: value => { setter_called = true; },
});
t.add_cleanup(() => { delete Object.prototype['10']; });
const tx = db.transaction('store', 'readwrite');
const result = await promiseForRequest(t, tx.objectStore('store').put(
'value', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'key']));
assert_false(setter_called,
'Setter should not be called for key result.');
assert_true(result.hasOwnProperty('10'),
'Result should have own-property overriding prototype setter.');
assert_equals(result[10], 'key',
'Result should have expected property.');
}, 'Returning keys to script should bypass prototype setters');
promise_test(async t => {
const db = await createDatabase(t, db => {
db.createObjectStore('store', {autoIncrement: true, keyPath: 'id'});
});
let setter_called = false;
Object.defineProperty(Object.prototype, 'id', {
configurable: true,
set: value => { setter_called = true; },
});
t.add_cleanup(() => { delete Object.prototype['id']; });
const tx = db.transaction('store', 'readwrite');
tx.objectStore('store').put({});
const result = await promiseForRequest(t, tx.objectStore('store').get(1));
assert_false(setter_called,
'Setter should not be called for key result.');
assert_true(result.hasOwnProperty('id'),
'Result should have own-property overriding prototype setter.');
assert_equals(result.id, 1,
'Own property should match primary key generator value');
}, 'Returning values to script should bypass prototype setters');
promise_test(async t => {
const db = await createDatabase(t, db => {
db.createObjectStore('store', {autoIncrement: true, keyPath: 'a.b.c'});
});
Object.prototype.a = {b: {c: 'on proto'}};
t.add_cleanup(() => { delete Object.prototype.a; });
const tx = db.transaction('store', 'readwrite');
tx.objectStore('store').put({});
const result = await promiseForRequest(t, tx.objectStore('store').get(1));
assert_true(result.hasOwnProperty('a'),
'Result should have own-properties overriding prototype.');
assert_true(result.a.hasOwnProperty('b'),
'Result should have own-properties overriding prototype.');
assert_true(result.a.b.hasOwnProperty('c'),
'Result should have own-properties overriding prototype.');
assert_equals(result.a.b.c, 1,
'Own property should match primary key generator value');
assert_equals(Object.prototype.a.b.c, 'on proto',
'Prototype should not be modified');
}, 'Returning values to script should bypass prototype chain');
</script>

View file

@ -0,0 +1,35 @@
<!doctype html>
<meta charset=utf-8>
<title>IndexedDB: ES bindings - Inject a key into a value - Keys bypass setters</title>
<meta name="help"
href="https://w3c.github.io/IndexedDB/#inject-key-into-value-keys-bypass-setters">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support-promises.js"></script>
<script>
promise_test(async t => {
const db = await createDatabase(t, db => {
db.createObjectStore('store');
});
let setter_called = false;
Object.defineProperty(Object.prototype, '10', {
configurable: true,
set: value => { setter_called = true; },
});
t.add_cleanup(() => { delete Object.prototype['10']; });
const tx = db.transaction('store', 'readwrite');
const result = await promiseForRequest(t, tx.objectStore('store').put(
'value', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'key']));
assert_false(setter_called,
'Setter should not be called for key result.');
assert_true(result.hasOwnProperty('10'),
'Result should have own-property overriding prototype setter.');
assert_equals(result[10], 'key',
'Result should have expected property.');
}, 'Returning keys to script should bypass prototype setters');
</script>

View file

@ -0,0 +1,35 @@
<!doctype html>
<meta charset=utf-8>
<title>IndexedDB: ES bindings - Inject a key into a value - Values bypass chain</title>
<meta name="help"
href="https://w3c.github.io/IndexedDB/#inject-key-into-value-values-bypass-chain">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support-promises.js"></script>
<script>
promise_test(async t => {
const db = await createDatabase(t, db => {
db.createObjectStore('store', {autoIncrement: true, keyPath: 'a.b.c'});
});
Object.prototype.a = {b: {c: 'on proto'}};
t.add_cleanup(() => { delete Object.prototype.a; });
const tx = db.transaction('store', 'readwrite');
tx.objectStore('store').put({});
const result = await promiseForRequest(t, tx.objectStore('store').get(1));
assert_true(result.hasOwnProperty('a'),
'Result should have own-properties overriding prototype.');
assert_true(result.a.hasOwnProperty('b'),
'Result should have own-properties overriding prototype.');
assert_true(result.a.b.hasOwnProperty('c'),
'Result should have own-properties overriding prototype.');
assert_equals(result.a.b.c, 1,
'Own property should match primary key generator value');
assert_equals(Object.prototype.a.b.c, 'on proto',
'Prototype should not be modified');
}, 'Returning values to script should bypass prototype chain');
</script>

View file

@ -0,0 +1,36 @@
<!doctype html>
<meta charset=utf-8>
<title>IndexedDB: ES bindings - Inject a key into a value - Values bypass
setters</title>
<meta name="help"
href="https://w3c.github.io/IndexedDB/#inject-key-into-value-values-bypass-setters">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support-promises.js"></script>
<script>
promise_test(async t => {
const db = await createDatabase(t, db => {
db.createObjectStore('store', {autoIncrement: true, keyPath: 'id'});
});
let setter_called = false;
Object.defineProperty(Object.prototype, 'id', {
configurable: true,
set: value => { setter_called = true; },
});
t.add_cleanup(() => { delete Object.prototype['id']; });
const tx = db.transaction('store', 'readwrite');
tx.objectStore('store').put({});
const result = await promiseForRequest(t, tx.objectStore('store').get(1));
assert_false(setter_called,
'Setter should not be called for key result.');
assert_true(result.hasOwnProperty('id'),
'Result should have own-property overriding prototype setter.');
assert_equals(result.id, 1,
'Own property should match primary key generator value');
}, 'Returning values to script should bypass prototype setters');
</script>

View file

@ -15,46 +15,83 @@ window.assert_times_equal = (actual, expected, description) => {
</script> </script>
<script src="/web-animations/testcommon.js"></script> <script src="/web-animations/testcommon.js"></script>
<script src="common.js"></script> <script src="common.js"></script>
<style>
.scroller {
overflow: auto;
height: 100px;
width: 100px;
}
.contents {
height: 1000px;
width: 100%;
}
</style>
<body> <body>
<div id="log"></div> <div id="log"></div>
<script> <script>
'use strict'; 'use strict';
function InstantiateWorkletAnimation(test) { function createWorkletAnimation(test) {
const DURATION = 10000; // ms const DURATION = 10000; // ms
const KEYFRAMES = { height : ['100px', '50px'] }; const KEYFRAMES = { transform: ['translateY(100px)', 'translateY(200px)'] };
return new WorkletAnimation('passthrough', new KeyframeEffect(createDiv(test), return new WorkletAnimation('passthrough', new KeyframeEffect(createDiv(test),
KEYFRAMES, DURATION), document.timeline); KEYFRAMES, DURATION), document.timeline);
} }
function createScroller(test) {
var scroller = createDiv(test);
scroller.innerHTML = "<div class='contents'></div>";
scroller.classList.add('scroller');
return scroller;
}
function createScrollLinkedWorkletAnimation(test) {
const timeline = new ScrollTimeline({
scrollSource: createScroller(test),
timeRange: 1000
});
const DURATION = 10000; // ms
const KEYFRAMES = { transform: ['translateY(100px)', 'translateY(200px)'] };
return new WorkletAnimation('passthrough', new KeyframeEffect(createDiv(test),
KEYFRAMES, DURATION), timeline);
}
setup(setupAndRegisterTests, {explicit_done: true});
function setupAndRegisterTests() {
registerPassthroughAnimator().then(() => {
promise_test(async t => { promise_test(async t => {
await registerPassthroughAnimator(); const animation = createWorkletAnimation(t);
const animation = InstantiateWorkletAnimation(t);
animation.playbackRate = 0.5; animation.playbackRate = 0.5;
animation.play(); animation.play();
assert_equals(animation.currentTime, 0, assert_equals(animation.currentTime, 0,
'Zero current time is not affected by playbackRate.'); 'Zero current time is not affected by playbackRate.');
}, 'Zero current time is not affected by playbackRate set while the animation is in idle state.'); }, 'Zero current time is not affected by playbackRate set while the ' +
'animation is in idle state.');
promise_test(async t => { promise_test(async t => {
await registerPassthroughAnimator(); const animation = createWorkletAnimation(t);
const animation = InstantiateWorkletAnimation(t);
animation.play(); animation.play();
animation.playbackRate = 0.5; animation.playbackRate = 0.5;
assert_equals(animation.currentTime, 0, assert_equals(animation.currentTime, 0,
'Zero current time is not affected by playbackRate.'); 'Zero current time is not affected by playbackRate.');
}, 'Zero current time is not affected by playbackRate set while the animation is in play-pending state.'); }, 'Zero current time is not affected by playbackRate set while the ' +
'animation is in play-pending state.');
promise_test(async t => { promise_test(async t => {
await registerPassthroughAnimator(); const animation = createWorkletAnimation(t);
const animation = InstantiateWorkletAnimation(t);
const playbackRate = 2; const playbackRate = 2;
animation.play(); animation.play();
await waitForNextFrame(); await waitForAnimationFrameWithCondition(_=> {
return animation.playState == "running"
});
// Make sure the current time is not Zero.
await waitForDocumentTimelineAdvance();
// Set playback rate while the animation is playing. // Set playback rate while the animation is playing.
const prevCurrentTime = animation.currentTime; const prevCurrentTime = animation.currentTime;
@ -62,79 +99,255 @@ promise_test(async t => {
assert_times_equal(animation.currentTime, prevCurrentTime, assert_times_equal(animation.currentTime, prevCurrentTime,
'The current time should stay unaffected by setting playback rate.'); 'The current time should stay unaffected by setting playback rate.');
}, 'Non zero current time is not affected by playbackRate set while the animation is in play state.'); }, 'Non zero current time is not affected by playbackRate set while the ' +
'animation is in play state.');
promise_test(async t => { promise_test(async t => {
await registerPassthroughAnimator(); const animation = createWorkletAnimation(t);
const animation = InstantiateWorkletAnimation(t); const playbackRate = 0.2;
const playbackRate = 2;
animation.play(); animation.play();
await waitForNextFrame(); await waitForAnimationFrameWithCondition(_=> {
return animation.playState == "running"
});
// Set playback rate while the animation is playing // Set playback rate while the animation is playing.
const prevCurrentTime = animation.currentTime; const prevCurrentTime = animation.currentTime;
const prevTimelineTime = document.timeline.currentTime; const prevTimelineTime = document.timeline.currentTime;
animation.playbackRate = playbackRate; animation.playbackRate = playbackRate;
// Play the animation some more. // Play the animation some more.
await waitForNextFrame(); await waitForDocumentTimelineAdvance();
const currentTime = animation.currentTime; const currentTime = animation.currentTime;
const currentTimelineTime = document.timeline.currentTime; const currentTimelineTime = document.timeline.currentTime;
assert_times_equal(currentTime - prevCurrentTime, (currentTimelineTime - prevTimelineTime) * playbackRate, assert_times_equal(
'The current time should increase two times faster than timeline.'); currentTime - prevCurrentTime,
(currentTimelineTime - prevTimelineTime) * playbackRate,
'The current time should increase 0.2 times faster than timeline.');
}, 'The playback rate affects the rate of progress of the current time.'); }, 'The playback rate affects the rate of progress of the current time.');
promise_test(async t => { promise_test(async t => {
await registerPassthroughAnimator(); const animation = createWorkletAnimation(t);
const animation = InstantiateWorkletAnimation(t);;
const playbackRate = 2; const playbackRate = 2;
// Set playback rate while the animation is in 'idle' state. // Set playback rate while the animation is in 'idle' state.
animation.playbackRate = playbackRate; animation.playbackRate = playbackRate;
animation.play();
const prevTimelineTime = document.timeline.currentTime; const prevTimelineTime = document.timeline.currentTime;
animation.play();
await waitForNextFrame(); await waitForAnimationFrameWithCondition(_=> {
return animation.playState == "running"
});
await waitForDocumentTimelineAdvance();
const currentTime = animation.currentTime; const currentTime = animation.currentTime;
const timelineTime = document.timeline.currentTime; const timelineTime = document.timeline.currentTime;
assert_times_equal(currentTime, (timelineTime - prevTimelineTime) * playbackRate, assert_times_equal(
currentTime,
(timelineTime - prevTimelineTime) * playbackRate,
'The current time should increase two times faster than timeline.'); 'The current time should increase two times faster than timeline.');
}, 'The playback rate set before the animation started playing affects the ' + }, 'The playback rate set before the animation started playing affects ' +
'rate of progress of the current time'); 'the rate of progress of the current time');
promise_test(async t => { promise_test(async t => {
await registerPassthroughAnimator();
const timing = { duration: 100, const timing = { duration: 100,
easing: 'linear', easing: 'linear',
fill: 'none', fill: 'none',
iterations: 1 iterations: 1
}; };
// TODO(crbug.com/937382): Currently composited
// workletAnimation.currentTime and the corresponding
// effect.getComputedTiming().localTime are computed by main and
// compositing threads respectively and, as a result, don't match.
// To workaround this limitation we compare the output of two identical
// animations that only differ in playback rate. The expectation is that
// their output matches after taking their playback rates into
// consideration. This works since these two animations start at the same
// time on the same thread.
// Once the issue is fixed, this test needs to change so expected
// effect.getComputedTiming().localTime is compared against
// workletAnimation.currentTime.
const target = createDiv(t); const target = createDiv(t);
const keyframeEffect = new KeyframeEffect(target, { opacity: [0, 1] }, timing); const targetRef = createDiv(t);
const animation = new WorkletAnimation('passthrough', keyframeEffect, document.timeline); const keyframeEffect = new KeyframeEffect(
target, { opacity: [1, 0] }, timing);
const keyframeEffectRef = new KeyframeEffect(
targetRef, { opacity: [1, 0] }, timing);
const animation = new WorkletAnimation(
'passthrough', keyframeEffect, document.timeline);
const animationRef = new WorkletAnimation(
'passthrough', keyframeEffectRef, document.timeline);
const playbackRate = 2;
animation.playbackRate = playbackRate;
animation.play();
animationRef.play();
// wait until local times are synced back to the main thread.
await waitForAnimationFrameWithCondition(_ => {
return getComputedStyle(target).opacity != '1';
});
assert_times_equal(
keyframeEffect.getComputedTiming().localTime,
keyframeEffectRef.getComputedTiming().localTime * playbackRate,
'When playback rate is set on WorkletAnimation, the underlying ' +
'effect\'s timing should be properly updated.');
assert_approx_equals(
1 - Number(getComputedStyle(target).opacity),
(1 - Number(getComputedStyle(targetRef).opacity)) * playbackRate,
0.001,
'When playback rate is set on WorkletAnimation, the underlying effect' +
' should produce correct visual result.');
}, 'When playback rate is updated, the underlying effect is properly ' +
'updated with the current time of its WorkletAnimation and produces ' +
'correct visual result.');
promise_test(async t => {
const animation = createScrollLinkedWorkletAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const timeRange = animation.timeline.timeRange;
scroller.scrollTop = 0.2 * maxScroll;
animation.playbackRate = 0.5;
animation.play();
await waitForAnimationFrameWithCondition(_=> {
return animation.playState == "running"
});
assert_equals(animation.currentTime, 0.2 * timeRange * 0.5,
'Initial current time is scaled by playbackRate.');
}, 'Initial current time is scaled by playbackRate set while ' +
'scroll-linked animation is in idle state.');
promise_test(async t => {
const animation = createScrollLinkedWorkletAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const timeRange = animation.timeline.timeRange;
scroller.scrollTop = 0.2 * maxScroll;
animation.play();
animation.playbackRate = 0.5;
assert_equals(animation.currentTime, 0.2 * timeRange,
'Initial current time is not affected by playbackRate.');
}, 'Initial current time is not affected by playbackRate set while '+
'scroll-linked animation is in play-pending state.');
promise_test(async t => {
const animation = createScrollLinkedWorkletAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const timeRange = animation.timeline.timeRange;
const playbackRate = 2; const playbackRate = 2;
animation.play(); animation.play();
scroller.scrollTop = 0.2 * maxScroll;
await waitForAnimationFrameWithCondition(_=> {
return animation.playState == "running"
});
// Set playback rate while the animation is playing.
animation.playbackRate = playbackRate;
assert_times_equal(animation.currentTime, 0.2 * timeRange,
'The current time should stay unaffected by setting playback rate.');
}, 'The current time is not affected by playbackRate set while the ' +
'scroll-linked animation is in play state.');
promise_test(async t => {
const animation = createScrollLinkedWorkletAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const playbackRate = 2;
const timeRange = animation.timeline.timeRange;
animation.play();
await waitForAnimationFrameWithCondition(_=> {
return animation.playState == "running"
});
scroller.scrollTop = 0.1 * maxScroll;
// Set playback rate while the animation is playing.
animation.playbackRate = playbackRate; animation.playbackRate = playbackRate;
await waitForNextFrame(); scroller.scrollTop = 0.2 * maxScroll;
assert_times_equal(keyframeEffect.getComputedTiming().localTime, animation.currentTime, assert_times_equal(
'When playback rate is set on WorkletAnimation, the underlying effect\'s timing should be properly updated.'); animation.currentTime - 0.1 * timeRange, 0.1 * timeRange * playbackRate,
'The current time should increase twice faster than scroll timeline.');
}, 'Scroll-linked animation playback rate affects the rate of progress ' +
'of the current time.');
assert_approx_equals(Number(getComputedStyle(target).opacity), promise_test(async t => {
animation.currentTime / 100, 0.001, const animation = createScrollLinkedWorkletAnimation(t);
'When playback rate is set on WorkletAnimation, the underlying effect should produce correct visual result.'); const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const timeRange = animation.timeline.timeRange;
const playbackRate = 2;
}, 'When playback rate is updated, the underlying effect is properly updated ' + // Set playback rate while the animation is in 'idle' state.
'with the current time of its WorkletAnimation and produces correct ' + animation.playbackRate = playbackRate;
'visual result.'); animation.play();
await waitForAnimationFrameWithCondition(_=> {
return animation.playState == "running"
});
scroller.scrollTop = 0.2 * maxScroll;
assert_times_equal(animation.currentTime, 0.2 * timeRange * playbackRate,
'The current time should increase two times faster than timeline.');
}, 'The playback rate set before scroll-linked animation started playing ' +
'affects the rate of progress of the current time');
promise_test(async t => {
const scroller = createScroller(t);
const timeline = new ScrollTimeline({
scrollSource: scroller,
timeRange: 1000
});
const timing = { duration: 1000,
easing: 'linear',
fill: 'none',
iterations: 1
};
const target = createDiv(t);
const keyframeEffect = new KeyframeEffect(
target, { opacity: [1, 0] }, timing);
const animation = new WorkletAnimation(
'passthrough', keyframeEffect, timeline);
const playbackRate = 2;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const timeRange = timeline.timeRange;
animation.play();
animation.playbackRate = playbackRate;
await waitForAnimationFrameWithCondition(_=> {
return animation.playState == "running"
});
scroller.scrollTop = 0.2 * maxScroll;
// wait until local times are synced back to the main thread.
await waitForAnimationFrameWithCondition(_ => {
return getComputedStyle(target).opacity != '1';
});
assert_times_equal(
keyframeEffect.getComputedTiming().localTime,
0.2 * timeRange * playbackRate,
'When playback rate is set on WorkletAnimation, the underlying ' +
'effect\'s timing should be properly updated.');
assert_approx_equals(
Number(getComputedStyle(target).opacity),
1 - 0.2 * timeRange * playbackRate / 1000, 0.001,
'When playback rate is set on WorkletAnimation, the underlying ' +
'effect should produce correct visual result.');
}, 'When playback rate is updated, the underlying effect is properly ' +
'updated with the current time of its scroll-linked WorkletAnimation ' +
'and produces correct visual result.');
done();
});
}
</script> </script>
</body> </body>

View file

@ -61,7 +61,10 @@
const animation = new WorkletAnimation('passthrough', effect, timeline); const animation = new WorkletAnimation('passthrough', effect, timeline);
animation.play(); animation.play();
// Ensure that the WorkletAnimation will have been started on the compositor.
waitForAsyncAnimationFrames(1).then(_ => { waitForAsyncAnimationFrames(1).then(_ => {
// Now return the scroller to the world, which will cause it to be composited
// and the animation should update on the compositor side.
scroller.classList.remove('removed'); scroller.classList.remove('removed');
const maxScroll = scroller.scrollHeight - scroller.clientHeight; const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.5 * maxScroll; scroller.scrollTop = 0.5 * maxScroll;

View file

@ -7,6 +7,7 @@
background-color: green; background-color: green;
transform: translate(0, 100px); transform: translate(0, 100px);
opacity: 0.5; opacity: 0.5;
will-change: transform; /* force compositing */
} }
#covered { #covered {
@ -19,6 +20,7 @@
overflow: hidden; overflow: hidden;
height: 100px; height: 100px;
width: 100px; width: 100px;
will-change: transform; /* force compositing */
} }
#contents { #contents {

View file

@ -7,6 +7,7 @@
background-color: green; background-color: green;
transform: translate(0, 100px); transform: translate(0, 100px);
opacity: 0.5; opacity: 0.5;
will-change: transform; /* force compositing */
} }
#covered { #covered {
@ -19,8 +20,7 @@
overflow: auto; overflow: auto;
height: 100px; height: 100px;
width: 100px; width: 100px;
/* TODO(yigu): Rewrite the test to not rely on compositing. */ will-change: transform; /* force compositing */
will-change: transform;
} }
#contents { #contents {

View file

@ -14,6 +14,7 @@
background-color: green; background-color: green;
transform: translate(0, 100px); transform: translate(0, 100px);
opacity: 0.5; opacity: 0.5;
will-change: transform; /* force compositing */
} }
#covered { #covered {

View file

@ -11,32 +11,25 @@ test(() => {
assert_equals(navigator.clipboard, navigator.clipboard); assert_equals(navigator.clipboard, navigator.clipboard);
}, "navigator.clipboard exists"); }, "navigator.clipboard exists");
/* clipboard.write(text/plain Blob) */
promise_test(async () => { promise_test(async () => {
const blob = new Blob(["hello"], {type: 'text/plain'}); const blob = new Blob(["hello"], {type: 'text/plain'});
await navigator.clipboard.write(blob); await navigator.clipboard.write([blob]);
}, "navigator.clipboard.write(text/plain Blob) succeeds"); }, "navigator.clipboard.write([text/plain Blob]) succeeds");
/* clipboard.write(invalid input) */
promise_test(async t => { promise_test(async t => {
await promise_rejects(t, new TypeError(), await promise_rejects(t, new TypeError(),
navigator.clipboard.write()); navigator.clipboard.write());
}, "navigator.clipboard.write() fails (expect Blob)"); }, "navigator.clipboard.write() fails (expect [Blob])");
promise_test(async t => { promise_test(async t => {
await promise_rejects(t, new TypeError(), await promise_rejects(t, new TypeError(),
navigator.clipboard.write(null)); navigator.clipboard.write(null));
}, "navigator.clipboard.write(null) fails (expect Blob)"); }, "navigator.clipboard.write(null) fails (expect [Blob])");
promise_test(async t => { promise_test(async t => {
await promise_rejects(t, new TypeError(), await promise_rejects(t, new TypeError(),
navigator.clipboard.write("Bad string")); navigator.clipboard.write("Bad string"));
}, "navigator.clipboard.write(DOMString) fails (expect Blob)"); }, "navigator.clipboard.write(DOMString) fails (expect [Blob])");
/* clipboard.writeText() */
promise_test(async () => { promise_test(async () => {
await navigator.clipboard.writeText("New clipboard text"); await navigator.clipboard.writeText("New clipboard text");
@ -47,27 +40,21 @@ promise_test(async t => {
navigator.clipboard.writeText()); navigator.clipboard.writeText());
}, "navigator.clipboard.writeText() fails (expect DOMString)"); }, "navigator.clipboard.writeText() fails (expect DOMString)");
/* clipboard.write(image/png Blob) */
promise_test(async () => { promise_test(async () => {
const fetched = await fetch( const fetched = await fetch(
'http://localhost:8001/clipboard-apis/resources/greenbox.png'); 'http://localhost:8001/clipboard-apis/resources/greenbox.png');
const image = await fetched.blob(); const image = await fetched.blob();
await navigator.clipboard.write(image); await navigator.clipboard.write([image]);
}, "navigator.clipboard.write(image/png Blob) succeeds"); }, "navigator.clipboard.write([image/png Blob]) succeeds");
/* text/plain or image/png Blob clipboard.read() */
promise_test(async () => { promise_test(async () => {
const result = await navigator.clipboard.read(); const result = await navigator.clipboard.read();
assert_true(result instanceof Blob); assert_true(result instanceof Array);
assert_true(result[0] instanceof Blob);
assert_equals(typeof result, "object"); assert_equals(typeof result, "object");
}, "navigator.clipboard.read() succeeds"); }, "navigator.clipboard.read() succeeds");
/* clipboard.readText() */
promise_test(async () => { promise_test(async () => {
const result = await navigator.clipboard.readText(); const result = await navigator.clipboard.readText();
assert_equals(typeof result, "string"); assert_equals(typeof result, "string");

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>
Async Clipboard write blobs -> read blobs tests
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
async function loadBlob(fileName) {
const fetched = await fetch(fileName);
return await fetched.blob();
}
promise_test(async t => {
const blobText = new Blob(["test text"], {type: 'text/plain'});
const blobImage = await loadBlob('resources/greenbox.png');
assert_equals(blobText.type, "text/plain");
assert_equals(blobImage.type, "image/png");
await navigator.clipboard.write([blobText, blobImage]);
const output = await navigator.clipboard.read();
assert_equals(output.length, 2);
assert_equals(output[0].type, "text/plain");
assert_equals(output[1].type, "image/png");
}, "Verify write and read clipboard (multiple blobs)");
</script>
<p>
Note: This is a manual test because it writes/reads to the shared system
clipboard and thus cannot be run async with other tests that might interact
with the clipboard.
</p>

View file

@ -1,6 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Async Clipboard write (text/plain Blob) -> read (text/plain Blob) tests</title> <title>
Async Clipboard write ([text/plain Blob]) -> read ([text/plain Blob]) tests
</title>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script> <script>
@ -8,8 +10,10 @@ async function readWriteTest(textInput) {
promise_test(async t => { promise_test(async t => {
const blobInput = new Blob([textInput], {type: 'text/plain'}); const blobInput = new Blob([textInput], {type: 'text/plain'});
await navigator.clipboard.write(blobInput); await navigator.clipboard.write([blobInput]);
const blobOutput = await navigator.clipboard.read(); const blobsOutput = await navigator.clipboard.read();
assert_equals(blobsOutput.length, 1);
const blobOutput = blobsOutput[0];
assert_equals(blobOutput.type, "text/plain"); assert_equals(blobOutput.type, "text/plain");
const textOutput = await (new Response(blobOutput)).text(); const textOutput = await (new Response(blobOutput)).text();
@ -17,7 +21,7 @@ async function readWriteTest(textInput) {
}, "Verify write and read clipboard given text: " + textInput); }, "Verify write and read clipboard given text: " + textInput);
} }
readWriteTest("Clipboard write (text/plain Blob) -> read (text/plain Blob) test"); readWriteTest("Clipboard write ([text/plain Blob]) -> read ([text/plain Blob]) test");
readWriteTest("non-Latin1 text encoding test データ"); readWriteTest("non-Latin1 text encoding test データ");
</script> </script>
<p> <p>

View file

@ -1,6 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Async Clipboard write (text/plain Blob) -> readText tests</title> <title>Async Clipboard write ([text/plain Blob]) -> readText tests</title>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script> <script>
@ -8,14 +8,14 @@ async function readWriteTest(textInput) {
promise_test(async t => { promise_test(async t => {
const blobInput = new Blob([textInput], {type: 'text/plain'}); const blobInput = new Blob([textInput], {type: 'text/plain'});
await navigator.clipboard.write(blobInput); await navigator.clipboard.write([blobInput]);
const textOutput = await navigator.clipboard.readText(); const textOutput = await navigator.clipboard.readText();
assert_equals(textOutput, textInput); assert_equals(textOutput, textInput);
}, "Verify write and read clipboard given text: " + textInput); }, "Verify write and read clipboard given text: " + textInput);
} }
readWriteTest("Clipboard write (text/plain Blob) -> read text test"); readWriteTest("Clipboard write ([text/plain Blob]) -> read text test");
readWriteTest("non-Latin1 text encoding test データ"); readWriteTest("non-Latin1 text encoding test データ");
</script> </script>
<p> <p>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>
Async Clipboard write duplicate mime type test
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
promise_test(async t => {
const blobText = new Blob(["test text"], {type: 'text/plain'});
const blobText2 = new Blob(["test text"], {type: 'text/plain'});
assert_equals(blobText.type, "text/plain");
assert_equals(blobText2.type, "text/plain");
await promise_rejects(t, 'NotAllowedError',
navigator.clipboard.write([blobText, blobText2]));
}, "Verify write and read clipboard (multiple blobs)");
</script>
<p>
Note: This is a manual test because it writes/reads to the shared system
clipboard and thus cannot be run async with other tests that might interact
with the clipboard.
</p>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<title> <title>
Async Clipboard write image/png Blob -> read image/png Blob tests Async Clipboard write [image/png Blob] -> read [image/png Blob] tests
</title> </title>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
@ -37,21 +37,23 @@ async function loadBlob(fileName) {
} }
promise_test(async t => { promise_test(async t => {
const input = await loadBlob('resources/greenbox.png'); const blobInput = await loadBlob('resources/greenbox.png');
assert_equals(input.type, "image/png"); assert_equals(blobInput.type, "image/png");
await navigator.clipboard.write(input); await navigator.clipboard.write([blobInput]);
const output = await navigator.clipboard.read(); const blobsOutput = await navigator.clipboard.read();
assert_equals(output.type, "image/png"); assert_equals(blobsOutput.length, 1);
const blobOutput = blobsOutput[0];
assert_equals(blobOutput.type, "image/png");
document.getElementById('image-on-clipboard').src = document.getElementById('image-on-clipboard').src =
window.URL.createObjectURL(output); window.URL.createObjectURL(blobOutput);
const comparableInput = await getBitmapString(input); const comparableInput = await getBitmapString(blobInput);
const comparableOutput = await getBitmapString(output); const comparableOutput = await getBitmapString(blobOutput);
assert_equals(comparableOutput, comparableInput); assert_equals(comparableOutput, comparableInput);
}, "Verify write and read clipboard (DOMString)"); }, "Verify write and read clipboard ([image/png Blob])");
</script> </script>
<p> <p>
Note: This is a manual test because it writes/reads to the shared system Note: This is a manual test because it writes/reads to the shared system

View file

@ -1,13 +1,15 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Async Clipboard writeText -> read (text/plain Blob) tests</title> <title>Async Clipboard writeText -> read ([text/plain Blob]) tests</title>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script> <script>
async function readWriteTest(textInput) { async function readWriteTest(textInput) {
promise_test(async t => { promise_test(async t => {
await navigator.clipboard.writeText(textInput); await navigator.clipboard.writeText(textInput);
const blobOutput = await navigator.clipboard.read(); const blobsOutput = await navigator.clipboard.read();
assert_equals(blobsOutput.length, 1);
const blobOutput = blobsOutput[0];
assert_equals(blobOutput.type, "text/plain"); assert_equals(blobOutput.type, "text/plain");
const textOutput = await (new Response(blobOutput)).text(); const textOutput = await (new Response(blobOutput)).text();
@ -15,7 +17,7 @@ async function readWriteTest(textInput) {
}, "Verify write and read clipboard given text: " + textInput); }, "Verify write and read clipboard given text: " + textInput);
} }
readWriteTest("Clipboard write text -> read (text/plain Blob) test"); readWriteTest("Clipboard write text -> read ([text/plain Blob]) test");
readWriteTest("non-Latin1 text encoding test データ"); readWriteTest("non-Latin1 text encoding test データ");
</script> </script>
<p> <p>

View file

@ -0,0 +1,55 @@
<!DOCTYPE html>
<title>Custom Elements: CEReactions on HTMLMeterElement interface</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<meta name="assert" content="value, min, max, low, high, optimum of
HTMLMeterElement interface must have CEReactions">
<meta name="help" content="https://html.spec.whatwg.org/#the-meter-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/custom-elements-helpers.js"></script>
<script src="./resources/reactions.js"></script>
<body>
<script>
function getParentElement() {
return document.body;
}
function setAttributes(instance) {
instance.setAttribute('value', '0.6');
}
testReflectAttribute(
'value', 'value', '0.3',
'0.4', 'value on HTMLMeterElement', 'meter',
HTMLMeterElement
);
testReflectAttributeWithDependentAttributes(
'min', 'min', '0.1',
'0.2', 'min on HTMLMeterElement', 'meter',
getParentElement, instance => setAttributes(instance), HTMLMeterElement
);
testReflectAttributeWithDependentAttributes(
'max', 'max', '2',
'3', 'max on HTMLMeterElement', 'meter',
getParentElement, instance => setAttributes(instance), HTMLMeterElement
);
testReflectAttributeWithDependentAttributes(
'low', 'low', '0.1',
'0.2', 'low on HTMLMeterElement', 'meter',
getParentElement, instance => setAttributes(instance), HTMLMeterElement
);
testReflectAttributeWithDependentAttributes(
'high', 'high', '2',
'3', 'high on HTMLMeterElement', 'meter',
getParentElement, instance => setAttributes(instance), HTMLMeterElement
);
testReflectAttributeWithDependentAttributes(
'optimum', 'optimum', '0.3',
'0.4', 'optimum on HTMLMeterElement', 'meter',
getParentElement, instance => setAttributes(instance), HTMLMeterElement
);
</script>
</body>

View file

@ -0,0 +1,38 @@
<!DOCTYPE html>
<title>Custom Elements: CEReactions on HTMLOptGroupElement interface</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<meta name="assert" content="disabled, label of
HTMLOptGroupElement interface must have CEReactions">
<meta name="help" content="https://html.spec.whatwg.org/#the-optgroup-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/custom-elements-helpers.js"></script>
<script src="./resources/reactions.js"></script>
<body>
<script>
function getParentElement() {
let element = document.createElement('select');
document.body.appendChild(element);
return element;
}
function setAttributes(instance) {
instance.setAttribute('label', 'group1');
}
testReflectBooleanAttributeWithDependentAttributes(
'disabled', 'disabled', 'disabled on HTMLOptGroupElement',
'optgroup', getParentElement, instance => setAttributes(instance),
HTMLOptGroupElement
);
testReflectAttributeWithParentNode(
'label', 'label', 'group1',
'group2', 'label on HTMLOptGroupElement', 'optgroup',
getParentElement, HTMLOptGroupElement
);
</script>
</body>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<title>Custom Elements: CEReactions on HTMLParamElement interface</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<meta name="assert" content="name, value of HTMLParamElement
interface must have CEReactions">
<meta name="help" content="https://html.spec.whatwg.org/#the-param-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/custom-elements-helpers.js"></script>
<script src="./resources/reactions.js"></script>
<body>
<script>
function getParentElement() {
let element = document.createElement('object');
element['type'] = 'image/png';
element['data'] = '/images/blue.png';
document.body.appendChild(element);
return element;
}
function setAttributes(instance, attribute, value) {
instance.setAttribute(attribute, value);
}
testReflectAttributeWithDependentAttributes(
'name', 'name', 'image1',
'image2', 'name on HTMLParamElement', 'param',
getParentElement, instance => setAttributes(instance, 'value', 'blue'),
HTMLParamElement
);
testReflectAttributeWithDependentAttributes(
'value', 'value', 'blue1',
'blue2', 'value on HTMLParamElement', 'param',
getParentElement, instance => setAttributes(instance, 'name', 'image'),
HTMLParamElement
);
</script>
</body>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<title>Custom Elements: CEReactions on HTMLProgressElement interface</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<meta name="assert" content="value, max of HTMLProgressElement
interface must have CEReactions">
<meta name="help" content="https://html.spec.whatwg.org/#the-progress-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/custom-elements-helpers.js"></script>
<script src="./resources/reactions.js"></script>
<script>
testReflectAttribute(
'value', 'value', '0.15',
'0.2', 'value on HTMLProgressElement', 'progress',
HTMLProgressElement
);
testReflectAttribute(
'max', 'max', '2',
'4', 'max on HTMLProgressElement', 'progress',
HTMLProgressElement
);
</script>

View file

@ -239,7 +239,7 @@ class SeleniumProtocol(Protocol):
### Firefox ### Firefox
We use the [set window rect](http://marionette-client.readthedocs.io/en/master/reference.html#marionette_driver.marionette.Marionette.set_window_rect) Marionette command. We use the [set window rect](https://firefox-source-docs.mozilla.org/python/marionette_driver.html#marionette_driver.marionette.Marionette.set_window_rect) Marionette command.
We will use [executormarionette](tools/wptrunner/wptrunner/executors/executormarionette.py) and use the Marionette Python API. We will use [executormarionette](tools/wptrunner/wptrunner/executors/executormarionette.py) and use the Marionette Python API.

View file

@ -1,15 +1,27 @@
<!DOCTYPE HTML> <!DOCTYPE HTML>
<meta charset=utf-8> <meta charset=utf-8>
<title>Element Timing: do NOT observe cross-origin images</title> <title>Element Timing: observe cross-origin images but without startTime</title>
<body> <body>
<style>
body {
margin: 0;
}
</style>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/element-timing-helpers.js"></script> <script src="resources/element-timing-helpers.js"></script>
<script> <script>
async_test((t) => { async_test((t) => {
const pathname = 'http://{{domains[www]}}:{{ports[http][1]}}'
+ '/element-timing/resources/square100.png';
const observer = new PerformanceObserver( const observer = new PerformanceObserver(
t.step_func_done((entryList) => { t.step_func_done((entryList) => {
assert_unreached("We should not observe a cross origin element."); assert_equals(entryList.getEntries().length, 1);
const entry = entryList.getEntries()[0];
checkElement(entry, pathname, 'my_image', 0);
assert_equals(entry.startTime, 0,
'The startTime of a cross-origin image should be 0.');
checkRect(entry, [0, 100, 0, 100]);
}) })
); );
observer.observe({entryTypes: ['element']}); observer.observe({entryTypes: ['element']});
@ -19,15 +31,8 @@
window.onload = t.step_func(() => { window.onload = t.step_func(() => {
// Add a cross origin image resource. // Add a cross origin image resource.
const img = document.createElement('img'); const img = document.createElement('img');
img.src = 'http://{{domains[www]}}:{{ports[http][1]}}' img.src = pathname;
+ '/element-timing/resources/square100.png';
img.setAttribute('elementtiming', 'my_image'); img.setAttribute('elementtiming', 'my_image');
img.onload = t.step_func(() => {
t.step_timeout( () => {
// After some wait, assume observer did not receive the entry, so the test passes.
t.done();
}, 100);
});
document.body.appendChild(img); document.body.appendChild(img);
}); });
}, 'Cross-origin image element is NOT observable.'); }, 'Cross-origin image element is NOT observable.');

View file

@ -1,6 +1,6 @@
<!DOCTYPE HTML> <!DOCTYPE HTML>
<meta charset=utf-8> <meta charset=utf-8>
<title>Element Timing: observe elements from same-origin iframes</title> <title>Element Timing: do NOT observe elements from same-origin iframes</title>
<body> <body>
<style> <style>
body { body {

View file

@ -0,0 +1,39 @@
function assert_closed_opener(w, closed, opener) {
assert_equals(w.closed, closed);
assert_equals(w.opener, opener);
}
async_test(t => {
const openee = window.open();
assert_closed_opener(openee, false, self);
openee.onunload = t.step_func(() => {
assert_closed_opener(openee, true, self);
t.step_timeout(() => {
assert_closed_opener(openee, true, null);
t.done();
}, 0);
});
openee.close();
assert_closed_opener(openee, true, self);
}, "window.close() queues a task to discard, but window.closed knows immediately");
async_test(t => {
const openee = window.open("", "greatname");
assert_closed_opener(openee, false, self);
openee.close();
assert_closed_opener(openee, true, self);
const openee2 = window.open("", "greatname");
assert_not_equals(openee, openee2);
assert_closed_opener(openee, true, self); // Ensure second window.open() call was synchronous
openee2.onunload = t.step_func(() => {
assert_closed_opener(openee2, true, self);
t.step_timeout(() => {
assert_closed_opener(openee, true, null);
assert_closed_opener(openee2, true, null);
t.done();
}, 0);
});
openee2.close();
assert_closed_opener(openee, true, self); // Ensure second close() call was synchronous
assert_closed_opener(openee2, true, self);
}, "window.close() affects name targeting immediately");

View file

@ -133,7 +133,6 @@ enum XREye {
[SecureContext, Exposed=Window] interface XRView { [SecureContext, Exposed=Window] interface XRView {
readonly attribute XREye eye; readonly attribute XREye eye;
readonly attribute Float32Array projectionMatrix; readonly attribute Float32Array projectionMatrix;
readonly attribute Float32Array viewMatrix;
readonly attribute XRRigidTransform transform; readonly attribute XRRigidTransform transform;
}; };
@ -150,6 +149,8 @@ interface XRRigidTransform {
readonly attribute DOMPointReadOnly position; readonly attribute DOMPointReadOnly position;
readonly attribute DOMPointReadOnly orientation; readonly attribute DOMPointReadOnly orientation;
readonly attribute Float32Array matrix; readonly attribute Float32Array matrix;
XRRigidTransform inverse();
}; };
[SecureContext, Exposed=Window, [SecureContext, Exposed=Window,
@ -200,6 +201,7 @@ dictionary XRWebGLLayerInit {
boolean depth = true; boolean depth = true;
boolean stencil = false; boolean stencil = false;
boolean alpha = true; boolean alpha = true;
boolean ignoreDepthValues = false;
double framebufferScaleFactor = 1.0; double framebufferScaleFactor = 1.0;
}; };
@ -214,6 +216,7 @@ interface XRWebGLLayer : XRLayer {
readonly attribute boolean depth; readonly attribute boolean depth;
readonly attribute boolean stencil; readonly attribute boolean stencil;
readonly attribute boolean alpha; readonly attribute boolean alpha;
readonly attribute boolean ignoreDepthValues;
readonly attribute WebGLFramebuffer framebuffer; readonly attribute WebGLFramebuffer framebuffer;
readonly attribute unsigned long framebufferWidth; readonly attribute unsigned long framebufferWidth;

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
promise_test(async t => {
var iframe = document.createElement("iframe");
iframe.src = "resources/portal-inside-iframe.html"
var waitForLoad = new Promise((resolve, reject) => {
iframe.onload = resolve;
});
document.body.appendChild(iframe);
await waitForLoad;
const portal = iframe.contentDocument.getElementById("portal");
return promise_rejects(t, "InvalidStateError", portal.activate());
}, "activating portal inside iframe should fail");
</script>
</body>

View file

@ -0,0 +1,4 @@
<!DOCTYPE html>
<body>
<portal id="portal" />
</body>

View file

@ -328,11 +328,18 @@ class MockRuntime {
} }
getEnvironmentIntegrationProvider(environmentProviderRequest) { getEnvironmentIntegrationProvider(environmentProviderRequest) {
let environmentProviderBinding = new mojo.AssociatedBinding( this.environmentProviderBinding_ = new mojo.AssociatedBinding(
device.mojom.XREnvironmentIntegrationProvider, this, device.mojom.XREnvironmentIntegrationProvider, this,
environmentProviderRequest); environmentProviderRequest);
} }
// Note that if getEnvironmentProvider hasn't finished running yet this will
// be undefined. It's recommended that you allow a successful task to post
// first before attempting to close.
closeEnvironmentIntegrationProvider() {
this.environmentProviderBinding_.close();
}
updateSessionGeometry(frame_size, display_rotation) { updateSessionGeometry(frame_size, display_rotation) {
// This function must exist to ensure that calls to it do not crash, but we // This function must exist to ensure that calls to it do not crash, but we
// do not have any use for this data at present. // do not have any use for this data at present.

View file

@ -13,10 +13,10 @@
<h:script src="/css/support/parsing-testcommon.js"/> <h:script src="/css/support/parsing-testcommon.js"/>
<script><![CDATA[ <script><![CDATA[
test_valid_value("stroke-dashoffset", "0"); test_valid_value("stroke-dashoffset", "0", "0px");
test_valid_value("stroke-dashoffset", "10px"); test_valid_value("stroke-dashoffset", "10px");
test_valid_value("stroke-dashoffset", "-20%"); test_valid_value("stroke-dashoffset", "-20%");
test_valid_value("stroke-dashoffset", "30"); test_valid_value("stroke-dashoffset", "30", "30px");
test_valid_value("stroke-dashoffset", "40Q", "40q"); test_valid_value("stroke-dashoffset", "40Q", "40q");
test_valid_value("stroke-dashoffset", "calc(2em + 3ex)"); test_valid_value("stroke-dashoffset", "calc(2em + 3ex)");

Before

Width:  |  Height:  |  Size: 975 B

After

Width:  |  Height:  |  Size: 990 B

Before After
Before After

View file

@ -50,9 +50,9 @@ for (let lengthUnit of lengthUnits) {
target.style.strokeWidth = length; target.style.strokeWidth = length;
const ref = document.getElementById('ref'); const ref = document.getElementById('ref');
ref.style.wordSpacing = length; ref.style.textIndent = length;
assert_equals(getComputedStyle(target).strokeWidth, getComputedStyle(ref).wordSpacing); assert_equals(getComputedStyle(target).strokeWidth, getComputedStyle(ref).textIndent);
}, 'stroke-width computes ' + lengthUnit + ' lengths'); }, 'stroke-width computes ' + lengthUnit + ' lengths');
} }

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

View file

@ -13,8 +13,8 @@
<h:script src="/css/support/parsing-testcommon.js"/> <h:script src="/css/support/parsing-testcommon.js"/>
<script><![CDATA[ <script><![CDATA[
test_valid_value("stroke-width", "0"); test_valid_value("stroke-width", "0", "0px");
test_valid_value("stroke-width", "10"); test_valid_value("stroke-width", "10", "10px");
test_valid_value("stroke-width", "1px"); test_valid_value("stroke-width", "1px");
test_valid_value("stroke-width", "calc(2em + 3ex)"); test_valid_value("stroke-width", "calc(2em + 3ex)");
test_valid_value("stroke-width", "4%"); test_valid_value("stroke-width", "4%");

Before

Width:  |  Height:  |  Size: 990 B

After

Width:  |  Height:  |  Size: 1,005 B

Before After
Before After

View file

@ -1218,7 +1218,7 @@ const gCSSProperties = {
// https://svgwg.org/svg2-draft/painting.html#StrokeDasharrayProperty // https://svgwg.org/svg2-draft/painting.html#StrokeDasharrayProperty
types: [ types: [
'dasharray', 'dasharray',
{ type: 'discrete', options: [ [ 'none', '10, 20' ] ] } { type: 'discrete', options: [ [ 'none', '10px, 20px' ] ] }
] ]
}, },
'stroke-dashoffset': { 'stroke-dashoffset': {

View file

@ -473,14 +473,14 @@ const lengthPercentageOrCalcType = {
}; };
const positiveNumberType = { const positiveNumberType = {
testInterpolation: (property, setup) => { testInterpolation: (property, setup, expectedUnit='') => {
test(t => { test(t => {
const idlName = propertyToIDL(property); const idlName = propertyToIDL(property);
const target = createTestElement(t, setup); const target = createTestElement(t, setup);
const animation = target.animate({ [idlName]: [1.1, 1.5] }, const animation = target.animate({ [idlName]: [1.1, 1.5] },
{ duration: 1000, fill: 'both' }); { duration: 1000, fill: 'both' });
testAnimationSamples(animation, idlName, testAnimationSamples(animation, idlName,
[{ time: 500, expected: '1.3' }]); [{ time: 500, expected: '1.3' + expectedUnit }]);
}, `${property} supports animating as a positive number`); }, `${property} supports animating as a positive number`);
}, },
@ -2622,7 +2622,7 @@ const rectType = {
const dasharrayType = { const dasharrayType = {
testInterpolation: (property, setup) => { testInterpolation: (property, setup) => {
percentageType.testInterpolation(property, setup); percentageType.testInterpolation(property, setup);
positiveNumberType.testInterpolation(property, setup); positiveNumberType.testInterpolation(property, setup, 'px');
test(t => { test(t => {
const idlName = propertyToIDL(property); const idlName = propertyToIDL(property);
@ -2633,7 +2633,7 @@ const dasharrayType = {
{ duration: 1000, fill: 'both' }); { duration: 1000, fill: 'both' });
testAnimationSamples( testAnimationSamples(
animation, idlName, animation, idlName,
[{ time: 500, expected: '6, 12, 8, 12, 10, 6, 10, 16, 4, 8, 14, 10' }]); [{ time: 500, expected: '6px, 12px, 8px, 12px, 10px, 6px, 10px, 16px, 4px, 8px, 14px, 10px' }]);
}, `${property} supports animating as a dasharray (mismatched length)`); }, `${property} supports animating as a dasharray (mismatched length)`);
test(t => { test(t => {
@ -2645,8 +2645,8 @@ const dasharrayType = {
{ duration: 1000, fill: 'both' }); { duration: 1000, fill: 'both' });
testAnimationSamples( testAnimationSamples(
animation, idlName, animation, idlName,
[{ time: 500, expected: '4, 40%, 4, 6' }]); [{ time: 500, expected: '4px, 40%, 4px, 6px' }]);
}, `${property} supports animating as a dasharray (mixed number and percentage)`); }, `${property} supports animating as a dasharray (mixed lengths and percentages)`);
}, },
@ -2665,7 +2665,7 @@ const dasharrayType = {
{ duration: 1000, composite }); { duration: 1000, composite });
testAnimationSamples( testAnimationSamples(
animation, idlName, animation, idlName,
[{ time: 0, expected: '1, 2, 3, 4, 5' }]); [{ time: 0, expected: '1px, 2px, 3px, 4px, 5px' }]);
}, `${property}: dasharray`); }, `${property}: dasharray`);
}, },