Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!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>