189 lines
8.4 KiB
HTML
189 lines
8.4 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="timeout" content="long">
|
|
<title>Testing contenteditable=plaintext-only which is nested with contenteditable=true</title>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/resources/testdriver.js"></script>
|
|
<script src="/resources/testdriver-vendor.js"></script>
|
|
<script src="/resources/testdriver-actions.js"></script>
|
|
<script src="../include/editor-test-utils.js"></script>
|
|
<script>
|
|
"use strict";
|
|
|
|
addEventListener("load", () => {
|
|
const editingHost = document.createElement("div");
|
|
editingHost.setAttribute("contenteditable", "");
|
|
document.body.appendChild(editingHost);
|
|
editingHost.focus();
|
|
const utils = new EditorTestUtils(editingHost);
|
|
for (const trueOrEmpty of ["", "true"]) {
|
|
for (const explicitlySetFocus of [false, true]) {
|
|
for (const data of [
|
|
{
|
|
desc: `contenteditable="plaintext-only" in contenteditable="${trueOrEmpty}" should support style edit`,
|
|
init: `<div contenteditable="plaintext-only">[abc]</div>`,
|
|
run: function () {
|
|
document.execCommand("bold");
|
|
},
|
|
expected: `<div contenteditable="plaintext-only"><b>abc</b></div>`
|
|
},
|
|
{
|
|
desc: `contenteditable="plaintext-only" in contenteditable="${
|
|
trueOrEmpty
|
|
}" and contenteditable="false" should not support style edit`,
|
|
init: `<div contenteditable="false"><div contenteditable="plaintext-only">[abc]</div></div>`,
|
|
run: function () {
|
|
document.execCommand("bold");
|
|
},
|
|
expected: `<div contenteditable="false"><div contenteditable="plaintext-only">abc</div></div>`,
|
|
},
|
|
{
|
|
desc: `contenteditable="plaintext-only" in contenteditable="${trueOrEmpty}" should insert paragraph at typing Enter`,
|
|
init: `<div contenteditable="plaintext-only"><p>a[b]c</p></div>`,
|
|
run: function () {
|
|
return utils.sendEnterKey();
|
|
},
|
|
expected: `<div contenteditable="plaintext-only"><p>a</p><p>c</p></div>`
|
|
},
|
|
{
|
|
desc: `contenteditable="plaintext-only" in contenteditable="${
|
|
trueOrEmpty
|
|
}" and contenteditable="false" should insert line break at typing Enter`,
|
|
init: `<div contenteditable="false"><div contenteditable="plaintext-only"><p>a[b]c</p></div></div>`,
|
|
run: function () {
|
|
return utils.sendEnterKey();
|
|
},
|
|
expected: `<div contenteditable="false"><div contenteditable="plaintext-only"><p>a<br>c</p></div></div>`,
|
|
},
|
|
{
|
|
desc: `styling start boundary of contenteditable="plaintext-only" in contenteditable="${
|
|
trueOrEmpty
|
|
}" should apply the style to entire the range`,
|
|
init: `A[B<div contenteditable="plaintext-only">C]D</div>EF`,
|
|
run: function () {
|
|
document.execCommand("bold");
|
|
},
|
|
expected: `A<b>B</b><div contenteditable="plaintext-only"><b>C</b>D</div>EF`,
|
|
},
|
|
{
|
|
desc: `styling end boundary of contenteditable="plaintext-only" in contenteditable="${
|
|
trueOrEmpty
|
|
}" should apply the style to entire the range`,
|
|
init: `AB<div contenteditable="plaintext-only">C[D</div>E]F`,
|
|
run: function () {
|
|
document.execCommand("bold");
|
|
},
|
|
expected: `AB<div contenteditable="plaintext-only">C<b>D</b></div><b>E</b>F`,
|
|
},
|
|
{
|
|
desc: `even after moving selection into contenteditable="plaintext-only" in contenteditable="${
|
|
trueOrEmpty
|
|
}" and contenteditable="false" from parent editing host should not support style edit`,
|
|
init: `A[]B<div contenteditable="false"><div contenteditable="plaintext-only">CD</div></div>EF`,
|
|
run: function () {
|
|
getSelection().selectAllChildren(editingHost.querySelector("div[contenteditable=plaintext-only]"));
|
|
document.execCommand("bold");
|
|
},
|
|
expected: `AB<div contenteditable="false"><div contenteditable="plaintext-only">CD</div></div>EF`,
|
|
},
|
|
]) {
|
|
promise_test(async () => {
|
|
editingHost.setAttribute("contenteditable", trueOrEmpty);
|
|
utils.setupEditingHost(data.init);
|
|
if (explicitlySetFocus) {
|
|
editingHost.querySelector("[contenteditable=plaintext-only]").focus();
|
|
}
|
|
await data.run();
|
|
assert_equals(editingHost.outerHTML, `<div contenteditable="${trueOrEmpty}">${data.expected}</div>`);
|
|
}, data.desc + (explicitlySetFocus ? " (explicitly setting focus to the nested one)" : ""));
|
|
}
|
|
|
|
for (const data of [
|
|
{
|
|
desc: `contenteditable="${trueOrEmpty}" in contenteditable="plaintext-only" should not support style edit`,
|
|
init: `<div contenteditable="${trueOrEmpty}">[abc]</div>`,
|
|
run: function () {
|
|
document.execCommand("bold");
|
|
},
|
|
expected: `<div contenteditable="${trueOrEmpty}">abc</div>`
|
|
},
|
|
{
|
|
desc: `contenteditable="${
|
|
trueOrEmpty
|
|
}" in contenteditable="plaintext-only" and contenteditable="false" should support style edit`,
|
|
init: `<div contenteditable="false"><div contenteditable="${trueOrEmpty}">[abc]</div></div>`,
|
|
run: function () {
|
|
document.execCommand("bold");
|
|
},
|
|
expected: `<div contenteditable="false"><div contenteditable="${trueOrEmpty}"><b>abc</b></div></div>`,
|
|
},
|
|
{
|
|
desc: `contenteditable="${trueOrEmpty}" in contenteditable="plaintext-only" should insert line break at typing Enter`,
|
|
init: `<div contenteditable="${trueOrEmpty}"><p>a[b]c</p></div>`,
|
|
run: function () {
|
|
return utils.sendEnterKey();
|
|
},
|
|
expected: `<div contenteditable="${trueOrEmpty}"><p>a<br>c</p></div>`
|
|
},
|
|
{
|
|
desc: `contenteditable="${
|
|
trueOrEmpty
|
|
}" in contenteditable="plaintext-only" and contenteditable="false" should insert paragraph at typing Enter`,
|
|
init: `<div contenteditable="false"><div contenteditable="${trueOrEmpty}"><p>a[b]c</p></div></div>`,
|
|
run: function () {
|
|
return utils.sendEnterKey();
|
|
},
|
|
expected: `<div contenteditable="false"><div contenteditable="${trueOrEmpty}"><p>a</p><p>c</p></div></div>`,
|
|
},
|
|
{
|
|
desc: `styling start boundary of contenteditable="${
|
|
trueOrEmpty
|
|
}" in contenteditable="plaintext-only" should not apply the style`,
|
|
init: `A[B<div contenteditable="${trueOrEmpty}">C]D</div>EF`,
|
|
run: function () {
|
|
document.execCommand("bold");
|
|
},
|
|
expected: `AB<div contenteditable="${trueOrEmpty}">CD</div>EF`,
|
|
},
|
|
{
|
|
desc: `styling end boundary of contenteditable="${
|
|
trueOrEmpty
|
|
}" in contenteditable="plaintext-only" should not apply the style`,
|
|
init: `AB<div contenteditable="${trueOrEmpty}">C[D</div>E]F`,
|
|
run: function () {
|
|
document.execCommand("bold");
|
|
},
|
|
expected: `AB<div contenteditable="${trueOrEmpty}">CD</div>EF`,
|
|
},
|
|
{
|
|
desc: `even after moving selection into contenteditable="${
|
|
trueOrEmpty
|
|
}" in contenteditable="plaintext-only" and contenteditable="false" from parent editing host should support style edit`,
|
|
init: `A[]B<div contenteditable="false"><div contenteditable="${trueOrEmpty}">CD</div></div>EF`,
|
|
run: function () {
|
|
getSelection().selectAllChildren(editingHost.querySelector(`div[contenteditable="${trueOrEmpty}"]`));
|
|
document.execCommand("bold");
|
|
},
|
|
expected: `AB<div contenteditable="false"><div contenteditable="${trueOrEmpty}"><b>CD</b></div></div>EF`,
|
|
},
|
|
]) {
|
|
promise_test(async () => {
|
|
editingHost.setAttribute("contenteditable", "plaintext-only");
|
|
utils.setupEditingHost(data.init);
|
|
if (explicitlySetFocus) {
|
|
editingHost.querySelector(`[contenteditable='${trueOrEmpty}']`).focus();
|
|
}
|
|
await data.run();
|
|
assert_equals(editingHost.outerHTML, `<div contenteditable="plaintext-only">${data.expected}</div>`);
|
|
}, data.desc + (explicitlySetFocus ? " (explicitly setting focus to the nested one)" : ""));
|
|
}
|
|
}
|
|
}
|
|
}, {once: true});
|
|
</script>
|
|
</head>
|
|
<body></body>
|
|
</html>
|