commit bb27cf41370349dc619fdf7f97b3c7799503a9d6 parent cc67c80b2a4435348b4ce091845697cab9741334 Author: Masayuki Nakano <masayuki@d-toybox.com> Date: Fri, 24 Oct 2025 01:26:44 +0000 Bug 1995912 - Get rid of editing tests which depend on the legacy DOM mutation events r=smaug,dom-core All browsers have dropped supporting the legacy DOM mutation events and there are some crash tests under `testing/web-platform/tests/editing` because Gecko supported them even if the mutation is caused by the builtin editor. I've already filed a spec issue for this [1]. This patch removes all tests which we added, however, there is only one exception, that is `insertAdjacentElement-with-DOMSubtreeModified.html`. Although it's not related to editing, but no body worked on moving it into the proper directly (I filed an issue for this one year ago [2]). Therefore, I leave it as-is but removing the `DOMSubtreeModified` event listener because it seems that the listener triggers flushing pending things. So, the other part may be still valuable for its author. 1. https://github.com/web-platform-tests/wpt/issues/54682 2. https://github.com/web-platform-tests/wpt/issues/48874 Differential Revision: https://phabricator.services.mozilla.com/D269700 Diffstat:
20 files changed, 1 insertion(+), 477 deletions(-)
diff --git a/testing/web-platform/meta/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-without-focus.html.ini b/testing/web-platform/meta/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-without-focus.html.ini @@ -1,3 +0,0 @@ -[forwarddelete-in-list-editing-host-after-selectall-without-focus.html] - expected: - if tsan: [PASS, TIMEOUT] diff --git a/testing/web-platform/tests/editing/crashtests/backcolor-in-nested-editing-host-td-from-DOMAttrModified.html b/testing/web-platform/tests/editing/crashtests/backcolor-in-nested-editing-host-td-from-DOMAttrModified.html @@ -1,29 +0,0 @@ -<html class="test-wait"> -<head> -<script type="text/javascript"> -function boom() -{ - function x() - { - document.removeEventListener("DOMAttrModified", x); - document.execCommand("backcolor", false, "green"); - } - - document.getElementById("td").focus(); - - document.addEventListener("DOMAttrModified", x); - try { - document.execCommand("subscript", false, null); - } catch(e) { - } - document.removeEventListener("DOMAttrModified", x); - document.documentElement.removeAttribute("class"); -} -</script> -</head> - -<body contenteditable="true" onload="setTimeout(boom, 30);"> -<table><tbody contenteditable="false"><tr><td contenteditable="true" id="td"></td></tr></tbody></table> -</body> - -</html> diff --git a/testing/web-platform/tests/editing/crashtests/delete-and-justifycenter-recursively-with-mutation-event-listeners.html b/testing/web-platform/tests/editing/crashtests/delete-and-justifycenter-recursively-with-mutation-event-listeners.html @@ -1,34 +0,0 @@ -<!doctype html> -<html class="test-wait"> -<head> -<meta charset="utf-8"> -<script> -try { - function onDOMNodeInsertedOfContentEditable() { - getSelection().collapse(document.querySelector("input")); - document.execCommand("justifyCenter"); - document.querySelector("dl").addEventListener("DOMSubtreeModified", onDOMSubtreeModifiedOfDLElement); - document.querySelector("dl").appendChild(document.querySelector("style")); - } - function onDOMSubtreeModifiedOfDLElement() { - document.execCommand("delete"); - document.querySelector("label").appendChild(document.querySelector("input")); - document.querySelector("dd[contenteditable]").addEventListener("DOMNodeInserted", onDOMNodeInsertedOfContentEditable); - } - addEventListener("load", () => { - onDOMNodeInsertedOfContentEditable(); - document.documentElement.removeAttribute("class"); - }); -} catch (ex) { - // maybe too many recursive exception would be thrown. - document.documentElement.removeAttribute("class"); -} -</script> -</head> -<body><label></label> -<dl> -<dd contenteditable> -<style>@</style> -<input> -</body> -</html> -\ No newline at end of file diff --git a/testing/web-platform/tests/editing/crashtests/delete-in-dd-editing-host-after-selectall-with-focus.html b/testing/web-platform/tests/editing/crashtests/delete-in-dd-editing-host-after-selectall-with-focus.html @@ -1,12 +0,0 @@ -<script> -addEventListener("DOMContentLoaded", () => { - document.querySelector("dd[contenteditable]").focus(); - document.querySelector("dd[contenteditable]").addEventListener("DOMNodeRemoved", () => { - document.querySelector("h6").textContent = ""; - }); - document.execCommand("selectAll"); - document.execCommand("delete"); -}) -</script> -<h6> -<dd contenteditable> diff --git a/testing/web-platform/tests/editing/crashtests/delete-in-dd-editing-host-after-selectall-without-focus.html b/testing/web-platform/tests/editing/crashtests/delete-in-dd-editing-host-after-selectall-without-focus.html @@ -1,12 +0,0 @@ -<script> -addEventListener("DOMContentLoaded", () => { - document.querySelector("dd[contenteditable]").blur(); - document.querySelector("dd[contenteditable]").addEventListener("DOMNodeRemoved", () => { - document.querySelector("h6").textContent = ""; - }); - document.execCommand("selectAll"); - document.execCommand("delete"); -}) -</script> -<h6> -<dd contenteditable> diff --git a/testing/web-platform/tests/editing/crashtests/designMode-off-during-inserthorizontalrule.html b/testing/web-platform/tests/editing/crashtests/designMode-off-during-inserthorizontalrule.html @@ -1,22 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="utf-8"> -<script> -document.addEventListener("DOMContentLoaded", () => { - document.designMode = "on"; - document.addEventListener("DOMNodeRemoved", () => { - document.documentElement.normalize(); - document.designMode = "off"; - }); - getSelection().collapse(document.querySelector("address").firstChild, 1); - document.execCommand("insertHorizontalRule"); -}); -</script> -</head> -<body> -<address> -A -</address> -</body> -</html> diff --git a/testing/web-platform/tests/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-with-focus.html b/testing/web-platform/tests/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-with-focus.html @@ -1,15 +0,0 @@ -<script> -addEventListener("load", () => { - document.querySelector("ol[contenteditable]").focus(); - document.execCommand("selectAll"); - const targetListItem = document.querySelector("li + li"); - targetListItem.addEventListener("DOMSubtreeModified", () => { - document.execCommand("forwardDelete"); - document.querySelector("script").appendChild(targetListItem); - }); - targetListItem.setAttribute("scrolling", "auto"); -}); -</script> -<ol contenteditable> -<li> -<li>a</li> diff --git a/testing/web-platform/tests/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-without-focus.html b/testing/web-platform/tests/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-without-focus.html @@ -1,15 +0,0 @@ -<script> -addEventListener("load", () => { - document.querySelector("ol[contenteditable]").blur(); - document.execCommand("selectAll"); - const targetListItem = document.querySelector("li + li"); - targetListItem.addEventListener("DOMSubtreeModified", () => { - document.execCommand("forwardDelete"); - document.querySelector("script").appendChild(targetListItem); - }); - targetListItem.setAttribute("scrolling", "auto"); -}); -</script> -<ol contenteditable> -<li> -<li>a</li> diff --git a/testing/web-platform/tests/editing/crashtests/insertAdjacentElement-with-DOMSubtreeModified.html b/testing/web-platform/tests/editing/crashtests/insertAdjacentElement-with-DOMSubtreeModified.html @@ -3,12 +3,7 @@ <script src="../resources/js-test.js"></script> <script> function onLoad() { - const x1 = document.getElementById('x1'); - x1.addEventListener('DOMSubtreeModified', () => { - const x2 = document.getElementById('x2'); - x2.contentDocument; - }); - x1.setAttribute('inputmode', 'url'); + document.getElementById('x1').setAttribute('inputmode', 'url'); } function insertAdjacent() { const x2 = document.getElementById('x2'); diff --git a/testing/web-platform/tests/editing/crashtests/insertText-nested-by-DOMSubtreeModified.html b/testing/web-platform/tests/editing/crashtests/insertText-nested-by-DOMSubtreeModified.html @@ -1,29 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="utf-8"> -<script> -document.addEventListener("DOMContentLoaded", () => { - const output = document.querySelector("output"); - const table = document.querySelector("table"); - table.addEventListener("DOMSubtreeModified", () => { - document.execCommand("bold"); - document.execCommand("hiliteColor", false, "white"); - output.appendChild(table); - document.execCommand("forwardDelete"); - table.setAttribute("onwebkitsourceclose", "foo()"); - document.execCommand("insertText", false, "a"); - }); - document.execCommand("selectAll"); - table.insertRow(); -}); -</script> -</head> -<body> -<canvas contenteditable> -<output> -<table tabindex="0" autofocus></table> -</output> -</canvas> -</body> -</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertparagraph-from-DOMNodeInserted-caused-by-insertorderedlist.html b/testing/web-platform/tests/editing/crashtests/insertparagraph-from-DOMNodeInserted-caused-by-insertorderedlist.html @@ -1,23 +0,0 @@ -<html> -<head> -<script type="text/javascript"> - -function boom() -{ - document.addEventListener("DOMNodeInserted", x); - - function x() - { - document.removeEventListener("DOMNodeInserted", x); - document.execCommand("insertParagraph", false, ""); - } - - document.execCommand("insertorderedlist", false, ""); -} - -</script> -</head> - -<body contenteditable="true" onload="boom()"></body> - -</html> diff --git a/testing/web-platform/tests/editing/crashtests/justifycenter-then-delete-selection-on-DOMSubtreeModified.html b/testing/web-platform/tests/editing/crashtests/justifycenter-then-delete-selection-on-DOMSubtreeModified.html @@ -1,24 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="utf-8"> -<script> -document.addEventListener("DOMContentLoaded", () => { - document.execCommand("selectAll"); - document.querySelector("li").addEventListener("DOMSubtreeModified", () => { - document.designMode = "on"; - document.execCommand("justifyCenter"); - getSelection().deleteFromDocument(); - }); - document.querySelector("li").type = "1"; -}); -</script> -</head> -<body> -<li> - <h3 align="right"> - <option contenteditable="true"></option> - </h3> -</li> -</body> -</html> diff --git a/testing/web-platform/tests/editing/crashtests/normalize_document_at_DOMSubtreeModified_during_insertparagraph.html b/testing/web-platform/tests/editing/crashtests/normalize_document_at_DOMSubtreeModified_during_insertparagraph.html @@ -1,16 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="utf-8"> -<script> -addEventListener("load", () => { - document.documentElement.innerHTML = "<main>\n>"; - document.addEventListener("DOMSubtreeModified", () => { - document.normalize(); - }, {capture: true}); - document.designMode = "on" - document.execCommand("insertParagraph"); -}); -</script> -</head> -</html> diff --git a/testing/web-platform/tests/editing/crashtests/remove-editing-host-during-forwarddelete.html b/testing/web-platform/tests/editing/crashtests/remove-editing-host-during-forwarddelete.html @@ -1,65 +0,0 @@ -<!doctype html> -<html class="test-wait"> -<head> -<meta charset="utf-8"> -<style> -dir { - animation: kf, 0s infinite paused; -} -svg { - animation-name: kf; -} -@keyframes kf {} -</style> -<script> -let dir; -// animationend for <svg> and <dir> may be fired before "DOMContentLoaded". -// Therefore, let's start to listen them immediately. -const waitForAnimationEnd = new Promise(resolve => { - let count = 0; - function onAnimationEnd() { - window.find("AAAAAAAAAA"); - document.execCommand("forwardDelete"); - count++; - function getRemainingEventCount(event) { - if (count >= 2) { - return 0; - } - if (event.target.tagName == "DIR") { - return 0; - } - // If `animationend` is delayed and `<dir>` has already been removed, - // `animationend` for it is never fired anymore. - return dir && !dir.isConnected ? 0 : 1; - } - if (!getRemainingEventCount()) { - window.removeEventListener("animationend", onAnimationEnd); - resolve(); - } - } - window.addEventListener("animationend", onAnimationEnd); -}); - -document.addEventListener("DOMContentLoaded", async () => { - dir = document.querySelector("dir"); - window.find("A"); - document.execCommand("insertHTML", false, "AAAAAAAAAAAAAAAA"); - dir.addEventListener("DOMNodeRemoved", event => { - dir.remove(); - }); - window.find("A"); - document.execCommand("delete"); - await waitForAnimationEnd; - document.documentElement.removeAttribute("class"); -}); -</script> -</head> -<body> -<svg> -<s></s> -<dir contenteditable> -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -</dir> -</svg> -</body> -</html> diff --git a/testing/web-platform/tests/editing/crashtests/remove-editing-host-on-DOMNodeInserted-at-indent.html b/testing/web-platform/tests/editing/crashtests/remove-editing-host-on-DOMNodeInserted-at-indent.html @@ -1,24 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="utf-8"> -<script> -document.addEventListener("DOMContentLoaded", () => { - const editingHost = document.querySelector("h6[contenteditable]"); - document.querySelector("wbr").addEventListener( - "DOMNodeInserted", - () => editingHost.remove() - ); - window.find("A"); - document.execCommand("indent"); -}) -</script> -</head> -<body> -<h6 contenteditable> -<time> -<wbr> -<main></main> -A -</time></h6></body> -</html> diff --git a/testing/web-platform/tests/editing/crashtests/remove-parent-element-during-inserthtml.html b/testing/web-platform/tests/editing/crashtests/remove-parent-element-during-inserthtml.html @@ -1,24 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="utf-8"> -<script> -document.addEventListener("DOMContentLoaded", () => { - document.onselectionchange = () => { - document.execCommand("insertHTML", false, "a") - document.designMode = "on" - }; - window.find("a"); - document.querySelector("dl[contenteditable] > dd").addEventListener("DOMNodeRemoved", () => { - document.querySelector("dl[contenteditable]").remove(); - }); -}); -</script> -</head> -<body> -<dl contenteditable> -<dd></dd> -a -</dl> -</body> -</html> diff --git a/testing/web-platform/tests/editing/crashtests/remove-right-block-during-joining-with-parent-left-block.html b/testing/web-platform/tests/editing/crashtests/remove-right-block-during-joining-with-parent-left-block.html @@ -1,33 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="utf-8"> -<title>Test removing right block while joining it and parent left block</title> -<script> -addEventListener("load", () => { - const editingHosts = document.querySelectorAll("div[contenteditable]"); - for (const editingHost of editingHosts) { - editingHost.focus(); - const rightChildBlock = editingHost.querySelector("div > div > div"); - getSelection().collapse(rightChildBlock.firstChild.firstChild, 0); - editingHost.addEventListener("DOMSubtreeModified", () => { - document.body.appendChild(rightChildBlock); - }); - document.execCommand("delete"); - } -}); -</script> -</head> -<body> - <div contenteditable> - <div>parent<div><b>child</b></div>parent</div> - </div> - <div contenteditable> - <div>parent<div><b>child<br>2nd line</b></div>parent</div> - </div> - <div contenteditable style="white-space:pre"> - <div>parent<div>child -2nd line</div>parent</div> - </div> -</body> -</html> diff --git a/testing/web-platform/tests/editing/crashtests/removeformat-from-DOMNodeRemoved.html b/testing/web-platform/tests/editing/crashtests/removeformat-from-DOMNodeRemoved.html @@ -1,29 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="utf-8"> -<script> -document.addEventListener("DOMContentLoaded", () => { - window.find("a"); - document.addEventListener("DOMNodeRemoved", () => { - try { - document.getElementById("target").normalize(); - document.execCommand("removeFormat"); - } catch (e) { - } - }); - document.adoptNode(document.querySelector("datalist")); -}); -</script> -</head> -<body> -<kbd> -<datalist> -</kbd> -<figcaption contenteditable> -<font id="target"> -a -</font> -</figcaption> -</body> -</html> diff --git a/testing/web-platform/tests/editing/crashtests/replace-parent-of-editing-host-on-DOMSubtreeModified.html b/testing/web-platform/tests/editing/crashtests/replace-parent-of-editing-host-on-DOMSubtreeModified.html @@ -1,28 +0,0 @@ -<!doctype html> -<html> -<head> -<script> -document.addEventListener("DOMContentLoaded", () => { - getSelection().collapse(document.querySelector("content"), 1); - document.querySelector("div[contenteditable]").addEventListener("DOMSubtreeModified", () => { - document.querySelector("tr").replaceChild( - document.querySelector("meter"), - document.querySelector("th") - ); - }); - document.execCommand("justifyFull"); -}); -</script> -</head> -<body> -<table> -<tr> -<th> -<div contenteditable> -<meter> -<content> -<ul></ul> -</div> -</th></tr></table> -</body> -</html> diff --git a/testing/web-platform/tests/editing/crashtests/set-output-value-to-empty-while-deleting-its-content.html b/testing/web-platform/tests/editing/crashtests/set-output-value-to-empty-while-deleting-its-content.html @@ -1,33 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="utf-8"> -<script> -document.addEventListener("DOMContentLoaded", () => { - document.designMode = "on"; - window.find("AA"); - document.addEventListener( - "selectionchange", - onSelectionChangeOrDOMNodeInserted, - {once: true} - ); - document.querySelector("output").addEventListener( - "DOMNodeInserted", - onSelectionChangeOrDOMNodeInserted - ); - document.execCommand("forwarddelete"); -}); - -function onSelectionChangeOrDOMNodeInserted() { - document.execCommand("delete"); - document.querySelector("output").value = ""; -} -</script> -</head> -<body> -<output> -<ruby></ruby> -<div> -AAA -</div></output></body> -</html>