aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWPT Sync Bot <josh+wptsync@joshmatthews.net>2020-06-16 08:20:51 +0000
committerWPT Sync Bot <josh+wptsync@joshmatthews.net>2020-06-16 10:58:22 +0000
commit1a24e35f18a311873ee77ffb5f046abea033a341 (patch)
tree059da1082512802b25780e8610ed0e41e78d681c
parent19c1f72eb2fe5178311161b6c85a67956a5a69b3 (diff)
downloadservo-1a24e35f18a311873ee77ffb5f046abea033a341.tar.gz
servo-1a24e35f18a311873ee77ffb5f046abea033a341.zip
Update web-platform-tests to revision 4af6af604800559d2c58cf3561621ae43e28aaa8
-rw-r--r--tests/wpt/metadata-layout-2020/FileAPI/url/url-in-tags-revoke.window.js.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-003.html.ini (renamed from tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-004.html.ini)2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-border-box.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-content-box.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-fill-box.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-initial.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-stroke-box.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-view-box.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-border-box.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-content-box.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-fill-box.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-initial.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-stroke-box.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-view-box.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPoint-001.html.ini4
-rw-r--r--tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPosition.html.ini3
-rw-r--r--tests/wpt/metadata-layout-2020/fetch/content-type/response.window.js.ini19
-rw-r--r--tests/wpt/metadata-layout-2020/fetch/content-type/script.window.js.ini3
-rw-r--r--tests/wpt/metadata-layout-2020/fetch/nosniff/parsing-nosniff.window.js.ini3
-rw-r--r--tests/wpt/metadata-layout-2020/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini4
-rw-r--r--tests/wpt/metadata-layout-2020/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini4
-rw-r--r--tests/wpt/metadata-layout-2020/html/dom/elements/the-innertext-idl-attribute/getter.html.ini301
-rw-r--r--tests/wpt/metadata-layout-2020/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini12
-rw-r--r--tests/wpt/metadata-layout-2020/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini2
-rw-r--r--tests/wpt/metadata-layout-2020/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini1
-rw-r--r--tests/wpt/metadata-layout-2020/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini4
-rw-r--r--tests/wpt/metadata-layout-2020/html/semantics/scripting-1/the-script-element/execution-timing/077.html.ini4
-rw-r--r--tests/wpt/metadata-layout-2020/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini4
-rw-r--r--tests/wpt/metadata-layout-2020/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini5
-rw-r--r--tests/wpt/metadata-layout-2020/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.ini5
-rw-r--r--tests/wpt/metadata-layout-2020/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.ini (renamed from tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request.sub.https.html.ini)5
-rw-r--r--tests/wpt/metadata-layout-2020/webmessaging/with-ports/017.html.ini5
-rw-r--r--tests/wpt/metadata-layout-2020/webmessaging/with-ports/018.html.ini5
-rw-r--r--tests/wpt/metadata-layout-2020/webmessaging/without-ports/017.html.ini5
-rw-r--r--tests/wpt/metadata-layout-2020/webmessaging/without-ports/018.html.ini5
-rw-r--r--tests/wpt/metadata-layout-2020/workers/semantics/run-a-worker/003.html.ini1
-rw-r--r--tests/wpt/metadata/FileAPI/url/url-in-tags-revoke.window.js.ini2
-rw-r--r--tests/wpt/metadata/MANIFEST.json462
-rw-r--r--tests/wpt/metadata/css/CSS2/floats/hit-test-floats-003.html.ini (renamed from tests/wpt/metadata/css/CSS2/floats/hit-test-floats-004.html.ini)2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/cssbox-border-box.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/cssbox-content-box.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/cssbox-fill-box.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/cssbox-initial.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/cssbox-stroke-box.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/cssbox-view-box.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/svgbox-border-box.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/svgbox-content-box.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/svgbox-fill-box.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/svgbox-initial.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/svgbox-stroke-box.html.ini2
-rw-r--r--tests/wpt/metadata/css/css-transforms/transform-box/svgbox-view-box.html.ini2
-rw-r--r--tests/wpt/metadata/css/cssom-view/elementFromPoint-001.html.ini4
-rw-r--r--tests/wpt/metadata/css/cssom-view/elementFromPosition.html.ini3
-rw-r--r--tests/wpt/metadata/fetch/content-type/response.window.js.ini19
-rw-r--r--tests/wpt/metadata/fetch/content-type/script.window.js.ini3
-rw-r--r--tests/wpt/metadata/fetch/nosniff/parsing-nosniff.window.js.ini3
-rw-r--r--tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini4
-rw-r--r--tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini4
-rw-r--r--tests/wpt/metadata/html/dom/elements/the-innertext-idl-attribute/getter.html.ini9
-rw-r--r--tests/wpt/metadata/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini12
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini2
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini1
-rw-r--r--tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini4
-rw-r--r--tests/wpt/metadata/html/semantics/scripting-1/the-script-element/execution-timing/077.html.ini4
-rw-r--r--tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini4
-rw-r--r--tests/wpt/metadata/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini5
-rw-r--r--tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.ini5
-rw-r--r--tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.ini5
-rw-r--r--tests/wpt/metadata/webmessaging/with-ports/017.html.ini5
-rw-r--r--tests/wpt/metadata/webmessaging/with-ports/018.html.ini5
-rw-r--r--tests/wpt/metadata/webmessaging/without-ports/017.html.ini5
-rw-r--r--tests/wpt/metadata/webmessaging/without-ports/018.html.ini5
-rw-r--r--tests/wpt/metadata/workers/semantics/run-a-worker/003.html.ini1
-rw-r--r--tests/wpt/web-platform-tests/beacon/resources/beacon.py61
-rw-r--r--tests/wpt/web-platform-tests/beacon/resources/content-type.py22
-rw-r--r--tests/wpt/web-platform-tests/beacon/resources/inspect-header.py22
-rw-r--r--tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-no-room-after-000.html12
-rw-r--r--tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-no-room-after-001.html14
-rw-r--r--tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-000.html16
-rw-r--r--tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-001.html15
-rw-r--r--tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-002.html15
-rw-r--r--tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-003.html18
-rw-r--r--tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-004.html18
-rw-r--r--tests/wpt/web-platform-tests/css/css-contain/counter-scoping-002.html2
-rw-r--r--tests/wpt/web-platform-tests/css/css-lists/parsing/counter-set-computed.html23
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-border-box.html30
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-content-box.html30
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-fill-box.html30
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-initial.html29
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-stroke-box.html30
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-view-box.html30
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/reference/cssbox-ref.html14
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/reference/svgbox-ref.html14
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-border-box.html28
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-content-box.html28
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-fill-box.html28
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-initial.html27
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-stroke-box.html28
-rw-r--r--tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-view-box.html28
-rw-r--r--tests/wpt/web-platform-tests/css/css-transitions/Document-getAnimations.tentative.html7
-rw-r--r--tests/wpt/web-platform-tests/css/css-typed-om/the-stylepropertymap/properties/counter-set.html24
-rw-r--r--tests/wpt/web-platform-tests/docs/writing-tests/general-guidelines.md2
-rw-r--r--tests/wpt/web-platform-tests/docs/writing-tests/lint-tool.md38
-rw-r--r--tests/wpt/web-platform-tests/docs/writing-tests/testharness-api.md43
-rw-r--r--tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-delete.tentative.html340
-rw-r--r--tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-forwarddelete.tentative.html356
-rw-r--r--tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-insertlinebreak.tentative.html150
-rw-r--r--tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-insertparagraph.tentative.html72
-rw-r--r--tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-inserttext.tentative.html526
-rw-r--r--tests/wpt/web-platform-tests/fetch/api/resources/trickle.py8
-rw-r--r--tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/none.https.html6
-rw-r--r--tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp-about-blank.html23
-rw-r--r--tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp-about-srcdoc.html22
-rw-r--r--tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp.https.html35
-rw-r--r--tests/wpt/web-platform-tests/html/cross-origin-opener-policy/coop-sandbox.https.html3
-rw-r--r--tests/wpt/web-platform-tests/html/cross-origin-opener-policy/popup-same-origin-non-initial-about-blank.https.html12
-rw-r--r--tests/wpt/web-platform-tests/html/obsolete/requirements-for-implementations/the-marquee-element-0/marquee-adopt-to-inactive-document-crash.html9
-rw-r--r--tests/wpt/web-platform-tests/lint.ignore5
-rw-r--r--tests/wpt/web-platform-tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001-ref.html125
-rw-r--r--tests/wpt/web-platform-tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001.html166
-rw-r--r--tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html26
-rw-r--r--tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.headers1
-rw-r--r--tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html (renamed from tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html)9
-rw-r--r--tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.headers (renamed from tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.html.headers)0
-rw-r--r--tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.html22
-rw-r--r--tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html.headers2
-rw-r--r--tests/wpt/web-platform-tests/referrer-policy/generic/resources/referrer.py9
-rw-r--r--tests/wpt/web-platform-tests/resources/test/tests/functional/step_wait.html59
-rw-r--r--tests/wpt/web-platform-tests/resources/test/tests/functional/step_wait_func.html50
-rw-r--r--tests/wpt/web-platform-tests/resources/testharness.js99
-rw-r--r--tests/wpt/web-platform-tests/tools/wpt/browser.py33
-rw-r--r--tests/wpt/web-platform-tests/url/urlencoded-parser.any.js6
-rw-r--r--tests/wpt/web-platform-tests/url/urlsearchparams-constructor.any.js22
-rw-r--r--tests/wpt/web-platform-tests/url/urlsearchparams-stringifier.any.js12
-rw-r--r--tests/wpt/web-platform-tests/webrtc/receiver-track-live.https.html (renamed from tests/wpt/web-platform-tests/webrtc/receiver-track-live.html)0
-rw-r--r--tests/wpt/web-platform-tests/workers/baseurl/beta/import.py2
-rw-r--r--tests/wpt/web-platform-tests/workers/baseurl/beta/importScripts.py2
-rw-r--r--tests/wpt/web-platform-tests/workers/baseurl/beta/sharedworker.py2
-rw-r--r--tests/wpt/web-platform-tests/workers/baseurl/beta/worker.py2
-rw-r--r--tests/wpt/web-platform-tests/workers/baseurl/beta/xhr-worker.py2
-rw-r--r--tests/wpt/web-platform-tests/workers/baseurl/beta/xhr.py2
-rw-r--r--tests/wpt/web-platform-tests/workers/interfaces/WorkerGlobalScope/location/helper-redirect.py2
-rw-r--r--tests/wpt/web-platform-tests/workers/modules/resources/export-credentials.py14
-rw-r--r--tests/wpt/web-platform-tests/workers/modules/resources/export-referrer-checker.py8
-rw-r--r--tests/wpt/web-platform-tests/workers/modules/resources/postmessage-credentials.py28
-rw-r--r--tests/wpt/web-platform-tests/workers/modules/resources/postmessage-referrer-checker.py22
-rw-r--r--tests/wpt/web-platform-tests/workers/semantics/encodings/003-1.py2
-rw-r--r--tests/wpt/web-platform-tests/workers/support/imported_script.py2
-rw-r--r--tests/wpt/web-platform-tests/workers/support/nosiniff-error-worker.py4
-rw-r--r--tests/wpt/web-platform-tests/xhr/send-data-string-invalid-unicode.any.js46
150 files changed, 3695 insertions, 413 deletions
diff --git a/tests/wpt/metadata-layout-2020/FileAPI/url/url-in-tags-revoke.window.js.ini b/tests/wpt/metadata-layout-2020/FileAPI/url/url-in-tags-revoke.window.js.ini
index 76b44d9e9cf..3605e8f3fc9 100644
--- a/tests/wpt/metadata-layout-2020/FileAPI/url/url-in-tags-revoke.window.js.ini
+++ b/tests/wpt/metadata-layout-2020/FileAPI/url/url-in-tags-revoke.window.js.ini
@@ -4,7 +4,7 @@
expected: TIMEOUT
[Opening a blob URL in a new window immediately before revoking it works.]
- expected: FAIL
+ expected: TIMEOUT
[Fetching a blob URL immediately before revoking it works in an iframe.]
expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-004.html.ini b/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-003.html.ini
index 4bfb0c2053a..f29da48a2a0 100644
--- a/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-004.html.ini
+++ b/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-003.html.ini
@@ -1,4 +1,4 @@
-[hit-test-floats-004.html]
+[hit-test-floats-003.html]
[Miss float below something else]
expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-border-box.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-border-box.html.ini
new file mode 100644
index 00000000000..709fcddaefb
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-border-box.html.ini
@@ -0,0 +1,2 @@
+[cssbox-border-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-content-box.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-content-box.html.ini
new file mode 100644
index 00000000000..39281adef09
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-content-box.html.ini
@@ -0,0 +1,2 @@
+[cssbox-content-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-fill-box.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-fill-box.html.ini
new file mode 100644
index 00000000000..7331e7a0d1c
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-fill-box.html.ini
@@ -0,0 +1,2 @@
+[cssbox-fill-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-initial.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-initial.html.ini
new file mode 100644
index 00000000000..5e34c3d474a
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-initial.html.ini
@@ -0,0 +1,2 @@
+[cssbox-initial.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-stroke-box.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-stroke-box.html.ini
new file mode 100644
index 00000000000..7a339b8bc80
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-stroke-box.html.ini
@@ -0,0 +1,2 @@
+[cssbox-stroke-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-view-box.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-view-box.html.ini
new file mode 100644
index 00000000000..a54685ae780
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/cssbox-view-box.html.ini
@@ -0,0 +1,2 @@
+[cssbox-view-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-border-box.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-border-box.html.ini
new file mode 100644
index 00000000000..8c34a3b478c
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-border-box.html.ini
@@ -0,0 +1,2 @@
+[svgbox-border-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-content-box.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-content-box.html.ini
new file mode 100644
index 00000000000..95cc7d4fe16
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-content-box.html.ini
@@ -0,0 +1,2 @@
+[svgbox-content-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-fill-box.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-fill-box.html.ini
new file mode 100644
index 00000000000..fe46f80ca70
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-fill-box.html.ini
@@ -0,0 +1,2 @@
+[svgbox-fill-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-initial.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-initial.html.ini
new file mode 100644
index 00000000000..f26e8f2bf7f
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-initial.html.ini
@@ -0,0 +1,2 @@
+[svgbox-initial.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-stroke-box.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-stroke-box.html.ini
new file mode 100644
index 00000000000..dc663e13f6c
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-stroke-box.html.ini
@@ -0,0 +1,2 @@
+[svgbox-stroke-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-view-box.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-view-box.html.ini
new file mode 100644
index 00000000000..2a9e2356590
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-box/svgbox-view-box.html.ini
@@ -0,0 +1,2 @@
+[svgbox-view-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPoint-001.html.ini b/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPoint-001.html.ini
new file mode 100644
index 00000000000..e38782d8c85
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPoint-001.html.ini
@@ -0,0 +1,4 @@
+[elementFromPoint-001.html]
+ [CSSOM View - 5 - extensions to the Document interface]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPosition.html.ini b/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPosition.html.ini
index c131078eace..23c61ede1a1 100644
--- a/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPosition.html.ini
+++ b/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPosition.html.ini
@@ -17,3 +17,6 @@
[test the top of layer]
expected: FAIL
+ [test some point of the element: top left corner]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata-layout-2020/fetch/content-type/response.window.js.ini b/tests/wpt/metadata-layout-2020/fetch/content-type/response.window.js.ini
index ef47d932a1f..7e7bd2ce287 100644
--- a/tests/wpt/metadata-layout-2020/fetch/content-type/response.window.js.ini
+++ b/tests/wpt/metadata-layout-2020/fetch/content-type/response.window.js.ini
@@ -312,18 +312,27 @@
[Response: combined response Content-Type: text/html;" \\" text/plain ";charset=GBK]
expected: NOTRUN
- [<iframe>: combined response Content-Type: text/html */*]
+ [<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
- [<iframe>: combined response Content-Type: text/html;" text/plain]
+ [<iframe>: combined response Content-Type: */* text/html]
expected: FAIL
- [<iframe>: separate response Content-Type: text/html;" text/plain]
+ [<iframe>: separate response Content-Type: text/html */*]
+ expected: FAIL
+
+ [<iframe>: separate response Content-Type: text/plain */*]
+ expected: FAIL
+
+ [<iframe>: combined response Content-Type: text/html */*;charset=gbk]
+ expected: FAIL
+
+ [<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL
- [<iframe>: separate response Content-Type: text/html */*;charset=gbk]
+ [<iframe>: combined response Content-Type: text/html;" \\" text/plain]
expected: FAIL
- [<iframe>: separate response Content-Type: text/html;" \\" text/plain]
+ [<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/fetch/content-type/script.window.js.ini b/tests/wpt/metadata-layout-2020/fetch/content-type/script.window.js.ini
index d2df9b78483..258fe374697 100644
--- a/tests/wpt/metadata-layout-2020/fetch/content-type/script.window.js.ini
+++ b/tests/wpt/metadata-layout-2020/fetch/content-type/script.window.js.ini
@@ -56,3 +56,6 @@
[separate text/javascript x/x]
expected: FAIL
+ [separate text/javascript ]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata-layout-2020/fetch/nosniff/parsing-nosniff.window.js.ini b/tests/wpt/metadata-layout-2020/fetch/nosniff/parsing-nosniff.window.js.ini
index 30e1b851fd4..ec1fd06e1f5 100644
--- a/tests/wpt/metadata-layout-2020/fetch/nosniff/parsing-nosniff.window.js.ini
+++ b/tests/wpt/metadata-layout-2020/fetch/nosniff/parsing-nosniff.window.js.ini
@@ -11,3 +11,6 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL
+ [X-Content-Type-Options%3A%0D%0AX-Content-Type-Options%3A%20nosniff]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata-layout-2020/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini b/tests/wpt/metadata-layout-2020/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini
deleted file mode 100644
index 87b07c3e670..00000000000
--- a/tests/wpt/metadata-layout-2020/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[traverse_the_history_1.html]
- [Multiple history traversals from the same task]
- expected: FAIL
-
diff --git a/tests/wpt/metadata-layout-2020/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini b/tests/wpt/metadata-layout-2020/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
deleted file mode 100644
index 51f8272a6de..00000000000
--- a/tests/wpt/metadata-layout-2020/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[traverse_the_history_3.html]
- [Multiple history traversals, last would be aborted]
- expected: FAIL
-
diff --git a/tests/wpt/metadata-layout-2020/html/dom/elements/the-innertext-idl-attribute/getter.html.ini b/tests/wpt/metadata-layout-2020/html/dom/elements/the-innertext-idl-attribute/getter.html.ini
new file mode 100644
index 00000000000..f2c57c9cc19
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/html/dom/elements/the-innertext-idl-attribute/getter.html.ini
@@ -0,0 +1,301 @@
+[getter.html]
+ [<b> gets no special treatment ("<div>123<b>abc</b>def")]
+ expected: FAIL
+
+ [::first-line styles applied ("<div class='first-line-uppercase' style='width:0'>abc def")]
+ expected: FAIL
+
+ [<rt> and no <rp> ("<div><ruby>abc<rt>def</rt></ruby>")]
+ expected: FAIL
+
+ [Soft breaks ignored in presence of word-break:break-word ("<div style='width:1px; word-break:break-word'>Hello Kitty</div>")]
+ expected: FAIL
+
+ [text-transform handles Turkish casing ("<div><div lang='tr' style='text-transform:uppercase'>i ı")]
+ expected: FAIL
+
+ [Tab-separated table cells in a border-collapse table ("<div><table style='border-collapse:collapse'><tr><td>abc<td>def</table>")]
+ expected: FAIL
+
+ [<em> gets no special treatment ("<div>123<em>abc</em>def")]
+ expected: FAIL
+
+ [Newline-separated table rows ("<div><div class='table'><span class='row'><span class='cell'>abc</span></span>\\n<span class='row'><span class='cell'>def</span></span></div>")]
+ expected: FAIL
+
+ [<select size='1'> contents of options preserved ("<select size='1'><option>abc</option><option>def")]
+ expected: FAIL
+
+ [<optgroup> containing <optgroup> ("<select><optgroup class='poke-optgroup'></select>")]
+ expected: FAIL
+
+ [soft hyphen preserved ("<div style='width:0'>abc&shy;def")]
+ expected: FAIL
+
+ [No newlines around inline-table ("<div>abc<div class='itable'><span class='cell'>def</span></div>ghi")]
+ expected: FAIL
+
+ [::first-letter styles applied ("<div class='first-letter-uppercase' style='width:0'>abc def")]
+ expected: FAIL
+
+ [<optgroup> containing <option> ("<select><optgroup><option>abc</select>")]
+ expected: FAIL
+
+ [Newlines around table ("<div>abc<div class='table'><span class='cell'>def</span></div>ghi")]
+ expected: FAIL
+
+ [<video> contents ok for element not being rendered ("<video style='display:block'><source id='target' class='poke' style='display:block'>")]
+ expected: FAIL
+
+ [<option> in <div> ("<div>a<option>123</option>bc")]
+ expected: FAIL
+
+ [Element boundaries ignored for soft break handling (2) ("<div style='width:1px; word-break:break-word'><x>Hello</x><x> Kitty</x></div>")]
+ expected: FAIL
+
+ [::first-letter float ignored ("<div class='first-letter-float' style='width:0'>abc def")]
+ expected: FAIL
+
+ [No newlines at display:inline-block boundary ("<div>123<span style='display:inline-block'>abc</span>def")]
+ expected: FAIL
+
+ [Blank lines around <p> even without margin ("<div>123<p style='margin:0px'>abc</p>def")]
+ expected: FAIL
+
+ [<br> induces line break even at end of block ("<div>abc<br>")]
+ expected: FAIL
+
+ [Tab-separated table cells ("<div><div class='itable'><span class='cell'>abc</span>\\n<span class='cell'>def</span></div>")]
+ expected: FAIL
+
+ [Leading whitespace after hard line break removed ("<div>abc<br> def")]
+ expected: FAIL
+
+ [Blank line after <p> ("<div><p>abc</p>def")]
+ expected: FAIL
+
+ [visibility:collapse cell ("<table><tr><td style='visibility:collapse'>abc")]
+ expected: FAIL
+
+ [Whitespace collapses across element boundaries at soft break (1) ("<div style='width:1px; word-break:break-word'><x>Hello</x> <x> Kitty</x></div>")]
+ expected: FAIL
+
+ [<br> returned as newline, adjacent spaces collapsed across element boundaries ("<div style='width:1px; word-break:break-word'><x>Hello </x> <br> <x> Kitty</x></div>")]
+ expected: FAIL
+
+ [Newlines around table ("<div>abc<table><td>def</table>ghi")]
+ expected: FAIL
+
+ [Whitespace collapses across element boundaries at soft break (2) ("<div style='width:1px; word-break:break-word'><x>Hello </x> <x>Kitty</x></div>")]
+ expected: FAIL
+
+ [<canvas><div id='target'> contents ok for element not being rendered ("<canvas><div id='target'>abc")]
+ expected: FAIL
+
+ [Trailing whitespace before hard line break removed ("<div>abc <br>def")]
+ expected: FAIL
+
+ [Tab-separated table cells including trailing empty cells ("<div><table><tr><td>abc<td><td></table>")]
+ expected: FAIL
+
+ [display:table-row on the element itself ("<div style='display:table-row'>")]
+ expected: FAIL
+
+ [Whitespace collapses across element boundaries ("<div><span>abc </span><span></span> def")]
+ expected: FAIL
+
+ [Whitespace collapses across element boundaries at soft break (4) ("<div style='width:1px; word-break:break-word'><x>Hello </x> <x> Kitty</x></div>")]
+ expected: FAIL
+
+ [display:table-cell on the element itself ("<div style='display:table-cell'>")]
+ expected: FAIL
+
+ [Soft line breaks ignored ("<div style='width:0'>abc def")]
+ expected: FAIL
+
+ [<audio> contents ok for element not being rendered ("<audio style='display:block'><source id='target' class='poke' style='display:block'>")]
+ expected: FAIL
+
+ [visibility:visible child rendered ("<div style='visibility:hidden'>123<span style='visibility:visible'>abc")]
+ expected: FAIL
+
+ [Whitespace around <input> should not be collapsed ("<div>abc <input> def")]
+ expected: FAIL
+
+ [Element boundaries ignored for soft break handling (1) ("<div style='width:1px; word-break:break-word'><x>Hello</x> <x>Kitty</x></div>")]
+ expected: FAIL
+
+ [Soft breaks ignored, text-transform applied ("<div style='width:1px; word-break:break-word; text-transform:uppercase'>Hello Kitty</div>")]
+ expected: FAIL
+
+ [Leading/trailing space removal at display:inline-block boundary ("<div>123<span style='display:inline-block'> abc </span>def")]
+ expected: FAIL
+
+ [<tt> gets no special treatment ("<div>123<tt>abc</tt>def")]
+ expected: FAIL
+
+ [Blank lines around a <p> in its own block ("<div>abc<div><p>123</p></div>def")]
+ expected: FAIL
+
+ [Element boundaries ignored for soft break handling (4) ("<div style='width:1px; word-break:break-word'><x>Hello</x> Kitty</div>")]
+ expected: FAIL
+
+ [Whitespace collapses across element boundaries ("<div><span>abc </span><span style='white-space:pre'></span> def")]
+ expected: FAIL
+
+ [text-overflow:ellipsis ignored ("<div style='width:0; overflow:hidden; text-overflow:ellipsis'>abc")]
+ expected: FAIL
+
+ [<optgroup> in <div> ("<div>a<optgroup>123</optgroup>bc")]
+ expected: FAIL
+
+ [Blank lines between <p>s separated by non-empty block ("<div><p>abc</p><div>123</div><p>def")]
+ expected: FAIL
+
+ [<br> returned as newline, following space collapsed ("<div style='width:1px; word-break:break-word'>Hello<br> Kitty</div>")]
+ expected: FAIL
+
+ [visibility:collapse row-group with visible cell ("<table><tbody style='visibility:collapse'><tr><td style='visibility:visible'>abc")]
+ expected: FAIL
+
+ [empty <select> ("<div>a<select></select>bc")]
+ expected: FAIL
+
+ [position:relative has no effect ("<div>abc<span style='position:relative'>123</span>def")]
+ expected: FAIL
+
+ [ ("<table><tfoot><tr><td>footer</tfoot><thead><tr><td style='visibility:collapse'>thead</thead><tbody><tr><td>tbody</tbody></table>")]
+ expected: FAIL
+
+ [Newline-separated table rows ("<div><div class='itable'><span class='row'><span class='cell'>abc</span></span>\\n<span class='row'><span class='cell'>def</span></span></div>")]
+ expected: FAIL
+
+ [empty <optgroup> in <div> ("<div>a<optgroup></optgroup>bc")]
+ expected: FAIL
+
+ [<div> in <option> ("<select><option class='poke-div'>123</select>")]
+ expected: FAIL
+
+ [position:absolute induces a block boundary ("<div>abc<div style='position:absolute'>123</div>def")]
+ expected: FAIL
+
+ [<br> returned as newline, preceding space collapsed ("<div style='width:1px; word-break:break-word'>Hello <br>Kitty</div>")]
+ expected: FAIL
+
+ [<select size='1'> contents of options preserved ("<div><select size='1'><option>abc</option><option>def")]
+ expected: FAIL
+
+ [Whitespace around <img> should not be collapsed ("<div>abc <img> def")]
+ expected: FAIL
+
+ [Element boundaries ignored for soft break handling (3) ("<div style='width:1px; word-break:break-word'><x>Hello </x><x>Kitty</x></div>")]
+ expected: FAIL
+
+ [visibility:hidden child not rendered ("<div>123<span style='visibility:hidden'>abc")]
+ expected: FAIL
+
+ [<rp> ("<div><ruby>abc<rp>(</rp><rt>def</rt><rp>)</rp></ruby>")]
+ expected: FAIL
+
+ [<br> induces line break ("<div>abc<br>def")]
+ expected: FAIL
+
+ [Tab-separated table cells including empty cells ("<div><table><tr><td>abc<td><td>def</table>")]
+ expected: FAIL
+
+ [No newline on table-row itself ("<table><tr id=target><td>abc</td><td>def</td></tr><tr id=target><td>ghi</td><td>jkl</td></tr>")]
+ expected: FAIL
+
+ [opacity:0 child rendered ("<div>123<span style='opacity:0'>abc")]
+ expected: FAIL
+
+ [Element boundaries ignored for soft break handling (5) ("<div style='width:1px; word-break:break-word'><x>Hello </x>Kitty</div>")]
+ expected: FAIL
+
+ [<span> boundaries are irrelevant ("<div>123<span>abc</span>def")]
+ expected: FAIL
+
+ [<strong> gets no special treatment ("<div>123<strong>abc</strong>def")]
+ expected: FAIL
+
+ [empty <option> in <div> ("<div>a<option></option>bc")]
+ expected: FAIL
+
+ [<select size='2'> contents of options preserved ("<div><select size='2'><option>abc</option><option>def")]
+ expected: FAIL
+
+ [Newline-separated table rows ("<div><table><tr><td>abc<tr><td>def</table>")]
+ expected: FAIL
+
+ [Trailing space at end of inline-block should be collapsed ("<div>abc <span style='display:inline-block'> def </span> ghi")]
+ expected: FAIL
+
+ [<br> content ignored ("<div><br class='poke'>")]
+ expected: FAIL
+
+ [Single newline in two-row inline-table ("<div>abc<div class='itable'><span class='row'><span class='cell'>def</span></span>\\n<span class='row'><span class='cell'>123</span></span></div>ghi")]
+ expected: FAIL
+
+ [Newline between cells and caption ("<div><table><tr><td>abc<caption>def</caption></table>")]
+ expected: FAIL
+
+ [<i> gets no special treatment ("<div>123<i>abc</i>def")]
+ expected: FAIL
+
+ [Soft line break at hyphen ignored ("<div style='width:0'>abc-def")]
+ expected: FAIL
+
+ [visibility:collapse row with visible cell ("<table><tr style='visibility:collapse'><td style='visibility:visible'>abc")]
+ expected: FAIL
+
+ [block-in-inline doesn't add unnecessary newlines ("<div>abc<span>123<div>456</div>789</span>def")]
+ expected: FAIL
+
+ [<select> containing text node child ("<select class='poke'></select>")]
+ expected: FAIL
+
+ [Whitespace around <img> should not be collapsed ("<div>abc <img width=1 height=1> def")]
+ expected: FAIL
+
+ [<select size='2'> contents of options preserved ("<select size='2'><option>abc</option><option>def")]
+ expected: FAIL
+
+ [<span> boundaries are irrelevant ("<div style='width:0'>123 <span>abc</span> def")]
+ expected: FAIL
+
+ [Whitespace collapses across element boundaries ("<div><span>abc </span> def")]
+ expected: FAIL
+
+ [<code> gets no special treatment ("<div>123<code>abc</code>def")]
+ expected: FAIL
+
+ [Tab-separated table cells ("<div><table><tr><td>abc<td>def</table>")]
+ expected: FAIL
+
+ [<span> boundaries are irrelevant ("<div>123 <span>abc</span> def")]
+ expected: FAIL
+
+ [Whitespace around inline-block should not be collapsed ("<div>abc <span style='display:inline-block'></span> def")]
+ expected: FAIL
+
+ [Whitespace text node preserved ("<div style='width:0'><span>abc</span> <span>def</span>")]
+ expected: FAIL
+
+ [visibility:collapse honored on grid item ("<div style='display:grid'><span style='visibility:collapse'>1</span><span>2</span></div>")]
+ expected: FAIL
+
+ [Whitespace collapses across element boundaries at soft break (3) ("<div style='width:1px; word-break:break-word'><x>Hello </x><x> Kitty</x></div>")]
+ expected: FAIL
+
+ [Tab-separated table cells ("<div><div class='table'><span class='cell'>abc</span>\\n<span class='cell'>def</span></div>")]
+ expected: FAIL
+
+ [Ignoring non-rendered table whitespace ("<div><table style='white-space:pre'> <td>abc</td> </table>")]
+ expected: FAIL
+
+ [<br> ("<br>")]
+ expected: FAIL
+
+ [No tab on table-cell itself ("<table><tr><td id=target>abc</td><td>def</td>")]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata-layout-2020/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini b/tests/wpt/metadata-layout-2020/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
index af14e19a466..f45aaafe1c5 100644
--- a/tests/wpt/metadata-layout-2020/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
+++ b/tests/wpt/metadata-layout-2020/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
@@ -1,20 +1,16 @@
[supported-elements.html]
- expected: TIMEOUT
[Contenteditable element should support autofocus]
expected: FAIL
[Host element with delegatesFocus including no focusable descendants should be skipped]
- expected: NOTRUN
+ expected: FAIL
[Element with tabindex should support autofocus]
- expected: TIMEOUT
+ expected: FAIL
[Area element should support autofocus]
- expected: NOTRUN
+ expected: FAIL
[Host element with delegatesFocus should support autofocus]
- expected: NOTRUN
-
- [Non-HTMLElement should not support autofocus]
- expected: NOTRUN
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini b/tests/wpt/metadata-layout-2020/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
index 3080be9afc0..d913fcbb129 100644
--- a/tests/wpt/metadata-layout-2020/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
+++ b/tests/wpt/metadata-layout-2020/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
@@ -1,5 +1,5 @@
[iframe_sandbox_popups_nonescaping-1.html]
- expected: CRASH
+ expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN
diff --git a/tests/wpt/metadata-layout-2020/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini b/tests/wpt/metadata-layout-2020/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
index 0218bc9ba9d..c792a071c3b 100644
--- a/tests/wpt/metadata-layout-2020/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
+++ b/tests/wpt/metadata-layout-2020/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
@@ -1,4 +1,5 @@
[iframe_sandbox_popups_nonescaping-2.html]
+ expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox]
expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini b/tests/wpt/metadata-layout-2020/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini
deleted file mode 100644
index 9f416703229..00000000000
--- a/tests/wpt/metadata-layout-2020/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[form-double-submit-3.html]
- [<button> should have the same double-submit protection as <input type=submit>]
- expected: FAIL
-
diff --git a/tests/wpt/metadata-layout-2020/html/semantics/scripting-1/the-script-element/execution-timing/077.html.ini b/tests/wpt/metadata-layout-2020/html/semantics/scripting-1/the-script-element/execution-timing/077.html.ini
deleted file mode 100644
index bcd2fd0eab8..00000000000
--- a/tests/wpt/metadata-layout-2020/html/semantics/scripting-1/the-script-element/execution-timing/077.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[077.html]
- [ adding several types of scripts through the DOM and removing some of them confuses scheduler ]
- expected: FAIL
-
diff --git a/tests/wpt/metadata-layout-2020/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini b/tests/wpt/metadata-layout-2020/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini
deleted file mode 100644
index fca4d908c89..00000000000
--- a/tests/wpt/metadata-layout-2020/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[module-static-import-delayed.html]
- [document.write in an imported module]
- expected: FAIL
-
diff --git a/tests/wpt/metadata-layout-2020/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini b/tests/wpt/metadata-layout-2020/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
index 5ddb9bfeff6..a1effd5f801 100644
--- a/tests/wpt/metadata-layout-2020/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
+++ b/tests/wpt/metadata-layout-2020/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
@@ -1,10 +1,9 @@
[promise-job-entry.html]
- expected: TIMEOUT
[Fulfillment handler on fulfilled promise]
expected: FAIL
[Rejection handler on pending-then-rejected promise]
- expected: TIMEOUT
+ expected: FAIL
[Sanity check: this all works as expected with no promises involved]
expected: FAIL
@@ -16,5 +15,5 @@
expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/tests/wpt/metadata-layout-2020/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.ini b/tests/wpt/metadata-layout-2020/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.ini
new file mode 100644
index 00000000000..6f0c8ced098
--- /dev/null
+++ b/tests/wpt/metadata-layout-2020/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.ini
@@ -0,0 +1,5 @@
+[iframe-upgrade-request-to-cross-origin.sub.html]
+ expected: TIMEOUT
+ [If an insecure iframe request is upgraded to https to be cross-origin, referrer policies that consider same-origin-ness should be applied correctly]
+ expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request.sub.https.html.ini b/tests/wpt/metadata-layout-2020/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.ini
index e99a8517594..c9c31769d5d 100644
--- a/tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request.sub.https.html.ini
+++ b/tests/wpt/metadata-layout-2020/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.ini
@@ -1,4 +1,5 @@
-[iframe-upgrade-request.sub.https.html]
+[iframe-upgrade-request-to-same-origin.sub.https.html]
+ expected: TIMEOUT
[If an insecure iframe request is upgraded to https to be same-origin, referrer policies that consider same-origin-ness should be applied correctly]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/metadata-layout-2020/webmessaging/with-ports/017.html.ini b/tests/wpt/metadata-layout-2020/webmessaging/with-ports/017.html.ini
deleted file mode 100644
index 064cf47545b..00000000000
--- a/tests/wpt/metadata-layout-2020/webmessaging/with-ports/017.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[017.html]
- expected: TIMEOUT
- [origin of the script that invoked the method, about:blank]
- expected: TIMEOUT
-
diff --git a/tests/wpt/metadata-layout-2020/webmessaging/with-ports/018.html.ini b/tests/wpt/metadata-layout-2020/webmessaging/with-ports/018.html.ini
deleted file mode 100644
index 663a1f8fa30..00000000000
--- a/tests/wpt/metadata-layout-2020/webmessaging/with-ports/018.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[018.html]
- expected: TIMEOUT
- [origin of the script that invoked the method, javascript:]
- expected: TIMEOUT
-
diff --git a/tests/wpt/metadata-layout-2020/webmessaging/without-ports/017.html.ini b/tests/wpt/metadata-layout-2020/webmessaging/without-ports/017.html.ini
deleted file mode 100644
index 064cf47545b..00000000000
--- a/tests/wpt/metadata-layout-2020/webmessaging/without-ports/017.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[017.html]
- expected: TIMEOUT
- [origin of the script that invoked the method, about:blank]
- expected: TIMEOUT
-
diff --git a/tests/wpt/metadata-layout-2020/webmessaging/without-ports/018.html.ini b/tests/wpt/metadata-layout-2020/webmessaging/without-ports/018.html.ini
deleted file mode 100644
index 663a1f8fa30..00000000000
--- a/tests/wpt/metadata-layout-2020/webmessaging/without-ports/018.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[018.html]
- expected: TIMEOUT
- [origin of the script that invoked the method, javascript:]
- expected: TIMEOUT
-
diff --git a/tests/wpt/metadata-layout-2020/workers/semantics/run-a-worker/003.html.ini b/tests/wpt/metadata-layout-2020/workers/semantics/run-a-worker/003.html.ini
index dd49aa8e457..c2c57aec558 100644
--- a/tests/wpt/metadata-layout-2020/workers/semantics/run-a-worker/003.html.ini
+++ b/tests/wpt/metadata-layout-2020/workers/semantics/run-a-worker/003.html.ini
@@ -1,5 +1,4 @@
[003.html]
- expected: ERROR
[shared]
expected: FAIL
diff --git a/tests/wpt/metadata/FileAPI/url/url-in-tags-revoke.window.js.ini b/tests/wpt/metadata/FileAPI/url/url-in-tags-revoke.window.js.ini
index d4f62ed7113..faa00f45ecf 100644
--- a/tests/wpt/metadata/FileAPI/url/url-in-tags-revoke.window.js.ini
+++ b/tests/wpt/metadata/FileAPI/url/url-in-tags-revoke.window.js.ini
@@ -7,7 +7,7 @@
expected: FAIL
[Opening a blob URL in a new window immediately before revoking it works.]
- expected: FAIL
+ expected: TIMEOUT
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
expected: TIMEOUT
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index 1b9030a31e9..64dd4374e35 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -548,6 +548,19 @@
}
}
},
+ "obsolete": {
+ "requirements-for-implementations": {
+ "the-marquee-element-0": {
+ "marquee-adopt-to-inactive-document-crash.html": [
+ "395f0a2a91c4d62ab4918695aa9000c1c653db35",
+ [
+ null,
+ {}
+ ]
+ ]
+ }
+ }
+ },
"rendering": {
"non-replaced-elements": {
"the-fieldset-and-legend-elements": {
@@ -123424,6 +123437,97 @@
{}
]
],
+ "overflowed-block-with-no-room-after-000.html": [
+ "084e16fb38de072fb83f92ba01302a2e404cdd97",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square-only.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "overflowed-block-with-no-room-after-001.html": [
+ "48d028ecc2c9ce2924495ff8d037a538eb7b3dc3",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square-only.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "overflowed-block-with-room-after-000.html": [
+ "319f4af077f69e8fb1dfd59661ec71a8b27c072b",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square.xht",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "overflowed-block-with-room-after-001.html": [
+ "625f06cb588e8904ab753f048dd1150d270033cf",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square.xht",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "overflowed-block-with-room-after-002.html": [
+ "cb06faec9c9f159ab5dd2db78717e6689e48c6ea",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square.xht",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "overflowed-block-with-room-after-003.html": [
+ "dfd011109d72dbb515250895f048a130128366a9",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square.xht",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "overflowed-block-with-room-after-004.html": [
+ "ba3d62241f1f1d2dba6e0971dddaa2430777dc34",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square.xht",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"tall-break-inside-avoid-at-start.html": [
"6e9ab8bd9f56502247a6d8c2c2045b8f3af3605d",
[
@@ -128093,7 +128197,7 @@
]
],
"counter-scoping-002.html": [
- "0af148cd5e6e2eb38b2816736f3d442967fc24d4",
+ "077dca5b7a72c8635a31a75a9a9396815bb44474",
[
null,
[
@@ -185184,6 +185288,84 @@
]
],
"transform-box": {
+ "cssbox-border-box.html": [
+ "d0176e367b4133cde295ecea8b14b1167d30fadf",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/cssbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "cssbox-content-box.html": [
+ "31a44282930b71e5483fa0dc9774c99843b0fd93",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/cssbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "cssbox-fill-box.html": [
+ "6821140bfead737f01fd227fd57fc029b385502e",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/cssbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "cssbox-initial.html": [
+ "5344fb23490bec08dfffdd2ec712eb89e849dda0",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/cssbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "cssbox-stroke-box.html": [
+ "fd0db2321551c990152a8a7dc724a9af80aca7cf",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/cssbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "cssbox-view-box.html": [
+ "2336957bf1c1f802f8ae5b826a85db576dc54c7f",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/cssbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"fill-box-001.html": [
"7e9b133aead426b36702e5377c3cd1347e36ff5f",
[
@@ -185236,6 +185418,84 @@
{}
]
],
+ "svgbox-border-box.html": [
+ "921dba1d73881554b74e30deccd47f8696d6ad1b",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/svgbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "svgbox-content-box.html": [
+ "2f7f2dd071aaed3f1415ca9acfcbe5ddca0f6e4d",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/svgbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "svgbox-fill-box.html": [
+ "111d8dbcfb3d819017fb8c126d1ed6793aa34bca",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/svgbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "svgbox-initial.html": [
+ "ba07c884522745269476a249202a2a1efed497ce",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/svgbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "svgbox-stroke-box.html": [
+ "d2ca1411ae833fa87323c8e628b4cb6a5f414db4",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/svgbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "svgbox-view-box.html": [
+ "dbce635d6e78652c5f96904fa095f3d3f23ac134",
+ [
+ null,
+ [
+ [
+ "/css/css-transforms/transform-box/reference/svgbox-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"value-changed.html": [
"4aca90a61c1f76a9ee83b912bd20acf31a0e295d",
[
@@ -237195,6 +237455,19 @@
]
},
"radicals": {
+ "dynamic-radical-paint-invalidation-001.html": [
+ "5ff82f51271197af5d1502bd3e80d18666bd93ad",
+ [
+ null,
+ [
+ [
+ "/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"radical-rendering-from-in-flow.html": [
"44e449e8fddc7e70b2ac741bc9edf3cea975d739",
[
@@ -247119,15 +247392,15 @@
},
"resources": {
"beacon.py": [
- "34b55b1a95b9fb6b925b71541a090f23a4aba21d",
+ "f5caaf4b8d3d64a8016b080c110414f9cb1eb3f7",
[]
],
"content-type.py": [
- "2ea18d510a0cd416c8e6a5f3636e5392286fd185",
+ "d3be7d4dc124aa4314db9cc2ecb7a99403cced18",
[]
],
"inspect-header.py": [
- "e0b0e92cb78248d8a09c85af817e60001898fc63",
+ "f926ed43fc4477bcf7eb63a3d1e121b5ce5f118a",
[]
]
}
@@ -307612,9 +307885,17 @@
],
"transform-box": {
"reference": {
+ "cssbox-ref.html": [
+ "138d65df940ec03b930ff37deca2f6745cc42830",
+ []
+ ],
"greensquare200x200.html": [
"bee8bc70fe5d3ff49f7bd39d473bbb8a230f7d08",
[]
+ ],
+ "svgbox-ref.html": [
+ "c765ebe8665a71d2f79a9512dad4c9bd63756299",
+ []
]
}
},
@@ -318341,7 +318622,7 @@
[]
],
"general-guidelines.md": [
- "531c9a5e2e1f4f78dc2405ec12de241edf19174a",
+ "45e8769ae1edf1f327047ca4c094c772bd661966",
[]
],
"github-intro.md": [
@@ -318361,7 +318642,7 @@
[]
],
"lint-tool.md": [
- "f9caca35fef670aa2c22f3eec7cc9bfcbaee199a",
+ "551a9c1b605f51e2adbf00ef2f33d80e0d7db25b",
[]
],
"making-a-testing-plan.md": [
@@ -318419,7 +318700,7 @@
[]
],
"testharness-api.md": [
- "8160ca298ed3dcac1fbb2f9c3153e27260d758c1",
+ "bd7d42be9682b3405a0702fefd21f7df5466d88f",
[]
],
"testharness-tutorial.md": [
@@ -321460,7 +321741,7 @@
[]
],
"trickle.py": [
- "57c9407dc4b2db368b87930163efd6f36b49e849",
+ "9b3aa37b25c9c99fe1fc6a988cd79ea6c793c287",
[]
],
"utils.js": [
@@ -336041,7 +336322,7 @@
]
},
"lint.ignore": [
- "ae2e266a8ea470c75835a3e8b7e2477ebd06349d",
+ "db7f36426b17d1b0543bd8a2d09dc18e8784355c",
[]
],
"loading": {
@@ -336323,6 +336604,10 @@
}
},
"radicals": {
+ "dynamic-radical-paint-invalidation-001-ref.html": [
+ "632d6739db9fdea3b68c850db0aadbc64e5a19c1",
+ []
+ ],
"radical-rendering-from-in-flow-ref.html": [
"e1b8c3d161079da854a3e8ef4a560bf7e18cc2c4",
[]
@@ -340362,15 +340647,11 @@
}
},
"generic": {
- "iframe-upgrade-request.sub.html": [
- "259c14f43e955b9b275e6b9b78ded02e591622f9",
- []
- ],
- "iframe-upgrade-request.sub.html.headers": [
- "fd9ee0f03283651fd8679ef58ea2732f70b51a42",
+ "iframe-upgrade-request-to-cross-origin.sub.html.headers": [
+ "ad768e632941490d27b63386b536e7f24f8866cc",
[]
],
- "iframe-upgrade-request.sub.https.html.headers": [
+ "iframe-upgrade-request-to-same-origin.sub.https.html.headers": [
"fd9ee0f03283651fd8679ef58ea2732f70b51a42",
[]
],
@@ -340404,7 +340685,7 @@
],
"resources": {
"referrer.py": [
- "ada048dc490f0d491329a4c0d6474d784ac9c1b8",
+ "a969b80f54b4550eefcb386a3f4c855f650d7ca9",
[]
]
},
@@ -341198,6 +341479,14 @@
"e47250d763cfdf209efd954ac7d7758f4bf54db5",
[]
],
+ "step_wait.html": [
+ "14c41b00d2ac216a12578c6a720fc4b14a0276f6",
+ []
+ ],
+ "step_wait_func.html": [
+ "b9a488b27f0b87a33cea4b0c35417db9854ace08",
+ []
+ ],
"task-scheduling-promise-test.html": [
"fb4cc2dd27d52573c4113aa1a6f8d833ce80c9be",
[]
@@ -341424,7 +341713,7 @@
[]
],
"testharness.js": [
- "cf361bac3920ef1b34a1861fcc4f886d442e21a3",
+ "7e2d4600f0f1302b5131ef81086ab283c0a83fc1",
[]
],
"testharness.js.headers": [
@@ -351971,7 +352260,7 @@
[]
],
"browser.py": [
- "366dc781d90ee21b820b9334c69ede2c451cb4b8",
+ "4423afd9c4f7c8b866ffbff2f5343ec5fe65e650",
[]
],
"commands.json": [
@@ -357944,11 +358233,11 @@
"baseurl": {
"beta": {
"import.py": [
- "db18c830a4e1b2b1a97a115483755b1c2f81903a",
+ "cea229dbf3714b17e9c99fd89ae48ebc1c452024",
[]
],
"importScripts.py": [
- "75dac194f76dfa6aefb99309d59b709413c39284",
+ "688427d59da6adb08474bd88bdfbd2510d73ea95",
[]
],
"script.js": [
@@ -357956,7 +358245,7 @@
[]
],
"sharedworker.py": [
- "875cc9a047cef867f584a6ced50fdf573317db6f",
+ "bd6f70e7d9478c3239c047618f815fb9e6a06ce3",
[]
],
"subsharedworker.js": [
@@ -357972,15 +358261,15 @@
[]
],
"worker.py": [
- "44baf5203e856e7dee4a1b7ea604d743a7efb770",
+ "46db05efe5e9fdbb8f0730f6d0f20a23c707b2b8",
[]
],
"xhr-worker.py": [
- "77270536a50d751d4ea8288e0eacecd39b476f54",
+ "86c033b985bd409b035785f54f53feca71adcefd",
[]
],
"xhr.py": [
- "de3f04ed0e21a62c60d86589fcbe753f6279d0dc",
+ "11d6eb776a4a9eef81b679e3b19a2e365640867a",
[]
]
},
@@ -358235,7 +358524,7 @@
},
"location": {
"helper-redirect.py": [
- "eb1599a577fb6f8c69ae1955294fc2bc493dd4e2",
+ "c8cd3543487ba2c40ee71b331b728218f28c8bd0",
[]
],
"members.js": [
@@ -358454,7 +358743,7 @@
[]
],
"export-credentials.py": [
- "be6d2ff2fc17b94d69548746cd25d6b6c471cb0c",
+ "3d0ba778d13d345686220e7dbf35a61aa2e2b42e",
[]
],
"export-on-dynamic-import-script.js": [
@@ -358482,7 +358771,7 @@
[]
],
"export-referrer-checker.py": [
- "2928d28aff53f5d7f976fb804c4fdc52734d8dab",
+ "3b0fda1aa6a32cff5d8a31ad38c12bb4774b2dea",
[]
],
"import-meta-url-export.js": [
@@ -358522,11 +358811,11 @@
[]
],
"postmessage-credentials.py": [
- "8fe46bddc80cfefe107e5018d7ca832d18ea8fd0",
+ "a054a1a923cb0f821863c5f69004e234b0b24019",
[]
],
"postmessage-referrer-checker.py": [
- "f926834ddfc3b6b42d9e008a02ede45af80decdc",
+ "699af684a2366fc0aaa8c1e64abf3240489cf7be",
[]
],
"static-import-and-then-dynamic-import-worker.js": [
@@ -358656,7 +358945,7 @@
[]
],
"003-1.py": [
- "1e899aac2714189ab78abeecad09598a67a2ee67",
+ "4f5df2bb10d294693c8b28456beba424c3efac12",
[]
],
"003.js": [
@@ -358927,7 +359216,7 @@
[]
],
"imported_script.py": [
- "88cd2285e82162679c0bcbcc1ff756c91c12a5a0",
+ "2f9c6a81d9d92a1a9f6d660abce74adc694f00e4",
[]
],
"invalidScript.js": [
@@ -358943,7 +359232,7 @@
[]
],
"nosiniff-error-worker.py": [
- "3a2c1b3901c70bb62ca8ea93b690c88c11451a22",
+ "e4367ba6e1a04b0b887f5eb1b43f9153b55c6666",
[]
],
"parent_of_nested_worker.js": [
@@ -392149,6 +392438,13 @@
{}
]
],
+ "counter-set-computed.html": [
+ "d0a92896ed7f8f08c550a708e2592bf4e5fb8908",
+ [
+ null,
+ {}
+ ]
+ ],
"counter-set-invalid.html": [
"9cc5be7c928305e647f97cdc360249dcba19b263",
[
@@ -400724,7 +401020,7 @@
]
],
"Document-getAnimations.tentative.html": [
- "a8986d0bdbd35789dc95c090135e19116fd9c45b",
+ "d1cf6e499bf0443d898284ef16c0c46da167d04f",
[
null,
{}
@@ -402385,6 +402681,13 @@
{}
]
],
+ "counter-set.html": [
+ "db57f269de1782466ec10a8fe93afe1a9e668c99",
+ [
+ null,
+ {}
+ ]
+ ],
"cursor.html": [
"7465b1a74a3b9966b5eaa15f6a19b6b0b399d43a",
[
@@ -412566,6 +412869,41 @@
null,
{}
]
+ ],
+ "white-spaces-after-execCommand-delete.tentative.html": [
+ "3592b2dc0cc15973a3d9eb8a2ce25f0cc668f2c9",
+ [
+ null,
+ {}
+ ]
+ ],
+ "white-spaces-after-execCommand-forwarddelete.tentative.html": [
+ "4a94c6bcddf37f4cf81324c5373e0c1038baaefb",
+ [
+ null,
+ {}
+ ]
+ ],
+ "white-spaces-after-execCommand-insertlinebreak.tentative.html": [
+ "a961ee77bc33cd5107b579db19915e613259de15",
+ [
+ null,
+ {}
+ ]
+ ],
+ "white-spaces-after-execCommand-insertparagraph.tentative.html": [
+ "854e6b3dae5ac7e416dd5cbac4ed681b5a007e7b",
+ [
+ null,
+ {}
+ ]
+ ],
+ "white-spaces-after-execCommand-inserttext.tentative.html": [
+ "4b4146b5095ef47248424bbaf1aa35b97a752ed7",
+ [
+ null,
+ {}
+ ]
]
},
"run": {
@@ -450925,7 +451263,7 @@
]
],
"none.https.html": [
- "e603753084cf2c3c85b0187a7a8f66b3de8cf401",
+ "0fbd4165a5f19f19a4e6cca3ee43bba88f0336b5",
[
null,
{
@@ -450970,14 +451308,14 @@
]
],
"require-corp-about-blank.html": [
- "5c51df71ae5b6a84f5c68c90a4012729a9e9c380",
+ "945333b83d54cf2148070f1a842e11155a14434c",
[
null,
{}
]
],
"require-corp-about-srcdoc.html": [
- "4d1c1f864644dad1382092f3bdab3097d412d4cc",
+ "5d06286d915aef65355fe6f155176c45b6e179d4",
[
null,
{}
@@ -451012,7 +451350,7 @@
]
],
"require-corp.https.html": [
- "769bc87586d8038372255c27b6ce1db2fa3a6e51",
+ "477145657d77da20e4ae02072bd116c9032bcf26",
[
null,
{
@@ -451151,7 +451489,7 @@
]
],
"coop-sandbox.https.html": [
- "6f10945cfafb5c2c4c00d0f29fe12c4ddaacd228",
+ "ceb744c215bcc2fcdf9a0a81d6e3820d4efd49eb",
[
null,
{}
@@ -451379,7 +451717,7 @@
]
],
"popup-same-origin-non-initial-about-blank.https.html": [
- "d4005ac20d8d7d9b215fe73785d9a1a3466fcef3",
+ "2e58ea455333b61cd786a3dd0cba3b7600203207",
[
null,
{}
@@ -491285,8 +491623,15 @@
{}
]
],
- "iframe-upgrade-request.sub.https.html": [
- "243efb7671933b8f89c64fb91a92cbe9995d4099",
+ "iframe-upgrade-request-to-cross-origin.sub.html": [
+ "4040072ab9abe80d2c180f7c12deea5cf797fc97",
+ [
+ null,
+ {}
+ ]
+ ],
+ "iframe-upgrade-request-to-same-origin.sub.https.html": [
+ "f9163bec546c2ff1b440b1b27ee945c150caf67c",
[
null,
{}
@@ -508398,7 +508743,7 @@
]
],
"urlencoded-parser.any.js": [
- "65e894b94c26b0bd21d07706ff2601bd54a3d134",
+ "46b932bb01436418ca923e0f329c3507d2d66ee7",
[
"url/urlencoded-parser.any.html",
{}
@@ -508420,7 +508765,7 @@
]
],
"urlsearchparams-constructor.any.js": [
- "8d855a4fd4d01cb34732a7e3b3ef2da5f639a82b",
+ "1135d5d3dbbfa3625391e090985231c41e88f2c6",
[
"url/urlsearchparams-constructor.any.html",
{}
@@ -508508,7 +508853,7 @@
]
],
"urlsearchparams-stringifier.any.js": [
- "ef95c1434c796418bf7fcaaa1732c46719ca3205",
+ "bc7bedd533f58d526b1f16d288b8ec544dba992b",
[
"url/urlsearchparams-stringifier.any.html",
{}
@@ -517526,7 +517871,7 @@
]
]
},
- "receiver-track-live.html": [
+ "receiver-track-live.https.html": [
"3d41724fb59015065759a072a2e16c8258a56f2e",
[
null,
@@ -529149,6 +529494,31 @@
}
]
],
+ "send-data-string-invalid-unicode.any.js": [
+ "d9dc5a6bcf8de536ae211d7975891bd8bb52e3d9",
+ [
+ "xhr/send-data-string-invalid-unicode.any.html",
+ {
+ "script_metadata": [
+ [
+ "title",
+ "XMLHttpRequest.send(invalidUnicodeString)"
+ ]
+ ]
+ }
+ ],
+ [
+ "xhr/send-data-string-invalid-unicode.any.worker.html",
+ {
+ "script_metadata": [
+ [
+ "title",
+ "XMLHttpRequest.send(invalidUnicodeString)"
+ ]
+ ]
+ }
+ ]
+ ],
"send-data-unexpected-tostring.htm": [
"290ae2065fc0fe91395276496a3dedfd2cd7872e",
[
diff --git a/tests/wpt/metadata/css/CSS2/floats/hit-test-floats-004.html.ini b/tests/wpt/metadata/css/CSS2/floats/hit-test-floats-003.html.ini
index 4bfb0c2053a..f29da48a2a0 100644
--- a/tests/wpt/metadata/css/CSS2/floats/hit-test-floats-004.html.ini
+++ b/tests/wpt/metadata/css/CSS2/floats/hit-test-floats-003.html.ini
@@ -1,4 +1,4 @@
-[hit-test-floats-004.html]
+[hit-test-floats-003.html]
[Miss float below something else]
expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-border-box.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-border-box.html.ini
new file mode 100644
index 00000000000..709fcddaefb
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-border-box.html.ini
@@ -0,0 +1,2 @@
+[cssbox-border-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-content-box.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-content-box.html.ini
new file mode 100644
index 00000000000..39281adef09
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-content-box.html.ini
@@ -0,0 +1,2 @@
+[cssbox-content-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-fill-box.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-fill-box.html.ini
new file mode 100644
index 00000000000..7331e7a0d1c
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-fill-box.html.ini
@@ -0,0 +1,2 @@
+[cssbox-fill-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-initial.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-initial.html.ini
new file mode 100644
index 00000000000..5e34c3d474a
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-initial.html.ini
@@ -0,0 +1,2 @@
+[cssbox-initial.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-stroke-box.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-stroke-box.html.ini
new file mode 100644
index 00000000000..7a339b8bc80
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-stroke-box.html.ini
@@ -0,0 +1,2 @@
+[cssbox-stroke-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-view-box.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-view-box.html.ini
new file mode 100644
index 00000000000..a54685ae780
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/cssbox-view-box.html.ini
@@ -0,0 +1,2 @@
+[cssbox-view-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-border-box.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-border-box.html.ini
new file mode 100644
index 00000000000..8c34a3b478c
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-border-box.html.ini
@@ -0,0 +1,2 @@
+[svgbox-border-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-content-box.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-content-box.html.ini
new file mode 100644
index 00000000000..95cc7d4fe16
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-content-box.html.ini
@@ -0,0 +1,2 @@
+[svgbox-content-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-fill-box.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-fill-box.html.ini
new file mode 100644
index 00000000000..fe46f80ca70
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-fill-box.html.ini
@@ -0,0 +1,2 @@
+[svgbox-fill-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-initial.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-initial.html.ini
new file mode 100644
index 00000000000..f26e8f2bf7f
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-initial.html.ini
@@ -0,0 +1,2 @@
+[svgbox-initial.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-stroke-box.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-stroke-box.html.ini
new file mode 100644
index 00000000000..dc663e13f6c
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-stroke-box.html.ini
@@ -0,0 +1,2 @@
+[svgbox-stroke-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-view-box.html.ini b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-view-box.html.ini
new file mode 100644
index 00000000000..2a9e2356590
--- /dev/null
+++ b/tests/wpt/metadata/css/css-transforms/transform-box/svgbox-view-box.html.ini
@@ -0,0 +1,2 @@
+[svgbox-view-box.html]
+ expected: FAIL
diff --git a/tests/wpt/metadata/css/cssom-view/elementFromPoint-001.html.ini b/tests/wpt/metadata/css/cssom-view/elementFromPoint-001.html.ini
new file mode 100644
index 00000000000..e38782d8c85
--- /dev/null
+++ b/tests/wpt/metadata/css/cssom-view/elementFromPoint-001.html.ini
@@ -0,0 +1,4 @@
+[elementFromPoint-001.html]
+ [CSSOM View - 5 - extensions to the Document interface]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/css/cssom-view/elementFromPosition.html.ini b/tests/wpt/metadata/css/cssom-view/elementFromPosition.html.ini
index 85e94926cb3..5733d536fd3 100644
--- a/tests/wpt/metadata/css/cssom-view/elementFromPosition.html.ini
+++ b/tests/wpt/metadata/css/cssom-view/elementFromPosition.html.ini
@@ -21,3 +21,6 @@
[test the top of layer]
expected: FAIL
+ [test some point of the element: top left corner]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/fetch/content-type/response.window.js.ini b/tests/wpt/metadata/fetch/content-type/response.window.js.ini
index abb1983dc56..7a66dcc1a12 100644
--- a/tests/wpt/metadata/fetch/content-type/response.window.js.ini
+++ b/tests/wpt/metadata/fetch/content-type/response.window.js.ini
@@ -312,18 +312,27 @@
[fetch(): separate response Content-Type: text/plain ]
expected: NOTRUN
- [<iframe>: combined response Content-Type: text/html */*]
+ [<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
- [<iframe>: combined response Content-Type: text/html;" text/plain]
+ [<iframe>: combined response Content-Type: */* text/html]
expected: FAIL
- [<iframe>: separate response Content-Type: text/html;" text/plain]
+ [<iframe>: separate response Content-Type: text/html */*]
+ expected: FAIL
+
+ [<iframe>: separate response Content-Type: text/plain */*]
+ expected: FAIL
+
+ [<iframe>: combined response Content-Type: text/html */*;charset=gbk]
+ expected: FAIL
+
+ [<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL
- [<iframe>: separate response Content-Type: text/html */*;charset=gbk]
+ [<iframe>: combined response Content-Type: text/html;" \\" text/plain]
expected: FAIL
- [<iframe>: separate response Content-Type: text/html;" \\" text/plain]
+ [<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
expected: FAIL
diff --git a/tests/wpt/metadata/fetch/content-type/script.window.js.ini b/tests/wpt/metadata/fetch/content-type/script.window.js.ini
index d2df9b78483..258fe374697 100644
--- a/tests/wpt/metadata/fetch/content-type/script.window.js.ini
+++ b/tests/wpt/metadata/fetch/content-type/script.window.js.ini
@@ -56,3 +56,6 @@
[separate text/javascript x/x]
expected: FAIL
+ [separate text/javascript ]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/fetch/nosniff/parsing-nosniff.window.js.ini b/tests/wpt/metadata/fetch/nosniff/parsing-nosniff.window.js.ini
index 30e1b851fd4..ec1fd06e1f5 100644
--- a/tests/wpt/metadata/fetch/nosniff/parsing-nosniff.window.js.ini
+++ b/tests/wpt/metadata/fetch/nosniff/parsing-nosniff.window.js.ini
@@ -11,3 +11,6 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL
+ [X-Content-Type-Options%3A%0D%0AX-Content-Type-Options%3A%20nosniff]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini
deleted file mode 100644
index 87b07c3e670..00000000000
--- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[traverse_the_history_1.html]
- [Multiple history traversals from the same task]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
deleted file mode 100644
index 51f8272a6de..00000000000
--- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[traverse_the_history_3.html]
- [Multiple history traversals, last would be aborted]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/dom/elements/the-innertext-idl-attribute/getter.html.ini b/tests/wpt/metadata/html/dom/elements/the-innertext-idl-attribute/getter.html.ini
index 5ad7fa91917..6bbf5c59047 100644
--- a/tests/wpt/metadata/html/dom/elements/the-innertext-idl-attribute/getter.html.ini
+++ b/tests/wpt/metadata/html/dom/elements/the-innertext-idl-attribute/getter.html.ini
@@ -29,12 +29,6 @@
[visibility:visible child rendered ("<div style='visibility:hidden'>123<span style='visibility:visible'>abc")]
expected: FAIL
- [visibility:collapse row-group ("<table><tbody style='visibility:collapse'><tr><td>abc")]
- expected: FAIL
-
- [visibility:collapse row ("<table><tr style='visibility:collapse'><td>abc")]
- expected: FAIL
-
[visibility:collapse cell ("<table><tr><td style='visibility:collapse'>abc")]
expected: FAIL
@@ -44,9 +38,6 @@
[visibility:collapse row with visible cell ("<table><tr style='visibility:collapse'><td style='visibility:visible'>abc")]
expected: FAIL
- [visibility:collapse honored on flex item ("<div style='display:flex'><span style='visibility:collapse'>1</span><span>2</span></div>")]
- expected: FAIL
-
[visibility:collapse honored on grid item ("<div style='display:grid'><span style='visibility:collapse'>1</span><span>2</span></div>")]
expected: FAIL
diff --git a/tests/wpt/metadata/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini b/tests/wpt/metadata/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
index 8b743f36e1d..6b68e9094e4 100644
--- a/tests/wpt/metadata/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
+++ b/tests/wpt/metadata/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
@@ -1,20 +1,16 @@
[supported-elements.html]
- expected: TIMEOUT
[Contenteditable element should support autofocus]
expected: FAIL
[Element with tabindex should support autofocus]
- expected: TIMEOUT
+ expected: FAIL
[Host element with delegatesFocus including no focusable descendants should be skipped]
- expected: NOTRUN
+ expected: FAIL
[Area element should support autofocus]
- expected: NOTRUN
+ expected: FAIL
[Host element with delegatesFocus should support autofocus]
- expected: NOTRUN
-
- [Non-HTMLElement should not support autofocus]
- expected: NOTRUN
+ expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
index 963d4cd20ef..9df1ac56f2a 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
@@ -1,6 +1,6 @@
[iframe_sandbox_popups_nonescaping-1.html]
type: testharness
- expected: CRASH
+ expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
index 3a32693ffa8..06bbed1fcac 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
@@ -1,5 +1,6 @@
[iframe_sandbox_popups_nonescaping-2.html]
type: testharness
+ expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini b/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini
deleted file mode 100644
index 9f416703229..00000000000
--- a/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[form-double-submit-3.html]
- [<button> should have the same double-submit protection as <input type=submit>]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/execution-timing/077.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/execution-timing/077.html.ini
deleted file mode 100644
index bcd2fd0eab8..00000000000
--- a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/execution-timing/077.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[077.html]
- [ adding several types of scripts through the DOM and removing some of them confuses scheduler ]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini b/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini
deleted file mode 100644
index fca4d908c89..00000000000
--- a/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[module-static-import-delayed.html]
- [document.write in an imported module]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
index 5ddb9bfeff6..a1effd5f801 100644
--- a/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
+++ b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
@@ -1,10 +1,9 @@
[promise-job-entry.html]
- expected: TIMEOUT
[Fulfillment handler on fulfilled promise]
expected: FAIL
[Rejection handler on pending-then-rejected promise]
- expected: TIMEOUT
+ expected: FAIL
[Sanity check: this all works as expected with no promises involved]
expected: FAIL
@@ -16,5 +15,5 @@
expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.ini b/tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.ini
new file mode 100644
index 00000000000..6f0c8ced098
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.ini
@@ -0,0 +1,5 @@
+[iframe-upgrade-request-to-cross-origin.sub.html]
+ expected: TIMEOUT
+ [If an insecure iframe request is upgraded to https to be cross-origin, referrer policies that consider same-origin-ness should be applied correctly]
+ expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.ini b/tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.ini
new file mode 100644
index 00000000000..c9c31769d5d
--- /dev/null
+++ b/tests/wpt/metadata/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.ini
@@ -0,0 +1,5 @@
+[iframe-upgrade-request-to-same-origin.sub.https.html]
+ expected: TIMEOUT
+ [If an insecure iframe request is upgraded to https to be same-origin, referrer policies that consider same-origin-ness should be applied correctly]
+ expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/webmessaging/with-ports/017.html.ini b/tests/wpt/metadata/webmessaging/with-ports/017.html.ini
deleted file mode 100644
index 064cf47545b..00000000000
--- a/tests/wpt/metadata/webmessaging/with-ports/017.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[017.html]
- expected: TIMEOUT
- [origin of the script that invoked the method, about:blank]
- expected: TIMEOUT
-
diff --git a/tests/wpt/metadata/webmessaging/with-ports/018.html.ini b/tests/wpt/metadata/webmessaging/with-ports/018.html.ini
deleted file mode 100644
index 663a1f8fa30..00000000000
--- a/tests/wpt/metadata/webmessaging/with-ports/018.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[018.html]
- expected: TIMEOUT
- [origin of the script that invoked the method, javascript:]
- expected: TIMEOUT
-
diff --git a/tests/wpt/metadata/webmessaging/without-ports/017.html.ini b/tests/wpt/metadata/webmessaging/without-ports/017.html.ini
deleted file mode 100644
index 064cf47545b..00000000000
--- a/tests/wpt/metadata/webmessaging/without-ports/017.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[017.html]
- expected: TIMEOUT
- [origin of the script that invoked the method, about:blank]
- expected: TIMEOUT
-
diff --git a/tests/wpt/metadata/webmessaging/without-ports/018.html.ini b/tests/wpt/metadata/webmessaging/without-ports/018.html.ini
deleted file mode 100644
index 663a1f8fa30..00000000000
--- a/tests/wpt/metadata/webmessaging/without-ports/018.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[018.html]
- expected: TIMEOUT
- [origin of the script that invoked the method, javascript:]
- expected: TIMEOUT
-
diff --git a/tests/wpt/metadata/workers/semantics/run-a-worker/003.html.ini b/tests/wpt/metadata/workers/semantics/run-a-worker/003.html.ini
index 49f489d2a1c..d6e39444229 100644
--- a/tests/wpt/metadata/workers/semantics/run-a-worker/003.html.ini
+++ b/tests/wpt/metadata/workers/semantics/run-a-worker/003.html.ini
@@ -1,6 +1,5 @@
[003.html]
type: testharness
- expected: ERROR
[shared]
expected: FAIL
diff --git a/tests/wpt/web-platform-tests/beacon/resources/beacon.py b/tests/wpt/web-platform-tests/beacon/resources/beacon.py
index 34b55b1a95b..f5caaf4b8d3 100644
--- a/tests/wpt/web-platform-tests/beacon/resources/beacon.py
+++ b/tests/wpt/web-platform-tests/beacon/resources/beacon.py
@@ -1,5 +1,6 @@
import json
+from wptserve.utils import isomorphic_decode
def main(request, response):
"""Helper handler for Beacon tests.
@@ -33,30 +34,30 @@ def main(request, response):
id - the unique identifier of the test.
"""
- id = request.GET.first("id")
- command = request.GET.first("cmd").lower()
+ id = request.GET.first(b"id")
+ command = request.GET.first(b"cmd").lower()
# Append CORS headers if needed.
- if "origin" in request.GET:
- response.headers.set("Access-Control-Allow-Origin",
- request.GET.first("origin"))
- if "credentials" in request.GET:
- response.headers.set("Access-Control-Allow-Credentials",
- request.GET.first("credentials"))
+ if b"origin" in request.GET:
+ response.headers.set(b"Access-Control-Allow-Origin",
+ request.GET.first(b"origin"))
+ if b"credentials" in request.GET:
+ response.headers.set(b"Access-Control-Allow-Credentials",
+ request.GET.first(b"credentials"))
# Handle the 'store' and 'stat' commands.
- if command == "store":
+ if command == b"store":
error = None
# Only store the actual POST requests, not any preflight/OPTIONS
# requests we may get.
- if request.method == "POST":
- payload = ""
- if "Content-Type" in request.headers and \
- "form-data" in request.headers["Content-Type"]:
- if "payload" in request.POST:
+ if request.method == u"POST":
+ payload = b""
+ if b"Content-Type" in request.headers and \
+ b"form-data" in request.headers[b"Content-Type"]:
+ if b"payload" in request.POST:
# The payload was sent as a FormData.
- payload = request.POST.first("payload")
+ payload = request.POST.first(b"payload")
else:
# A FormData was sent with an empty payload.
pass
@@ -64,42 +65,42 @@ def main(request, response):
# The payload was sent as either a string, Blob, or BufferSource.
payload = request.body
- payload_parts = filter(None, payload.split(":"))
+ payload_parts = list(filter(None, payload.split(b":")))
if len(payload_parts) > 0:
payload_size = int(payload_parts[0])
# Confirm the payload size sent matches with the number of
# characters sent.
if payload_size != len(payload_parts[1]):
- error = "expected %d characters but got %d" % (
+ error = u"expected %d characters but got %d" % (
payload_size, len(payload_parts[1]))
else:
# Confirm the payload contains the correct characters.
for i in range(0, payload_size):
- if payload_parts[1][i] != "*":
- error = "expected '*' at index %d but got '%s''" % (
- i, payload_parts[1][i])
+ if payload_parts[1][i:i+1] != b"*":
+ error = u"expected '*' at index %d but got '%s''" % (
+ i, isomorphic_decode(payload_parts[1][i:i+1]))
break
# Store the result in the stash so that it can be retrieved
# later with a 'stat' command.
- request.server.stash.put(id, {"error": error})
- elif request.method == "OPTIONS":
+ request.server.stash.put(id, {u"error": error})
+ elif request.method == u"OPTIONS":
# If we expect a preflight, then add the cors headers we expect,
# otherwise log an error as we shouldn't send a preflight for all
# requests.
- if "preflightExpected" in request.GET:
- response.headers.set("Access-Control-Allow-Headers",
- "content-type")
- response.headers.set("Access-Control-Allow-Methods", "POST")
+ if b"preflightExpected" in request.GET:
+ response.headers.set(b"Access-Control-Allow-Headers",
+ b"content-type")
+ response.headers.set(b"Access-Control-Allow-Methods", b"POST")
else:
- error = "Preflight not expected."
- request.server.stash.put(id, {"error": error})
- elif command == "stat":
+ error = u"Preflight not expected."
+ request.server.stash.put(id, {u"error": error})
+ elif command == b"stat":
test_data = request.server.stash.take(id)
results = [test_data] if test_data else []
- response.headers.set("Content-Type", "text/plain")
+ response.headers.set(b"Content-Type", b"text/plain")
response.content = json.dumps(results)
else:
response.status = 400 # BadRequest
diff --git a/tests/wpt/web-platform-tests/beacon/resources/content-type.py b/tests/wpt/web-platform-tests/beacon/resources/content-type.py
index 2ea18d510a0..d3be7d4dc12 100644
--- a/tests/wpt/web-platform-tests/beacon/resources/content-type.py
+++ b/tests/wpt/web-platform-tests/beacon/resources/content-type.py
@@ -1,14 +1,14 @@
def main(request, response):
- command = request.GET.first("cmd").lower();
- test_id = request.GET.first("id")
- if command == "put":
- request.server.stash.put(test_id, request.headers.get("Content-Type", ""))
- return [("Content-Type", "text/plain")], ""
+ command = request.GET.first(b"cmd").lower()
+ test_id = request.GET.first(b"id")
+ if command == b"put":
+ request.server.stash.put(test_id, request.headers.get(b"Content-Type", b""))
+ return [(b"Content-Type", b"text/plain")], u""
- if command == "get":
- stashed_header = request.server.stash.take(test_id)
- if stashed_header is not None:
- return [("Content-Type", "text/plain")], stashed_header
+ if command == b"get":
+ stashed_header = request.server.stash.take(test_id)
+ if stashed_header is not None:
+ return [(b"Content-Type", b"text/plain")], stashed_header
- response.set_error(400, "Bad Command")
- return "ERROR: Bad Command!"
+ response.set_error(400, u"Bad Command")
+ return u"ERROR: Bad Command!"
diff --git a/tests/wpt/web-platform-tests/beacon/resources/inspect-header.py b/tests/wpt/web-platform-tests/beacon/resources/inspect-header.py
index e0b0e92cb78..f926ed43fc4 100644
--- a/tests/wpt/web-platform-tests/beacon/resources/inspect-header.py
+++ b/tests/wpt/web-platform-tests/beacon/resources/inspect-header.py
@@ -1,18 +1,18 @@
def main(request, response):
- headers = [("Content-Type", "text/plain")]
- command = request.GET.first("cmd").lower();
- test_id = request.GET.first("id")
- header = request.GET.first("header")
- if command == "put":
- request.server.stash.put(test_id, request.headers.get(header, ""))
+ headers = [(b"Content-Type", b"text/plain")]
+ command = request.GET.first(b"cmd").lower()
+ test_id = request.GET.first(b"id")
+ header = request.GET.first(b"header")
+ if command == b"put":
+ request.server.stash.put(test_id, request.headers.get(header, b""))
- elif command == "get":
+ elif command == b"get":
stashed_header = request.server.stash.take(test_id)
if stashed_header is not None:
- headers.append(("x-request-" + header, stashed_header ))
+ headers.append((b"x-request-" + header, stashed_header))
else:
- response.set_error(400, "Bad Command")
- return "ERROR: Bad Command!"
+ response.set_error(400, u"Bad Command")
+ return u"ERROR: Bad Command!"
- return headers, ""
+ return headers, u""
diff --git a/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-no-room-after-000.html b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-no-room-after-000.html
new file mode 100644
index 00000000000..084e16fb38d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-no-room-after-000.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-break-3/#parallel-flows">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div style="margin-bottom:-30px; width:50px; height:30px; background:green;"></div>
+<div style="columns:2; column-fill:auto; column-gap:0; width:100px; height:70px; margin-top:30px;">
+ <div style="height:80px;">
+ <div style="height:140px; background:green;"></div>
+ </div>
+ <div style="margin-top:-40px; height:30px; background:green;"></div>
+</div>
diff --git a/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-no-room-after-001.html b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-no-room-after-001.html
new file mode 100644
index 00000000000..48d028ecc2c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-no-room-after-001.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-break-3/#parallel-flows">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div style="margin-bottom:-30px; width:50px; height:30px; background:green;"></div>
+<div style="columns:2; column-fill:auto; column-gap:0; width:100px; height:70px; margin-top:30px;">
+ <div>
+ <div style="height:80px;">
+ <div style="height:140px; background:green;"></div>
+ </div>
+ </div>
+ <div style="margin-top:-40px; height:30px; background:green;"></div>
+</div>
diff --git a/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-000.html b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-000.html
new file mode 100644
index 00000000000..319f4af077f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-000.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-break-3/#parallel-flows">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="columns:2; column-fill:auto; column-gap:0; width:100px; height:100px; background:red;">
+ <div style="height:70px;">
+ <div style="height:200px;">
+ <div style="height:70px; background:green;"></div>
+ <div style="height:60px;"></div>
+ <div style="height:70px; background:green;"></div>
+ </div>
+ </div>
+ <div style="height:30px; background:green;"></div>
+ <div style="height:30px; background:green;"></div>
+</div>
diff --git a/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-001.html b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-001.html
new file mode 100644
index 00000000000..625f06cb588
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-001.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-break-3/#parallel-flows">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="columns:2; column-fill:auto; column-gap:0; width:100px; height:100px; background:red;">
+ <div style="height:70px;">
+ <div style="height:200px;">
+ <div style="height:70px; background:green;"></div>
+ <div style="height:60px;"></div>
+ <div style="height:70px; background:green;"></div>
+ </div>
+ </div>
+ <div style="height:60px; background:green;"></div>
+</div>
diff --git a/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-002.html b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-002.html
new file mode 100644
index 00000000000..cb06faec9c9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-002.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-break-3/#parallel-flows">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="columns:4; column-fill:auto; column-gap:0; width:100px; height:100px; background:red;">
+ <div style="height:70px;">
+ <div style="height:400px;">
+ <div style="height:70px; background:green;"></div>
+ <div style="height:60px;"></div>
+ <div style="height:270px; background:green;"></div>
+ </div>
+ </div>
+ <div style="height:60px; background:green;"></div>
+</div>
diff --git a/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-003.html b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-003.html
new file mode 100644
index 00000000000..dfd011109d7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-003.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-break-3/#parallel-flows">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="columns:2; column-fill:auto; column-gap:0; width:100px; height:100px; background:red;">
+ <div>
+ <div style="height:70px;">
+ <div style="height:200px;">
+ <div style="height:70px; background:green;"></div>
+ <div style="height:60px;"></div>
+ <div style="height:70px; background:green;"></div>
+ </div>
+ </div>
+ </div>
+ <div style="height:30px; background:green;"></div>
+ <div style="height:30px; background:green;"></div>
+</div>
diff --git a/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-004.html b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-004.html
new file mode 100644
index 00000000000..ba3d62241f1
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-break/overflowed-block-with-room-after-004.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-break-3/#parallel-flows">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="columns:2; column-fill:auto; column-gap:0; width:100px; height:100px; background:red;">
+ <div>
+ <div style="height:100px;">
+ <div style="height:200px;">
+ <div style="height:70px; background:green;"></div>
+ <div style="height:60px;"></div>
+ <div style="height:70px; background:green;"></div>
+ </div>
+ </div>
+ </div>
+ <div style="margin-top:-30px; height:30px; background:green;"></div>
+ <div style="height:30px; background:green;"></div>
+</div>
diff --git a/tests/wpt/web-platform-tests/css/css-contain/counter-scoping-002.html b/tests/wpt/web-platform-tests/css/css-contain/counter-scoping-002.html
index 0af148cd5e6..077dca5b7a7 100644
--- a/tests/wpt/web-platform-tests/css/css-contain/counter-scoping-002.html
+++ b/tests/wpt/web-platform-tests/css/css-contain/counter-scoping-002.html
@@ -12,7 +12,7 @@
<style>
div {
contain: style;
- counter-set: n;
+ counter-set: n 1;
}
div::before, div::after {
content: counters(n, '.') " ";
diff --git a/tests/wpt/web-platform-tests/css/css-lists/parsing/counter-set-computed.html b/tests/wpt/web-platform-tests/css/css-lists/parsing/counter-set-computed.html
new file mode 100644
index 00000000000..d0a92896ed7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-lists/parsing/counter-set-computed.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Lists: getComputedStyle().counterSet</title>
+<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-counter-set">
+<meta name="assert" content="tests that counter-set grammar is supported.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value('counter-set', 'none');
+test_computed_value('counter-set', 'myCounter', 'myCounter 0');
+test_computed_value('counter-set', 'myCounter 5');
+test_computed_value('counter-set', 'myCounter 7 otherCounter 8');
+test_computed_value('counter-set', 'myCounter otherCounter 8', 'myCounter 0 otherCounter 8');
+test_computed_value('counter-set', 'myCounter 7 otherCounter', 'myCounter 7 otherCounter 0');
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-border-box.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-border-box.html
new file mode 100644
index 00000000000..d0176e367b4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-border-box.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>transform-box: border-box (CSS layout)</title>
+<link rel="match" href="./reference/cssbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a square with a black bar at the top whose top-left corner is at 100,100."/>
+
+<style>
+#target {
+ width: 150px;
+ height: 200px;
+ margin-left: 300px;
+ margin-top: 100px;
+ background-color: green;
+ border-left: solid 50px black;
+
+ transform: rotate(90deg);
+ transform-origin: 0 0;
+ transform-box: border-box;
+}
+</style>
+
+<div id="target"></div>
+
+<div id="error"></div>
+<script>
+var refStyle = "border-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-content-box.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-content-box.html
new file mode 100644
index 00000000000..31a44282930
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-content-box.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>transform-box: content-box (CSS layout)</title>
+<link rel="match" href="./reference/cssbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a square with a black bar at the top whose top-left corner is at 100,100."/>
+
+<style>
+#target {
+ width: 150px;
+ height: 200px;
+ margin-left: 300px;
+ margin-top: 100px;
+ background-color: green;
+ border-left: solid 50px black;
+
+ transform: rotate(90deg);
+ transform-origin: -50px 0;
+ transform-box: content-box;
+}
+</style>
+
+<div id="target"></div>
+
+<div id="error"></div>
+<script>
+var refStyle = "content-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-fill-box.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-fill-box.html
new file mode 100644
index 00000000000..6821140bfea
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-fill-box.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>transform-box: fill-box (CSS layout)</title>
+<link rel="match" href="./reference/cssbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a square with a black bar at the top whose top-left corner is at 100,100."/>
+
+<style>
+#target {
+ width: 150px;
+ height: 200px;
+ margin-left: 300px;
+ margin-top: 100px;
+ background-color: green;
+ border-left: solid 50px black;
+
+ transform: rotate(90deg);
+ transform-origin: -50px 0;
+ transform-box: fill-box; /* alias for content-box */
+}
+</style>
+
+<div id="target"></div>
+
+<div id="error"></div>
+<script>
+var refStyle = "fill-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-initial.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-initial.html
new file mode 100644
index 00000000000..5344fb23490
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-initial.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>transform-box: initial (CSS layout)</title>
+<link rel="match" href="./reference/cssbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a square with a black bar at the top whose top-left corner is at 100,100."/>
+
+<style>
+#target {
+ width: 150px;
+ height: 200px;
+ margin-left: 300px;
+ margin-top: 100px;
+ background-color: green;
+ border-left: solid 50px black;
+
+ transform: rotate(90deg);
+ transform-origin: 0 0;
+}
+</style>
+
+<div id="target"></div>
+
+<div id="error"></div>
+<script>
+var refStyle = "view-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-stroke-box.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-stroke-box.html
new file mode 100644
index 00000000000..fd0db232155
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-stroke-box.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>transform-box: stroke-box (CSS layout)</title>
+<link rel="match" href="./reference/cssbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a square with a black bar at the top whose top-left corner is at 100,100."/>
+
+<style>
+#target {
+ width: 150px;
+ height: 200px;
+ margin-left: 300px;
+ margin-top: 100px;
+ background-color: green;
+ border-left: solid 50px black;
+
+ transform: rotate(90deg);
+ transform-origin: 0 0;
+ transform-box: stroke-box; /* alias for border-box */
+}
+</style>
+
+<div id="target"></div>
+
+<div id="error"></div>
+<script>
+var refStyle = "stroke-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-view-box.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-view-box.html
new file mode 100644
index 00000000000..2336957bf1c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/cssbox-view-box.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>transform-box: view-box (CSS layout)</title>
+<link rel="match" href="./reference/cssbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a square with a black bar at the top whose top-left corner is at 100,100."/>
+
+<style>
+#target {
+ width: 150px;
+ height: 200px;
+ margin-left: 300px;
+ margin-top: 100px;
+ background-color: green;
+ border-left: solid 50px black;
+
+ transform: rotate(90deg);
+ transform-origin: 0 0;
+ transform-box: view-box; /* acts like border-box on css boxes */
+}
+</style>
+
+<div id="target"></div>
+
+<div id="error"></div>
+<script>
+var refStyle = "view-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/reference/cssbox-ref.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/reference/cssbox-ref.html
new file mode 100644
index 00000000000..138d65df940
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/reference/cssbox-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+
+<style>
+#target {
+ width: 200px;
+ height: 150px;
+ margin-left: 100px;
+ margin-top: 100px;
+ background-color: green;
+ border-top: solid 50px black;
+}
+</style>
+
+<div id="target"></div> \ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/reference/svgbox-ref.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/reference/svgbox-ref.html
new file mode 100644
index 00000000000..c765ebe8665
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/reference/svgbox-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+
+<style>
+#target {
+ fill: green;
+ stroke: black;
+ stroke-width: 50;
+ transform: none;
+}
+</style>
+
+<svg width="400" height="300">
+ <path id="target" d="M 200 100 h -100 v 100 h 100"/>
+</svg> \ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-border-box.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-border-box.html
new file mode 100644
index 00000000000..921dba1d738
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-border-box.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>transform-box: border-box (SVG layout)</title>
+<link rel="match" href="./reference/svgbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a C shape with the center of the top endpoint at 200,100."/>
+
+<style>
+#target {
+ fill: green;
+ stroke: black;
+ stroke-width: 50;
+ transform-box: border-box; /* alias for stroke-box */
+ transform-origin: 25px 0px;
+ transform: rotate(90deg);
+}
+</style>
+
+<svg width="400" height="300">
+ <path id="target" d="M 200 100 v 100 h 100 v -100"/>
+</svg>
+
+<div id="error"></div>
+<script>
+var refStyle = "border-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-content-box.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-content-box.html
new file mode 100644
index 00000000000..2f7f2dd071a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-content-box.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>transform-box: content-box (SVG layout)</title>
+<link rel="match" href="./reference/svgbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a C shape with the center of the top endpoint at 200,100."/>
+
+<style>
+#target {
+ fill: green;
+ stroke: black;
+ stroke-width: 50;
+ transform-box: content-box; /* alias for fill-box */
+ transform-origin: 0px 0px;
+ transform: rotate(90deg);
+}
+</style>
+
+<svg width="400" height="300">
+ <path id="target" d="M 200 100 v 100 h 100 v -100"/>
+</svg>
+
+<div id="error"></div>
+<script>
+var refStyle = "content-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-fill-box.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-fill-box.html
new file mode 100644
index 00000000000..111d8dbcfb3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-fill-box.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>transform-box: fill-box (SVG layout)</title>
+<link rel="match" href="./reference/svgbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a C shape with the center of the top endpoint at 200,100."/>
+
+<style>
+#target {
+ fill: green;
+ stroke: black;
+ stroke-width: 50;
+ transform-box: fill-box;
+ transform-origin: 0px 0px;
+ transform: rotate(90deg);
+}
+</style>
+
+<svg width="400" height="300">
+ <path id="target" d="M 200 100 v 100 h 100 v -100"/>
+</svg>
+
+<div id="error"></div>
+<script>
+var refStyle = "fill-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-initial.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-initial.html
new file mode 100644
index 00000000000..ba07c884522
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-initial.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>transform-box: initial (SVG layout)</title>
+<link rel="match" href="./reference/svgbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a C shape with the center of the top endpoint at 200,100."/>
+
+<style>
+#target {
+ fill: green;
+ stroke: black;
+ stroke-width: 50;
+ transform-origin: 200px 100px;
+ transform: rotate(90deg);
+}
+</style>
+
+<svg width="400" height="300">
+ <path id="target" d="M 200 100 v 100 h 100 v -100"/>
+</svg>
+
+<div id="error"></div>
+<script>
+var refStyle = "view-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-stroke-box.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-stroke-box.html
new file mode 100644
index 00000000000..d2ca1411ae8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-stroke-box.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>transform-box: stroke-box (SVG layout)</title>
+<link rel="match" href="./reference/svgbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a C shape with the center of the top endpoint at 200,100."/>
+
+<style>
+#target {
+ fill: green;
+ stroke: black;
+ stroke-width: 50;
+ transform-box: stroke-box;
+ transform-origin: 25px 0px;
+ transform: rotate(90deg);
+}
+</style>
+
+<svg width="400" height="300">
+ <path id="target" d="M 200 100 v 100 h 100 v -100"/>
+</svg>
+
+<div id="error"></div>
+<script>
+var refStyle = "stroke-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-view-box.html b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-view-box.html
new file mode 100644
index 00000000000..dbce635d6e7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-transforms/transform-box/svgbox-view-box.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>transform-box: view-box (SVG layout)</title>
+<link rel="match" href="./reference/svgbox-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#transform-box">
+<meta name="assert" content="This should display a C shape with the center of the top endpoint at 200,100."/>
+
+<style>
+#target {
+ fill: green;
+ stroke: black;
+ stroke-width: 50;
+ transform-box: view-box;
+ transform-origin: 200px 100px;
+ transform: rotate(90deg);
+}
+</style>
+
+<svg width="400" height="300">
+ <path id="target" d="M 200 100 v 100 h 100 v -100"/>
+</svg>
+
+<div id="error"></div>
+<script>
+var refStyle = "view-box";
+var compStyle = getComputedStyle(document.getElementById('target')).transformBox;
+if (refStyle != compStyle)
+ document.getElementById('error').textContent = "Error, got computed style " + compStyle;
+</script>
diff --git a/tests/wpt/web-platform-tests/css/css-transitions/Document-getAnimations.tentative.html b/tests/wpt/web-platform-tests/css/css-transitions/Document-getAnimations.tentative.html
index a8986d0bdbd..d1cf6e499bf 100644
--- a/tests/wpt/web-platform-tests/css/css-transitions/Document-getAnimations.tentative.html
+++ b/tests/wpt/web-platform-tests/css/css-transitions/Document-getAnimations.tentative.html
@@ -72,14 +72,15 @@ promise_test(async t => {
assert_equals(animations[0].transitionProperty, 'left');
assert_equals(animations[1].transitionProperty, 'top');
- await waitForAnimationFrames(2);
-
+ // Add one more transition. As the previous call to getAnimations triggered a
+ // style change, the new animation is in a higher transition generation even
+ // though no frame was rendered for the previous transitions.
div.style.opacity = '1'
div.style.transition = 'all 100s';
div.style.opacity = '0'
animations = document.getAnimations();
assert_equals(animations.length, 3,
- 'getAnimations returns two running CSS Transitions');
+ 'getAnimations returns three running CSS Transitions');
assert_equals(animations[0].transitionProperty, 'left', '1');
assert_equals(animations[1].transitionProperty, 'top', '2');
assert_equals(animations[2].transitionProperty, 'opacity', '3');
diff --git a/tests/wpt/web-platform-tests/css/css-typed-om/the-stylepropertymap/properties/counter-set.html b/tests/wpt/web-platform-tests/css/css-typed-om/the-stylepropertymap/properties/counter-set.html
new file mode 100644
index 00000000000..db57f269de1
--- /dev/null
+++ b/tests/wpt/web-platform-tests/css/css-typed-om/the-stylepropertymap/properties/counter-set.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>'counter-set' property</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-get">
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-set">
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#property-stle-value-normalization">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<script src="resources/testsuite.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+runPropertyTests('counter-set', [
+ { syntax: 'none' },
+]);
+
+runUnsupportedPropertyTests('counter-set', [
+ 'chapter', 'chapter 3'
+]);
+
+</script>
diff --git a/tests/wpt/web-platform-tests/docs/writing-tests/general-guidelines.md b/tests/wpt/web-platform-tests/docs/writing-tests/general-guidelines.md
index 531c9a5e2e1..45e8769ae1e 100644
--- a/tests/wpt/web-platform-tests/docs/writing-tests/general-guidelines.md
+++ b/tests/wpt/web-platform-tests/docs/writing-tests/general-guidelines.md
@@ -175,7 +175,7 @@ see the [lint-tool documentation][lint-tool].
But in the unusual case of error reports for things essential to a certain
test or that for other exceptional reasons shouldn't prevent a merge of a
-test, update and commit the `lint.whitelist` file in the web-platform-tests
+test, update and commit the `lint.ignorelist` file in the web-platform-tests
root directory to suppress the error reports. For details on doing that,
see the [lint-tool documentation][lint-tool].
diff --git a/tests/wpt/web-platform-tests/docs/writing-tests/lint-tool.md b/tests/wpt/web-platform-tests/docs/writing-tests/lint-tool.md
index f9caca35fef..551a9c1b605 100644
--- a/tests/wpt/web-platform-tests/docs/writing-tests/lint-tool.md
+++ b/tests/wpt/web-platform-tests/docs/writing-tests/lint-tool.md
@@ -11,16 +11,15 @@ web-platform-tests working directory like this:
The lint tool is also run automatically for every submitted pull request,
and reviewers will not merge branches with tests that have lint errors, so
you must either [fix all lint errors](#fixing-lint-errors), or you must
-[whitelist test files](#updating-the-whitelist) to suppress the errors.
+[add an exception](#updating-the-ignorelist) to suppress the errors.
## Fixing lint errors
-You must fix any errors the lint tool reports, unless an error is for
-something essential to a certain test or that for some other
-exceptional reason shouldn't prevent the test from being merged; in
-those cases you can [whitelist test files](#updating-the-whitelist)
-to suppress the errors. In all other cases, follow the instructions
-below to fix all errors reported.
+You must fix any errors the lint tool reports, unless an error is for something
+essential to a certain test or that for some other exceptional reason shouldn't
+prevent the test from being merged; in those cases you can [add an
+exception](#updating-the-ignorelist) to suppress the errors. In all other
+cases, follow the instructions below to fix all errors reported.
<!--
This listing is automatically generated from the linting tool's Python source
@@ -31,32 +30,30 @@ below to fix all errors reported.
.. wpt-lint-rules:: tools.lint.rules
```
-## Updating the whitelist
+## Updating the ignorelist
Normally you must [fix all lint errors](#fixing-lint-errors). But in the
unusual case of error reports for things essential to certain tests or that
for other exceptional reasons shouldn't prevent a merge of a test, you can
-update and commit the `lint.whitelist` file in the web-platform-tests root
+update and commit the `lint.ignorelist` file in the web-platform-tests root
directory to suppress errors the lint tool would report for a test file.
-To add a test file or directory to the whitelist, use the following format:
+To add a test file or directory to the list, use the following format:
```
ERROR TYPE:file/name/pattern
```
-For example, to whitelist the file `example/file.html` such that all
-`TRAILING WHITESPACE` errors the lint tool would report for it are
-suppressed, add the following line to the `lint.whitelist` file:
+For example, to ignore all `TRAILING WHITESPACE` errors in the file
+`example/file.html`, add the following line to the `lint.ignorelist` file:
```
TRAILING WHITESPACE:example/file.html
```
-To whitelist an entire directory rather than just one file, use the `*`
-wildcard. For example, to whitelist the `example` directory such that all
-`TRAILING WHITESPACE` errors the lint tool would report for any files in it
-are suppressed, add the following line to the `lint.whitelist` file:
+To ignore errors for an entire directory rather than just one file, use the `*`
+wildcard. For example, to ignore all `TRAILING WHITESPACE` errors in the
+`example` directory, add the following line to the `lint.ignorelist` file:
```
TRAILING WHITESPACE:example/*
@@ -67,15 +64,14 @@ use
[shell-style wildcards](https://docs.python.org/2/library/fnmatch.html) to
express other filename patterns or directory-name patterns.
-Finally, to whitelist just one line in a file, use the following format:
+Finally, to ignore just one line in a file, use the following format:
```
ERROR TYPE:file/name/pattern:line_number
```
-For example, to whitelist just line 128 of the file `example/file.html`
-such that any `TRAILING WHITESPACE` error the lint tool would report for
-that line is suppressed, add the following to the `lint.whitelist` file:
+For example, to ignore the `TRAILING WHITESPACE` error for just line 128 of the
+file `example/file.html`, add the following to the `lint.ignorelist` file:
```
TRAILING WHITESPACE:example/file.html:128
diff --git a/tests/wpt/web-platform-tests/docs/writing-tests/testharness-api.md b/tests/wpt/web-platform-tests/docs/writing-tests/testharness-api.md
index 8160ca298ed..bd7d42be968 100644
--- a/tests/wpt/web-platform-tests/docs/writing-tests/testharness-api.md
+++ b/tests/wpt/web-platform-tests/docs/writing-tests/testharness-api.md
@@ -392,8 +392,47 @@ timeout to use.
In other cases it may be necessary to use a timeout (e.g., for a test
that only passes if some event is *not* fired). In this case it is
-*not* permitted to use the standard `setTimeout` function. Instead one
-must use the `step_timeout` function:
+*not* permitted to use the standard `setTimeout` function.
+
+Instead, one of these functions can be used:
+
+* `step_wait` (returns a promise)
+* `step_wait_func` & `step_wait_func_done`
+* As a last resort, `step_timeout`
+
+### `step_wait`, `step_wait_func`, and `step_wait_func_done` ###
+
+These functions are preferred over `step_timeout` as they end when a condition or a timeout is reached, rather than just a timeout. This allows for setting a longer timeout while shortening the runtime of tests on faster machines.
+
+`step_wait(cond, description, timeout=3000, interval=100)` is useful inside `promise_test`, e.g.:
+
+```js
+promise_test(t => {
+ // …
+ await t.step_wait(() => frame.contentDocument === null, "Frame navigated to a cross-origin document");
+ // …
+}, "");
+```
+
+`step_wait_func(cond, func, description, timeout=3000, interval=100)` & `step_wait_func(cond, func, description, timeout=3000, interval=100)` are useful inside `async_test`:
+
+```js
+async_test(t => {
+ const popup = window.open("resources/coop-coep.py?coop=same-origin&coep=&navigate=about:blank");
+ t.add_cleanup(() => popup.close());
+ assert_equals(window, popup.opener);
+
+ popup.onload = t.step_func(() => {
+ assert_true(popup.location.href.endsWith("&navigate=about:blank"));
+ // Use step_wait_func_done as about:blank cannot message back.
+ t.step_wait_func_done(() => popup.location.href === "about:blank");
+ });
+}, "Navigating a popup to about:blank");
+```
+
+### `step_timeout` ###
+
+As a last resort one can use the `step_timeout` function:
```js
async_test(function(t) {
diff --git a/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-delete.tentative.html b/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-delete.tentative.html
new file mode 100644
index 00000000000..3592b2dc0cc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-delete.tentative.html
@@ -0,0 +1,340 @@
+<!doctype html>
+<html>
+<head>
+<meta charset=utf-8>
+<title>Testing normalizing white-space sequence after execCommand("delete", false, "")</title>
+<script src=../include/implementation.js></script>
+<script>var testsJsLibraryOnly = true</script>
+<script src="../include/tests.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+"use strict";
+
+setup({explicit_done: true});
+
+function runTests() {
+ // README:
+ // These tests based on the behavior of Chrome 83. This test does NOT define
+ // nor suggest any standard behavior (actually, some expected results might
+ // look odd), but this test must help you to understand how other browsers
+ // use different logic to normalize white-space sequence.
+
+ document.body.innerHTML = "<div contenteditable></div>";
+ let editor = document.querySelector("div[contenteditable]");
+ editor.focus();
+ let selection = document.getSelection();
+
+ function toPlaintext(str) {
+ return str.replace(/&nbsp;/g, "\u00A0");
+ }
+ function escape(str) {
+ return str.replace(/\u00A0/ig, "&nbsp;");
+ }
+
+ // Test simple removing in a text node.
+ // - initialText: Set to data of text node (only &nbsp; entity is handled)
+ // - expectedText: Set to data of the text node after `execCommand("delete")`
+ // - white-spaceRange: Set first item to start offset of white-space sequence,
+ // set second item to number of white-spaces.
+ for (const currentTest of [
+ { initialText: "a&nbsp;", expectedText: "a", whiteSpaceRange: [1, 1] },
+ { initialText: "a&nbsp;&nbsp;", expectedText: "a&nbsp;", whiteSpaceRange: [1, 2] },
+ { initialText: "a &nbsp;", expectedText: "a&nbsp;", whiteSpaceRange: [1, 2] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp;&nbsp;", whiteSpaceRange: [1, 3] },
+ { initialText: "a&nbsp; &nbsp;", expectedText: "a&nbsp;&nbsp;", whiteSpaceRange: [1, 3] },
+ { initialText: "a &nbsp;&nbsp;", expectedText: "a&nbsp;&nbsp;", whiteSpaceRange: [1, 3] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp;", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp;&nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp;", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp; &nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp;", whiteSpaceRange: [1, 4] },
+ { initialText: "a &nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp;", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp; &nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp;&nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp; &nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp; &nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [1, 10] },
+ { initialText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [1, 10] },
+ { initialText: "a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [1, 10] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 11] },
+ { initialText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 11] },
+ { initialText: "a&nbsp;b", expectedText: "ab", whiteSpaceRange: [1, 1] },
+ { initialText: "a b", expectedText: "ab", whiteSpaceRange: [1, 1] },
+ { initialText: "a&nbsp;&nbsp;b", expectedText: "a b", whiteSpaceRange: [1, 2] },
+ { initialText: "a&nbsp; b", expectedText: "a b", whiteSpaceRange: [1, 2] },
+ { initialText: "a &nbsp;b", expectedText: "a b", whiteSpaceRange: [1, 2] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; b", whiteSpaceRange: [1, 3] },
+ { initialText: "a&nbsp; &nbsp;b", expectedText: "a&nbsp; b", whiteSpaceRange: [1, 3] },
+ { initialText: "a &nbsp; b", expectedText: "a&nbsp; b", whiteSpaceRange: [1, 3] },
+ { initialText: "a &nbsp;&nbsp;b", expectedText: "a&nbsp; b", whiteSpaceRange: [1, 3] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp;b", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp; &nbsp; b", expectedText: "a&nbsp; &nbsp;b", whiteSpaceRange: [1, 4] },
+ { initialText: "a &nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp;b", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp;&nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp;b", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp; &nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp;b", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp; &nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a &nbsp; &nbsp; b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp; b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp;&nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp; &nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp; &nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a &nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [1, 10] },
+ { initialText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [1, 10] },
+ { initialText: "a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [1, 10] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [1, 11] },
+ { initialText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [1, 11] },
+ { initialText: "a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [1, 11] },
+ { initialText: "&nbsp;b", expectedText: "b", whiteSpaceRange: [0, 1] },
+ { initialText: "&nbsp;&nbsp;b", expectedText: "&nbsp;b", whiteSpaceRange: [0, 2] },
+ { initialText: "&nbsp; b", expectedText: "&nbsp;b", whiteSpaceRange: [0, 2] },
+ { initialText: "&nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; b", whiteSpaceRange: [0, 3] },
+ { initialText: "&nbsp; &nbsp;b", expectedText: "&nbsp; b", whiteSpaceRange: [0, 3] },
+ { initialText: "&nbsp;&nbsp; b", expectedText: "&nbsp; b", whiteSpaceRange: [0, 3] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp;b", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp; &nbsp; b", expectedText: "&nbsp; &nbsp;b", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp;&nbsp;&nbsp; b", expectedText: "&nbsp; &nbsp;b", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp;&nbsp; &nbsp;b", expectedText: "&nbsp; &nbsp;b", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp; &nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp;b", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp; b", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp; &nbsp; &nbsp;b", expectedText: "&nbsp; &nbsp; b", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp;&nbsp; &nbsp;b", expectedText: "&nbsp; &nbsp; b", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp; &nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp; b", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp; &nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp; b", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [0, 11] },
+ { initialText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [0, 11] },
+ { initialText: "&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [0, 11] },
+ { initialText: "&nbsp;", expectedText: "", whiteSpaceRange: [0, 1] },
+ { initialText: "&nbsp;&nbsp;", expectedText: "&nbsp;", whiteSpaceRange: [0, 2] },
+ { initialText: "&nbsp;&nbsp;&nbsp;", expectedText: "&nbsp;&nbsp;", whiteSpaceRange: [0, 3] },
+ { initialText: "&nbsp; &nbsp;", expectedText: "&nbsp;&nbsp;", whiteSpaceRange: [0, 3] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "&nbsp; &nbsp;", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp;&nbsp; &nbsp;", expectedText: "&nbsp; &nbsp;", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp; &nbsp;&nbsp;", expectedText: "&nbsp; &nbsp;", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp; &nbsp; &nbsp;", expectedText: "&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp;&nbsp; &nbsp;", expectedText: "&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp; &nbsp;&nbsp;", expectedText: "&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp; &nbsp;&nbsp;&nbsp;", expectedText: "&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 11] },
+ { initialText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 11] },
+ { initialText: "&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 11] },
+ ]) {
+ for (let i = currentTest.whiteSpaceRange[0]; i < currentTest.whiteSpaceRange[0] + currentTest.whiteSpaceRange[1]; i++) {
+ currentTest.getInitialText = function (aCaretPos) {
+ return escape(`${toPlaintext(this.initialText).slice(0, aCaretPos)}[]${toPlaintext(this.initialText).slice(aCaretPos)}`);
+ }
+ test(function () {
+ editor.innerHTML = "";
+ editor.appendChild(document.createTextNode(toPlaintext(currentTest.initialText)));
+ selection.collapse(editor.firstChild, i + 1);
+ document.execCommand("delete", false, "");
+ if (currentTest.expectedText.length) {
+ assert_equals(escape(editor.childNodes.item(0).data), currentTest.expectedText, "Modified text is wrong");
+ assert_equals(selection.focusNode, editor.childNodes.item(0), "Selection focus node is wrong");
+ assert_equals(selection.focusOffset, i, "Selection focus offset is wrong");
+ assert_equals(selection.anchorNode, editor.childNodes.item(0), "Selection anchor node is wrong");
+ assert_equals(selection.anchorOffset, i, "Selection anchor offset is wrong");
+ } else {
+ assert_equals(escape(editor.textContent), "", "Modified text is wrong");
+ assert_equals(selection.focusNode, editor, "Selection focus node is wrong");
+ assert_equals(selection.focusOffset, 0, "Selection focus offset is wrong");
+ assert_equals(selection.anchorNode, editor, "Selection anchor node is wrong");
+ assert_equals(selection.anchorOffset, 0, "Selection anchor offset is wrong");
+ }
+ }, `execCommand("delete", false, ""): "${currentTest.getInitialText(i + 1)}" (length of whiteSpace sequence: ${currentTest.whiteSpaceRange[1]})`);
+ }
+ }
+
+ // Test white space sequence split to multiple text node.
+ // - initialText: Set to data of text nodes. This must have "|" at least one.
+ // Then, the text will be split at every "|".
+ // Same as above test, only &nbsp; is handled at setting.
+ // "[]" means that caret position.
+ // - expectedText: Set to data of all text nodes as an array.
+ // Same as above test, only &nbsp; is handled before comparing.
+ for (const currentTest of [
+ { initialText: "a&nbsp; &nbsp;|[]&nbsp; &nbsp;b", expectedText: ["a&nbsp; []", "&nbsp; &nbsp;b"] },
+ { initialText: "a&nbsp; &nbsp;[]|&nbsp; &nbsp;b", expectedText: ["a&nbsp; []", "&nbsp; &nbsp;b"] },
+ { initialText: "a&nbsp; &nbsp;|[] &nbsp; b", expectedText: ["a&nbsp; []", "&nbsp; &nbsp;b"] },
+ { initialText: "a&nbsp; &nbsp;[]| &nbsp; b", expectedText: ["a&nbsp; []", "&nbsp; &nbsp;b"] },
+ { initialText: "a &nbsp; |[]&nbsp; &nbsp;b", expectedText: ["a &nbsp;[]", "&nbsp; &nbsp;b"] },
+ { initialText: "a &nbsp; []|&nbsp; &nbsp;b", expectedText: ["a &nbsp;[]", "&nbsp; &nbsp;b"] },
+ { initialText: "a&nbsp; &nbsp;|&nbsp;[] &nbsp;b", expectedText: ["a&nbsp; &nbsp;[]", "&nbsp; b"] },
+ { initialText: "a&nbsp; &nbsp;| []&nbsp; b", expectedText: ["a&nbsp; &nbsp;[]", "&nbsp; b"] },
+ { initialText: "a &nbsp; |&nbsp;[] &nbsp;b", expectedText: ["a &nbsp; []", "&nbsp; b"] },
+ { initialText: "a &nbsp; | []&nbsp; b", expectedText: ["a &nbsp;[]", "&nbsp; b"] },
+
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;[]&nbsp;&nbsp;b", expectedText: ["a&nbsp;&nbsp;&nbsp;&nbsp;", "&nbsp;[] &nbsp;b"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;[]&nbsp;&nbsp;&nbsp;b", expectedText: ["a&nbsp;&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp;b"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;|[]&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; b"] },
+ { initialText: "a&nbsp;b[]&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;[] &nbsp;", "&nbsp;&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;b[]&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp; []&nbsp;&nbsp;", "&nbsp;&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;b[]|&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;b|[]&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;b[]|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;b|[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;|b[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;|&nbsp;b[]&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;", "&nbsp;[] &nbsp; &nbsp;c"] },
+
+ { initialText: "a&nbsp;&nbsp;&nbsp;|&nbsp;|[]&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;| |[]&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;| []|&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;[]| |&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp;", "&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]&nbsp;| |&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp; []&nbsp;", " ", "&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]&nbsp;&nbsp;|&nbsp;|&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp; []&nbsp;&nbsp;", "&nbsp;", "&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]&nbsp;&nbsp;| |&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp; []&nbsp;&nbsp;", " ", "&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;||&nbsp;[]&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;||[]&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;|[]|&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;[]||&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]&nbsp;||&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp; []&nbsp;", "", "&nbsp;&nbsp;&nbsp;&nbsp;c"] },
+ ]) {
+ test(function () {
+ editor.innerHTML = "";
+ let caret = { container: null, offset: -1 };
+ for (let text of toPlaintext(currentTest.initialText).split("|")) {
+ let caretOffset = text.indexOf("[]");
+ if (caretOffset >= 0) {
+ text = text.slice(0, caretOffset) + text.slice(caretOffset + 2);
+ }
+ let textNode = document.createTextNode(text);
+ editor.appendChild(textNode);
+ if (caretOffset >= 0) {
+ caret = { container: textNode, offset: caretOffset };
+ }
+ }
+ selection.collapse(caret.container, caret.offset);
+ document.execCommand("delete", false, "");
+ let child = editor.firstChild;
+ for (let expectedText of currentTest.expectedText) {
+ expectedText = toPlaintext(expectedText);
+ let caretOffset = expectedText.indexOf("[]");
+ if (caretOffset >= 0) {
+ expectedText = expectedText.slice(0, caretOffset) + expectedText.slice(caretOffset + 2);
+ }
+ if (!child || child.nodeName !== "#text") {
+ assert_equals("", escape(expectedText), "Expected text node is not there");
+ if (caretOffset >= 0) {
+ assert_equals(-1, caretOffset, "Selection should be contained in this node");
+ }
+ } else {
+ assert_equals(escape(child.data), escape(expectedText), "Modified text is wrong");
+ if (caretOffset >= 0) {
+ assert_equals(selection.focusNode, child, "Selection focus node is wrong");
+ assert_equals(selection.focusOffset, caretOffset, "Selection focus offset is wrong");
+ assert_equals(selection.anchorNode, child, "Selection anchor node is wrong");
+ assert_equals(selection.anchorOffset, caretOffset, "Selection anchor offset is wrong");
+ }
+ }
+ child = child.nextSibling;
+ }
+ if (child && child.nodeName === "#text") {
+ assert_equals(escape(child.data), "", "Unexpected text node is there");
+ }
+ }, `execCommand("delete", false, ""): "${currentTest.initialText}"`);
+ }
+
+ // Test white spaces around inline element boundary
+ // - initialHTML: Set to innerHTML of the <div> ("[{" and "]}" set selection to the range)
+ // - expectedText: Set to innerHTML of the <div> after `execCommand("delete")`
+ for (const currentTest of [
+ { initialHTML: "<span>abc <span>&nbsp;[]def</span></span>", expectedHTML: "<span>abc <span>def</span></span>" },
+ { initialHTML: "<span>abc <span>[]&nbsp;def</span></span>", expectedHTML: "<span>abc<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc []<span>&nbsp;def</span></span>", expectedHTML: "<span>abc<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc&nbsp;<span>&nbsp;[]def</span></span>", expectedHTML: "<span>abc&nbsp;<span>def</span></span>" },
+ { initialHTML: "<span>abc&nbsp;<span>[]&nbsp;def</span></span>", expectedHTML: "<span>abc<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc&nbsp;[]<span>&nbsp;def</span></span>", expectedHTML: "<span>abc<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc&nbsp; <span>&nbsp;[]def</span></span>", expectedHTML: "<span>abc&nbsp; <span>def</span></span>" },
+ { initialHTML: "<span>abc&nbsp; <span>[]&nbsp;def</span></span>", expectedHTML: "<span>abc&nbsp;<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc&nbsp; []<span>&nbsp;def</span></span>", expectedHTML: "<span>abc&nbsp;<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc &nbsp;<span>&nbsp;[]def</span></span>", expectedHTML: "<span>abc &nbsp;<span>def</span></span>" },
+ { initialHTML: "<span>abc &nbsp;<span>[]&nbsp;def</span></span>", expectedHTML: "<span>abc <span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc &nbsp;[]<span>&nbsp;def</span></span>", expectedHTML: "<span>abc <span>&nbsp;def</span></span>" },
+
+ { initialHTML: "<span>abc </span><span>&nbsp;[]def</span>", expectedHTML: "<span>abc </span><span>def</span>" },
+ { initialHTML: "<span>abc </span><span>[]&nbsp;def</span>", expectedHTML: "<span>abc</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc []</span><span>&nbsp;def</span>", expectedHTML: "<span>abc</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp;</span><span>&nbsp;[]def</span>", expectedHTML: "<span>abc&nbsp;</span><span>def</span>" },
+ { initialHTML: "<span>abc&nbsp;</span><span>[]&nbsp;def</span>", expectedHTML: "<span>abc</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp;[]</span><span>&nbsp;def</span>", expectedHTML: "<span>abc</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp; </span><span>&nbsp;[]def</span>", expectedHTML: "<span>abc&nbsp; </span><span>def</span>" },
+ { initialHTML: "<span>abc&nbsp; </span><span>[]&nbsp;def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp; []</span><span>&nbsp;def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc &nbsp;</span><span>&nbsp;[]def</span>", expectedHTML: "<span>abc &nbsp;</span><span>def</span>" },
+ { initialHTML: "<span>abc &nbsp;</span><span>[]&nbsp;def</span>", expectedHTML: "<span>abc </span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc &nbsp;[]</span><span>&nbsp;def</span>", expectedHTML: "<span>abc </span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp;</span><span>&nbsp; []def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp;</span><span>&nbsp; &nbsp;[]def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp; def</span>" },
+ { initialHTML: "<span>abc&nbsp;</span><span>&nbsp; []&nbsp;def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp; def</span>" },
+ { initialHTML: "<span>abc&nbsp;</span><span>&nbsp;[] &nbsp;def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp; def</span>" },
+ { initialHTML: "<span>abc&nbsp;</span><span> &nbsp; []def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp; def</span>" },
+ { initialHTML: "<span>abc&nbsp;</span><span> &nbsp;[] def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp; def</span>" },
+ { initialHTML: "<span>abc&nbsp;</span><span> []&nbsp; def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp; def</span>" },
+ { initialHTML: "<span>abc&nbsp;</span><span>[] &nbsp; def</span>", expectedHTML: "<span>abc</span><span>&nbsp; &nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp;[]</span><span> &nbsp; def</span>", expectedHTML: "<span>abc</span><span>&nbsp; &nbsp;def</span>" },
+ { initialHTML: "<span>abc &nbsp;[]</span><span> &nbsp; def</span>", expectedHTML: "<span>abc </span><span>&nbsp; &nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp;&nbsp;[]</span><span> &nbsp; def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp; &nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp;&nbsp;[]</span><span>&nbsp; &nbsp;def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp; &nbsp;def</span>" },
+
+ { initialHTML: "<span><span>abc </span>&nbsp;[]def</span>", expectedHTML: "<span><span>abc </span>def</span>" },
+ { initialHTML: "<span><span>abc </span>[]&nbsp;def</span>", expectedHTML: "<span><span>abc</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc []</span>&nbsp;def</span>", expectedHTML: "<span><span>abc</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc&nbsp;</span>&nbsp;[]def</span>", expectedHTML: "<span><span>abc&nbsp;</span>def</span>" },
+ { initialHTML: "<span><span>abc&nbsp;</span>[]&nbsp;def</span>", expectedHTML: "<span><span>abc</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc&nbsp;[]</span>&nbsp;def</span>", expectedHTML: "<span><span>abc</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc&nbsp; </span>&nbsp;[]def</span>", expectedHTML: "<span><span>abc&nbsp; </span>def</span>" },
+ { initialHTML: "<span><span>abc&nbsp; </span>[]&nbsp;def</span>", expectedHTML: "<span><span>abc&nbsp;</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc&nbsp; []</span>&nbsp;def</span>", expectedHTML: "<span><span>abc&nbsp;</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc &nbsp;</span>&nbsp;[]def</span>", expectedHTML: "<span><span>abc &nbsp;</span>def</span>" },
+ { initialHTML: "<span><span>abc &nbsp;</span>[]&nbsp;def</span>", expectedHTML: "<span><span>abc </span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc &nbsp;[]</span>&nbsp;def</span>", expectedHTML: "<span><span>abc </span>&nbsp;def</span>" },
+
+ { initialHTML: "<span><span>abc &nbsp;</span></span><span>&nbsp;[]def</span>", expectedHTML: "<span><span>abc &nbsp;</span></span><span>def</span>" },
+ { initialHTML: "<span><span>abc &nbsp;</span></span><span>[]&nbsp;def</span>", expectedHTML: "<span><span>abc </span></span><span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc &nbsp;[]</span></span><span>&nbsp;def</span>", expectedHTML: "<span><span>abc </span></span><span>&nbsp;def</span>" },
+
+
+ { initialHTML: "a<span style=white-space:pre;>b[] </span>c", expectedHTML: "a<span style=\"white-space:pre;\"> </span>c" },
+ { initialHTML: "a<span style=white-space:pre;>b [] </span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" },
+ { initialHTML: "a<span style=white-space:pre;>b [] </span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" },
+ { initialHTML: "a<span style=white-space:pre;>b []</span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" },
+ { initialHTML: "a<span style=white-space:pre;>b [] </span>", expectedHTML: "a<span style=\"white-space:pre;\">b </span>" },
+ { initialHTML: "a<span style=white-space:pre;> </span>[]b", expectedHTML: "ab" },
+ { initialHTML: "a&nbsp;&nbsp;&nbsp;<span style=white-space:pre;>[] </span>", expectedHTML: "a&nbsp;&nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;&nbsp;&nbsp;[]<span style=white-space:pre;> </span>", expectedHTML: "a&nbsp;&nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;&nbsp;[]&nbsp;<span style=white-space:pre;> </span>", expectedHTML: "a&nbsp;&nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;[]&nbsp;&nbsp;<span style=white-space:pre;>b </span>", expectedHTML: "a&nbsp;&nbsp;<span style=\"white-space:pre;\">b </span>" },
+ { initialHTML: "a&nbsp;&nbsp;&nbsp;&nbsp;<span style=white-space:pre;>[] </span>", expectedHTML: "a&nbsp;&nbsp;&nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;&nbsp;&nbsp;&nbsp;[]<span style=white-space:pre;> </span>", expectedHTML: "a&nbsp;&nbsp;&nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;&nbsp;&nbsp;[]&nbsp;<span style=white-space:pre;> </span>", expectedHTML: "a&nbsp; &nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;&nbsp;[]&nbsp;<span style=white-space:pre;>b </span>", expectedHTML: "a&nbsp;&nbsp;<span style=\"white-space:pre;\">b </span>" },
+ { initialHTML: "<span style=white-space:pre;> [] </span>&nbsp;&nbsp;&nbsp;a", expectedHTML: "<span style=\"white-space:pre;\"> </span>&nbsp;&nbsp;&nbsp;a" },
+ { initialHTML: "<span style=white-space:pre;> []</span>&nbsp;&nbsp;&nbsp;a", expectedHTML: "<span style=\"white-space:pre;\"> </span>&nbsp; &nbsp;a" },
+ { initialHTML: "<span style=white-space:pre;> </span>[]&nbsp;&nbsp;&nbsp;a", expectedHTML: "<span style=\"white-space:pre;\"> </span>&nbsp; &nbsp;a" },
+ { initialHTML: "<span style=white-space:pre;> </span>&nbsp;[]&nbsp;&nbsp;&nbsp;a", expectedHTML: "<span style=\"white-space:pre;\"> </span>&nbsp; &nbsp;a" },
+ ]) {
+ test(function () {
+ let points = setupDiv(editor, currentTest.initialHTML);
+ selection.setBaseAndExtent(points[0], points[1], points[2], points[3]);
+ document.execCommand("delete", false, "");
+ assert_equals(editor.innerHTML, currentTest.expectedHTML);
+ }, `execCommand("delete", false, ""): "${currentTest.initialHTML}"`);
+ }
+
+ done();
+}
+
+window.addEventListener("load", runTests, {once: true});
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-forwarddelete.tentative.html b/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-forwarddelete.tentative.html
new file mode 100644
index 00000000000..4a94c6bcddf
--- /dev/null
+++ b/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-forwarddelete.tentative.html
@@ -0,0 +1,356 @@
+<!doctype html>
+<html>
+<head>
+<meta charset=utf-8>
+<title>Testing normalizing white space sequence after execCommand("forward", false, "")</title>
+<script src=../include/implementation.js></script>
+<script>var testsJsLibraryOnly = true</script>
+<script src="../include/tests.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+"use strict";
+
+setup({explicit_done: true});
+
+function runTests() {
+ // README:
+ // These tests based on the behavior of Chrome 83. This test does NOT define
+ // nor suggest any standard behavior (actually, some expected results might
+ // look odd), but this test must help you to understand how other browsers
+ // use different logic to normalize white-space sequence.
+
+ document.body.innerHTML = "<div contenteditable></div>";
+ let editor = document.querySelector("div[contenteditable]");
+ editor.focus();
+ let selection = document.getSelection();
+
+ function toPlaintext(str) {
+ return str.replace(/&nbsp;/g, "\u00A0");
+ }
+ function escape(str) {
+ return str.replace(/\u00A0/ig, "&nbsp;");
+ }
+
+ // Test simple removing in a text node.
+ // - initialText: Set to data of text node (only &nbsp; entity is handled)
+ // - expectedText: Set to data of the text node after `execCommand("forward")`
+ // - whiteSpaceRange: Set first item to start offset of whitespace sequence,
+ // set second item to number of white spaces.
+ for (const currentTest of [
+ { initialText: "a&nbsp;", expectedText: "a", whiteSpaceRange: [1, 1] },
+ { initialText: "a&nbsp;&nbsp;", expectedText: "a&nbsp;", whiteSpaceRange: [1, 2] },
+ { initialText: "a &nbsp;", expectedText: "a&nbsp;", whiteSpaceRange: [1, 2] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp;&nbsp;", whiteSpaceRange: [1, 3] },
+ { initialText: "a&nbsp; &nbsp;", expectedText: "a&nbsp;&nbsp;", whiteSpaceRange: [1, 3] },
+ { initialText: "a &nbsp;&nbsp;", expectedText: "a&nbsp;&nbsp;", whiteSpaceRange: [1, 3] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp;", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp;&nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp;", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp; &nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp;", whiteSpaceRange: [1, 4] },
+ { initialText: "a &nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp;", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp; &nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp;&nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp; &nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp; &nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [1, 10] },
+ { initialText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [1, 10] },
+ { initialText: "a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [1, 10] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 11] },
+ { initialText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", whiteSpaceRange: [1, 11] },
+ { initialText: "a&nbsp;b", expectedText: "ab", whiteSpaceRange: [1, 1] },
+ { initialText: "a b", expectedText: "ab", whiteSpaceRange: [1, 1] },
+ { initialText: "a&nbsp;&nbsp;b", expectedText: "a b", whiteSpaceRange: [1, 2] },
+ { initialText: "a&nbsp; b", expectedText: "a b", whiteSpaceRange: [1, 2] },
+ { initialText: "a &nbsp;b", expectedText: "a b", whiteSpaceRange: [1, 2] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; b", whiteSpaceRange: [1, 3] },
+ { initialText: "a&nbsp; &nbsp;b", expectedText: "a&nbsp; b", whiteSpaceRange: [1, 3] },
+ { initialText: "a &nbsp; b", expectedText: "a&nbsp; b", whiteSpaceRange: [1, 3] },
+ { initialText: "a &nbsp;&nbsp;b", expectedText: "a&nbsp; b", whiteSpaceRange: [1, 3] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp;b", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp; &nbsp; b", expectedText: "a&nbsp; &nbsp;b", whiteSpaceRange: [1, 4] },
+ { initialText: "a &nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp;b", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp;&nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp;b", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp; &nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp;b", whiteSpaceRange: [1, 4] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp; &nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a &nbsp; &nbsp; b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp; b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp;&nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp; &nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp; &nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a &nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; b", whiteSpaceRange: [1, 5] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [1, 10] },
+ { initialText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [1, 10] },
+ { initialText: "a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [1, 10] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [1, 11] },
+ { initialText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [1, 11] },
+ { initialText: "a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", expectedText: "a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [1, 11] },
+ { initialText: "&nbsp;b", expectedText: "b", whiteSpaceRange: [0, 1] },
+ { initialText: "&nbsp;&nbsp;b", expectedText: "&nbsp;b", whiteSpaceRange: [0, 2] },
+ { initialText: "&nbsp; b", expectedText: "&nbsp;b", whiteSpaceRange: [0, 2] },
+ { initialText: "&nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; b", whiteSpaceRange: [0, 3] },
+ { initialText: "&nbsp; &nbsp;b", expectedText: "&nbsp; b", whiteSpaceRange: [0, 3] },
+ { initialText: "&nbsp;&nbsp; b", expectedText: "&nbsp; b", whiteSpaceRange: [0, 3] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp;b", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp; &nbsp; b", expectedText: "&nbsp; &nbsp;b", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp;&nbsp;&nbsp; b", expectedText: "&nbsp; &nbsp;b", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp;&nbsp; &nbsp;b", expectedText: "&nbsp; &nbsp;b", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp; &nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp;b", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp; b", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp; &nbsp; &nbsp;b", expectedText: "&nbsp; &nbsp; b", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp;&nbsp; &nbsp;b", expectedText: "&nbsp; &nbsp; b", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp; &nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp; b", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp; &nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp; b", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [0, 11] },
+ { initialText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [0, 11] },
+ { initialText: "&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b", whiteSpaceRange: [0, 11] },
+ { initialText: "&nbsp;", expectedText: "", whiteSpaceRange: [0, 1] },
+ { initialText: "&nbsp;&nbsp;", expectedText: "&nbsp;", whiteSpaceRange: [0, 2] },
+ { initialText: "&nbsp;&nbsp;&nbsp;", expectedText: "&nbsp;&nbsp;", whiteSpaceRange: [0, 3] },
+ { initialText: "&nbsp; &nbsp;", expectedText: "&nbsp;&nbsp;", whiteSpaceRange: [0, 3] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "&nbsp; &nbsp;", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp;&nbsp; &nbsp;", expectedText: "&nbsp; &nbsp;", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp; &nbsp;&nbsp;", expectedText: "&nbsp; &nbsp;", whiteSpaceRange: [0, 4] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp; &nbsp; &nbsp;", expectedText: "&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp;&nbsp; &nbsp;", expectedText: "&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp; &nbsp;&nbsp;", expectedText: "&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp; &nbsp;&nbsp;&nbsp;", expectedText: "&nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 5] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", whiteSpaceRange: [0, 10] },
+ { initialText: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 11] },
+ { initialText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 11] },
+ { initialText: "&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", expectedText: "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;", whiteSpaceRange: [0, 11] },
+ ]) {
+ for (let i = currentTest.whiteSpaceRange[0]; i < currentTest.whiteSpaceRange[0] + currentTest.whiteSpaceRange[1]; i++) {
+ currentTest.getInitialText = function (aCaretPos) {
+ return escape(`${toPlaintext(this.initialText).slice(0, aCaretPos)}[]${toPlaintext(this.initialText).slice(aCaretPos)}`);
+ }
+ test(function () {
+ editor.innerHTML = "";
+ editor.appendChild(document.createTextNode(toPlaintext(currentTest.initialText)));
+ selection.collapse(editor.firstChild, i);
+ document.execCommand("forwarddelete", false, "");
+ if (currentTest.expectedText.length) {
+ assert_equals(escape(editor.childNodes.item(0).data), currentTest.expectedText, "Modified text is wrong");
+ assert_equals(selection.focusNode, editor.childNodes.item(0), "Selection focus node is wrong");
+ assert_equals(selection.focusOffset, i, "Selection focus offset is wrong");
+ assert_equals(selection.anchorNode, editor.childNodes.item(0), "Selection anchor node is wrong");
+ assert_equals(selection.anchorOffset, i, "Selection anchor offset is wrong");
+ } else {
+ assert_equals(escape(editor.textContent), "", "Modified text is wrong");
+ assert_equals(selection.focusNode, editor, "Selection focus node is wrong");
+ assert_equals(selection.focusOffset, 0, "Selection focus offset is wrong");
+ assert_equals(selection.anchorNode, editor, "Selection anchor node is wrong");
+ assert_equals(selection.anchorOffset, 0, "Selection anchor offset is wrong");
+ }
+ }, `execCommand("forwarddelete", false, ""): "${currentTest.getInitialText(i)}" (length of whitespace sequence: ${currentTest.whiteSpaceRange[1]})`);
+ }
+ }
+
+ // Test white space sequence split to multiple text node.
+ // - initialText: Set to data of text nodes. This must have "|" at least one.
+ // Then, the text will be split at every "|".
+ // Same as above test, only &nbsp; is handled at setting.
+ // "[]" means that caret position.
+ // - expectedText: Set to data of all text nodes as an array.
+ // Same as above test, only &nbsp; is handled before comparing.
+ for (const currentTest of [
+ { initialText: "a&nbsp; []&nbsp;|&nbsp; &nbsp;b", expectedText: ["a&nbsp; []", "&nbsp; &nbsp;b"] },
+ { initialText: "a&nbsp; []&nbsp;| &nbsp; b", expectedText: ["a&nbsp; []", "&nbsp; &nbsp;b"] },
+ { initialText: "a&nbsp; &nbsp;[]|&nbsp; &nbsp;b", expectedText: ["a&nbsp; &nbsp;[]", "&nbsp; b"] },
+ { initialText: "a&nbsp; &nbsp;[]| &nbsp; b", expectedText: ["a&nbsp; &nbsp;[]", "&nbsp; b"] },
+ { initialText: "a&nbsp; &nbsp;|[]&nbsp; &nbsp;b", expectedText: ["a&nbsp; &nbsp;[]", "&nbsp; b"] },
+ { initialText: "a&nbsp; &nbsp;|[] &nbsp; b", expectedText: ["a&nbsp; &nbsp;[]", "&nbsp; b"] },
+ { initialText: "a&nbsp; &nbsp;| []&nbsp; b", expectedText: ["a&nbsp; &nbsp;", "&nbsp;[] b"] },
+ { initialText: "a &nbsp; |[]&nbsp; &nbsp;b", expectedText: ["a &nbsp; []", "&nbsp; b"] },
+ { initialText: "a &nbsp; []|&nbsp; &nbsp;b", expectedText: ["a &nbsp; []", "&nbsp; b"] },
+ { initialText: "a &nbsp;[] |&nbsp; &nbsp;b", expectedText: ["a &nbsp;[]", "&nbsp; &nbsp;b"] },
+
+ { initialText: "a&nbsp;&nbsp;[]&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: ["a&nbsp; []&nbsp;", "&nbsp;&nbsp;&nbsp;&nbsp;b"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; b"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;[]|&nbsp;&nbsp;&nbsp;&nbsp;b", expectedText: ["a&nbsp;&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp;b"] },
+ { initialText: "a&nbsp;[]b&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;[] &nbsp;", "&nbsp;&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;[]b&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp; []&nbsp;&nbsp;", "&nbsp;&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]b|&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]|b&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;|[]b&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;|&nbsp;[]b&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;", "&nbsp;[] &nbsp; c"] },
+
+ { initialText: "a&nbsp;&nbsp;&nbsp;|&nbsp;|[]&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;", "&nbsp;[]", "&nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;| |[]&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;", " []", "&nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;| []|&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;", " []", "&nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;|[] |&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;[]| |&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]&nbsp;| |&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp;", "&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]&nbsp;&nbsp;|&nbsp;|&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp; &nbsp;[]&nbsp;", "&nbsp;", "&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]&nbsp;&nbsp;| |&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp; &nbsp;[]&nbsp;", " ", "&nbsp;&nbsp;&nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;||&nbsp;[]&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;&nbsp;", "", "&nbsp;[] &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;||[]&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;|[]|&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;&nbsp;[]||&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp;c"] },
+ { initialText: "a&nbsp;&nbsp;&nbsp;[]&nbsp;||&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp;&nbsp;&nbsp;[]", "&nbsp; &nbsp; c"] },
+ { initialText: "a&nbsp;&nbsp;[]&nbsp;&nbsp;||&nbsp;&nbsp;&nbsp;&nbsp;c", expectedText: ["a&nbsp; []&nbsp;", "", "&nbsp;&nbsp;&nbsp;&nbsp;c"] },
+ ]) {
+ test(function () {
+ editor.innerHTML = "";
+ let caret = { container: null, offset: -1 };
+ for (let text of toPlaintext(currentTest.initialText).split("|")) {
+ let caretOffset = text.indexOf("[]");
+ if (caretOffset >= 0) {
+ text = text.slice(0, caretOffset) + text.slice(caretOffset + 2);
+ }
+ let textNode = document.createTextNode(text);
+ editor.appendChild(textNode);
+ if (caretOffset >= 0) {
+ caret = { container: textNode, offset: caretOffset };
+ }
+ }
+ selection.collapse(caret.container, caret.offset);
+ document.execCommand("forwarddelete", false, "");
+ let child = editor.firstChild;
+ for (let expectedText of currentTest.expectedText) {
+ expectedText = toPlaintext(expectedText);
+ let caretOffset = expectedText.indexOf("[]");
+ if (caretOffset >= 0) {
+ expectedText = expectedText.slice(0, caretOffset) + expectedText.slice(caretOffset + 2);
+ }
+ if (!child || child.nodeName !== "#text") {
+ assert_equals("", escape(expectedText), "Expected text node is not there");
+ if (caretOffset >= 0) {
+ assert_equals(-1, caretOffset, "Selection should be contained in this node");
+ }
+ } else {
+ assert_equals(escape(child.data), escape(expectedText), "Modified text is wrong");
+ if (caretOffset >= 0) {
+ assert_equals(selection.focusNode, child, "Selection focus node is wrong");
+ assert_equals(selection.focusOffset, caretOffset, "Selection focus offset is wrong");
+ assert_equals(selection.anchorNode, child, "Selection anchor node is wrong");
+ assert_equals(selection.anchorOffset, caretOffset, "Selection anchor offset is wrong");
+ }
+ }
+ child = child.nextSibling;
+ }
+ if (child && child.nodeName === "#text") {
+ assert_equals(escape(child.data), "", "Unexpected text node is there");
+ }
+ }, `execCommand("forwarddelete", false, ""): "${currentTest.initialText}"`);
+ }
+
+ // Test white spaces around inline element boundary
+ // - initialHTML: Set to innerHTML of the <div> ("[{" and "]}" set selection to the range)
+ // - expectedText: Set to innerHTML of the <div> after `execCommand("delete")`
+ for (const currentTest of [
+ { initialHTML: "<span>abc[] <span>&nbsp;def</span></span>", expectedHTML: "<span>abc<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc[]&nbsp;<span>&nbsp;def</span></span>", expectedHTML: "<span>abc<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc[]&nbsp;<span> def</span></span>", expectedHTML: "<span>abc<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc []<span>&nbsp;def</span></span>", expectedHTML: "<span>abc <span>def</span></span>" },
+ { initialHTML: "<span>abc&nbsp;[]<span>&nbsp;def</span></span>", expectedHTML: "<span>abc&nbsp;<span>def</span></span>" },
+ { initialHTML: "<span>abc&nbsp;[]<span> def</span></span>", expectedHTML: "<span>abc&nbsp;<span>def</span></span>" },
+ { initialHTML: "<span>abc[]&nbsp;<span>&nbsp; def</span></span>", expectedHTML: "<span>abc<span>&nbsp; def</span></span>" },
+ { initialHTML: "<span>abc[]&nbsp;<span> &nbsp;def</span></span>", expectedHTML: "<span>abc<span>&nbsp; def</span></span>" },
+ { initialHTML: "<span>abc[]&nbsp; <span>&nbsp;&nbsp;def</span></span>", expectedHTML: "<span>abc&nbsp;<span>&nbsp;&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc[]&nbsp; <span>&nbsp; def</span></span>", expectedHTML: "<span>abc&nbsp;<span>&nbsp; def</span></span>" },
+ { initialHTML: "<span>abc[]&nbsp;&nbsp;<span>&nbsp;&nbsp;def</span></span>", expectedHTML: "<span>abc&nbsp;<span>&nbsp;&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc[] &nbsp;<span>&nbsp;&nbsp;def</span></span>", expectedHTML: "<span>abc&nbsp;<span>&nbsp;&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc[] &nbsp;<span> &nbsp;def</span></span>", expectedHTML: "<span>abc&nbsp;<span> &nbsp;def</span></span>" },
+ { initialHTML: "<span>abc[] &nbsp;<span>&nbsp; def</span></span>", expectedHTML: "<span>abc&nbsp;<span>&nbsp; def</span></span>" },
+ { initialHTML: "<span>abc&nbsp; []<span>&nbsp; def</span></span>", expectedHTML: "<span>abc&nbsp; <span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc&nbsp; <span>[]&nbsp; def</span></span>", expectedHTML: "<span>abc&nbsp; <span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc&nbsp;&nbsp;[]<span> &nbsp;def</span></span>", expectedHTML: "<span>abc&nbsp;&nbsp;<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc&nbsp;&nbsp;<span>[] &nbsp;def</span></span>", expectedHTML: "<span>abc&nbsp;&nbsp;<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc &nbsp;[]<span>&nbsp; def</span></span>", expectedHTML: "<span>abc &nbsp;<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc &nbsp;<span>[]&nbsp; def</span></span>", expectedHTML: "<span>abc &nbsp;<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc&nbsp; <span>&nbsp;[] def</span></span>", expectedHTML: "<span>abc&nbsp; <span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc &nbsp;<span>&nbsp;[] def</span></span>", expectedHTML: "<span>abc &nbsp;<span>&nbsp;def</span></span>" },
+ { initialHTML: "<span>abc &nbsp;<span> []&nbsp;def</span></span>", expectedHTML: "<span>abc &nbsp;<span>&nbsp;def</span></span>" },
+
+ { initialHTML: "<span><span>abc[] </span>&nbsp;def</span>", expectedHTML: "<span><span>abc</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc[]&nbsp;</span>&nbsp;def</span>", expectedHTML: "<span><span>abc</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc[]&nbsp;</span> def</span>", expectedHTML: "<span><span>abc</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc []</span>&nbsp;def</span>", expectedHTML: "<span><span>abc </span>def</span>" },
+ { initialHTML: "<span><span>abc&nbsp;[]</span>&nbsp;def</span>", expectedHTML: "<span><span>abc&nbsp;</span>def</span>" },
+ { initialHTML: "<span><span>abc&nbsp;[]</span> def</span>", expectedHTML: "<span><span>abc&nbsp;</span>def</span>" },
+ { initialHTML: "<span><span>abc[]&nbsp;</span>&nbsp; def</span>", expectedHTML: "<span><span>abc</span>&nbsp; def</span>" },
+ { initialHTML: "<span><span>abc[]&nbsp;</span> &nbsp;def</span>", expectedHTML: "<span><span>abc</span>&nbsp; def</span>" },
+ { initialHTML: "<span><span>abc[]&nbsp; </span>&nbsp;&nbsp;def</span>", expectedHTML: "<span><span>abc&nbsp;</span>&nbsp;&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc[]&nbsp; </span>&nbsp; def</span>", expectedHTML: "<span><span>abc&nbsp;</span>&nbsp; def</span>" },
+ { initialHTML: "<span><span>abc[]&nbsp;&nbsp;</span>&nbsp;&nbsp;def</span>", expectedHTML: "<span><span>abc&nbsp;</span>&nbsp;&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc[] &nbsp;</span>&nbsp;&nbsp;def</span>", expectedHTML: "<span><span>abc&nbsp;</span>&nbsp;&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc[] &nbsp;</span> &nbsp;def</span>", expectedHTML: "<span><span>abc&nbsp;</span> &nbsp;def</span>" },
+ { initialHTML: "<span><span>abc[] &nbsp;</span>&nbsp; def</span>", expectedHTML: "<span><span>abc&nbsp;</span>&nbsp; def</span>" },
+ { initialHTML: "<span><span>abc&nbsp; []</span>&nbsp; def</span>", expectedHTML: "<span><span>abc&nbsp; </span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc&nbsp; </span>[]&nbsp; def</span>", expectedHTML: "<span><span>abc&nbsp; </span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc&nbsp;&nbsp;[]</span> &nbsp;def</span>", expectedHTML: "<span><span>abc&nbsp;&nbsp;</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc&nbsp;&nbsp;</span>[] &nbsp;def</span>", expectedHTML: "<span><span>abc&nbsp;&nbsp;</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc &nbsp;[]</span>&nbsp; def</span>", expectedHTML: "<span><span>abc &nbsp;</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc &nbsp;</span>[]&nbsp; def</span>", expectedHTML: "<span><span>abc &nbsp;</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc&nbsp; </span>&nbsp;[] def</span>", expectedHTML: "<span><span>abc&nbsp; </span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc &nbsp;</span>&nbsp;[] def</span>", expectedHTML: "<span><span>abc &nbsp;</span>&nbsp;def</span>" },
+ { initialHTML: "<span><span>abc &nbsp;</span> []&nbsp;def</span>", expectedHTML: "<span><span>abc &nbsp;</span>&nbsp;def</span>" },
+
+ { initialHTML: "<span>abc[] </span><span>&nbsp;def</span>", expectedHTML: "<span>abc</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc[]&nbsp;</span><span>&nbsp;def</span>", expectedHTML: "<span>abc</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc[]&nbsp;</span><span> def</span>", expectedHTML: "<span>abc</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc []</span><span>&nbsp;def</span>", expectedHTML: "<span>abc </span><span>def</span>" },
+ { initialHTML: "<span>abc&nbsp;[]</span><span>&nbsp;def</span>", expectedHTML: "<span>abc&nbsp;</span><span>def</span>" },
+ { initialHTML: "<span>abc&nbsp;[]</span><span> def</span>", expectedHTML: "<span>abc&nbsp;</span><span>def</span>" },
+ { initialHTML: "<span>abc[]&nbsp;</span><span>&nbsp; def</span>", expectedHTML: "<span>abc</span><span>&nbsp; def</span>" },
+ { initialHTML: "<span>abc[]&nbsp;</span><span> &nbsp;def</span>", expectedHTML: "<span>abc</span><span>&nbsp; def</span>" },
+ { initialHTML: "<span>abc[]&nbsp; </span><span>&nbsp;&nbsp;def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp;&nbsp;def</span>" },
+ { initialHTML: "<span>abc[]&nbsp; </span><span>&nbsp; def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp; def</span>" },
+ { initialHTML: "<span>abc[]&nbsp;&nbsp;</span><span>&nbsp;&nbsp;def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp;&nbsp;def</span>" },
+ { initialHTML: "<span>abc[] &nbsp;</span><span>&nbsp;&nbsp;def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp;&nbsp;def</span>" },
+ { initialHTML: "<span>abc[] &nbsp;</span><span> &nbsp;def</span>", expectedHTML: "<span>abc&nbsp;</span><span> &nbsp;def</span>" },
+ { initialHTML: "<span>abc[] &nbsp;</span><span>&nbsp; def</span>", expectedHTML: "<span>abc&nbsp;</span><span>&nbsp; def</span>" },
+ { initialHTML: "<span>abc&nbsp; []</span><span>&nbsp; def</span>", expectedHTML: "<span>abc&nbsp; </span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp; </span><span>[]&nbsp; def</span>", expectedHTML: "<span>abc&nbsp; </span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp;&nbsp;[]</span><span> &nbsp;def</span>", expectedHTML: "<span>abc&nbsp;&nbsp;</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp;&nbsp;</span><span>[] &nbsp;def</span>", expectedHTML: "<span>abc&nbsp;&nbsp;</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc &nbsp;[]</span><span>&nbsp; def</span>", expectedHTML: "<span>abc &nbsp;</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc &nbsp;</span><span>[]&nbsp; def</span>", expectedHTML: "<span>abc &nbsp;</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc&nbsp; </span><span>&nbsp;[] def</span>", expectedHTML: "<span>abc&nbsp; </span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc &nbsp;</span><span>&nbsp;[] def</span>", expectedHTML: "<span>abc &nbsp;</span><span>&nbsp;def</span>" },
+ { initialHTML: "<span>abc &nbsp;</span><span> []&nbsp;def</span>", expectedHTML: "<span>abc &nbsp;</span><span>&nbsp;def</span>" },
+
+ { initialHTML: "a[]<span style=white-space:pre;>b </span>c", expectedHTML: "a<span style=\"white-space:pre;\"> </span>c" },
+ { initialHTML: "a<span style=white-space:pre;>b[] </span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" },
+ { initialHTML: "a<span style=white-space:pre;>b [] </span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" },
+ { initialHTML: "a<span style=white-space:pre;>b [] </span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" },
+ { initialHTML: "a<span style=white-space:pre;>b []</span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>" },
+ { initialHTML: "a<span style=white-space:pre;>b [] </span>", expectedHTML: "a<span style=\"white-space:pre;\">b </span>" },
+ { initialHTML: "a[]<span style=white-space:pre;> </span>b", expectedHTML: "ab" },
+ { initialHTML: "a&nbsp;&nbsp;&nbsp;[]<span style=white-space:pre;> </span>", expectedHTML: "a&nbsp;&nbsp;&nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;&nbsp;[]&nbsp;<span style=white-space:pre;> </span>", expectedHTML: "a&nbsp;&nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;[]&nbsp;&nbsp;<span style=white-space:pre;> </span>", expectedHTML: "a&nbsp;&nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;[]&nbsp;&nbsp;<span style=white-space:pre;>b </span>", expectedHTML: "a&nbsp;&nbsp;<span style=\"white-space:pre;\">b </span>" },
+ { initialHTML: "a&nbsp;&nbsp;&nbsp;[]&nbsp;<span style=white-space:pre;> </span>", expectedHTML: "a&nbsp;&nbsp;&nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;&nbsp;[]&nbsp;&nbsp;<span style=white-space:pre;> </span>", expectedHTML: "a&nbsp; &nbsp;<span style=\"white-space:pre;\"> </span>" },
+ { initialHTML: "a&nbsp;&nbsp;[]&nbsp;&nbsp;<span style=white-space:pre;>b </span>", expectedHTML: "a&nbsp; &nbsp;<span style=\"white-space:pre;\">b </span>" },
+ { initialHTML: "<span style=white-space:pre;> [] </span>&nbsp;&nbsp;&nbsp;a", expectedHTML: "<span style=\"white-space:pre;\"> </span>&nbsp;&nbsp;&nbsp;a" },
+ { initialHTML: "<span style=white-space:pre;> [] </span>&nbsp;&nbsp;&nbsp;a", expectedHTML: "<span style=\"white-space:pre;\"> </span>&nbsp; &nbsp;a" },
+ { initialHTML: "<span style=white-space:pre;> []</span>&nbsp;&nbsp;&nbsp;&nbsp;a", expectedHTML: "<span style=\"white-space:pre;\"> </span>&nbsp; &nbsp;a" },
+ { initialHTML: "<span style=white-space:pre;> </span>[]&nbsp;&nbsp;&nbsp;&nbsp;a", expectedHTML: "<span style=\"white-space:pre;\"> </span>&nbsp; &nbsp;a" },
+ ]) {
+ test(function () {
+ let points = setupDiv(editor, currentTest.initialHTML);
+ selection.setBaseAndExtent(points[0], points[1], points[2], points[3]);
+ document.execCommand("forwarddelete", false, "");
+ assert_equals(editor.innerHTML, currentTest.expectedHTML);
+ }, `execCommand("forwarddelete", false, ""): "${currentTest.initialHTML}"`);
+ }
+
+ done();
+}
+
+window.addEventListener("load", runTests, {once: true});
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-insertlinebreak.tentative.html b/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-insertlinebreak.tentative.html
new file mode 100644
index 00000000000..a961ee77bc3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-insertlinebreak.tentative.html
@@ -0,0 +1,150 @@
+<!doctype html>
+<html>
+<head>
+<meta charset=utf-8>
+<title>Testing normalizing white-space sequence after execCommand("insertlinebreak", false, "foo")</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+"use strict";
+
+setup({explicit_done: true});
+
+function runTests() {
+ // README:
+ // These tests based on the behavior of Chrome 83. This test does NOT define
+ // nor suggest any standard behavior (actually, some expected results might
+ // look odd), but this test must help you to understand how other browsers
+ // use different logic to normalize white-space sequence.
+
+ document.body.innerHTML = "<div contenteditable></div>";
+ let editor = document.querySelector("div[contenteditable]");
+ editor.focus();
+ let selection = document.getSelection();
+
+ function escape(str) {
+ return typeof(str) === "string" ? str.replace(/\u00A0/ig, "&nbsp;") : "";
+ }
+
+ function generateWhiteSpaces(num, lastIsAlwaysNBSP) {
+ let str = "";
+ for (let i = 0; i < num - 1; i++) {
+ str += i % 2 ? " " : "\u00A0";
+ }
+ str += lastIsAlwaysNBSP || num % 2 ? "\u00A0" : " ";
+ return escape(str);
+ }
+ function getDescriptionForTextNode(textNode) {
+ return selection.focusNode === textNode ?
+ `${escape(textNode.data.slice(0, selection.focusOffset))}[]${escape(textNode.data.slice(selection.focusOffset))}` :
+ escape(textNode);
+ }
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 0);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `<br>a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 1);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `a<br>${escape(generateWhiteSpaces(9, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 2);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `a&nbsp;<br>${escape(generateWhiteSpaces(8, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 3);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `a&nbsp;&nbsp;<br>${escape(generateWhiteSpaces(7, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 4);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `a&nbsp;&nbsp;&nbsp;<br>${escape(generateWhiteSpaces(6, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 5);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `a&nbsp;&nbsp;&nbsp;&nbsp;<br>${escape(generateWhiteSpaces(5, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 6);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>${escape(generateWhiteSpaces(4, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 7);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>${escape(generateWhiteSpaces(3, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 8);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>${escape(generateWhiteSpaces(2, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 9);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>${escape(generateWhiteSpaces(1, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, 10);
+ test(function () {
+ document.execCommand("insertlinebreak", false, "");
+ assert_equals(editor.innerHTML,
+ `a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>b`,
+ "Modified text is wrong");
+ }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ done();
+}
+
+window.addEventListener("load", runTests, {once: true});
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-insertparagraph.tentative.html b/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-insertparagraph.tentative.html
new file mode 100644
index 00000000000..854e6b3dae5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-insertparagraph.tentative.html
@@ -0,0 +1,72 @@
+<!doctype html>
+<html>
+<head>
+<meta charset=utf-8>
+<title>Testing normalizing white-space sequence after execCommand("insertparagraph", false, "foo")</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+"use strict";
+
+setup({explicit_done: true});
+
+function runTests() {
+ // README:
+ // These tests based on the behavior of Chrome 83. This test does NOT define
+ // nor suggest any standard behavior (actually, some expected results might
+ // look odd), but this test must help you to understand how other browsers
+ // use different logic to normalize white-space sequence.
+
+ document.body.innerHTML = "<div contenteditable></div>";
+ let editor = document.querySelector("div[contenteditable]");
+ editor.focus();
+ let selection = document.getSelection();
+
+ function escape(str) {
+ return typeof(str) === "string" ? str.replace(/\u00A0/ig, "&nbsp;") : "";
+ }
+
+ function generateWhiteSpaces(num, lastIsAlwaysNBSP) {
+ let str = "";
+ for (let i = 0; i < num - 1; i++) {
+ str += i % 2 ? " " : "\u00A0";
+ }
+ str += lastIsAlwaysNBSP || num % 2 ? "\u00A0" : " ";
+ return escape(str);
+ }
+ function getDescriptionForTextNode(textNode) {
+ return selection.focusNode === textNode ?
+ `${escape(textNode.data.slice(0, selection.focusOffset))}[]${escape(textNode.data.slice(selection.focusOffset))}` :
+ escape(textNode);
+ }
+
+ editor.innerHTML = "<div>a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b</div>";
+ selection.collapse(editor.firstChild.firstChild, 0);
+ test(function () {
+ document.execCommand("insertparagraph", false, "");
+ assert_equals(editor.innerHTML,
+ `<div><br></div><div>a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b</div>`,
+ "Modified text is wrong");
+ }, `execCommand("insertparagraph", false, "") at "<div>${getDescriptionForTextNode(editor.firstChild.firstChild)}</div>"`);
+
+ for (let i = 1; i <= 10; i++) {
+ editor.innerHTML = "<div>a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b</div>";
+ selection.collapse(editor.firstChild.firstChild, i);
+ test(function () {
+ let text = editor.firstChild.firstChild.data;
+ document.execCommand("insertparagraph", false, "");
+ assert_equals(editor.innerHTML,
+ `<div>${escape(text.slice(0, i))}</div><div>${escape(text.slice(i))}</div>`,
+ "Modified text is wrong");
+ }, `execCommand("insertparagraph", false, "") at "<div>${getDescriptionForTextNode(editor.firstChild.firstChild)}</div>"`);
+ }
+
+ done();
+}
+
+window.addEventListener("load", runTests, {once: true});
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-inserttext.tentative.html b/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-inserttext.tentative.html
new file mode 100644
index 00000000000..4b4146b5095
--- /dev/null
+++ b/tests/wpt/web-platform-tests/editing/other/white-spaces-after-execCommand-inserttext.tentative.html
@@ -0,0 +1,526 @@
+<!doctype html>
+<html>
+<head>
+<meta charset=utf-8>
+<title>Testing normalizing white-space sequence after execCommand("inserttext", false, "foo")</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+"use strict";
+
+setup({explicit_done: true});
+
+function runTests() {
+ // README:
+ // These tests based on the behavior of Chrome 83. This test does NOT define
+ // nor suggest any standard behavior (actually, some expected results might
+ // look odd), but this test must help you to understand how other browsers
+ // use different logic to normalize white-space sequence.
+
+ document.body.innerHTML = "<div contenteditable></div>";
+ let editor = document.querySelector("div[contenteditable]");
+ editor.focus();
+ let selection = document.getSelection();
+
+ function toPlaintext(str) {
+ return str.replace(/&nbsp;/g, "\u00A0");
+ }
+ function escape(str) {
+ return typeof(str) === "string" ? str.replace(/\u00A0/ig, "&nbsp;") : "";
+ }
+
+ function generateWhiteSpaces(num, lastIsAlwaysNBSP) {
+ if (!num) {
+ return "";
+ }
+ let str = "";
+ for (let i = 0; i < num - 1; i++) {
+ str += i % 2 ? " " : "\u00A0";
+ }
+ str += lastIsAlwaysNBSP || num % 2 ? "\u00A0" : " ";
+ return escape(str);
+ }
+ function getDescriptionForTextNode(textNode) {
+ return selection.focusNode === textNode ?
+ `${escape(textNode.data.slice(0, selection.focusOffset))}[]${escape(textNode.data.slice(selection.focusOffset))}` :
+ escape(textNode);
+ }
+
+ for (let i = 0; i < 12; i++) {
+ editor.innerHTML = `a${i === 1 ? " " : generateWhiteSpaces(i, false)}b`;
+ selection.collapse(editor.firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(escape(editor.firstChild.data),
+ `a${i === 0 ? " " : escape(generateWhiteSpaces(i + 1, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 0; i < 12; i++) {
+ editor.innerHTML = `a${generateWhiteSpaces(i, true)}`;
+ selection.collapse(editor.firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(escape(editor.firstChild.data),
+ `a${escape(generateWhiteSpaces(i + 1, true))}`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 0; i < 12; i++) {
+ editor.innerHTML = `${generateWhiteSpaces(i, false)}b`;
+ selection.collapse(editor.firstChild, i);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(escape(editor.firstChild.data),
+ `${i === 0 ? "&nbsp;" : escape(generateWhiteSpaces(i + 1, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 0; i < 12; i++) {
+ editor.innerHTML = `a${i === 0 ? " " : generateWhiteSpaces(i + 1, false)}b`;
+ selection.collapse(editor.firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(escape(editor.firstChild.data),
+ `a${i === 0 ? "&nbsp; " : escape(generateWhiteSpaces(i + 2, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ editor.innerHTML = "a&nbsp;b";
+ selection.collapse(editor.firstChild, 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(escape(editor.firstChild.data), "a&nbsp; b", "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ for (let i = 1; i <= 3; i++) {
+ editor.innerHTML = "a&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, i);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(escape(editor.firstChild.data),
+ `a${escape(generateWhiteSpaces(3, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 1; i <= 6; i++) {
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, i);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(escape(editor.firstChild.data),
+ `a${escape(generateWhiteSpaces(6, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 1; i <= 7; i++) {
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b";
+ selection.collapse(editor.firstChild, i);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(escape(editor.firstChild.data),
+ `a${escape(generateWhiteSpaces(7, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 0; i < 12; i++) {
+ editor.innerHTML = `a${generateWhiteSpaces(i)}b`;
+ selection.collapse(editor.firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, "\u00A0");
+ assert_equals(escape(editor.firstChild.data),
+ `a${i === 0 ? " " : escape(generateWhiteSpaces(i + 1, false))}b`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, "\\u00A0") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span>${i === 0 ? " " : generateWhiteSpaces(i + 1)}</span>b`;
+ selection.collapse(editor.querySelector("span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span>${escape(generateWhiteSpaces(i + 2, true))}</span>b`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span>b"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span>c`;
+ selection.collapse(editor.querySelector("span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span>c`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span>c"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span> c`;
+ selection.collapse(editor.querySelector("span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span> c`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span> c"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span>&nbsp;c`;
+ selection.collapse(editor.querySelector("span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span>&nbsp;c`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span>&nbsp;c"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span>c</span>`;
+ selection.collapse(editor.querySelector("span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span>c</span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span>c</span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span> c</span>`;
+ selection.collapse(editor.querySelector("span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span> c</span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span> c</span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span>&nbsp;c</span>`;
+ selection.collapse(editor.querySelector("span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span>&nbsp;c</span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span>&nbsp;c</span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span><span>c</span></span>`;
+ selection.collapse(editor.querySelector("span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span><span>c</span></span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span><span>c</span></span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span><span> c</span></span>`;
+ selection.collapse(editor.querySelector("span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span><span> c</span></span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span><span> c</span></span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span><span>&nbsp;c</span></span>`;
+ selection.collapse(editor.querySelector("span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span><span>&nbsp;c</span></span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span><span>&nbsp;c</span></span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span><span>b${generateWhiteSpaces(i, true)}</span></span><span>c</span>`;
+ selection.collapse(editor.querySelector("span span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span><span>b${escape(generateWhiteSpaces(i + 1, true))}</span></span><span>c</span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span><span>${getDescriptionForTextNode(editor.querySelector("span span").firstChild)}</span></span><span>c</span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span><span>b${generateWhiteSpaces(i, true)}</span></span><span> c</span>`;
+ selection.collapse(editor.querySelector("span span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span><span>b${escape(generateWhiteSpaces(i + 1, true))}</span></span><span> c</span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span><span>${getDescriptionForTextNode(editor.querySelector("span span").firstChild)}</span></span><span> c</span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a<span><span>b${generateWhiteSpaces(i, true)}</span></span><span>&nbsp;c</span>`;
+ selection.collapse(editor.querySelector("span span").firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a<span><span>b${escape(generateWhiteSpaces(i + 1, true))}</span></span><span>&nbsp;c</span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "a<span><span>${getDescriptionForTextNode(editor.querySelector("span span").firstChild)}</span></span><span>&nbsp;c</span>"`);
+ }
+
+ for (let i = 2; i < 8; i++) {
+ editor.innerHTML = "ab";
+ selection.collapse(editor.firstChild, 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ".repeat(i));
+ assert_equals(escape(editor.firstChild.data),
+ `a${i > 0 ? escape(generateWhiteSpaces(i, false)) : " "}b`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, "${" ".repeat(i)}") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 2; i < 8; i++) {
+ editor.innerHTML = "a";
+ selection.collapse(editor.firstChild, 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ".repeat(i));
+ assert_equals(escape(editor.firstChild.data),
+ `a${i > 0 ? escape(generateWhiteSpaces(i, true)) : " "}`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, "${" ".repeat(i)}") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 2; i < 8; i++) {
+ editor.innerHTML = "ab";
+ selection.collapse(editor.firstChild, 1);
+ test(function () {
+ document.execCommand("inserttext", false, "\u00A0".repeat(i));
+ assert_equals(escape(editor.firstChild.data),
+ `a${i > 0 ? escape(generateWhiteSpaces(i, false)) : " "}b`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, "${"\\u00A0".repeat(i)}") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 2; i < 8; i++) {
+ editor.innerHTML = "a";
+ selection.collapse(editor.firstChild, 1);
+ test(function () {
+ document.execCommand("inserttext", false, "\u00A0".repeat(i));
+ assert_equals(escape(editor.firstChild.data),
+ `a${i > 0 ? escape(generateWhiteSpaces(i, true)) : " "}`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, "${"\\u00A0".repeat(i)}") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre>b</span>`;
+ selection.collapse(editor.firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\">b</span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre>b</span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre> </span>`;
+ selection.collapse(editor.firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\"> </span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre> </span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre>&nbsp;</span>`;
+ selection.collapse(editor.firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, " ");
+ assert_equals(editor.innerHTML,
+ `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\">&nbsp;</span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre>&nbsp;</span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre>b</span>`;
+ selection.collapse(editor.firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, "\u00A0");
+ assert_equals(editor.innerHTML,
+ `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\">b</span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, "\\u00A0") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre>b</span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre> </span>`;
+ selection.collapse(editor.firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, "\u00A0");
+ assert_equals(editor.innerHTML,
+ `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\"> </span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, "\\u00A0") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre> </span>"`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre>&nbsp;</span>`;
+ selection.collapse(editor.firstChild, i + 1);
+ test(function () {
+ document.execCommand("inserttext", false, "\u00A0");
+ assert_equals(editor.innerHTML,
+ `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\">&nbsp;</span>`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, "\\u00A0") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre>&nbsp;</span>"`);
+ }
+
+ editor.innerHTML = "a&nbsp;&nbsp;c";
+ selection.collapse(editor.firstChild, 2);
+ test(function () {
+ document.execCommand("inserttext", false, "b");
+ assert_equals(escape(editor.firstChild.data), "a b c", "Modified text is wrong");
+ }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;c";
+ selection.collapse(editor.firstChild, 1);
+ test(function () {
+ document.execCommand("inserttext", false, "b");
+ assert_equals(escape(editor.firstChild.data), `ab${escape(generateWhiteSpaces(4))}c`, "Modified text is wrong");
+ }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;c";
+ selection.collapse(editor.firstChild, 2);
+ test(function () {
+ document.execCommand("inserttext", false, "b");
+ assert_equals(escape(editor.firstChild.data), `a b${escape(generateWhiteSpaces(3))}c`, "Modified text is wrong");
+ }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;c";
+ selection.collapse(editor.firstChild, 3);
+ test(function () {
+ document.execCommand("inserttext", false, "b");
+ assert_equals(escape(editor.firstChild.data),
+ `a${escape(generateWhiteSpaces(2))}b${escape(generateWhiteSpaces(2))}c`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;c";
+ selection.collapse(editor.firstChild, 4);
+ test(function () {
+ document.execCommand("inserttext", false, "b");
+ assert_equals(escape(editor.firstChild.data),
+ `a${escape(generateWhiteSpaces(3))}b c`,
+ "Modified text is wrong");
+ }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ editor.innerHTML = "a&nbsp;&nbsp;&nbsp;&nbsp;c";
+ selection.collapse(editor.firstChild, 5);
+ test(function () {
+ document.execCommand("inserttext", false, "b");
+ assert_equals(escape(editor.firstChild.data), `a${escape(generateWhiteSpaces(4))}bc`, "Modified text is wrong");
+ }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`);
+
+ // Test white space sequence split to multiple text node.
+ // - initialText: Set to data of text nodes. This must have "|" at least one.
+ // Then, the text will be split at every "|".
+ // Same as above test, only &nbsp; is handled at setting.
+ // "[]" means that caret position.
+ // - expectedText: Set to data of all text nodes as an array.
+ // Same as above test, only &nbsp; is handled before comparing.
+ for (const currentTest of [
+ { initialText: "a[]|b", expectedText: ["a", "b"] },
+ { initialText: "a []|b", expectedText: ["a ", "b"] },
+ { initialText: "a |[]b", expectedText: ["a ", "b"] },
+ { initialText: "a[]&nbsp;|b", expectedText: ["a&nbsp;", "b"] },
+ { initialText: "a&nbsp;[]|b", expectedText: ["a&nbsp;", "b"] },
+ { initialText: "a&nbsp;|[]b", expectedText: ["a&nbsp;", "b"] },
+ { initialText: "a[]|&nbsp;b", expectedText: ["a", "&nbsp;b"] },
+ { initialText: "a|[]&nbsp;b", expectedText: ["a", "&nbsp;b"] },
+ { initialText: "a|&nbsp;[]b", expectedText: ["a", "&nbsp;b"] },
+ { initialText: "a[] |&nbsp;b", expectedText: ["a ", "&nbsp;b"] },
+ { initialText: "a []|&nbsp;b", expectedText: ["a ", "&nbsp;b"] },
+ { initialText: "a |[]&nbsp;b", expectedText: ["a ", "&nbsp;b"] },
+ { initialText: "a |&nbsp;[]b", expectedText: ["a ", "&nbsp;b"] },
+ { initialText: "a[]&nbsp;| b", expectedText: ["a&nbsp;", " b"] },
+ { initialText: "a&nbsp;[]| b", expectedText: ["a&nbsp;", " b"] },
+ { initialText: "a&nbsp;|[] b", expectedText: ["a&nbsp;", " b"] },
+ { initialText: "a&nbsp;| []b", expectedText: ["a&nbsp;", " b"] },
+ { initialText: "a[]&nbsp;|&nbsp;b", expectedText: ["a&nbsp;", "&nbsp;b"] },
+ { initialText: "a&nbsp;[]|&nbsp;b", expectedText: ["a&nbsp;", "&nbsp;b"] },
+ { initialText: "a&nbsp;|[]&nbsp;b", expectedText: ["a&nbsp;", "&nbsp;b"] },
+ { initialText: "a&nbsp;|&nbsp;[]b", expectedText: ["a&nbsp;", "&nbsp;b"] },
+ ]) {
+ test(function () {
+ editor.innerHTML = "";
+ let caret = { container: null, offset: -1 };
+ for (let text of toPlaintext(currentTest.initialText).split("|")) {
+ let caretOffset = text.indexOf("[]");
+ if (caretOffset >= 0) {
+ text = text.slice(0, caretOffset) + text.slice(caretOffset + 2);
+ }
+ let textNode = document.createTextNode(text);
+ editor.appendChild(textNode);
+ if (caretOffset >= 0) {
+ caret = { container: textNode, offset: caretOffset };
+ }
+ }
+ selection.collapse(caret.container, caret.offset);
+ document.execCommand("inserttext", false, "");
+ let child = editor.firstChild;
+ for (let expectedText of currentTest.expectedText) {
+ expectedText = toPlaintext(expectedText);
+ let caretOffset = expectedText.indexOf("[]");
+ if (caretOffset >= 0) {
+ expectedText = expectedText.slice(0, caretOffset) + expectedText.slice(caretOffset + 2);
+ }
+ if (!child || child.nodeName !== "#text") {
+ assert_equals("", escape(expectedText), "Expected text node is not there");
+ if (caretOffset >= 0) {
+ assert_equals(-1, caretOffset, "Selection should be contained in this node");
+ }
+ } else {
+ assert_equals(escape(child.data), escape(expectedText), "Modified text is wrong");
+ if (caretOffset >= 0) {
+ assert_equals(selection.focusNode, child, "Selection focus node is wrong");
+ assert_equals(selection.focusOffset, caretOffset, "Selection focus offset is wrong");
+ assert_equals(selection.anchorNode, child, "Selection anchor node is wrong");
+ assert_equals(selection.anchorOffset, caretOffset, "Selection anchor offset is wrong");
+ }
+ }
+ child = child.nextSibling;
+ }
+ if (child && child.nodeName === "#text") {
+ assert_equals(escape(child.data), "", "Unexpected text node is there");
+ }
+ }, `execCommand("inserttext", false, ""): "${currentTest.initialText}"`);
+ }
+
+ done();
+}
+
+window.addEventListener("load", runTests, {once: true});
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/fetch/api/resources/trickle.py b/tests/wpt/web-platform-tests/fetch/api/resources/trickle.py
index 57c9407dc4b..9b3aa37b25c 100644
--- a/tests/wpt/web-platform-tests/fetch/api/resources/trickle.py
+++ b/tests/wpt/web-platform-tests/fetch/api/resources/trickle.py
@@ -3,14 +3,14 @@ import time
from six.moves import xrange
def main(request, response):
- delay = float(request.GET.first("ms", 500)) / 1E3
- count = int(request.GET.first("count", 50))
+ delay = float(request.GET.first(b"ms", 500)) / 1E3
+ count = int(request.GET.first(b"count", 50))
# Read request body
request.body
time.sleep(delay)
- response.headers.set("Content-type", "text/plain")
+ response.headers.set(b"Content-type", b"text/plain")
response.write_status_headers()
time.sleep(delay)
for i in xrange(count):
- response.writer.write_content("TEST_TRICKLE\n")
+ response.writer.write_content(u"TEST_TRICKLE\n")
time.sleep(delay)
diff --git a/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/none.https.html b/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/none.https.html
index e603753084c..0fbd4165a5f 100644
--- a/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/none.https.html
+++ b/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/none.https.html
@@ -46,11 +46,9 @@ async_test(t => {
t.add_cleanup(() => w.close());
w.onload = t.step_func(() => {
+ assert_true(w.location.href.endsWith("?to=navigate-require-corp.sub.html"));
w.history.back();
- t.step_timeout(() => {
- assert_not_equals(w.document, null);
- t.done();
- }, 1500);
+ t.step_wait_func_done(() => w.location.href.endsWith("/navigate-require-corp.sub.html"));
});
}, `"none" top-level: navigating a frame back from "require-corp" should succeed`);
diff --git a/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp-about-blank.html b/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp-about-blank.html
index 5c51df71ae5..945333b83d5 100644
--- a/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp-about-blank.html
+++ b/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp-about-blank.html
@@ -1,3 +1,4 @@
+<!doctype html>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
@@ -17,8 +18,6 @@ promise_test(async t => {
// The about:blank document can load.
await iframe_loaded;
assert_not_equals(iframe.contentDocument, null);
-
- t.done();
}, "about:blank can always be embedded by a 'require-corp' document");
promise_test(async t => {
@@ -34,16 +33,16 @@ promise_test(async t => {
assert_not_equals(iframe_B.contentDocument, null);
iframe_B.contentDocument.body.appendChild(iframe_C);
- t.step_timeout(() => {
- // The document nested under about:blank must not load because it does not
- // specify the Cross-Origin-Embedder-Policy: require-corp header.
- // An error page must be displayed instead.
- // See https://github.com/whatwg/html/issues/125 for why a timeout is used
- // here. Long term all network error handling should be similar and have a
- // reliable event.
- assert_equals(iframe_C.contentDocument, null);
- t.done();
- }, 500);
+
+ // The document nested under about:blank must not load because it does not
+ // specify the Cross-Origin-Embedder-Policy: require-corp header.
+ // An error page must be displayed instead.
+ // See https://github.com/whatwg/html/issues/125 for why a timeout is used
+ // here. Long term all network error handling should be similar and have a
+ // reliable event.
+ assert_equals(iframe_C.contentWindow.location.href, "about:blank");
+ assert_not_equals(iframe_C.contentDocument, null);
+ await t.step_wait(() => iframe_C.contentDocument === null);
}, "A(B(C)) A=require-corp, B=about:blank, C=no-require-corp => C can't load");
</script>
diff --git a/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp-about-srcdoc.html b/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp-about-srcdoc.html
index 4d1c1f86464..5d06286d915 100644
--- a/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp-about-srcdoc.html
+++ b/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp-about-srcdoc.html
@@ -18,8 +18,6 @@ promise_test(async t => {
await iframe_loaded;
assert_not_equals(iframe.contentDocument, null);
assert_equals(iframe.contentDocument.body.innerText, "loaded document");
-
- t.done();
}, "about:srcdoc can always be embedded by a 'require-corp' document");
promise_test(async t => {
@@ -36,17 +34,15 @@ promise_test(async t => {
assert_equals(iframe_B.contentDocument.body.innerText, "dummy content");
iframe_B.contentDocument.body.appendChild(iframe_C);
-
- t.step_timeout(() => {
- // The document nested under about:srcdoc must not load because it does not
- // specify the Cross-Origin-Embedder-Policy: require-corp header.
- // An error page must be displayed instead.
- // See https://github.com/whatwg/html/issues/125 for why a timeout is used
- // here. Long term all network error handling should be similar and have a
- // reliable event.
- assert_equals(iframe_C.contentDocument, null);
- t.done();
- }, 500);
+ // The document nested under about:srcdoc must not load because it does not
+ // specify the Cross-Origin-Embedder-Policy: require-corp header.
+ // An error page must be displayed instead.
+ // See https://github.com/whatwg/html/issues/125 for why a timeout is used
+ // here. Long term all network error handling should be similar and have a
+ // reliable event.
+ assert_equals(iframe_C.contentWindow.location.href, "about:blank");
+ assert_not_equals(iframe_C.contentDocument, null);
+ await t.step_wait(() => iframe_C.contentDocument === null);
}, "A(B(C)) A=require-corp, B=about:srcdoc, C=no-require-corp => C can't load");
</script>
diff --git a/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp.https.html b/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp.https.html
index 769bc87586d..477145657d7 100644
--- a/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp.https.html
+++ b/tests/wpt/web-platform-tests/html/cross-origin-embedder-policy/require-corp.https.html
@@ -13,16 +13,13 @@ const BASE = new URL("resources", location).pathname;
async_test(t => {
const frame = document.createElement("iframe");
t.add_cleanup(() => frame.remove());
- t.step_timeout(() => {
- // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a
- // timeout is used here. Long term all network error handling should be similar and have a
- // reliable event.
- assert_equals(frame.contentDocument, null);
- t.done();
- }, 2000);
frame.src = "/common/blank.html";
document.body.append(frame);
+ // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a
+ // timeout is used here. Long term all network error handling should be similar and have a
+ // reliable event.
assert_equals(frame.contentDocument.body.localName, "body");
+ t.step_wait_func_done(() => frame.contentDocument === null);
}, `"require-corp" top-level: navigating a frame to "none" should fail`);
async_test(t => {
@@ -33,10 +30,7 @@ async_test(t => {
assert_not_equals(frame.contentDocument, null);
let payload = event.data;
assert_equals(payload, "loaded");
- t.step_timeout(() => {
- assert_equals(frame.contentDocument, null);
- t.done();
- }, 2000);
+ t.step_wait_func_done(() => frame.contentDocument === null);
});
frame.src = `resources/navigate-require-corp.sub.html?channelName=${bc.name}&to=/common/blank.html`;
document.body.append(frame);
@@ -143,18 +137,17 @@ promise_test(t => {
async_test(t => {
let w = window.open();
const frame = w.document.createElement("iframe");
- t.add_cleanup(() => w.close());
- t.step_timeout(() => {
- // Make sure the iframe didn't load. See
- // https://github.com/whatwg/html/issues/125 for why a timeout is
- // used here. Long term all network error handling should be similar
- // and have a reliable event.
- assert_equals(frame.contentDocument, null);
- t.done();
- }, 2000);
+ t.add_cleanup(() => {
+ w.close();
+ frame.remove();
+ });
frame.src = "/common/blank.html";
document.body.append(frame);
+ // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a
+ // timeout is used here. Long term all network error handling should be similar and have a
+ // reliable event.
assert_equals(frame.contentDocument.body.localName, "body");
+ t.step_wait_func_done(() => frame.contentDocument === null);
}, `"require-corp" top-level: navigating an iframe to a page without CORP, through a WindowProxy, should fail`);
async_test(t => {
@@ -179,7 +172,7 @@ async_test(t => {
let loaded = false;
window.addEventListener('message', t.step_func((e) => {
if (e.data === id) {
- loaded = true;
+ loaded = true;
}
}));
t.step_timeout(() => {
diff --git a/tests/wpt/web-platform-tests/html/cross-origin-opener-policy/coop-sandbox.https.html b/tests/wpt/web-platform-tests/html/cross-origin-opener-policy/coop-sandbox.https.html
index 6f10945cfaf..ceb744c215b 100644
--- a/tests/wpt/web-platform-tests/html/cross-origin-opener-policy/coop-sandbox.https.html
+++ b/tests/wpt/web-platform-tests/html/cross-origin-opener-policy/coop-sandbox.https.html
@@ -20,6 +20,8 @@
<\/script>`;
document.body.append(frame);
addEventListener('load', t.step_func(() => {
+ // This uses a timeout to give some time for incorrect implementations to broadcast. A
+ // theoretical testdriver.js API for browsing contexts could be used to speed this up.
t.step_timeout(() => {
t.done()
}, 1500);
@@ -38,7 +40,6 @@ async_test(t => {
assert_equals(payload.name, frame.name, "name");
t.done();
});
- t.step_timeout(t.unreached_func("Timed out while waiting for iframe's message"), 1500);
t.add_cleanup(() => frame.remove());
document.body.append(frame);
}, `Iframe with sandbox and COOP must load.`);
diff --git a/tests/wpt/web-platform-tests/html/cross-origin-opener-policy/popup-same-origin-non-initial-about-blank.https.html b/tests/wpt/web-platform-tests/html/cross-origin-opener-policy/popup-same-origin-non-initial-about-blank.https.html
index d4005ac20d8..2e58ea45533 100644
--- a/tests/wpt/web-platform-tests/html/cross-origin-opener-policy/popup-same-origin-non-initial-about-blank.https.html
+++ b/tests/wpt/web-platform-tests/html/cross-origin-opener-policy/popup-same-origin-non-initial-about-blank.https.html
@@ -5,13 +5,13 @@
<script>
async_test(t => {
const popup = window.open("resources/coop-coep.py?coop=same-origin&coep=&navigate=about:blank");
+ t.add_cleanup(() => popup.close());
assert_equals(window, popup.opener);
- window.onload = t.step_func(() => {
- t.step_timeout(() => {
- assert_equals(popup.location.href, "about:blank");
- popup.close();
- t.done();
- }, 1500);
+
+ popup.onload = t.step_func(() => {
+ assert_true(popup.location.href.endsWith("&navigate=about:blank"));
+ // Use wait_for_callback as about:blank cannot message back.
+ t.step_wait_func_done(() => popup.location.href === "about:blank");
});
}, "Navigating a popup to about:blank");
</script>
diff --git a/tests/wpt/web-platform-tests/html/obsolete/requirements-for-implementations/the-marquee-element-0/marquee-adopt-to-inactive-document-crash.html b/tests/wpt/web-platform-tests/html/obsolete/requirements-for-implementations/the-marquee-element-0/marquee-adopt-to-inactive-document-crash.html
new file mode 100644
index 00000000000..395f0a2a91c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/obsolete/requirements-for-implementations/the-marquee-element-0/marquee-adopt-to-inactive-document-crash.html
@@ -0,0 +1,9 @@
+<iframe id="i"></iframe>
+<script>
+var marquee = document.createElement("marquee");
+marquee.start();
+
+var doc = i.contentDocument;
+i.remove();
+doc.adoptNode(marquee);
+</script>
diff --git a/tests/wpt/web-platform-tests/lint.ignore b/tests/wpt/web-platform-tests/lint.ignore
index ae2e266a8ea..db7f36426b1 100644
--- a/tests/wpt/web-platform-tests/lint.ignore
+++ b/tests/wpt/web-platform-tests/lint.ignore
@@ -314,6 +314,8 @@ SET TIMEOUT: resources/test/tests/functional/add_cleanup_async.html
SET TIMEOUT: resources/test/tests/functional/add_cleanup_async_rejection.html
SET TIMEOUT: resources/test/tests/functional/add_cleanup_async_rejection_after_load.html
SET TIMEOUT: resources/test/tests/functional/api-tests-1.html
+SET TIMEOUT: resources/test/tests/functional/step_wait.html
+SET TIMEOUT: resources/test/tests/functional/step_wait_func.html
SET TIMEOUT: resources/test/tests/functional/worker.js
SET TIMEOUT: resources/test/tests/functional/worker-uncaught-allow.js
SET TIMEOUT: resources/test/tests/unit/exceptional-cases.html
@@ -765,8 +767,5 @@ TESTHARNESS-IN-OTHER-TYPE: svg/extensibility/foreignObject/foreign-object-under-
TESTHARNESS-IN-OTHER-TYPE: svg/extensibility/foreignObject/foreign-object-under-defs-crash.html
TESTHARNESS-IN-OTHER-TYPE: svg/svg-in-svg/svg-in-svg-circular-filter-reference-crash.html
-TESTHARNESS-PATH: referrer-policy/generic/iframe-upgrade-request.sub.html
-TESTHARNESSREPORT-PATH: referrer-policy/generic/iframe-upgrade-request.sub.html
-
PRINT STATEMENT: webdriver/tests/print/printcmd.py
PRINT STATEMENT: webdriver/tests/print/user_prompts.py
diff --git a/tests/wpt/web-platform-tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001-ref.html b/tests/wpt/web-platform-tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001-ref.html
new file mode 100644
index 00000000000..632d6739db9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001-ref.html
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Dynamic radical: paint invalidation (expectation)</title>
+<style>
+ @font-face {
+ font-family: RadicalFont;
+ src: url("/fonts/math/radical-displaystyleverticalgap7000-rulethickness1000.woff");
+ }
+ math {
+ font-family: RadicalFont;
+ font-size: 10px;
+ }
+ #container > div {
+ height: 80px;
+ border-top: solid;
+ }
+ .withPaddingBorderAndMargin {
+ padding: 5px;
+ border: 5px solid yellow;
+ margin: 5px;
+ }
+</style>
+</head>
+<body>
+ <div id="container">
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <msqrt>
+ <mspace width="60px" height="10px" depth="10px" style="background: blue"/>
+ </msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <mroot>
+ <mspace width="60px" height="10px" depth="10px" style="background: blue"/>
+ <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/>
+ </mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <msqrt>
+ <mspace width="20px" height="20px" depth="10px" style="background: blue"/>
+ </msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <mroot>
+ <mspace width="20px" height="20px" depth="10px" style="background: blue"/>
+ <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/>
+ </mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <msqrt>
+ <mspace width="20px" height="10px" depth="40px" style="background: blue"/>
+ </msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <mroot>
+ <mspace width="20px" height="10px" depth="40px" style="background: blue"/>
+ <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/>
+ </mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ </msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/>
+ </mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <msqrt class="withPaddingBorderAndMargin">
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ </msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <mroot class="withPaddingBorderAndMargin">
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/>
+ </mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001.html b/tests/wpt/web-platform-tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001.html
new file mode 100644
index 00000000000..5ff82f51271
--- /dev/null
+++ b/tests/wpt/web-platform-tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001.html
@@ -0,0 +1,166 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>Dynamic radical: paint invalidation</title>
+<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#radicals-msqrt-mroot">
+<meta name="assert" content="">
+<link rel="match" href="dynamic-radical-paint-invalidation-001-ref.html">
+<style>
+ @font-face {
+ font-family: RadicalFont;
+ src: url("/fonts/math/radical-displaystyleverticalgap7000-rulethickness1000.woff");
+ }
+ @font-face {
+ font-family: RadicalFont2;
+ src: url("/fonts/math/radical-kernbeforedegree4000-rulethickness1000.woff");
+ }
+ math {
+ font-family: RadicalFont;
+ font-size: 10px;
+ }
+ #container > div {
+ height: 80px;
+ border-top: solid;
+ }
+ .withPaddingBorderAndMargin {
+ padding: 5px;
+ border: 5px solid yellow;
+ margin: 5px;
+ }
+</style>
+<script>
+ window.addEventListener("load", () => { document.fonts.ready.then(runTests); });
+ function runTests() {
+ // force initial layout so we're sure what we're testing against
+ document.documentElement.getBoundingClientRect();
+
+ var mroot = document.getElementsByTagName("mroot");
+ var msqrt = document.getElementsByTagName("msqrt");
+
+ // Modify base's width.
+ msqrt[0].firstElementChild.setAttribute("width", "60px")
+ mroot[0].firstElementChild.setAttribute("width", "60px")
+
+ // Modify base's ascent.
+ msqrt[1].firstElementChild.setAttribute("height", "20px")
+ mroot[1].firstElementChild.setAttribute("height", "20px")
+
+ // Modify base's descent.
+ msqrt[2].firstElementChild.setAttribute("depth", "40px")
+ mroot[2].firstElementChild.setAttribute("depth", "40px")
+
+ // Modify the radical's font family.
+ msqrt[3].parentNode.removeAttribute("style");
+ mroot[3].parentNode.removeAttribute("style");
+
+ // Modify radical's margin/border/padding
+ msqrt[4].setAttribute("class", "withPaddingBorderAndMargin");
+ mroot[4].setAttribute("class", "withPaddingBorderAndMargin");
+
+ document.documentElement.classList.remove('reftest-wait');
+ };
+</script>
+</head>
+<body>
+ <div id="container">
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ </msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/>
+ </mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ </msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/>
+ </mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ </msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/>
+ </mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math style="font-family: RadicalFont2">
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ </msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math style="font-family: RadicalFont2">
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/>
+ </mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ </msqrt>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ <div>
+ <math>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ <mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: blue"/>
+ <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/>
+ </mroot>
+ <mspace width="20px" height="10px" depth="10px" style="background: gray"/>
+ </math>
+ </div>
+ </div>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html
new file mode 100644
index 00000000000..4040072ab9a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<link rel="author" title="Dominic Farolino" href="dom@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<!-- We need to set the CSP via the <meta> tag. If we were to use the HTTP
+ header, we'd have to specify the absolute HTTPS URL of the test harness and
+ reporter, but then this file is not recognized as a test harness test, and
+ will not run -->
+<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
+<body>
+<iframe id="iframe"></iframe>
+<script>
+async_test(t => {
+ const iframe = document.querySelector('iframe');
+ iframe.src =
+ 'http://{{domains[www]}}:{{ports[https][0]}}/referrer-policy/generic/resources/referrer.py';
+
+ addEventListener('message', t.step_func_done(msg => {
+ const referrer = msg.data;
+ assert_equals(referrer, new URL(location.href).origin + '/',
+ "The referrer header sent for the iframe request should be redacted");
+ }));
+}, "If an insecure iframe request is upgraded to https to be cross-origin, " +
+ "referrer policies that consider same-origin-ness should be applied correctly");
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.headers b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.headers
new file mode 100644
index 00000000000..ad768e63294
--- /dev/null
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.headers
@@ -0,0 +1 @@
+Referrer-Policy: origin-when-cross-origin
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html
index 243efb76719..f9163bec546 100644
--- a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html
@@ -10,12 +10,11 @@ async_test(t => {
const insecure_origin = new URL(location.href).origin.replace("https", "http");
iframe.src = insecure_origin + '/referrer-policy/generic/resources/referrer.py';
- iframe.onload = t.step_func_done(() => {
- assert_not_equals(iframe.contentDocument, null,
- "The iframe's contentDocument should be accessible");
- assert_equals(iframe.contentDocument.body.textContent, location.href,
+ addEventListener('message', t.step_func_done(msg => {
+ const referrer = msg.data;
+ assert_equals(referrer, location.href,
"The referrer header sent for the iframe request should not be redacted");
- });
+ }));
}, "If an insecure iframe request is upgraded to https to be same-origin, " +
"referrer policies that consider same-origin-ness should be applied correctly");
</script>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.html.headers b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.headers
index fd9ee0f0328..fd9ee0f0328 100644
--- a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.html.headers
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.headers
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.html b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.html
deleted file mode 100644
index 259c14f43e9..00000000000
--- a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!DOCTYPE html>
-<link rel="author" title="Dominic Farolino" href="dom@chromium.org">
-<script src="https://{{domains[www]}}:{{ports[https][0]}}/resources/testharness.js"></script>
-<script src="https://{{domains[www]}}:{{ports[https][0]}}/resources/testharnessreport.js"></script>
-<body>
-<iframe id="iframe"></iframe>
-<script>
-async_test(t => {
- const iframe = document.querySelector('iframe');
- const insecure_origin = new URL(location.href).origin;
- iframe.src = insecure_origin + '/referrer-policy4generic/resources/referrer.py';
-
- iframe.onload = t.step_func_done(() => {
- assert_true(iframe.contentDocument,
- "The iframe's contentDocument should be accessible, because the iframe");
- assert_equals(iframe.contentDocument.body.textContent, location.href + '/',
- "The referrer header sent for the iframe request should be redacted");
- });
-}, "If an insecure iframe request is upgraded to https to be cross-origin, " +
- "referrer policies that consider same-origin-ness should be applied correctly");
-</script>
-</body>
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html.headers b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html.headers
deleted file mode 100644
index fd9ee0f0328..00000000000
--- a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html.headers
+++ /dev/null
@@ -1,2 +0,0 @@
-Content-Security-Policy: upgrade-insecure-requests
-Referrer-Policy: origin-when-cross-origin
diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/resources/referrer.py b/tests/wpt/web-platform-tests/referrer-policy/generic/resources/referrer.py
index ada048dc490..a969b80f54b 100644
--- a/tests/wpt/web-platform-tests/referrer-policy/generic/resources/referrer.py
+++ b/tests/wpt/web-platform-tests/referrer-policy/generic/resources/referrer.py
@@ -1,3 +1,10 @@
def main(request, response):
response_headers = [(b"Access-Control-Allow-Origin", b"*")]
- return (200, response_headers, request.headers.get("referer", ""))
+ body = """
+ <p id=referrer>%s</p>
+ <script>
+ const referrer_text = referrer.textContent;
+ window.parent.postMessage(referrer_text, "*");
+ </script>
+ """ % request.headers.get("referer", "")
+ return (200, response_headers, body)
diff --git a/tests/wpt/web-platform-tests/resources/test/tests/functional/step_wait.html b/tests/wpt/web-platform-tests/resources/test/tests/functional/step_wait.html
new file mode 100644
index 00000000000..14c41b00d2a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/resources/test/tests/functional/step_wait.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<title>Tests for step_wait</title>
+<script src="../../variants.js"></script>
+<meta name="variant" content="?keep-promise">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+promise_test(async t => {
+ let x = 1;
+ Promise.resolve().then(() => ++x);
+ await t.step_wait(() => x === 1);
+ assert_equals(x, 2);
+}, "Basic step_wait() test");
+
+promise_test(async t => {
+ let cond = false;
+ let x = 0;
+ setTimeout(() => cond = true, 100);
+ await t.step_wait(() => {
+ ++x;
+ return cond;
+ });
+ assert_equals(x, 2);
+}, "step_wait() isn't invoked too often");
+
+promise_test(async t => {
+ await t.step_wait(); // Throws
+}, "step_wait() takes an argument");
+</script>
+<script type="text/json" id="expected">
+{
+ "summarized_tests": [
+ {
+ "name": "Basic step_wait() test",
+ "message": null,
+ "properties": {},
+ "status_string": "PASS"
+ },
+ {
+ "name": "step_wait() isn't invoked too often",
+ "message": null,
+ "properties": {},
+ "status_string": "PASS"
+ },
+ {
+ "name": "step_wait() takes an argument",
+ "message": "cond is not a function",
+ "properties": {},
+ "status_string": "FAIL"
+ }
+ ],
+ "type": "complete",
+ "summarized_status": {
+ "status_string": "OK",
+ "message": null
+ }
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/resources/test/tests/functional/step_wait_func.html b/tests/wpt/web-platform-tests/resources/test/tests/functional/step_wait_func.html
new file mode 100644
index 00000000000..b9a488b27f0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/resources/test/tests/functional/step_wait_func.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<title>Tests for step_wait_func and step_wait_func_done</title>
+<script src="../../variants.js"></script>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+async_test(t => {
+ let x = 0;
+ let step_x = 0;
+ setTimeout(() => ++x, 100);
+ t.step_wait_func(() => {
+ ++step_x;
+ return x === 1;
+ }, () => {
+ assert_equals(step_x, 2);
+ t.done();
+ });
+}, "Basic step_wait_func() test");
+
+async_test(t => {
+ let x = 0;
+ setTimeout(() => ++x, 100);
+ t.step_wait_func_done(() => true, () => assert_equals(x, 0));
+}, "Basic step_wait_func_done() test");
+
+</script>
+<script type="text/json" id="expected">
+{
+ "summarized_status": {
+ "message": null,
+ "status_string": "OK"
+ },
+ "summarized_tests": [
+ {
+ "properties": {},
+ "message": null,
+ "name": "Basic step_wait_func() test",
+ "status_string": "PASS"
+ },
+ {
+ "properties": {},
+ "message": null,
+ "name": "Basic step_wait_func_done() test",
+ "status_string": "PASS"
+ }
+ ],
+ "type": "complete"
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/resources/testharness.js b/tests/wpt/web-platform-tests/resources/testharness.js
index cf361bac392..7e2d4600f0f 100644
--- a/tests/wpt/web-platform-tests/resources/testharness.js
+++ b/tests/wpt/web-platform-tests/resources/testharness.js
@@ -2035,6 +2035,105 @@ policies and contribution forms [3].
return setTimeout(this.step_func(function() {
return f.apply(test_this, args);
}), timeout * tests.timeout_multiplier);
+ };
+
+ Test.prototype.step_wait_func = function(cond, func, description,
+ timeout=3000, interval=100) {
+ /**
+ * Poll for a function to return true, and call a callback
+ * function once it does, or assert if a timeout is
+ * reached. This is preferred over a simple step_timeout
+ * whenever possible since it allows the timeout to be longer
+ * to reduce intermittents without compromising test execution
+ * speed when the condition is quickly met.
+ *
+ * @param {Function} cond A function taking no arguments and
+ * returning a boolean. The callback is called
+ * when this function returns true.
+ * @param {Function} func A function taking no arguments to call once
+ * the condition is met.
+ * @param {string} description Error message to add to assert in case of
+ * failure.
+ * @param {number} timeout Timeout in ms. This is multiplied by the global
+ * timeout_multiplier
+ * @param {number} interval Polling interval in ms
+ *
+ **/
+
+ var timeout_full = timeout * tests.timeout_multiplier;
+ var remaining = Math.ceil(timeout_full / interval);
+ var test_this = this;
+
+ var wait_for_inner = test_this.step_func(() => {
+ if (cond()) {
+ func();
+ } else {
+ if(remaining === 0) {
+ assert(false, "wait_for", description,
+ "Timed out waiting on condition");
+ }
+ remaining--;
+ setTimeout(wait_for_inner, interval);
+ }
+ });
+
+ wait_for_inner();
+ };
+
+ Test.prototype.step_wait_func_done = function(cond, func, description,
+ timeout=3000, interval=100) {
+ /**
+ * Poll for a function to return true, and invoke a callback
+ * followed this.done() once it does, or assert if a timeout
+ * is reached. This is preferred over a simple step_timeout
+ * whenever possible since it allows the timeout to be longer
+ * to reduce intermittents without compromising test execution speed
+ * when the condition is quickly met.
+ *
+ * @param {Function} cond A function taking no arguments and
+ * returning a boolean. The callback is called
+ * when this function returns true.
+ * @param {Function} func A function taking no arguments to call once
+ * the condition is met.
+ * @param {string} description Error message to add to assert in case of
+ * failure.
+ * @param {number} timeout Timeout in ms. This is multiplied by the global
+ * timeout_multiplier
+ * @param {number} interval Polling interval in ms
+ *
+ **/
+
+ this.step_wait_func(cond, () => {
+ if (func) {
+ func();
+ }
+ this.done();
+ }, description, timeout, interval);
+ }
+
+ Test.prototype.step_wait = function(cond, description, timeout=3000, interval=100) {
+ /**
+ * Poll for a function to return true, and resolve a promise
+ * once it does, or assert if a timeout is reached. This is
+ * preferred over a simple step_timeout whenever possible
+ * since it allows the timeout to be longer to reduce
+ * intermittents without compromising test execution speed
+ * when the condition is quickly met.
+ *
+ * @param {Function} cond A function taking no arguments and
+ * returning a boolean.
+ * @param {string} description Error message to add to assert in case of
+ * failure.
+ * @param {number} timeout Timeout in ms. This is multiplied by the global
+ * timeout_multiplier
+ * @param {number} interval Polling interval in ms
+ * @returns {Promise} Promise resolved once cond is met.
+ *
+ **/
+
+ return new Promise(resolve => {
+ this.step_wait_func(cond, resolve, description, timeout, interval);
+ });
}
/*
diff --git a/tests/wpt/web-platform-tests/tools/wpt/browser.py b/tests/wpt/web-platform-tests/tools/wpt/browser.py
index 366dc781d90..4423afd9c4f 100644
--- a/tests/wpt/web-platform-tests/tools/wpt/browser.py
+++ b/tests/wpt/web-platform-tests/tools/wpt/browser.py
@@ -402,23 +402,28 @@ class Firefox(Browser):
if dest is None:
dest = os.getcwd()
+ path = None
if channel == "nightly":
path = self.install_geckodriver_nightly(dest)
- if path is not None:
- return path
- else:
+ if path is None:
self.logger.warning("Nightly webdriver not found; falling back to release")
- version = self._latest_geckodriver_version()
- format = "zip" if uname[0] == "Windows" else "tar.gz"
- self.logger.debug("Latest geckodriver release %s" % version)
- url = ("https://github.com/mozilla/geckodriver/releases/download/%s/geckodriver-%s-%s.%s" %
- (version, version, self.platform_string_geckodriver(), format))
- if format == "zip":
- unzip(get(url).raw, dest=dest)
- else:
- untar(get(url).raw, dest=dest)
- return find_executable(os.path.join(dest, "geckodriver"))
+ if path is None:
+ version = self._latest_geckodriver_version()
+ format = "zip" if uname[0] == "Windows" else "tar.gz"
+ self.logger.debug("Latest geckodriver release %s" % version)
+ url = ("https://github.com/mozilla/geckodriver/releases/download/%s/geckodriver-%s-%s.%s" %
+ (version, version, self.platform_string_geckodriver(), format))
+ if format == "zip":
+ unzip(get(url).raw, dest=dest)
+ else:
+ untar(get(url).raw, dest=dest)
+ path = find_executable(os.path.join(dest, "geckodriver"))
+
+ assert path is not None
+ self.logger.info("Installed %s" %
+ subprocess.check_output([path, "--version"]).splitlines()[0])
+ return path
def install_geckodriver_nightly(self, dest):
self.logger.info("Attempting to install webdriver from nightly")
@@ -428,7 +433,7 @@ class Firefox(Browser):
tc_platform = "%s%s" % (self.platform, platform_bits)
archive_ext = ".zip" if uname[0] == "Windows" else ".tar.gz"
- archive_name = "public/geckodriver%s" % archive_ext
+ archive_name = "public/build/geckodriver%s" % archive_ext
try:
resp = get_taskcluster_artifact(
diff --git a/tests/wpt/web-platform-tests/url/urlencoded-parser.any.js b/tests/wpt/web-platform-tests/url/urlencoded-parser.any.js
index 65e894b94c2..46b932bb014 100644
--- a/tests/wpt/web-platform-tests/url/urlencoded-parser.any.js
+++ b/tests/wpt/web-platform-tests/url/urlencoded-parser.any.js
@@ -28,7 +28,11 @@
{ "input": '%a=a', "output": [['%a', 'a']] },
{ "input": '%a_=a', "output": [['%a_', 'a']] },
{ "input": '%61=a', "output": [['a', 'a']] },
- { "input": '%61+%4d%4D=', "output": [['a MM', '']] }
+ { "input": '%61+%4d%4D=', "output": [['a MM', '']] },
+ { "input": "id=0&value=%", "output": [['id', '0'], ['value', '%']] },
+ { "input": "b=%2sf%2a", "output": [['b', '%2sf*']]},
+ { "input": "b=%2%2af%2a", "output": [['b', '%2*f*']]},
+ { "input": "b=%%2a", "output": [['b', '%*']]}
].forEach((val) => {
test(() => {
let sp = new URLSearchParams(val.input),
diff --git a/tests/wpt/web-platform-tests/url/urlsearchparams-constructor.any.js b/tests/wpt/web-platform-tests/url/urlsearchparams-constructor.any.js
index 8d855a4fd4d..1135d5d3dbb 100644
--- a/tests/wpt/web-platform-tests/url/urlsearchparams-constructor.any.js
+++ b/tests/wpt/web-platform-tests/url/urlsearchparams-constructor.any.js
@@ -56,6 +56,28 @@ test(function() {
assert_false(params.has('c'), 'Search params object did not have the name "c"');
assert_true(params.has(' c'), 'Search params object has name " c"');
assert_true(params.has('møø'), 'Search params object has name "møø"');
+
+ params = new URLSearchParams('id=0&value=%');
+ assert_true(params != null, 'constructor returned non-null value.');
+ assert_true(params.has('id'), 'Search params object has name "id"');
+ assert_true(params.has('value'), 'Search params object has name "value"');
+ assert_equals(params.get('id'), '0');
+ assert_equals(params.get('value'), '%');
+
+ params = new URLSearchParams('b=%2sf%2a');
+ assert_true(params != null, 'constructor returned non-null value.');
+ assert_true(params.has('b'), 'Search params object has name "b"');
+ assert_equals(params.get('b'), '%2sf*');
+
+ params = new URLSearchParams('b=%2%2af%2a');
+ assert_true(params != null, 'constructor returned non-null value.');
+ assert_true(params.has('b'), 'Search params object has name "b"');
+ assert_equals(params.get('b'), '%2*f*');
+
+ params = new URLSearchParams('b=%%2a');
+ assert_true(params != null, 'constructor returned non-null value.');
+ assert_true(params.has('b'), 'Search params object has name "b"');
+ assert_equals(params.get('b'), '%*');
}, 'URLSearchParams constructor, string.');
test(function() {
diff --git a/tests/wpt/web-platform-tests/url/urlsearchparams-stringifier.any.js b/tests/wpt/web-platform-tests/url/urlsearchparams-stringifier.any.js
index ef95c1434c7..bc7bedd533f 100644
--- a/tests/wpt/web-platform-tests/url/urlsearchparams-stringifier.any.js
+++ b/tests/wpt/web-platform-tests/url/urlsearchparams-stringifier.any.js
@@ -78,6 +78,9 @@ test(function() {
params.delete('a');
params.append('a%b', 'c');
assert_equals(params + '', 'a%25b=c');
+
+ params = new URLSearchParams('id=0&value=%')
+ assert_equals(params + '', 'id=0&value=%25')
}, 'Serialize %');
test(function() {
@@ -107,6 +110,15 @@ test(function() {
// The lone '=' _does_ survive the roundtrip.
params = new URLSearchParams('a=&a=b');
assert_equals(params.toString(), 'a=&a=b');
+
+ params = new URLSearchParams('b=%2sf%2a');
+ assert_equals(params.toString(), 'b=%252sf*');
+
+ params = new URLSearchParams('b=%2%2af%2a');
+ assert_equals(params.toString(), 'b=%252*f*');
+
+ params = new URLSearchParams('b=%%2a');
+ assert_equals(params.toString(), 'b=%25*');
}, 'URLSearchParams.toString');
test(() => {
diff --git a/tests/wpt/web-platform-tests/webrtc/receiver-track-live.html b/tests/wpt/web-platform-tests/webrtc/receiver-track-live.https.html
index 3d41724fb59..3d41724fb59 100644
--- a/tests/wpt/web-platform-tests/webrtc/receiver-track-live.html
+++ b/tests/wpt/web-platform-tests/webrtc/receiver-track-live.https.html
diff --git a/tests/wpt/web-platform-tests/workers/baseurl/beta/import.py b/tests/wpt/web-platform-tests/workers/baseurl/beta/import.py
index db18c830a4e..cea229dbf37 100644
--- a/tests/wpt/web-platform-tests/workers/baseurl/beta/import.py
+++ b/tests/wpt/web-platform-tests/workers/baseurl/beta/import.py
@@ -1,3 +1,3 @@
def main(request, response):
- return (302, "Moved"), [("Location", "../gamma/import.js")], "postMessage('executed redirecting script');"
+ return (302, b"Moved"), [(b"Location", b"../gamma/import.js")], u"postMessage('executed redirecting script');"
diff --git a/tests/wpt/web-platform-tests/workers/baseurl/beta/importScripts.py b/tests/wpt/web-platform-tests/workers/baseurl/beta/importScripts.py
index 75dac194f76..688427d59da 100644
--- a/tests/wpt/web-platform-tests/workers/baseurl/beta/importScripts.py
+++ b/tests/wpt/web-platform-tests/workers/baseurl/beta/importScripts.py
@@ -1,3 +1,3 @@
def main(request, response):
- return (302, "Moved"), [("Location", "../gamma/importScripts.js")], "postMessage('executed redirecting script');"
+ return (302, b"Moved"), [(b"Location", b"../gamma/importScripts.js")], u"postMessage('executed redirecting script');"
diff --git a/tests/wpt/web-platform-tests/workers/baseurl/beta/sharedworker.py b/tests/wpt/web-platform-tests/workers/baseurl/beta/sharedworker.py
index 875cc9a047c..bd6f70e7d94 100644
--- a/tests/wpt/web-platform-tests/workers/baseurl/beta/sharedworker.py
+++ b/tests/wpt/web-platform-tests/workers/baseurl/beta/sharedworker.py
@@ -1,3 +1,3 @@
def main(request, response):
- return (302, "Moved"), [("Location", "../gamma/sharedworker.js")], "postMessage('executed redirecting script');"
+ return (302, b"Moved"), [(b"Location", b"../gamma/sharedworker.js")], u"postMessage('executed redirecting script');"
diff --git a/tests/wpt/web-platform-tests/workers/baseurl/beta/worker.py b/tests/wpt/web-platform-tests/workers/baseurl/beta/worker.py
index 44baf5203e8..46db05efe5e 100644
--- a/tests/wpt/web-platform-tests/workers/baseurl/beta/worker.py
+++ b/tests/wpt/web-platform-tests/workers/baseurl/beta/worker.py
@@ -1,3 +1,3 @@
def main(request, response):
- return (302, "Moved"), [("Location", "../gamma/worker.js")], "postMessage('executed redirecting script');"
+ return (302, b"Moved"), [(b"Location", b"../gamma/worker.js")], u"postMessage('executed redirecting script');"
diff --git a/tests/wpt/web-platform-tests/workers/baseurl/beta/xhr-worker.py b/tests/wpt/web-platform-tests/workers/baseurl/beta/xhr-worker.py
index 77270536a50..86c033b985b 100644
--- a/tests/wpt/web-platform-tests/workers/baseurl/beta/xhr-worker.py
+++ b/tests/wpt/web-platform-tests/workers/baseurl/beta/xhr-worker.py
@@ -1,2 +1,2 @@
def main(request, response):
- return (302, "Moved"), [("Location", "../gamma/xhr-worker.js")], "postMessage('executed redirecting script');"
+ return (302, b"Moved"), [(b"Location", b"../gamma/xhr-worker.js")], u"postMessage('executed redirecting script');"
diff --git a/tests/wpt/web-platform-tests/workers/baseurl/beta/xhr.py b/tests/wpt/web-platform-tests/workers/baseurl/beta/xhr.py
index de3f04ed0e2..11d6eb776a4 100644
--- a/tests/wpt/web-platform-tests/workers/baseurl/beta/xhr.py
+++ b/tests/wpt/web-platform-tests/workers/baseurl/beta/xhr.py
@@ -1,3 +1,3 @@
def main(request, response):
- return (302, "Moved"), [("Location", "../gamma/xhr.js")], "postMessage('executed redirecting script');"
+ return (302, b"Moved"), [(b"Location", b"../gamma/xhr.js")], u"postMessage('executed redirecting script');"
diff --git a/tests/wpt/web-platform-tests/workers/interfaces/WorkerGlobalScope/location/helper-redirect.py b/tests/wpt/web-platform-tests/workers/interfaces/WorkerGlobalScope/location/helper-redirect.py
index eb1599a577f..c8cd3543487 100644
--- a/tests/wpt/web-platform-tests/workers/interfaces/WorkerGlobalScope/location/helper-redirect.py
+++ b/tests/wpt/web-platform-tests/workers/interfaces/WorkerGlobalScope/location/helper-redirect.py
@@ -1,3 +1,3 @@
def main(request, response):
response.status = 302
- response.headers.append("Location", "post-location-members.js?a")
+ response.headers.append(b"Location", b"post-location-members.js?a")
diff --git a/tests/wpt/web-platform-tests/workers/modules/resources/export-credentials.py b/tests/wpt/web-platform-tests/workers/modules/resources/export-credentials.py
index be6d2ff2fc1..3d0ba778d13 100644
--- a/tests/wpt/web-platform-tests/workers/modules/resources/export-credentials.py
+++ b/tests/wpt/web-platform-tests/workers/modules/resources/export-credentials.py
@@ -1,15 +1,15 @@
def main(request, response):
- cookie = request.cookies.first("COOKIE_NAME", None)
+ cookie = request.cookies.first(b"COOKIE_NAME", None)
- response_headers = [("Content-Type", "text/javascript"),
- ("Access-Control-Allow-Credentials", "true")]
+ response_headers = [(b"Content-Type", b"text/javascript"),
+ (b"Access-Control-Allow-Credentials", b"true")]
- origin = request.headers.get("Origin", None)
+ origin = request.headers.get(b"Origin", None)
if origin:
- response_headers.append(("Access-Control-Allow-Origin", origin))
+ response_headers.append((b"Access-Control-Allow-Origin", origin))
- cookie_value = '';
+ cookie_value = b'';
if cookie:
cookie_value = cookie.value;
return (200, response_headers,
- "export const cookie = '"+cookie_value+"';")
+ b"export const cookie = '"+cookie_value+b"';")
diff --git a/tests/wpt/web-platform-tests/workers/modules/resources/export-referrer-checker.py b/tests/wpt/web-platform-tests/workers/modules/resources/export-referrer-checker.py
index 2928d28aff5..3b0fda1aa6a 100644
--- a/tests/wpt/web-platform-tests/workers/modules/resources/export-referrer-checker.py
+++ b/tests/wpt/web-platform-tests/workers/modules/resources/export-referrer-checker.py
@@ -1,9 +1,9 @@
# Returns a worker script that posts the request's referrer header.
def main(request, response):
- referrer = request.headers.get("referer", "")
+ referrer = request.headers.get(b"referer", b"")
- response_headers = [("Content-Type", "text/javascript"),
- ("Access-Control-Allow-Origin", "*")]
+ response_headers = [(b"Content-Type", b"text/javascript"),
+ (b"Access-Control-Allow-Origin", b"*")]
return (200, response_headers,
- "export const referrer = '"+referrer+"';")
+ b"export const referrer = '"+referrer+b"';")
diff --git a/tests/wpt/web-platform-tests/workers/modules/resources/postmessage-credentials.py b/tests/wpt/web-platform-tests/workers/modules/resources/postmessage-credentials.py
index 8fe46bddc80..a054a1a923c 100644
--- a/tests/wpt/web-platform-tests/workers/modules/resources/postmessage-credentials.py
+++ b/tests/wpt/web-platform-tests/workers/modules/resources/postmessage-credentials.py
@@ -1,22 +1,22 @@
def main(request, response):
- cookie = request.cookies.first("COOKIE_NAME", None)
+ cookie = request.cookies.first(b"COOKIE_NAME", None)
- response_headers = [("Content-Type", "text/javascript"),
- ("Access-Control-Allow-Credentials", "true")]
+ response_headers = [(b"Content-Type", b"text/javascript"),
+ (b"Access-Control-Allow-Credentials", b"true")]
- origin = request.headers.get("Origin", None)
+ origin = request.headers.get(b"Origin", None)
if origin:
- response_headers.append(("Access-Control-Allow-Origin", origin))
+ response_headers.append((b"Access-Control-Allow-Origin", origin))
- cookie_value = '';
+ cookie_value = b'';
if cookie:
cookie_value = cookie.value;
return (200, response_headers,
- "if ('DedicatedWorkerGlobalScope' in self &&" +
- " self instanceof DedicatedWorkerGlobalScope) {" +
- " postMessage('"+cookie_value+"');" +
- "} else if (" +
- " 'SharedWorkerGlobalScope' in self &&" +
- " self instanceof SharedWorkerGlobalScope) {" +
- " onconnect = e => e.ports[0].postMessage('"+cookie_value+"');" +
- "}")
+ b"if ('DedicatedWorkerGlobalScope' in self &&" +
+ b" self instanceof DedicatedWorkerGlobalScope) {" +
+ b" postMessage('"+cookie_value+b"');" +
+ b"} else if (" +
+ b" 'SharedWorkerGlobalScope' in self &&" +
+ b" self instanceof SharedWorkerGlobalScope) {" +
+ b" onconnect = e => e.ports[0].postMessage('"+cookie_value+b"');" +
+ b"}")
diff --git a/tests/wpt/web-platform-tests/workers/modules/resources/postmessage-referrer-checker.py b/tests/wpt/web-platform-tests/workers/modules/resources/postmessage-referrer-checker.py
index f926834ddfc..699af684a23 100644
--- a/tests/wpt/web-platform-tests/workers/modules/resources/postmessage-referrer-checker.py
+++ b/tests/wpt/web-platform-tests/workers/modules/resources/postmessage-referrer-checker.py
@@ -1,16 +1,16 @@
# Returns a worker script that posts the request's referrer header.
def main(request, response):
- referrer = request.headers.get("referer", "")
+ referrer = request.headers.get(b"referer", b"")
- response_headers = [("Content-Type", "text/javascript"),
- ("Access-Control-Allow-Origin", "*")]
+ response_headers = [(b"Content-Type", b"text/javascript"),
+ (b"Access-Control-Allow-Origin", b"*")]
return (200, response_headers,
- "if ('DedicatedWorkerGlobalScope' in self &&" +
- " self instanceof DedicatedWorkerGlobalScope) {" +
- " postMessage('"+referrer+"');" +
- "} else if (" +
- " 'SharedWorkerGlobalScope' in self &&" +
- " self instanceof SharedWorkerGlobalScope) {" +
- " onconnect = e => e.ports[0].postMessage('"+referrer+"');" +
- "}")
+ b"if ('DedicatedWorkerGlobalScope' in self &&" +
+ b" self instanceof DedicatedWorkerGlobalScope) {" +
+ b" postMessage('"+referrer+b"');" +
+ b"} else if (" +
+ b" 'SharedWorkerGlobalScope' in self &&" +
+ b" self instanceof SharedWorkerGlobalScope) {" +
+ b" onconnect = e => e.ports[0].postMessage('"+referrer+b"');" +
+ b"}")
diff --git a/tests/wpt/web-platform-tests/workers/semantics/encodings/003-1.py b/tests/wpt/web-platform-tests/workers/semantics/encodings/003-1.py
index 1e899aac271..4f5df2bb10d 100644
--- a/tests/wpt/web-platform-tests/workers/semantics/encodings/003-1.py
+++ b/tests/wpt/web-platform-tests/workers/semantics/encodings/003-1.py
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
def main(request, response):
- return "PASS" if request.GET.first('x') == 'å' else "FAIL"
+ return u"PASS" if request.GET.first(b'x').decode('utf-8') == u'å' else u"FAIL"
diff --git a/tests/wpt/web-platform-tests/workers/support/imported_script.py b/tests/wpt/web-platform-tests/workers/support/imported_script.py
index 88cd2285e82..2f9c6a81d9d 100644
--- a/tests/wpt/web-platform-tests/workers/support/imported_script.py
+++ b/tests/wpt/web-platform-tests/workers/support/imported_script.py
@@ -1,2 +1,2 @@
def main(request, response):
- return [('Content-Type', request.GET['mime'])], ""
+ return [(b'Content-Type', request.GET[b'mime'])], u""
diff --git a/tests/wpt/web-platform-tests/workers/support/nosiniff-error-worker.py b/tests/wpt/web-platform-tests/workers/support/nosiniff-error-worker.py
index 3a2c1b3901c..e4367ba6e1a 100644
--- a/tests/wpt/web-platform-tests/workers/support/nosiniff-error-worker.py
+++ b/tests/wpt/web-platform-tests/workers/support/nosiniff-error-worker.py
@@ -1,3 +1,3 @@
def main(request, response):
- return [('Content-Type', 'text/html'),
- ('X-Content-Type-Options', 'nosniff')], ""
+ return [(b'Content-Type', b'text/html'),
+ (b'X-Content-Type-Options', b'nosniff')], u""
diff --git a/tests/wpt/web-platform-tests/xhr/send-data-string-invalid-unicode.any.js b/tests/wpt/web-platform-tests/xhr/send-data-string-invalid-unicode.any.js
new file mode 100644
index 00000000000..d9dc5a6bcf8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/xhr/send-data-string-invalid-unicode.any.js
@@ -0,0 +1,46 @@
+// META: title=XMLHttpRequest.send(invalidUnicodeString)
+
+const LEFT_SURROGATE = '\ud83d';
+const RIGHT_SURROGATE = '\udc94';
+
+// Unmatched surrogates should be replaced with the unicode replacement
+// character, 0xFFFD. '$' in these templates is replaced with one of
+// LEFT_SURROGATE or RIGHT_SURROGATE according to the test.
+const TEMPLATES = {
+ '$': [239, 191, 189],
+ '$ab': [239, 191, 189, 97, 98],
+ 'a$b': [97, 239, 191, 189, 98],
+ 'ab$': [97, 98, 239, 191, 189],
+};
+
+for (const surrogate of [LEFT_SURROGATE, RIGHT_SURROGATE]) {
+ for (const [template, expected] of Object.entries(TEMPLATES)) {
+ const invalidString = template.replace('$', surrogate);
+ const printableString = template.replace(
+ '$', '\\u{' + surrogate.charCodeAt(0).toString(16) + '}');
+ async_test(t => {
+ xhrSendStringAndCheckResponseBody(t, invalidString, expected);
+ }, `invalid unicode '${printableString}' should be fixed with ` +
+ `replacement character`);
+ }
+}
+
+// For the sake of completeness, verify that matched surrogates work.
+async_test(t => {
+ xhrSendStringAndCheckResponseBody(t, LEFT_SURROGATE + RIGHT_SURROGATE,
+ [240, 159, 146, 148]);
+}, 'valid unicode should be sent correctly');
+
+function xhrSendStringAndCheckResponseBody(t, string, expected) {
+ const xhr = new XMLHttpRequest();
+ xhr.responseType = 'arraybuffer';
+ xhr.onload = t.step_func(() => {
+ assert_equals(xhr.status, 200, 'status should be 200');
+ const actualBody = new Uint8Array(xhr.response);
+ assert_array_equals(actualBody, expected, 'content should match');
+ t.done();
+ });
+ xhr.onerror = t.unreached_func('no error should occur');
+ xhr.open('POST', 'resources/content.py', true);
+ xhr.send(string);
+}