зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1789967
- part 3: Make `HTMLEditor::CollapseSelectionToEndOfLastLeafNodeOfDocument` and `HTMLEditor::InitEditorContentAndSelection` do nothing if the document is partially editable r=m_kato
They and their callees work with the result of `GetRoot()` which is the document element or the body element. If the body is not editable, `Selection` should not be updated in non-editable region nor `<br>` elements should not be inserted in both non-focused editable elements and non-editable elements. Therefore, they should run only when the document element or the `<body>` element is editable. To keep testing crashtests as reported, this patch makes tests which have `contenteditable` except `<html>` and `<body>` initialize `Selection` as what we've done. And clean up the tests for helping to port them to WPT in the future (bug 1725850). Differential Revision: https://phabricator.services.mozilla.com/D157408
This commit is contained in:
Родитель
b1f3f5e5af
Коммит
a353ab7e90
|
@ -63,7 +63,7 @@
|
|||
turnCaretBrowsing(true);
|
||||
|
||||
// test caret offsets
|
||||
testCaretOffset(document, 15);
|
||||
testCaretOffset(document, 0); // because of no selection ranges
|
||||
testCaretOffset("textbox", -1);
|
||||
testCaretOffset("textarea", -1);
|
||||
testCaretOffset("p", -1);
|
||||
|
|
|
@ -26,42 +26,67 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1101364
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
async function test()
|
||||
{
|
||||
var iframe1 = document.getElementById('test1');
|
||||
iframe1.focus();
|
||||
var docShell = SpecialPowers.wrap(iframe1.contentWindow).docShell;
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(async () => {
|
||||
await (async () => {
|
||||
const iframe = document.getElementById("test1");
|
||||
iframe.focus();
|
||||
const docShell = SpecialPowers.wrap(iframe.contentWindow).docShell;
|
||||
|
||||
// test1
|
||||
docShell.doCommand("cmd_selectAll");
|
||||
var withoutContenteditable = await snapshotWindow(iframe1.contentWindow);
|
||||
docShell.doCommand("cmd_selectAll");
|
||||
info(
|
||||
"Waiting for getting screenshot of \"Select All\" without contenteditable..."
|
||||
);
|
||||
const withoutContenteditable = await snapshotWindow(iframe.contentWindow);
|
||||
|
||||
iframe1.contentDocument.getElementById('testDiv').setAttribute('contentEditable', true);
|
||||
docShell.doCommand("cmd_selectAll");
|
||||
var withContenteditable = await snapshotWindow(iframe1.contentWindow);
|
||||
dump(withoutContenteditable.toDataURL());
|
||||
dump(withContenteditable.toDataURL());
|
||||
iframe.contentDocument
|
||||
.getElementById("testDiv")
|
||||
.setAttribute("contentEditable", true);
|
||||
docShell.doCommand("cmd_selectAll");
|
||||
info(
|
||||
"Waiting for getting screenshot of \"Select All\" in contenteditable..."
|
||||
);
|
||||
const withContenteditable = await snapshotWindow(iframe.contentWindow);
|
||||
const result =
|
||||
compareSnapshots(withoutContenteditable, withContenteditable, true);
|
||||
ok(
|
||||
result[0],
|
||||
`Select all should look identical\ngot: ${
|
||||
result[2]
|
||||
}\nexpected: ${result[1]}`
|
||||
);
|
||||
})();
|
||||
|
||||
ok(compareSnapshots(withoutContenteditable, withContenteditable, true)[0], 'Select all should look identical');
|
||||
await (async () => {
|
||||
const iframe = document.getElementById("test2");
|
||||
iframe.focus();
|
||||
iframe.contentDocument.querySelector("div[contenteditable]").focus();
|
||||
const docShell = SpecialPowers.wrap(iframe.contentWindow).docShell;
|
||||
const test2Inner = iframe.contentDocument.getElementById("test2Inner");
|
||||
test2Inner.style.MozUserSelect = "text";
|
||||
docShell.doCommand("cmd_selectAll");
|
||||
info(
|
||||
"Waiting for getting screenshot of \"Select All\" in contenteditable (use-select: text)..."
|
||||
);
|
||||
const withoutUserSelect = await snapshotWindow(iframe.contentWindow);
|
||||
|
||||
// test2
|
||||
var iframe2 = document.getElementById('test2');
|
||||
iframe2.focus();
|
||||
var docShell = SpecialPowers.wrap(iframe2.contentWindow).docShell;
|
||||
var test2Inner = iframe2.contentDocument.getElementById('test2Inner');
|
||||
test2Inner.style.MozUserSelect = 'text';
|
||||
docShell.doCommand("cmd_selectAll");
|
||||
var withoutUserSelect = await snapshotWindow(iframe2.contentWindow);
|
||||
|
||||
test2Inner.style.MozUserSelect = 'none';
|
||||
docShell.doCommand("cmd_selectAll");
|
||||
var withUserSelect = await snapshotWindow(iframe2.contentWindow);
|
||||
ok(compareSnapshots(withoutUserSelect, withUserSelect, true)[0], 'Editable fields should ignore user select style');
|
||||
test2Inner.style.MozUserSelect = "none";
|
||||
docShell.doCommand("cmd_selectAll");
|
||||
info(
|
||||
"Waiting for getting screenshot of \"Select All\" in contenteditable (use-select: none)..."
|
||||
);
|
||||
const withUserSelect = await snapshotWindow(iframe.contentWindow);
|
||||
const result = compareSnapshots(withoutUserSelect, withUserSelect, true);
|
||||
ok(
|
||||
result[0],
|
||||
`Editable fields should ignore user select style\ngot: ${
|
||||
result[2]
|
||||
}\nexpected: ${result[1]}`
|
||||
);
|
||||
})();
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
window.onload = function() { setTimeout(test, 0); };
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -131,6 +131,12 @@ HTMLEditor::CreateRangeIncludingAdjuscentWhiteSpaces(
|
|||
nsresult HTMLEditor::InitEditorContentAndSelection() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
// We should do nothing with the result of GetRoot() if only a part of the
|
||||
// document is editable.
|
||||
if (!EntireDocumentIsEditable()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = MaybeCreatePaddingBRElementForEmptyEditor();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
|
@ -141,8 +147,8 @@ nsresult HTMLEditor::InitEditorContentAndSelection() {
|
|||
// If the selection hasn't been set up yet, set it up collapsed to the end of
|
||||
// our editable content.
|
||||
// XXX I think that this shouldn't do it in `HTMLEditor` because it maybe
|
||||
// removed by the web app and if they call `Selection::AddRange()`,
|
||||
// it may cause multiple selection ranges.
|
||||
// removed by the web app and if they call `Selection::AddRange()` without
|
||||
// checking the range count, it may cause multiple selection ranges.
|
||||
if (!SelectionRef().RangeCount()) {
|
||||
nsresult rv = CollapseSelectionToEndOfLastLeafNodeOfDocument();
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -154,6 +160,8 @@ nsresult HTMLEditor::InitEditorContentAndSelection() {
|
|||
}
|
||||
|
||||
if (IsInPlaintextMode()) {
|
||||
// XXX Should we do this in HTMLEditor? It's odd to guarantee that last
|
||||
// empty line is visible only when it's in the plain text mode.
|
||||
nsresult rv = EnsurePaddingBRElementInMultilineEditor();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
|
|
|
@ -733,6 +733,13 @@ bool HTMLEditor::IsInDesignMode() const {
|
|||
return document && document->IsInDesignMode();
|
||||
}
|
||||
|
||||
bool HTMLEditor::EntireDocumentIsEditable() const {
|
||||
Document* document = GetDocument();
|
||||
return document && document->GetDocumentElement() &&
|
||||
(document->GetDocumentElement()->IsEditable() ||
|
||||
(document->GetBody() && document->GetBody()->IsEditable()));
|
||||
}
|
||||
|
||||
void HTMLEditor::CreateEventListeners() {
|
||||
// Don't create the handler twice
|
||||
if (!mEventListener) {
|
||||
|
@ -807,6 +814,12 @@ NS_IMETHODIMP HTMLEditor::EndOfDocument() {
|
|||
nsresult HTMLEditor::CollapseSelectionToEndOfLastLeafNodeOfDocument() const {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
// We should do nothing with the result of GetRoot() if only a part of the
|
||||
// document is editable.
|
||||
if (!EntireDocumentIsEditable()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<Element> bodyOrDocumentElement = GetRoot();
|
||||
if (NS_WARN_IF(!bodyOrDocumentElement)) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -667,10 +667,17 @@ class HTMLEditor final : public EditorBase,
|
|||
}
|
||||
|
||||
/**
|
||||
* Retruns true if we're in designMode.
|
||||
* Return true if we're in designMode.
|
||||
*/
|
||||
bool IsInDesignMode() const;
|
||||
|
||||
/**
|
||||
* Return true if entire the document is editable (although the document
|
||||
* may have non-editable nodes, e.g.,
|
||||
* <body contenteditable><div contenteditable="false"></div></body>
|
||||
*/
|
||||
bool EntireDocumentIsEditable() const;
|
||||
|
||||
/**
|
||||
* Basically, this always returns true if we're for `contenteditable` or
|
||||
* `designMode` editor in web apps. However, e.g., Composer of SeaMonkey
|
||||
|
|
|
@ -2,21 +2,22 @@
|
|||
<!-- saved from url=(0065)https://bug1134545.bugzilla.mozilla.org/attachment.cgi?id=8566418 -->
|
||||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
textNode = document.createTextNode(" ");
|
||||
x.appendChild(textNode);
|
||||
x.setAttribute('contenteditable', "true");
|
||||
textNode.remove();
|
||||
window.getSelection().selectAllChildren(textNode);
|
||||
document.execCommand("increasefontsize", false, null);
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body>, i.e., at the text node after the <div contenteditable>.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
const textNode = document.createTextNode(" ");
|
||||
const editingHost = document.querySelector("div[contenteditable]");
|
||||
editingHost.appendChild(textNode);
|
||||
editingHost.setAttribute('contenteditable', "true");
|
||||
textNode.remove();
|
||||
getSelection().selectAllChildren(textNode);
|
||||
document.execCommand("increasefontsize");
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();">
|
||||
<div id="x" contenteditable="true"></div>
|
||||
<body onload="onLoad();">
|
||||
<div contenteditable></div>
|
||||
|
||||
|
||||
</body></html>
|
|
@ -1,11 +1,14 @@
|
|||
<body>
|
||||
<table contenteditable="true"></table>
|
||||
<table contenteditable></table>
|
||||
</body>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.execCommand("useCSS", false, false);
|
||||
document.designMode = 'on';
|
||||
document.execCommand("insertunorderedlist", false);
|
||||
document.execCommand("justifyfull", false);
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body>, i.e., at the text node after the <table>.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
document.execCommand("styleWithCSS", false, false);
|
||||
document.designMode = "on";
|
||||
document.execCommand("insertUnorderedList");
|
||||
document.execCommand("justifyFull");
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -3,22 +3,25 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
addEventListener('DOMContentLoaded', function(){
|
||||
document.documentElement.className = 'lizard';
|
||||
setTimeout(function(){
|
||||
document.execCommand('selectAll', false, null);
|
||||
document.designMode = 'on';
|
||||
document.execCommand('removeformat', false, null);
|
||||
}, 0);
|
||||
addEventListener('DOMContentLoaded', () => {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body>, i.e., at the text node after the last invalid </span>.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
document.documentElement.className = 'lizard';
|
||||
setTimeout(() => {
|
||||
document.execCommand('selectAll');
|
||||
document.designMode = 'on';
|
||||
document.execCommand('removeformat');
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.lizard{
|
||||
-webkit-user-select:all;
|
||||
.lizard {
|
||||
-webkit-user-select: all;
|
||||
}
|
||||
*{
|
||||
position:fixed;
|
||||
display:table-column;
|
||||
* {
|
||||
position: fixed;
|
||||
display: table-column;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
|
|
@ -1,23 +1,60 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
try { o1 = document.createElement('style'); } catch(e) { }
|
||||
try { o2 = document.createElement('output') } catch(e) { }
|
||||
try { o3 = document.createElement('input') } catch(e) { }
|
||||
try { o4 = document.createElement('script'); } catch(e) { }
|
||||
try { o5 = o2.cloneNode(false); } catch(e) { }
|
||||
try { document.documentElement.appendChild(o1) } catch(e) { }
|
||||
try { o1.outerHTML = '<a contenteditable=\'true\'>'; } catch(e) { }
|
||||
try { document.documentElement.appendChild(o3) } catch(e) { }
|
||||
try { o7 = document.createTextNode(' '); } catch(e) { }
|
||||
try { o4.appendChild(o7) } catch(e) { }
|
||||
try { document.documentElement.appendChild(o4) } catch(e) { }
|
||||
try { o6 = window.getSelection() } catch(e) { }
|
||||
try { o3.select() } catch(e) { }
|
||||
try { document.replaceChild(document.documentElement, document.documentElement); } catch(e) { }
|
||||
try { o6.setBaseAndExtent(o7, 0, o5, 0) } catch(e) { }
|
||||
try { document.designMode = 'on'; } catch(e) { }
|
||||
try { document.execCommand('insertimage', false, 'http://localhost/') } catch(e) { }
|
||||
</script>
|
||||
</head>
|
||||
<head>
|
||||
<script>
|
||||
try {
|
||||
var style = document.createElement("style");
|
||||
} catch(e) {}
|
||||
try {
|
||||
var output = document.createElement("output");
|
||||
} catch(e) {}
|
||||
try {
|
||||
var input = document.createElement("input");
|
||||
} catch(e) {}
|
||||
try {
|
||||
var script = document.createElement("script");
|
||||
} catch(e) {}
|
||||
try {
|
||||
var clonedOutput = output.cloneNode(false);
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.documentElement.appendChild(style);
|
||||
} catch(e) {}
|
||||
try {
|
||||
style.outerHTML = '<a contenteditable="true">';
|
||||
} catch(e) {}
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body> which must be empty (<style> was added after the <body>).
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
try {
|
||||
document.documentElement.appendChild(input);
|
||||
} catch(e) {}
|
||||
try {
|
||||
var text = document.createTextNode(" ");
|
||||
} catch(e) {}
|
||||
try {
|
||||
script.appendChild(text);
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.documentElement.appendChild(script);
|
||||
} catch(e) {}
|
||||
try {
|
||||
var selection = getSelection();
|
||||
} catch(e) {}
|
||||
try {
|
||||
input.select();
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.replaceChild(document.documentElement, document.documentElement);
|
||||
} catch(e) {}
|
||||
try {
|
||||
selection.setBaseAndExtent(text, 0, clonedOutput, 0);
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.designMode = "on";
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("insertImage", false, "http://localhost/");
|
||||
} catch(e) {}
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
||||
|
|
|
@ -2,20 +2,28 @@
|
|||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
function load() {
|
||||
document.getElementById("spacer").addEventListener("DOMNodeInserted", () => {
|
||||
document.getElementById("style").appendChild(
|
||||
document.getElementById("table"));
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <p> which is the deepest last child of the <body> (<spacer> can contain
|
||||
// <p>).
|
||||
getSelection().collapse(
|
||||
document.querySelector("p"),
|
||||
document.querySelector("p").childNodes.length
|
||||
);
|
||||
document.querySelector("spacer").addEventListener("DOMNodeInserted", () => {
|
||||
document.querySelector("style").appendChild(
|
||||
document.querySelector("table")
|
||||
);
|
||||
document.documentElement.classList.remove("reftest-wait");
|
||||
});
|
||||
document.execCommand("insertOrderedList", false);
|
||||
document.execCommand("insertOrderedList");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="load()">
|
||||
<table id="table"></table>
|
||||
<style id="style"></style>
|
||||
<spacer id="spacer" contenteditable="true">
|
||||
<p id="p"></p>
|
||||
<body onload="onLoad()">
|
||||
<table></table>
|
||||
<style></style>
|
||||
<spacer contenteditable>
|
||||
<p></p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="application/javascript">
|
||||
function do_test() {
|
||||
document.execCommand("insertUnorderedList", false);
|
||||
<script>
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body>, i.e., at the text node after the <table>.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
document.execCommand("insertUnorderedList");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="do_test()">
|
||||
<body onload="onLoad()">
|
||||
<table>
|
||||
<th contenteditable="true">
|
||||
<ol contenteditable="false">
|
||||
<th contenteditable>
|
||||
<ol contenteditable>
|
||||
</th>
|
||||
</table>
|
||||
</body>
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
<script>
|
||||
function jsfuzzer() {
|
||||
try { var var00007 = eventhandler5; } catch(e) { }
|
||||
try { var var00006 = var00007; } catch(e) { }
|
||||
try { htmlvar00007.addEventListener("DOMNodeInserted", var00006); } catch(e) { }
|
||||
try { document.execCommand("justifyFull", false); } catch(e) { }
|
||||
}
|
||||
function eventhandler5() {
|
||||
try { htmlvar00008.replaceWith("1"); } catch(e) { }
|
||||
function onLoad() {
|
||||
const shadow = document.querySelector("shadow");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <shadow> which is the deepest last child of the <body>.
|
||||
getSelection().collapse(shadow, shadow.childNodes.length);
|
||||
try {
|
||||
document.querySelector("dd[contenteditable]").addEventListener(
|
||||
"DOMNodeInserted",
|
||||
() => {
|
||||
try {
|
||||
shadow.replaceWith("1");
|
||||
} catch(e) {}
|
||||
}
|
||||
);
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("justifyFull");
|
||||
} catch(e) {}
|
||||
}
|
||||
</script>
|
||||
<body onload=jsfuzzer()>
|
||||
<dd id="htmlvar00007" contenteditable="true">
|
||||
<shadow id="htmlvar00008">
|
||||
<body onload="onLoad();">
|
||||
<dd contenteditable>
|
||||
<shadow>
|
|
@ -1,29 +1,36 @@
|
|||
<script>
|
||||
function jsfuzzer() {
|
||||
var option = document.getElementById("option");
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// parent of <embed> (<embed> is not a container, therefore, its parent is the
|
||||
// deepest last child container element of the <body>).
|
||||
getSelection().collapse(
|
||||
document.querySelector("embed").parentElement,
|
||||
document.querySelector("embed").parentElement.childNodes.length
|
||||
); // Point the <embed>
|
||||
const option = document.querySelector("option");
|
||||
option.addEventListener("click", () => {
|
||||
document.execCommand("forwardDelete", false);
|
||||
document.execCommand("forwardDelete");
|
||||
});
|
||||
var li2 = document.getElementById("li2");
|
||||
const li2 = document.getElementById("li2");
|
||||
li2.addEventListener("DOMNodeInserted", () => {
|
||||
option.click();
|
||||
});
|
||||
var select = document.getElementById("select");
|
||||
const select = document.querySelector("select");
|
||||
select.parentElement.setAttribute("onpageshow", "onPageShow()");
|
||||
}
|
||||
|
||||
function onPageShow() {
|
||||
var li1 = document.getElementById("li1");
|
||||
const li1 = document.getElementById("li1");
|
||||
li1.addEventListener("DOMSubtreeModified", () => {
|
||||
document.execCommand("selectAll", false);
|
||||
document.execCommand("indent", false);
|
||||
document.execCommand("selectAll");
|
||||
document.execCommand("indent");
|
||||
});
|
||||
li1.appendChild(document.createElement("legend"));
|
||||
}
|
||||
</script>
|
||||
<body onload=jsfuzzer()>
|
||||
<select id="select">
|
||||
<option id="option"></option>
|
||||
<body onload="onLoad()">
|
||||
<select>
|
||||
<option></option>
|
||||
</select>
|
||||
<li id="li1"></li>
|
||||
<ul contenteditable="true">
|
||||
|
|
|
@ -1,23 +1,40 @@
|
|||
<script>
|
||||
var target;
|
||||
function jsfuzzer() {
|
||||
target = htmlvar00017; // Cache the target for removing the event handler.
|
||||
try { target.addEventListener("DOMSubtreeModified", eventhandler5); } catch(e) { }
|
||||
try { target.align = ""; } catch(e) { }
|
||||
let th;
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <colgroup> which is the last child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("colgroup"),
|
||||
document.querySelector("colgroup").childNodes.length
|
||||
);
|
||||
th = document.querySelector("th"); // Cache the target for removing the event handler.
|
||||
try {
|
||||
th.addEventListener("DOMSubtreeModified", onDOMSubtreeModified);
|
||||
} catch(e) {}
|
||||
try {
|
||||
th.align = "";
|
||||
} catch(e) {}
|
||||
}
|
||||
var count = 0;
|
||||
function eventhandler5() {
|
||||
if (count++ == 1) {
|
||||
// If we didn't stop testing this, this event handler would be called too
|
||||
// many times. It's enough to run twice to reproduce the bug report.
|
||||
target.removeEventListener("DOMSubtreeModified", eventhandler5);
|
||||
}
|
||||
try { document.execCommand("selectAll", false); } catch(e) { }
|
||||
try { document.execCommand("justifyCenter", false); } catch(e) { }
|
||||
try { document.execCommand("forwardDelete", false); } catch(e) { }
|
||||
|
||||
let count = 0;
|
||||
function onDOMSubtreeModified() {
|
||||
if (count++ == 1) {
|
||||
// If we didn't stop testing this, this event handler would be called too
|
||||
// many times. It's enough to run twice to reproduce the bug report.
|
||||
th.removeEventListener("DOMSubtreeModified", onDOMSubtreeModified);
|
||||
}
|
||||
try {
|
||||
document.execCommand("selectAll");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("justifyCenter");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("forwardDelete");
|
||||
} catch(e) {}
|
||||
}
|
||||
</script>
|
||||
<body onload=jsfuzzer()>
|
||||
<table contenteditable="">
|
||||
<th id="htmlvar00017"></th>
|
||||
<body onload="onLoad()">
|
||||
<table contenteditable>
|
||||
<th></th>
|
||||
<colgroup>
|
|
@ -2,15 +2,22 @@
|
|||
* { position: absolute; }
|
||||
</style>
|
||||
<script>
|
||||
function jsfuzzer() {
|
||||
del1.addEventListener("DOMSubtreeModified", () => {
|
||||
document.execCommand("italic", false);
|
||||
document.execCommand("selectAll", false);
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <iframe> which is the last child of the <body>. Note that <iframe> is
|
||||
// treated as a container in HTMLEditor.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
document.querySelector("del").addEventListener("DOMSubtreeModified", () => {
|
||||
document.execCommand("italic");
|
||||
document.execCommand("selectAll");
|
||||
});
|
||||
a1.replaceChild(iframe1, a1.childNodes[0]);
|
||||
document.querySelector("a[contenteditable]").replaceChild(
|
||||
document.querySelector("iframe"),
|
||||
document.querySelector("a[contenteditable]").childNodes[0]
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<body onload=jsfuzzer()>
|
||||
<a contenteditable="" id="a1">
|
||||
<del id="del1">
|
||||
<iframe id="iframe1">
|
||||
<body onload="onLoad()">
|
||||
<a contenteditable>
|
||||
<del>
|
||||
<iframe>
|
||||
|
|
|
@ -1,20 +1,41 @@
|
|||
<script>
|
||||
function jsfuzzer() {
|
||||
try { document.execCommand("insertUnorderedList", false); } catch(e) { }
|
||||
try { document.execCommand("delete", false); } catch(e) { }
|
||||
function onLoad() {
|
||||
try {
|
||||
document.execCommand("insertUnorderedList");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("delete");
|
||||
} catch(e) {}
|
||||
}
|
||||
function eventhandler1() {
|
||||
try { window.getSelection().collapse(htmlvar00001,1); } catch(e) { }
|
||||
|
||||
function onToggle1() {
|
||||
try {
|
||||
getSelection().collapse(
|
||||
document.querySelector("font"),
|
||||
1
|
||||
);
|
||||
} catch(e) {}
|
||||
}
|
||||
function eventhandler2() {
|
||||
try { htmlvar00002.appendChild(htmlvar00001); } catch(e) { }
|
||||
|
||||
function onToggle2() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <summary> which is the last child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("summary"),
|
||||
document.querySelector("summary").childNodes.length
|
||||
);
|
||||
try {
|
||||
document.querySelector("label").appendChild(
|
||||
document.querySelector("font")
|
||||
);
|
||||
} catch(e) {}
|
||||
}
|
||||
</script>
|
||||
<body onload=jsfuzzer()>
|
||||
<label id="htmlvar00002" contenteditable="true">
|
||||
<details ontoggle="eventhandler2()" open="true">
|
||||
<body onload="onLoad()">
|
||||
<label contenteditable>
|
||||
<details ontoggle="onToggle2()" open>
|
||||
</details>
|
||||
</label>
|
||||
<details ontoggle="eventhandler1()" open="true">
|
||||
<font id="htmlvar00001" dir="rtl">
|
||||
<details ontoggle="onToggle1()" open>
|
||||
<font dir="rtl">
|
||||
<summary>
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
<script>
|
||||
function jsfuzzer() {
|
||||
var var00043 = window.getSelection();
|
||||
htmlvar00018.addEventListener("DOMNodeRemoved", eh1);
|
||||
var00043.setPosition(htmlvar00016);
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <option> which is the last child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("option"),
|
||||
document.querySelector("option").childNodes.length
|
||||
);
|
||||
document.querySelector("ins").addEventListener(
|
||||
"DOMNodeRemoved",
|
||||
onDOMNodeRemoved
|
||||
);
|
||||
getSelection().setPosition(
|
||||
document.querySelector("shadow")
|
||||
);
|
||||
document.execCommand("insertText", false, "1");
|
||||
}
|
||||
function eh1() {
|
||||
document.execCommand("insertHorizontalRule", false);
|
||||
document.execCommand("justifyCenter", false);
|
||||
function onDOMNodeRemoved() {
|
||||
document.execCommand("insertHorizontalRule");
|
||||
document.execCommand("justifyCenter");
|
||||
}
|
||||
</script>
|
||||
<body onload=jsfuzzer()>
|
||||
<li contenteditable="true">
|
||||
<shadow id="htmlvar00016">
|
||||
<ins id="htmlvar00018">
|
||||
<body onload="onLoad()">
|
||||
<li contenteditable>
|
||||
<shadow>
|
||||
<ins>
|
||||
<option>
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
<script>
|
||||
function go() {
|
||||
document.getElementById("label1").addEventListener("DOMNodeRemoved", () => {
|
||||
document.getElementById("a1").innerText = "";
|
||||
function onLoad() {
|
||||
const label = document.querySelector("label");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <label> which is the last child of the <body>, i.e., at the comment node.
|
||||
getSelection().collapse(label, label.childNodes.length);
|
||||
label.addEventListener("DOMNodeRemoved", () => {
|
||||
document.querySelector("a").innerText = "";
|
||||
});
|
||||
document.execCommand("indent", false);
|
||||
document.execCommand("indent");
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<li contenteditable="">
|
||||
<a id="a1">
|
||||
<label id="label1"></br>
|
||||
<body onload="onLoad()">
|
||||
<li contenteditable>
|
||||
<a>
|
||||
<label></br>
|
||||
<!---
|
||||
|
|
|
@ -1,15 +1,24 @@
|
|||
<script>
|
||||
function go() {
|
||||
svgvar00002.addEventListener("DOMNodeInserted", () => {
|
||||
svg.appendChild(svgvar00008);
|
||||
function onLoad() {
|
||||
const svg = document.querySelector("svg");
|
||||
const feConvolveMatrix = document.querySelectorAll("feConvolveMatrix");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// last <svg> which is the deepest last child of the <body> (i.e., at the
|
||||
// text node after the last <feConvolveMatrix>).
|
||||
getSelection().collapse(svg, svg.childNodes.length);
|
||||
feConvolveMatrix[0].addEventListener("DOMNodeInserted", () => {
|
||||
svg.appendChild(feConvolveMatrix[1]);
|
||||
document.execCommand("insertOrderedList", false);
|
||||
});
|
||||
svgvar00002.insertAdjacentHTML("afterBegin", table.outerHTML);
|
||||
feConvolveMatrix[0].insertAdjacentHTML(
|
||||
"afterBegin",
|
||||
document.querySelector("table").outerHTML
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<table id="table"></table>
|
||||
<b contenteditable="true">
|
||||
<svg id="svg">
|
||||
<feConvolveMatrix id="svgvar00002"/>
|
||||
<feConvolveMatrix id="svgvar00008"/>
|
||||
<body onload="onLoad()">
|
||||
<table></table>
|
||||
<b contenteditable>
|
||||
<svg>
|
||||
<feConvolveMatrix/>
|
||||
<feConvolveMatrix/>
|
||||
|
|
|
@ -1,29 +1,49 @@
|
|||
<script>
|
||||
function go() {
|
||||
let selection = window.getSelection();
|
||||
selection.setPosition(htmlvar00007, 1);
|
||||
selection.setBaseAndExtent(htmlvar00011, 0, htmlvar00043, 0);
|
||||
svgvar00014.before(svgvar00008.previousElementSibling);
|
||||
function onLoad() {
|
||||
const feComponentTransfer = document.querySelector("feComponentTransfer");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <feComponentTransfer> which is the deepest last child of the <body>.
|
||||
getSelection().collapse(
|
||||
feComponentTransfer,
|
||||
feComponentTransfer.childNodes.length
|
||||
);
|
||||
getSelection().setPosition(
|
||||
document.querySelector("pre[contenteditable]"),
|
||||
1
|
||||
);
|
||||
getSelection().setBaseAndExtent(
|
||||
document.querySelector("fieldset"),
|
||||
0,
|
||||
document.querySelector("use"),
|
||||
0
|
||||
);
|
||||
feComponentTransfer.before(
|
||||
document.querySelector("font-face-uri").previousElementSibling
|
||||
);
|
||||
|
||||
document.execCommand("removeFormat", false);
|
||||
document.execCommand("removeFormat");
|
||||
document.execCommand("hiliteColor", false, "-moz-buttondefault");
|
||||
document.execCommand("insertText", false, "");
|
||||
}
|
||||
function eh1() {
|
||||
svgvar00007.appendChild(htmlvar00011);
|
||||
htmlvar00003.appendChild(htmlvar00035);
|
||||
function onBegin() {
|
||||
document.querySelector("desc").appendChild(
|
||||
document.querySelector("fieldset")
|
||||
);
|
||||
document.querySelector("span").appendChild(
|
||||
document.querySelector("a[hidden][contenteditable]")
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<span id="htmlvar00003">
|
||||
<pre id="htmlvar00007" contenteditable="true">
|
||||
<fieldset id="htmlvar00011"></fieldset>
|
||||
<body onload="onLoad()">
|
||||
<span>
|
||||
<pre contenteditable>
|
||||
<fieldset></fieldset>
|
||||
<iframe srcdoc="H"></iframe>
|
||||
<a id="htmlvar00035" hidden="hidden" contenteditable="true">
|
||||
<a hidden contenteditable>
|
||||
<svg>
|
||||
<set onbegin="eh1()"/>
|
||||
<use id="htmlvar00043">
|
||||
<desc id="svgvar00007"></desc>
|
||||
<set onbegin="onBegin()"/>
|
||||
<use>
|
||||
<desc></desc>
|
||||
</use>
|
||||
<font-face-uri id="svgvar00008"/>
|
||||
<feComponentTransfer id="svgvar00014">
|
||||
<font-face-uri/>
|
||||
<feComponentTransfer>
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
<script>
|
||||
function go() {
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body>, i.e., at the text node after the <meter>.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
document.scrollingElement.addEventListener("DOMNodeInserted", () => {
|
||||
document.execCommand("selectAll", false);
|
||||
document.execCommand("insertOrderedList", false);
|
||||
document.execCommand("selectAll");
|
||||
document.execCommand("insertOrderedList");
|
||||
});
|
||||
a.appendChild(document.createElement("e"));
|
||||
document.querySelector("style").appendChild(
|
||||
document.createElement("e")
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<meter contenteditable="true">
|
||||
<body onload="onLoad()">
|
||||
<meter contenteditable>
|
||||
<dialog>
|
||||
<style id="a"></style>
|
||||
<style></style>
|
||||
</dialog>
|
||||
</meter>
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
<script>
|
||||
function go() {
|
||||
a.setAttribute("contenteditable", "true");
|
||||
b.addEventListener("DOMNodeRemoved", eh);
|
||||
b.appendChild(c);
|
||||
function onLoad() {
|
||||
const pre = document.querySelector("pre[contenteditable]");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <pre> which is the deepest last child of the <body>, i.e., at the text
|
||||
// node after the <input>.
|
||||
getSelection().collapse(pre, pre.childNodes.length);
|
||||
document.querySelector("li").setAttribute("contenteditable", "true");
|
||||
pre.addEventListener("DOMNodeRemoved", onDOMNodeRemoved);
|
||||
pre.appendChild(
|
||||
document.querySelector("input")
|
||||
);
|
||||
}
|
||||
function eh() {
|
||||
document.body.appendChild(b);
|
||||
document.execCommand("justifyFull", false);
|
||||
document.execCommand("delete", false);
|
||||
function onDOMNodeRemoved() {
|
||||
document.body.appendChild(
|
||||
document.querySelector("pre[contenteditable]")
|
||||
);
|
||||
document.execCommand("justifyFull");
|
||||
document.execCommand("delete");
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<li id="a">
|
||||
<body onload="onLoad()">
|
||||
<li>
|
||||
A
|
||||
<pre id="b" contenteditable="true">
|
||||
<input autofocus="autofocus" id="c">
|
||||
<pre contenteditable>
|
||||
<input autofocus>
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
input:focus { counter-increment: c; }
|
||||
</style>
|
||||
<script>
|
||||
function go() {
|
||||
a.select();
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body>, i.e., at the text node after the <input contenteditable>.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
document.querySelector("input[type=number][contenteditable]").select();
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<input id="a" type="number" contenteditable="true">
|
||||
<body onload="onLoad()">
|
||||
<input type="number" contenteditable>
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
<script>
|
||||
function go() {
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <dialog> which is the deepest last child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("dialog"),
|
||||
document.querySelector("dialog").childNodes.length
|
||||
);
|
||||
document.execCommand("insertImage", false, "o")
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<meter contenteditable="true">
|
||||
<body onload="onLoad()">
|
||||
<meter contenteditable>
|
||||
<dialog>
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
<script>
|
||||
var count = 0;
|
||||
|
||||
function go() {
|
||||
document.execCommand("delete", false);
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <s> which is the deepest last child (and a container) of the <body> (i.e.,
|
||||
// at the the text node after the last comment node).
|
||||
getSelection().collapse(
|
||||
document.querySelector("s"),
|
||||
document.querySelector("s").childNodes.length
|
||||
);
|
||||
document.execCommand("delete");
|
||||
}
|
||||
function eh() {
|
||||
count++;
|
||||
if (count >= 3) {
|
||||
|
||||
function onInputOrDOMNodeInserted() {
|
||||
if (++count >= 3) {
|
||||
return;
|
||||
}
|
||||
window.addEventListener("DOMNodeInserted", eh);
|
||||
document.execCommand("removeFormat", false);
|
||||
addEventListener("DOMNodeInserted", onInputOrDOMNodeInserted);
|
||||
document.execCommand("removeFormat");
|
||||
document.execCommand("insertText", false, "1");
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<ol oninput="eh()" contenteditable="true">
|
||||
<body onload="onLoad()">
|
||||
<ol oninput="onInputOrDOMNodeInserted()" contenteditable>
|
||||
<!-- x -->
|
||||
<s>
|
||||
<!-- x -->
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
<script>
|
||||
function go() {
|
||||
document.getSelection().setPosition(b);
|
||||
a.addEventListener("DOMNodeInserted", eh);
|
||||
function onLoad() {
|
||||
const dd = document.querySelector("dd[contenteditable]");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <dd contenteditable> which is the deepest last child of the <body> (at the
|
||||
// text node after the <template>).
|
||||
getSelection().collapse(dd, dd.childNodes.length);
|
||||
getSelection().setPosition(
|
||||
document.querySelector("template")
|
||||
);
|
||||
dd.addEventListener("DOMNodeInserted", () => {
|
||||
document.execCommand("selectAll");
|
||||
document.execCommand("insertText", false, "");
|
||||
});
|
||||
document.execCommand("insertImage", false, "#");
|
||||
}
|
||||
function eh() {
|
||||
document.execCommand("selectAll", false);
|
||||
document.execCommand("insertText", false, "");
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<dd id="a" contenteditable="true">
|
||||
<template id="b"></template>
|
||||
<body onload="onLoad()">
|
||||
<dd contenteditable>
|
||||
<template></template>
|
||||
|
|
|
@ -2,16 +2,21 @@
|
|||
abc
|
||||
<head>
|
||||
<script>
|
||||
function start() {
|
||||
document.execCommand('justifyleft', false, )
|
||||
document.designMode = 'on'
|
||||
document.execCommand('insertparagraph', false, )
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', start)
|
||||
</script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <em> which is the deepest last child of the <body> (at the comment node).
|
||||
getSelection().collapse(
|
||||
document.querySelector("em[contenteditable]"),
|
||||
document.querySelector("em[contenteditable]").childNodes.length
|
||||
);
|
||||
document.execCommand("justifyLeft");
|
||||
document.designMode = 'on';
|
||||
document.execCommand("insertParagraph");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<h4>
|
||||
<em contenteditable="">
|
||||
<em contenteditable>
|
||||
<big>
|
||||
<button autofocus formnovalidate formtarget="">
|
||||
</button>
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
<script>
|
||||
function go() {
|
||||
document.execCommand("styleWithCSS", false, true)
|
||||
document.execCommand("delete", false)
|
||||
a.addEventListener("DOMNodeRemoved", function() {
|
||||
var c = window.getSelection()
|
||||
var d = document.createRange()
|
||||
d.setEndAfter(b)
|
||||
c.addRange(d)
|
||||
c.deleteFromDocument()
|
||||
})
|
||||
document.execCommand("outdent", false)
|
||||
function onLoad() {
|
||||
const button = document.querySelector("button");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <button> which is the deepest last child of the <body>.
|
||||
getSelection().collapse(button, button.childNodes.length);
|
||||
document.execCommand("styleWithCSS", false, true);
|
||||
document.execCommand("delete");
|
||||
document.querySelector("ul[contenteditable]")
|
||||
.addEventListener("DOMNodeRemoved", () => {
|
||||
const range = document.createRange();
|
||||
range.setEndAfter(button);
|
||||
getSelection().addRange(range);
|
||||
getSelection().deleteFromDocument();
|
||||
});
|
||||
document.execCommand("outdent");
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<ul id="a" contenteditable="true" style="margin: -1px 0px 1px 6px">
|
||||
<body onload="onLoad()">
|
||||
<ul contenteditable style="margin: -1px 0px 1px 6px">
|
||||
<dd></dd>
|
||||
<dd>
|
||||
<button id="b">
|
||||
<button>
|
|
@ -1,14 +1,19 @@
|
|||
<script>
|
||||
function go() {
|
||||
document.execCommand("justifyFull", false)
|
||||
document.execCommand("selectAll", false)
|
||||
window.top.addEventListener("DOMNodeRemoved", eh)
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <dd contenteditable> which is the last child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("dd[contenteditable]"),
|
||||
document.querySelector("dd[contenteditable]").childNodes.length
|
||||
);
|
||||
document.execCommand("justifyFull");
|
||||
document.execCommand("selectAll");
|
||||
window.top.addEventListener("DOMNodeRemoved", () => {
|
||||
document.execCommand("insertHTML", false, undefined)
|
||||
});
|
||||
document.execCommand("heading", false, "H1")
|
||||
}
|
||||
function eh() {
|
||||
document.execCommand("insertHTML", false, undefined)
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<dd contenteditable="true">A
|
||||
<body onload="onLoad()">
|
||||
<dd contenteditable>A
|
||||
<!-- A -->
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function start () {
|
||||
const selection = window.getSelection()
|
||||
selection.setPosition(hr, 0)
|
||||
document.execCommand('delete', false)
|
||||
}
|
||||
</script>
|
||||
<body onload="start()">
|
||||
<p id="" hidden="">
|
||||
<canvas id="" contenteditable="">
|
||||
<hr id="hr" contenteditable="true">
|
||||
<script>
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body> (at the text node after the <p hidden>).
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
getSelection().setPosition(
|
||||
document.querySelector("hr"),
|
||||
0
|
||||
);
|
||||
document.execCommand("delete");
|
||||
}
|
||||
</script>
|
||||
<body onload="onLoad()">
|
||||
<p hidden>
|
||||
<canvas contenteditable>
|
||||
<hr contenteditable>
|
||||
3uW4*</hr></canvas>
|
||||
</p>
|
||||
</body>
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
<script>
|
||||
function go() {
|
||||
document.getSelection().selectAllChildren(a)
|
||||
document.execCommand("insertUnorderedList", false)
|
||||
document.execCommand("enableObjectResizing", false)
|
||||
function onError() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <dl> which is the last deepest child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("dl"),
|
||||
document.querySelector("dl").childNodes.length
|
||||
);
|
||||
getSelection().selectAllChildren(
|
||||
document.querySelector("img")
|
||||
);
|
||||
document.execCommand("insertUnorderedList");
|
||||
document.execCommand("enableObjectResizing");
|
||||
}
|
||||
</script>
|
||||
<dd contenteditable="true">
|
||||
<audio src="data:text/html,foo" onerror="go()">
|
||||
<img id="a"></img>
|
||||
<audio src="data:text/html,foo" onerror="onError()">
|
||||
<img></img>
|
||||
<dl>
|
||||
|
|
|
@ -3,10 +3,16 @@
|
|||
body { display: contents }
|
||||
</style>
|
||||
<script>
|
||||
function go() {
|
||||
document.execCommand("enableInlineTableEditing", false)
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <th> which is the deepest last child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("th"),
|
||||
document.querySelector("th").childNodes.length
|
||||
);
|
||||
document.execCommand("enableInlineTableEditing");
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<table contenteditable="true">
|
||||
<body onload="onLoad()">
|
||||
<table contenteditable>
|
||||
<th>
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
<script>
|
||||
function go() {
|
||||
b.appendChild(document.body.firstChild)
|
||||
document.getSelection().setBaseAndExtent(c.appendChild(b),0,b,1)
|
||||
a.addEventListener("DOMCharacterDataModified", function() {
|
||||
window.getSelection().removeAllRanges()
|
||||
})
|
||||
document.execCommand("delete", false)
|
||||
function onLoad() {
|
||||
const data = document.querySelector("data");
|
||||
const source = document.querySelector("source");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <data> which is the deepest last child (and a container) of the <body>.
|
||||
getSelection().collapse(data, data.childNodes.length);
|
||||
source.appendChild(
|
||||
document.body.firstChild // The invisible text node
|
||||
);
|
||||
getSelection().setBaseAndExtent(
|
||||
data.appendChild(source),
|
||||
0,
|
||||
source,
|
||||
1
|
||||
);
|
||||
document.querySelector("audio")
|
||||
.addEventListener("DOMCharacterDataModified", () => {
|
||||
getSelection().removeAllRanges()
|
||||
});
|
||||
document.execCommand("delete");
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<audio id="a">
|
||||
<li contenteditable="true">
|
||||
<data id="c">
|
||||
<source id="b">
|
||||
<body onload="onLoad()">
|
||||
<audio>
|
||||
<li contenteditable>
|
||||
<data>
|
||||
<source>
|
||||
|
|
|
@ -1,19 +1,40 @@
|
|||
<html id="a"><script type="text/javascript" id="__gaOptOutExtension">window["_gaUserPrefs"] = { ioo : function() { return true; } }</script><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=windows-1252"><script>
|
||||
function go() {
|
||||
b.addEventListener("DOMCharacterDataModified", () => {
|
||||
a.appendChild(b)
|
||||
})
|
||||
document.execCommand("delete", false)
|
||||
<html><script>
|
||||
window["_gaUserPrefs"] = { ioo : function() { return true; } }
|
||||
</script><head>
|
||||
<meta charset="windows-1252"><script>
|
||||
function onLoad() {
|
||||
const form = document.querySelector("form");
|
||||
form.addEventListener("DOMCharacterDataModified", () => {
|
||||
document.documentElement.appendChild(form);
|
||||
});
|
||||
document.execCommand("delete");
|
||||
}
|
||||
function eh() {
|
||||
b.reset()
|
||||
|
||||
function onToggle() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <button> which is the deepest last child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("button"),
|
||||
document.querySelector("button").childNodes.length
|
||||
);
|
||||
document.querySelector("form").reset();
|
||||
}
|
||||
</script>
|
||||
</head><body onload="go()">
|
||||
<details ontoggle="eh()" open="">
|
||||
<dt contenteditable="">
|
||||
</head><body onload="onLoad()">
|
||||
<details ontoggle="onToggle()" open>
|
||||
<dt contenteditable>
|
||||
</dt>
|
||||
</details><aside style="position: fixed; top: 0px; right: 0px; font-family: "Lucida Console", monospace; background-color: rgb(242, 230, 217); padding: 3px; z-index: 10000; text-align: center; max-width: 120px; opacity: 0; transition: opacity 0.5s linear 0s;">1194 x 73</aside></body><form id="b"><keygen>
|
||||
<button autofocus="">
|
||||
</details><aside style="
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
font-family: "Lucida Console", monospace;
|
||||
background-color: rgb(242, 230, 217);
|
||||
padding: 3px;
|
||||
z-index: 10000;
|
||||
text-align: center;
|
||||
max-width: 120px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s linear 0s;">1194 x 73</aside></body><form id="b"><keygen>
|
||||
<button autofocus>
|
||||
</button></form></html>
|
|
@ -1,11 +1,19 @@
|
|||
<script id="a">
|
||||
function go() {
|
||||
a.appendChild(b)
|
||||
document.execCommand("indent", false)
|
||||
document.execCommand("delete", false)
|
||||
<script>
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <textarea> which is the last child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("textarea"),
|
||||
document.querySelector("textarea").childNodes.length
|
||||
);
|
||||
document.querySelector("script").appendChild(
|
||||
document.querySelector("li[contenteditable=false]")
|
||||
);
|
||||
document.execCommand("indent");
|
||||
document.execCommand("delete");
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<ul contenteditable="true">
|
||||
<li id="b" contenteditable="false">
|
||||
<body onload="onLoad()">
|
||||
<ul contenteditable>
|
||||
<li contenteditable="false">
|
||||
<textarea autofocus>
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
<script>
|
||||
window.onload = () => {
|
||||
a.addEventListener("DOMNodeRemoved", () => {
|
||||
document.getSelection().collapse(document.getElementById(""))
|
||||
})
|
||||
document.execCommand("delete", false)
|
||||
}
|
||||
addEventListener("load", () => {
|
||||
const editingHost = document.querySelector("div[contenteditable]");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <div contenteditable> which is the last child of the <body>.
|
||||
getSelection().collapse(editingHost, editingHost.childNodes.length);
|
||||
editingHost.addEventListener("DOMNodeRemoved", () => {
|
||||
getSelection().collapse(null);
|
||||
});
|
||||
document.execCommand("delete");
|
||||
});
|
||||
</script>
|
||||
<div id="a" contenteditable>x</link>
|
||||
<div contenteditable>x</link>
|
|
@ -1,17 +1,20 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const br = document.getElementById('id_29')
|
||||
br.contentEditable = true
|
||||
document.execCommand('indent', false, null)
|
||||
})
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const code = document.querySelector("code[contenteditable=false]");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <code> which is the last inline container of the <body>.
|
||||
getSelection().collapse(code, code.childNodes.length);
|
||||
code.querySelector("br").contentEditable = true;
|
||||
document.execCommand("indent");
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<b class='' contenteditable='true' hidden>
|
||||
<script class=''></script>
|
||||
<code class='' contenteditable='false'>
|
||||
<br class='' id='id_29'>
|
||||
<b contenteditable hidden>
|
||||
<script></script>
|
||||
<code contenteditable="false">
|
||||
<br>
|
||||
</body>
|
||||
</head>
|
||||
</html>
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
window.addEventListener('load', () => {
|
||||
const el_0 = document.createElement('a')
|
||||
const el_1 = document.createElement('b')
|
||||
const el_2 = document.createElement('c')
|
||||
document.documentElement.appendChild(el_0)
|
||||
el_0.appendChild(el_1)
|
||||
el_1.setAttribute('contenteditable', 'true')
|
||||
el_1.appendChild(el_2)
|
||||
el_2.outerHTML = '<s contenteditable=\'false\'><b contenteditable=\'true\'>'
|
||||
const selection = self.getSelection()
|
||||
selection.setBaseAndExtent(document, 0, document.documentElement, 0)
|
||||
const range = selection.getRangeAt((260523900 % selection.rangeCount))
|
||||
selection.selectAllChildren(el_1)
|
||||
range.collapse(false)
|
||||
range.setEndAfter(document.documentElement)
|
||||
range.extractContents()
|
||||
})
|
||||
</script>
|
||||
<script>
|
||||
addEventListener("load", () => {
|
||||
const anchor = document.createElement("a");
|
||||
const b = document.createElement("b");
|
||||
const c = document.createElement("c");
|
||||
document.documentElement.appendChild(anchor);
|
||||
anchor.appendChild(b);
|
||||
b.setAttribute("contenteditable", "true");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body> which must be empty because this test appends the new elements after
|
||||
// the <body>.
|
||||
const selection = self.getSelection();
|
||||
selection.collapse(document.body, document.body.childNodes.length);
|
||||
b.appendChild(c);
|
||||
c.outerHTML = '<s contenteditable="false"><b contenteditable="true">';
|
||||
selection.setBaseAndExtent(document, 0, document.documentElement, 0);
|
||||
const range = selection.getRangeAt((260523900 % selection.rangeCount));
|
||||
selection.selectAllChildren(b);
|
||||
range.collapse(false);
|
||||
range.setEndAfter(document.documentElement);
|
||||
range.extractContents();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
<script>
|
||||
window.onload = () => {
|
||||
document.execCommand("undo", false)
|
||||
document.execCommand("undo");
|
||||
}
|
||||
function go() {
|
||||
var a = document.getElementById("a")
|
||||
document.execCommand("delete", false)
|
||||
b.contentDocument.adoptNode(a)
|
||||
function onToggle() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body> (at the text node after the <iframe>).
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
const link = document.querySelector("link");
|
||||
document.execCommand("delete");
|
||||
document.querySelector("iframe").contentDocument.adoptNode(link);
|
||||
}
|
||||
</script>
|
||||
<p contenteditable="true">
|
||||
<link id="a" item="">
|
||||
<details open="" ontoggle="go()">
|
||||
<iframe id="b"></iframe>
|
||||
<p contenteditable>
|
||||
<link item="">
|
||||
<details open ontoggle="onToggle()">
|
||||
<iframe></iframe>
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<div contenteditable> a</div>
|
||||
<script>
|
||||
let editor = document.querySelector("div[contenteditable]");
|
||||
editor.insertBefore(document.createTextNode(""), editor.firstChild);
|
||||
let selection = getSelection();
|
||||
selection.collapse(editor.firstChild.nextSibling, 2);
|
||||
document.execCommand("delete", false);
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body>, i.e., at the text node after this <script>.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
const editingHost = document.querySelector("div[contenteditable]");
|
||||
editingHost.insertBefore(document.createTextNode(""), editingHost.firstChild);
|
||||
getSelection().collapse(editingHost.firstChild.nextSibling, 2);
|
||||
document.execCommand("delete");
|
||||
</script>
|
|
@ -1,7 +1,10 @@
|
|||
<!doctype html>
|
||||
<div contenteditable>abc<span></span><span></span></div>
|
||||
<script>
|
||||
let editor = document.querySelector("div[contenteditable]");
|
||||
getSelection().collapse(editor, 3);
|
||||
document.execCommand("inserttext", false, " ");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body>, i.e., at the text node after this <script>.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
const editingHost = document.querySelector("div[contenteditable]");
|
||||
getSelection().collapse(editingHost, 3);
|
||||
document.execCommand("insertText", false, " ");
|
||||
</script>
|
||||
|
|
|
@ -1,19 +1,29 @@
|
|||
<script>
|
||||
window.addEventListener('load', () => {
|
||||
const map = document.getElementById('id_2')
|
||||
const anchor = document.getElementById('id_9')
|
||||
map.replaceChild(anchor, map.childNodes[(2828994049 % map.childNodes.length)])
|
||||
anchor.innerHTML = '<o>'
|
||||
const selection = self.getSelection()
|
||||
selection.setBaseAndExtent(document, (2019424593 % document.childNodes.length), document.documentElement, (3503355750 % document.documentElement.childNodes.length))
|
||||
document.designMode = 'on'
|
||||
document.execCommand('forwardDelete', false, null)
|
||||
document.execCommand('forwardDelete', false, null)
|
||||
})
|
||||
window.addEventListener('load', () => {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body> (at the comment node).
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
const map = document.querySelector("map");
|
||||
const anchor = document.querySelector("a");
|
||||
map.replaceChild(
|
||||
anchor,
|
||||
map.childNodes[(2828994049 % map.childNodes.length)]
|
||||
);
|
||||
anchor.innerHTML = "<o>";
|
||||
getSelection().setBaseAndExtent(
|
||||
document,
|
||||
(2019424593 % document.childNodes.length),
|
||||
document.documentElement,
|
||||
(3503355750 % document.documentElement.childNodes.length)
|
||||
);
|
||||
document.designMode = "on";
|
||||
document.execCommand("forwardDelete");
|
||||
document.execCommand("forwardDelete");
|
||||
});
|
||||
</script>
|
||||
<sub contenteditable='true'>
|
||||
<map id='id_2'>
|
||||
<sub contenteditable>
|
||||
<map>
|
||||
<address></address>
|
||||
<a id='id_9'>
|
||||
<a>
|
||||
</a>
|
||||
<!-- COMMENT -->
|
|
@ -1,27 +1,30 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
let node
|
||||
const textarea = document.getElementById('id_14')
|
||||
const abbr = document.getElementById('id_9')
|
||||
document.addEventListener('DOMAttrModified', (e) => {
|
||||
node = e.originalTarget.getRootNode({})
|
||||
abbr.insertBefore(textarea, abbr.childNodes[0])
|
||||
}, false)
|
||||
abbr.contentEditable = false
|
||||
node.normalize()
|
||||
document.designMode = 'on'
|
||||
document.execCommand('insertParagraph', false, null)
|
||||
})
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body> (at the text node after the <h3>).
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
const textarea = document.querySelector("textarea");
|
||||
const abbr = document.querySelector("abbr");
|
||||
let node;
|
||||
document.addEventListener("DOMAttrModified", event => {
|
||||
node = event.originalTarget.getRootNode({});
|
||||
abbr.insertBefore(textarea, abbr.childNodes[0]);
|
||||
}, false);
|
||||
abbr.contentEditable = false;
|
||||
node.normalize();
|
||||
document.designMode = "on";
|
||||
document.execCommand("insertParagraph");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<dfn contenteditable='true'>
|
||||
<abbr id='id_9'></abbr>
|
||||
<dfn contenteditable>
|
||||
<abbr></abbr>
|
||||
</dfn>
|
||||
<h3>
|
||||
<textarea id='id_14' autofocus></textarea>
|
||||
<textarea autofocus></textarea>
|
||||
<script></script>
|
||||
</h3>
|
||||
</body>
|
||||
|
|
|
@ -1,21 +1,24 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const element_0 = document.getElementById('id_0')
|
||||
const element_1 = document.getElementById('id_1')
|
||||
element_1.after('foo')
|
||||
element_0.addEventListener('DOMAttrModified', () => {
|
||||
window.find('foo')
|
||||
document.execCommand('insertImage', false, '#')
|
||||
})
|
||||
element_0.setAttribute('i', '')
|
||||
})
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body> (at the text node after the <feDistantLight>).
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
const feDistantLight = document.querySelector("feDistantLight");
|
||||
const li = document.querySelector("li");
|
||||
li.after('foo');
|
||||
feDistantLight.addEventListener("DOMAttrModified", () => {
|
||||
window.find("foo");
|
||||
document.execCommand("insertImage", false, "#");
|
||||
})
|
||||
feDistantLight.setAttribute("i", "");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<feDistantLight id="id_0" contenteditable="true">
|
||||
<li id="id_1">A</li>
|
||||
<feDistantLight contenteditable>
|
||||
<li>A</li>
|
||||
<!-- COMMENT -->
|
||||
</feDistantLight>
|
||||
</body>
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
<script>
|
||||
window.onload = () => {
|
||||
document.execCommand("insertHorizontalRule", false)
|
||||
window.getSelection().collapse(b)
|
||||
document.execCommand("forwardDelete", false)
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <body> (at the text node after the <input>).
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
document.execCommand("insertHorizontalRule");
|
||||
getSelection().collapse(
|
||||
document.querySelector("b")
|
||||
);
|
||||
document.execCommand("forwardDelete");
|
||||
}
|
||||
function go() {
|
||||
document.getSelection().setPosition(a)
|
||||
function onFocusChangeOfInput() {
|
||||
document.getSelection().setPosition(document.querySelector("pre"));
|
||||
}
|
||||
</script>
|
||||
<pre id="a">
|
||||
<pre>
|
||||
<time contenteditable>a|</t>
|
||||
<input id="b" onfocus="go()" autofocus onblur="go()">
|
||||
<input onfocus="onFocusChangeOfInput()" autofocus onblur="onFocusChangeOfInput()">
|
||||
|
|
|
@ -1,19 +1,28 @@
|
|||
<script>
|
||||
function func_a() {
|
||||
a.appendChild(b)
|
||||
document.execCommand("indent", false)
|
||||
function onError() {
|
||||
document.querySelector("details").appendChild(
|
||||
document.querySelector("p")
|
||||
);
|
||||
document.execCommand("indent");
|
||||
}
|
||||
function func_b() {
|
||||
document.execCommand("delete", false)
|
||||
a.contentEditable = "true"
|
||||
c.select()
|
||||
|
||||
function onLoadOfStyle() {
|
||||
document.execCommand("delete");
|
||||
document.querySelector("details").contentEditable = "true";
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <style>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("style"),
|
||||
document.querySelector("style").childNodes.length
|
||||
);
|
||||
document.querySelector("input").select();
|
||||
}
|
||||
</script>
|
||||
<video focus="false">
|
||||
<source onerror="func_a()">
|
||||
<source onerror="onError()">
|
||||
</video>
|
||||
<details id="a" open="tru">
|
||||
<p id="b">
|
||||
<input id="c" contenteditable="pla">
|
||||
<style onload="func_b()">
|
||||
<details open>
|
||||
<p>
|
||||
<input contenteditable="false">
|
||||
<style onload="onLoadOfStyle()">
|
||||
<!-- x -->
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const table = document.getElementById('id_39')
|
||||
const paragraph = document.getElementById('id_41')
|
||||
document.documentElement.contentEditable = true
|
||||
const selection = document.getSelection()
|
||||
selection.setBaseAndExtent(document, 0, document.documentElement, 1)
|
||||
paragraph.contentEditable = false
|
||||
table.insertRow(0)
|
||||
document.execCommand('forwardDelete', false, null)
|
||||
})
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const table = document.querySelector("table");
|
||||
// For emulating traditional behavior, collapse Selection to end of the
|
||||
// <table>.
|
||||
getSelection().collapse(table, table.childNodes.length);
|
||||
const paragraph = document.querySelector("p");
|
||||
document.documentElement.contentEditable = true;
|
||||
getSelection().setBaseAndExtent(document, 0, document.documentElement, 1);
|
||||
paragraph.contentEditable = false;
|
||||
table.insertRow(0);
|
||||
document.execCommand("forwardDelete");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<p id='id_41'>
|
||||
<p>
|
||||
<del>
|
||||
<button contenteditable='true'>
|
||||
<button contenteditable>
|
||||
</button>
|
||||
<table id='id_39'>
|
||||
<table>
|
||||
</table>
|
||||
</del>
|
||||
</p>
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
<script>
|
||||
window.onload = () => {
|
||||
b.style.setProperty("text-decoration", "overline underline line-through")
|
||||
b.appendChild(a)
|
||||
document.execCommand("selectAll", false)
|
||||
window.getSelection().extend(b, 0)
|
||||
document.execCommand("underline", false)
|
||||
const font = document.querySelector("font");
|
||||
// For emulating traditional behavior, collapse Selection to end of the
|
||||
// <font>.
|
||||
getSelection().collapse(font, font.childNodes.length);
|
||||
const meta = document.querySelector("meta");
|
||||
meta.style.setProperty(
|
||||
"text-decoration",
|
||||
"overline underline line-through"
|
||||
);
|
||||
meta.appendChild(font);
|
||||
document.execCommand("selectAll");
|
||||
getSelection().extend(meta, 0);
|
||||
document.execCommand("underline");
|
||||
}
|
||||
</script>
|
||||
<ins contenteditable="true">
|
||||
<ins contenteditable>
|
||||
a
|
||||
<meta id="b"></meta>
|
||||
<font id="a">
|
||||
<meta></meta>
|
||||
<font>
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
|
||||
function boom()
|
||||
{
|
||||
document.getElementsByTagName("td")[0].contentEditable = "true";
|
||||
document.getElementsByTagName("td")[0].focus();
|
||||
function onLoad() {
|
||||
document.querySelector("td").contentEditable = "true";
|
||||
getSelection().collapse(
|
||||
document.querySelector("td"),
|
||||
document.querySelector("td").childNodes.length
|
||||
);
|
||||
document.querySelector("td").focus();
|
||||
document.documentElement.contentEditable = "true";
|
||||
document.documentElement.focus();
|
||||
document.execCommand("indent", false, null);
|
||||
document.execCommand("insertParagraph", false, null);
|
||||
document.execCommand("indent");
|
||||
document.execCommand("insertParagraph");
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom();" contenteditable="false"><td></td></body>
|
||||
<body onload="onLoad();" contenteditable="false"><td></td></body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
<head contenteditable="true">
|
||||
<script type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
function boom()
|
||||
{
|
||||
var r = document.createRange();
|
||||
function onLoad() {
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
const r = document.createRange();
|
||||
r.selectNode(document.body);
|
||||
r.deleteContents();
|
||||
try { document.execCommand("selectAll", false, null); } catch(e) { }
|
||||
try {
|
||||
document.execCommand("selectAll");
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom();" contenteditable="true"></body>
|
||||
<body onload="onLoad();" contenteditable="true"></body>
|
||||
</html>
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml"><head><script>
|
||||
<![CDATA[
|
||||
|
||||
function boom()
|
||||
{
|
||||
document.execCommand("selectAll", false, null);
|
||||
document.execCommand("selectAll", false, null);
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <textarea> which is the deepest last child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("textarea"),
|
||||
document.querySelector("textarea").childNodes.length
|
||||
);
|
||||
document.execCommand("selectAll");
|
||||
document.execCommand("selectAll");
|
||||
document.execCommand("inserthtml", false, "<span><div>");
|
||||
var textarea = document.getElementById("textarea");
|
||||
var span = document.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||
textarea.appendChild(span);
|
||||
const span = document.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||
document.querySelector("textarea").appendChild(span);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script></head><div contenteditable="true"></div><body onload="boom();"><textarea id="textarea">f</textarea></body></html>
|
||||
</script></head><div contenteditable="true"></div><body onload="onLoad();"><textarea>f</textarea></body></html>
|
||||
|
|
|
@ -1,35 +1,67 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
|
||||
<body><div contenteditable="true"></div><div><input id="i"><div></div></input></div></body>
|
||||
<body><div contenteditable="true"></div><div><input><div></div></input></div></body>
|
||||
|
||||
<script id="s">
|
||||
<script>
|
||||
<![CDATA[
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// parent <div> of the <input>. In XHTML document, the <input> may have the
|
||||
// <div> child. Therefore, the deepest last child container element of the
|
||||
// <body> is the parent of the <input>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("input").parentElement,
|
||||
document.querySelector("input").parentElement.childNodes.length
|
||||
);
|
||||
document.querySelector("input").focus();
|
||||
|
||||
function boom()
|
||||
{
|
||||
document.getElementById("i").focus();
|
||||
try {
|
||||
document.execCommand("stylewithcss", false, "true");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("inserthtml", false, "<x>X</x>");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("underline");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("justifyfull");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("underline");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("insertParagraph");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("delete");
|
||||
} catch(e) {}
|
||||
|
||||
try { document.execCommand("stylewithcss", false, "true") } catch(e) { }
|
||||
try { document.execCommand("inserthtml", false, "<x>X</x>"); } catch(e) { }
|
||||
try { document.execCommand("underline", false, null); } catch(e) { }
|
||||
try { document.execCommand("justifyfull", false, null); } catch(e) { }
|
||||
try { document.execCommand("underline", false, null); } catch(e) { }
|
||||
try { document.execCommand("insertParagraph", false, null); } catch(e) { }
|
||||
try { document.execCommand("delete", false, null); } catch(e) { }
|
||||
|
||||
try { document.execCommand("stylewithcss", false, "false") } catch(e) { }
|
||||
try { document.execCommand("inserthtml", false, "<x>X</x>"); } catch(e) { }
|
||||
try { document.execCommand("underline", false, null); } catch(e) { }
|
||||
try { document.execCommand("justifyfull", false, null); } catch(e) { }
|
||||
try { document.execCommand("underline", false, null); } catch(e) { }
|
||||
try { document.execCommand("insertParagraph", false, null); } catch(e) { }
|
||||
try { document.execCommand("delete", false, null); } catch(e) { }
|
||||
try {
|
||||
document.execCommand("stylewithcss", false, "false");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("inserthtml", false, "<x>X</x>");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("underline");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("justifyfull");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("underline");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("insertParagraph");
|
||||
} catch(e) {}
|
||||
try {
|
||||
document.execCommand("delete");
|
||||
} catch(e) {}
|
||||
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
setTimeout(boom, 10);
|
||||
|
||||
addEventListener("load", onLoad);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
try { document.execCommand("removeformat", false, null); } catch(e) { }
|
||||
function onLoad() {
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// <td> which is the deepest last child of the <body>.
|
||||
getSelection().collapse(
|
||||
document.querySelector("td"),
|
||||
document.querySelector("td").childNodes.length
|
||||
);
|
||||
try {
|
||||
document.execCommand("removeformat");
|
||||
} catch(e) {}
|
||||
document.adoptNode(document.documentElement);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();"><td contenteditable="true" /></body>
|
||||
<body onload="onLoad();"><td contenteditable="true"/></body>
|
||||
</html>
|
||||
|
|
|
@ -2,19 +2,20 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
window.getSelection().removeAllRanges();
|
||||
var r = document.createRange();
|
||||
r.setStart(document.getElementById("x"), 1);
|
||||
r.setEnd(document.getElementById("y"), 0);
|
||||
window.getSelection().addRange(r);
|
||||
document.execCommand("insertorderedlist", false, null);
|
||||
function onLoad() {
|
||||
const editingHost = document.querySelectorAll("div[contenteditable]");
|
||||
// For emulating the traditional behavior, collapse Selection to end of the
|
||||
// last <div contenteditable> which is the deepest last child of the <body>.
|
||||
getSelection().collapse(editingHost[1], editingHost[1].childNodes.length);
|
||||
getSelection().removeAllRanges();
|
||||
const r = document.createRange();
|
||||
r.setStart(editingHost[0], 1);
|
||||
r.setEnd(editingHost[1], 0);
|
||||
getSelection().addRange(r);
|
||||
document.execCommand("insertOrderedList");
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom();"><div id="x" contenteditable="true">a</div><div id="y" contenteditable="true"></div></body>
|
||||
<body onload="onLoad();"><div contenteditable>a</div><div contenteditable></div></body>
|
||||
</html>
|
||||
|
|
|
@ -37,23 +37,25 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1268736
|
|||
|
||||
function getEditor() {
|
||||
const Ci = SpecialPowers.Ci;
|
||||
var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
|
||||
const editingSession = SpecialPowers.wrap(window).docShell.editingSession;
|
||||
return editingSession.getEditorForWindow(window).QueryInterface(Ci.nsITableEditor);
|
||||
}
|
||||
|
||||
var table = document.getElementById("table");
|
||||
var tableHTML = table.innerHTML;
|
||||
var editor = getEditor();
|
||||
const table = document.getElementById("table");
|
||||
const tableHTML = table.innerHTML;
|
||||
const editor = getEditor();
|
||||
|
||||
var cell = document.getElementById("cell_readonly");
|
||||
cell.focus();
|
||||
editor.deleteTableCellContents();
|
||||
const readOnlyCell = document.getElementById("cell_readonly");
|
||||
readOnlyCell.focus();
|
||||
try {
|
||||
editor.deleteTableCellContents();
|
||||
} catch (e) {}
|
||||
is(table.innerHTML == tableHTML, true, "editor should not modify non-editable table cell" );
|
||||
|
||||
cell = document.getElementById("cell_writable");
|
||||
cell.focus();
|
||||
const editableCell = document.getElementById("cell_writable");
|
||||
editableCell.focus();
|
||||
editor.deleteTableCellContents();
|
||||
is(cell.innerHTML == "<br>", true, "editor can modify editable table cells" );
|
||||
is(editableCell.innerHTML == "<br>", true, "editor can modify editable table cells" );
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -85,10 +85,7 @@ SimpleTest.waitForFocus(() => {
|
|||
const otherEditor = document.getElementById("otherEditor");
|
||||
|
||||
(function test_initial_state_on_load() {
|
||||
// XXX if there is a contenteditable element, HTML editor sets dom selection
|
||||
// to first editable node, but this makes inconsistency with normal document
|
||||
// behavior.
|
||||
todo_is(
|
||||
is(
|
||||
getSelection().rangeCount,
|
||||
0,
|
||||
"There should be no selection range at start"
|
||||
|
|
|
@ -29,9 +29,7 @@
|
|||
if (done)
|
||||
return;
|
||||
try {
|
||||
var r = window.getSelection().getRangeAt(0);
|
||||
r.setStart(p.childNodes[0],14);
|
||||
r.setEnd(p.childNodes[0],14);
|
||||
getSelection().collapse(p.childNodes[0], 14);
|
||||
} catch (e) {}
|
||||
document.documentElement.removeAttribute('class');
|
||||
done = true;
|
||||
|
|
|
@ -28,9 +28,7 @@
|
|||
if (done)
|
||||
return;
|
||||
try {
|
||||
var r = window.getSelection().getRangeAt(0);
|
||||
r.setStart(p.childNodes[0],14);
|
||||
r.setEnd(p.childNodes[0],14);
|
||||
getSelection().collapse(p.childNodes[0], 14);
|
||||
} catch (e) {}
|
||||
document.documentElement.removeAttribute('class');
|
||||
done = true;
|
||||
|
|
|
@ -10,10 +10,14 @@
|
|||
</style>
|
||||
<script>
|
||||
window.onload = () => {
|
||||
document.execCommand("selectAll", false)
|
||||
document.execCommand("selectAll", false)
|
||||
document.execCommand("backColor", false, "r")
|
||||
document.execCommand("superscript", false)
|
||||
getSelection().collapse(
|
||||
document.querySelector("dl"),
|
||||
document.querySelector("dl").childNodes.length
|
||||
);
|
||||
document.execCommand("selectAll");
|
||||
document.execCommand("selectAll");
|
||||
document.execCommand("backColor", false, "r");
|
||||
document.execCommand("superscript");
|
||||
}
|
||||
</script>
|
||||
<dl style="columns:1px">
|
||||
|
|
|
@ -80,7 +80,11 @@ alert(e+'\n'+elm.id+'\n'+t)
|
|||
}
|
||||
}
|
||||
function selectText() {
|
||||
var divs = document.getElementsByTagName('div');
|
||||
// For putting selection ranges to multiple editing hosts, we need to put
|
||||
// a range outside all editable elements first, then, selection's ancestor
|
||||
// limiter won't be set to an editing host.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
var divs = document.getElementsByTagName('div');
|
||||
for (i = 0; i < divs.length; ++i) {
|
||||
addRange(divs[i]);
|
||||
}
|
||||
|
|
|
@ -82,7 +82,11 @@ alert(e+'\n'+elm.id+'\n'+t)
|
|||
}
|
||||
}
|
||||
function selectText() {
|
||||
var divs = document.getElementsByTagName('div');
|
||||
// For putting selection ranges to multiple editing hosts, we need to put
|
||||
// a range outside all editable elements first, then, selection's ancestor
|
||||
// limiter won't be set to an editing host.
|
||||
getSelection().collapse(document.body, document.body.childNodes.length);
|
||||
var divs = document.getElementsByTagName('div');
|
||||
for (i = 0; i < divs.length; ++i) {
|
||||
addRange(divs[i]);
|
||||
}
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[selection-contenteditable-011.html]
|
||||
expected: FAIL
|
|
@ -1,5 +1,4 @@
|
|||
[forced-colors-mode-43.html]
|
||||
expected:
|
||||
if (os == "mac") and debug: [FAIL, PASS]
|
||||
if os == "android": PASS
|
||||
[PASS, FAIL]
|
||||
|
|
Загрузка…
Ссылка в новой задаче