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">
<meta name="variant" content="?white-space=normal">
<meta name="variant" content="?white-space=pre">
<meta name="variant" content="?white-space=pre-line">
<meta name="variant" content="?white-space=pre-wrap">
<title>Inserting a line break in plaintext-only</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";
const searchParams = new URLSearchParams(document.location.search);
const whiteSpace = searchParams.get("white-space");
const useBR = whiteSpace == "normal";
const collapseWhiteSpaces = whiteSpace == "normal" || whiteSpace == "pre-line";
const isSafari = navigator.platform.includes("Mac") &&
navigator.userAgent.includes("Safari") &&
!navigator.userAgent.includes("Chrome");
addEventListener("load", () => {
const editingHost = document.createElement("div");
editingHost.style.whiteSpace = whiteSpace;
editingHost.setAttribute("contenteditable", "plaintext-only");
document.body.appendChild(editingHost);
editingHost.focus();
editingHost.getBoundingClientRect();
const utils = new EditorTestUtils(editingHost);
let lastBeforeInputEvent;
editingHost.addEventListener("beforeinput", event => lastBeforeInputEvent = event);
for (const data of [
{
initialInnerHTML: "A[]B",
expected: useBR ? "A<br>B" : "A\nB",
},
{
initialInnerHTML: "<p>{}<br></p>",
expected: useBR ? "<p><br><br></p>" : "<p>\n\n</p>",
},
{
initialInnerHTML: `<p style="white-space:normal">A[]B</p>`,
expected: `<p style="white-space:normal">A<br>B</p>`,
},
{
initialInnerHTML: `<p style="white-space:pre">A[]B</p>`,
expected: [`<p style="white-space:pre">A<br>B</p>`, `<p style="white-space:pre">A\nB</p>`],
},
{
initialInnerHTML: `<p style="white-space:pre-line">A[]B</p>`,
expected: [`<p style="white-space:pre-line">A<br>B</p>`, `<p style="white-space:pre-line">A\nB</p>`],
},
{
initialInnerHTML: `<p style="white-space:pre-wrap">A[]B</p>`,
expected: [`<p style="white-space:pre-wrap">A<br>B</p>`, `<p style="white-space:pre-wrap">A\nB</p>`],
},
{
initialInnerHTML: "<ul><li>[]AB</li></ul>",
expected: useBR ? "<ul><li><br>AB</li></ul>" : "<ul><li>\nAB</li></ul>",
},
{
initialInnerHTML: "<ul><li>A[]B</li></ul>",
expected: useBR ? "<ul><li>A<br>B</li></ul>" : "<ul><li>A\nB</li></ul>",
},
{
initialInnerHTML: "<ul><li>AB[]</li></ul>",
expected: useBR
? "<ul><li>AB<br><br></li></ul>"
: "<ul><li>AB\n\n</li></ul>",
},
{
initialInnerHTML: "<dl><dt>[]AB</dt></dl>",
expected: useBR ? "<dl><dt><br>AB</dt></dl>" : "<dl><dt>\nAB</dt></dl>",
},
{
initialInnerHTML: "<dl><dt>A[]B</dt></dl>",
expected: useBR ? "<dl><dt>A<br>B</dt></dl>" : "<dl><dt>A\nB</dt></dl>",
},
{
initialInnerHTML: "<dl><dt>AB[]</dt></dl>",
expected: useBR
? "<dl><dt>AB<br><br></dt></dl>"
: "<dl><dt>AB\n\n</dt></dl>",
},
{
initialInnerHTML: "<dl><dd>[]AB</dd></dl>",
expected: useBR ? "<dl><dd><br>AB</dd></dl>" : "<dl><dd>\nAB</dd></dl>",
},
{
initialInnerHTML: "<dl><dd>A[]B</dd></dl>",
expected: useBR ? "<dl><dd>A<br>B</dd></dl>" : "<dl><dd>A\nB</dd></dl>",
},
{
initialInnerHTML: "<dl><dd>AB[]</dd></dl>",
expected: useBR
? "<dl><dd>AB<br><br></dd></dl>"
: "<dl><dd>AB\n\n</dd></dl>",
},
{
initialInnerHTML: "<table><tbody><tr><td>[]AB</td></tr></tbody></table>",
expected: useBR
? "<table><tbody><tr><td><br>AB</td></tr></tbody></table>"
: "<table><tbody><tr><td>\nAB</td></tr></tbody></table>",
},
{
initialInnerHTML: "<table><tbody><tr><td>A[]B</td></tr></tbody></table>",
expected: useBR
? "<table><tbody><tr><td>A<br>B</td></tr></tbody></table>"
: "<table><tbody><tr><td>A\nB</td></tr></tbody></table>",
},
{
initialInnerHTML: "<table><tbody><tr><td>AB[]</td></tr></tbody></table>",
expected: useBR
? "<table><tbody><tr><td>AB<br><br></td></tr></tbody></table>"
: "<table><tbody><tr><td>AB\n\n</td></tr></tbody></table>",
},
{
initialInnerHTML: "<h1>[]AB</h1>",
expected: useBR ? "<h1><br>AB</h1>" : "<h1>\nAB</h1>",
},
{
initialInnerHTML: "<h1>A[]B</h1>",
expected: useBR ? "<h1>A<br>B</h1>" : "<h1>A\nB</h1>",
},
{
initialInnerHTML: "<h1>AB[]</h1>",
expected: useBR ? "<h1>AB<br><br></h1>" : "<h1>AB\n\n</h1>",
},
]) {
test(() => {
utils.setupEditingHost(data.initialInnerHTML);
document.execCommand("insertLineBreak");
if (Array.isArray(data.expected)) {
assert_in_array(editingHost.innerHTML, data.expected);
} else {
assert_equals(editingHost.innerHTML, data.expected);
}
}, `execCommand("insertLineBreak") when ${data.initialInnerHTML}`);
promise_test(async t => {
utils.setupEditingHost(data.initialInnerHTML);
lastBeforeInputEvent = undefined;
await utils.sendEnterKey();
test(() => {
assert_equals(
lastBeforeInputEvent?.inputType,
"insertLineBreak",
`inputType should be "insertLineBreak"`
);
}, `${t.name}: beforeinput`);
test(() => {
if (Array.isArray(data.expected)) {
assert_in_array(editingHost.innerHTML, data.expected);
} else {
assert_equals(editingHost.innerHTML, data.expected);
}
}, `${t.name}: editingHost.innerHTML`);
}, `Pressing Enter when ${
data.initialInnerHTML
} should cause "insertLineBreak" and shouldn't insert new paragraph`);
promise_test(async t => {
utils.setupEditingHost(data.initialInnerHTML);
lastBeforeInputEvent = undefined;
await utils.sendEnterKey(isSafari ? utils.kControl : utils.kShift);
test(() => {
assert_equals(
lastBeforeInputEvent?.inputType,
"insertLineBreak",
`inputType should be "insertLineBreak"`
);
}, `${t.name}: beforeinput`);
test(() => {
if (Array.isArray(data.expected)) {
assert_in_array(editingHost.innerHTML, data.expected);
} else {
assert_equals(editingHost.innerHTML, data.expected);
}
}, `${t.name}: editingHost.innerHTML`);
}, `Pressing ${isSafari ? "Ctrl" : "Shift"}+Enter when ${
data.initialInnerHTML
} should cause "insertLineBreak" and shouldn't insert new paragraph`);
}
}, {once: true});
</script>
</head>
<body></body>
</html>