Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=normal&display=block&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=normal&display=block&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=normal&display=inline&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=normal&display=inline&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=normal&display=inline-block&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=normal&display=inline-block&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=normal&display=list-item&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=normal&display=list-item&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=normal&display=table-cell&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=normal&display=table-cell&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre&display=block&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre&display=block&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre&display=inline&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre&display=inline&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre&display=inline-block&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre&display=inline-block&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre&display=list-item&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre&display=list-item&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre&display=table-cell&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre&display=table-cell&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-line&display=block&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-line&display=block&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-line&display=inline&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-line&display=inline&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-line&display=inline-block&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-line&display=inline-block&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-line&display=list-item&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-line&display=list-item&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-line&display=table-cell&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-line&display=table-cell&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-wrap&display=block&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-wrap&display=block&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-wrap&display=inline&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-wrap&display=inline&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-wrap&display=inline-block&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-wrap&display=inline-block&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-wrap&display=list-item&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-wrap&display=list-item&method=shift-enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-wrap&display=table-cell&method=enter - WPT Dashboard Interop Dashboard
- /editing/other/insertparagraph-in-inline-editing-host.tentative.html?white-space=pre-wrap&display=table-cell&method=shift-enter - WPT Dashboard Interop Dashboard
<!doctype html>
<meta chareset="utf-8">
<meta name="timeout" content="long">
<meta name="variant" content="?white-space=normal&display=inline&method=enter">
<meta name="variant" content="?white-space=normal&display=inline&method=shift-enter">
<meta name="variant" content="?white-space=normal&display=inline-block&method=enter">
<meta name="variant" content="?white-space=normal&display=inline-block&method=shift-enter">
<meta name="variant" content="?white-space=normal&display=block&method=enter">
<meta name="variant" content="?white-space=normal&display=block&method=shift-enter">
<meta name="variant" content="?white-space=normal&display=list-item&method=enter">
<meta name="variant" content="?white-space=normal&display=list-item&method=shift-enter">
<meta name="variant" content="?white-space=normal&display=table-cell&method=enter">
<meta name="variant" content="?white-space=normal&display=table-cell&method=shift-enter">
<meta name="variant" content="?white-space=pre&display=inline&method=enter">
<meta name="variant" content="?white-space=pre&display=inline&method=shift-enter">
<meta name="variant" content="?white-space=pre&display=inline-block&method=enter">
<meta name="variant" content="?white-space=pre&display=inline-block&method=shift-enter">
<meta name="variant" content="?white-space=pre&display=block&method=enter">
<meta name="variant" content="?white-space=pre&display=block&method=shift-enter">
<meta name="variant" content="?white-space=pre&display=list-item&method=enter">
<meta name="variant" content="?white-space=pre&display=list-item&method=shift-enter">
<meta name="variant" content="?white-space=pre&display=table-cell&method=enter">
<meta name="variant" content="?white-space=pre&display=table-cell&method=shift-enter">
<meta name="variant" content="?white-space=pre-line&display=inline&method=enter">
<meta name="variant" content="?white-space=pre-line&display=inline&method=shift-enter">
<meta name="variant" content="?white-space=pre-line&display=inline-block&method=enter">
<meta name="variant" content="?white-space=pre-line&display=inline-block&method=shift-enter">
<meta name="variant" content="?white-space=pre-line&display=block&method=enter">
<meta name="variant" content="?white-space=pre-line&display=block&method=shift-enter">
<meta name="variant" content="?white-space=pre-line&display=list-item&method=enter">
<meta name="variant" content="?white-space=pre-line&display=list-item&method=shift-enter">
<meta name="variant" content="?white-space=pre-line&display=table-cell&method=enter">
<meta name="variant" content="?white-space=pre-line&display=table-cell&method=shift-enter">
<meta name="variant" content="?white-space=pre-wrap&display=inline&method=enter">
<meta name="variant" content="?white-space=pre-wrap&display=inline&method=shift-enter">
<meta name="variant" content="?white-space=pre-wrap&display=inline-block&method=enter">
<meta name="variant" content="?white-space=pre-wrap&display=inline-block&method=shift-enter">
<meta name="variant" content="?white-space=pre-wrap&display=block&method=enter">
<meta name="variant" content="?white-space=pre-wrap&display=block&method=shift-enter">
<meta name="variant" content="?white-space=pre-wrap&display=list-item&method=enter">
<meta name="variant" content="?white-space=pre-wrap&display=list-item&method=shift-enter">
<meta name="variant" content="?white-space=pre-wrap&display=table-cell&method=enter">
<meta name="variant" content="?white-space=pre-wrap&display=table-cell&method=shift-enter">
<title>Line breaking in inline editing host</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>
<div><span contenteditable></span></div>
<script>
"use strict";
const searchParams = new URLSearchParams(document.location.search);
const testingInsertParagraph = searchParams.get("method") == "enter";
const whiteSpace = searchParams.get("white-space");
const display = searchParams.get("display");
const isPreformatted =
whiteSpace == "pre" || whiteSpace == "pre-line" || whiteSpace == "pre-wrap";
const editingHost = document.querySelector("span[contenteditable]");
const container = editingHost.parentElement;
const utils = new EditorTestUtils(editingHost);
const modifiers = (() => {
if (testingInsertParagraph) {
return null;
}
// Only Safari treats `Ctrl+Enter` as insertLineBreak
if (navigator.platform.includes("Mac") &&
navigator.userAgent.includes("Safari") &&
!navigator.userAgent.includes("Chrom")) {
return utils.kControl;
}
// The others including WebKitGTK treat `Shift+Enter` as it.
return utils.kShift;
})();
for (const defaultParagraphSeparator of ["div", "p"]) {
document.execCommand(
"defaultParagraphSeparator",
false,
defaultParagraphSeparator
);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
utils.setupEditingHost("{}");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
// In this case, the inserting line break is the last visible thing in the
// block. Therefore, additional <br> or a preformatted linefeed is also
// required to make the new line visible.
if (!isPreformatted) {
assert_equals(
container.innerHTML,
'<span contenteditable=""><br><br></span>',
`A <br> and additional <br> should be inserted when ${t.name}`
);
} else {
assert_in_array(
container.innerHTML,
[
'<span contenteditable="">\n<br></span>',
'<span contenteditable="">\n\n</span>',
],
`A linefeed and additional line breaker should be inserted when ${t.name}`
);
}
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${whiteSpace}">{}</span> (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
const brElement = document.createElement("br");
try {
container.appendChild(brElement);
utils.setupEditingHost("{}");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
// Even if the <span> element is followed by an invisible <br>, it does
// not make the new line in the <span> element visible. Therefore,
// inserting additional line break is required in this case too.
if (!isPreformatted) {
assert_equals(
container.innerHTML,
'<span contenteditable=""><br><br></span><br>',
`A <br> and additional <br> should be inserted when ${t.name}`
);
} else {
assert_in_array(
container.innerHTML,
[
`<span contenteditable="">\n\n</span><br>`,
`<span contenteditable="">\n<br></span><br>`,
],
`A linefeed and additional line break should be inserted when ${t.name}`
);
}
} finally {
brElement.remove();
}
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${
whiteSpace
}">{}</span> followed by a <br> (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
const divElement = document.createElement("div");
divElement.textContent = "efg";
try {
container.appendChild(divElement);
utils.setupEditingHost("{}");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
// When the <span> element is followed by a <div>, making empty last
// line visible requires an invisible <br> after a line break.
if (!isPreformatted) {
assert_equals(
container.innerHTML,
'<span contenteditable=""><br><br></span><div>efg</div>',
`A <br> and additional <br> should be inserted when ${t.name}`
);
} else {
assert_in_array(
container.innerHTML,
[
`<span contenteditable="">\n\n</span><div>efg</div>`,
`<span contenteditable="">\n<br></span><div>efg</div>`,
],
`A linefeed and additional line break should be inserted when ${t.name}`
);
}
} finally {
divElement.remove();
}
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${
whiteSpace
}">{}</span> followed by a <div> (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
const text = document.createTextNode("abc");
try {
container.appendChild(text);
utils.setupEditingHost("{}");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
// Even if the <span> element is followed by visible text, it does
// not make the new line in the <span> element visible. Therefore,
// inserting additional line break is required in this case too.
if (!isPreformatted) {
assert_equals(
container.innerHTML,
'<span contenteditable=""><br><br></span>abc',
`A <br> and additional <br> should be inserted when ${t.name}`
);
} else {
assert_in_array(
container.innerHTML,
[
`<span contenteditable="">\n\n</span>abc`,
`<span contenteditable="">\n<br></span>abc`,
],
`A linefeed and additional line break should be inserted when ${t.name}`
);
}
} finally {
text.remove();
}
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${
whiteSpace
}">{}</span> followed by text (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
utils.setupEditingHost("{}<br>");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
// In this case, there is a <br> element which makes the new line (last
// line) visible. Therefore, only a line break should be inserted.
if (!isPreformatted) {
assert_equals(
container.innerHTML,
`<span contenteditable=""><br><br></span>`,
`A <br> should be inserted when ${t.name}`
);
} else {
assert_equals(
container.innerHTML,
`<span contenteditable="">\n<br></span>`,
`A <br> should be inserted when ${t.name}`
);
}
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${whiteSpace}">{}<br></span> (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
utils.setupEditingHost("[]abcd");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
assert_equals(
container.innerHTML,
`<span contenteditable="">${
isPreformatted ? "\n" : "<br>"
}abcd</span>`,
`${
isPreformatted ? "A linefeed" : "A <br>"
} should be inserted when ${t.name}`
);
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${whiteSpace}">[]abcd</span> (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
utils.setupEditingHost("ab[]cd");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
assert_equals(
container.innerHTML,
`<span contenteditable="">ab${
isPreformatted ? "\n" : "<br>"
}cd</span>`,
`${
isPreformatted ? "A linefeed" : "A <br>"
} should be inserted when ${t.name}`
);
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${whiteSpace}">ab[]cd</span> (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
utils.setupEditingHost("abcd[]");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
// In this case, the inserting line break is the last visible thing in the
// block. Therefore, additional line break is also required to make the
// new line visible.
if (!isPreformatted) {
assert_equals(
container.innerHTML,
`<span contenteditable="">abcd<br><br></span>`,
`A <br> and additional <br> should be inserted when ${t.name}`
);
} else {
assert_in_array(
container.innerHTML,
[
`<span contenteditable="">abcd\n<br></span>`,
`<span contenteditable="">abcd\n\n</span>`,
],
`A linefeed and additional line break should be inserted when ${t.name}`
);
}
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${whiteSpace}">abcd[]</span> (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
const brElement = document.createElement("br");
try {
container.appendChild(brElement);
utils.setupEditingHost("abcd[]");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
// Even if the <span> element is followed by an invisible <br>, it does
// not make the new line in the <span> element visible. Therefore,
// inserting additional line break is required in this case too.
if (!isPreformatted) {
assert_equals(
container.innerHTML,
'<span contenteditable="">abcd<br><br></span><br>',
`A <br> and additional <br> should be inserted when ${t.name}`
);
} else {
assert_in_array(
container.innerHTML,
[
`<span contenteditable="">abcd\n<br></span><br>`,
`<span contenteditable="">abcd\n\n</span><br>`,
],
`A linefeed and additional line break should be inserted when ${t.name}`
);
}
} finally {
brElement.remove();
}
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${
whiteSpace
}">abcd[]</span> followed by a <br> element (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
const divElement = document.createElement("div");
divElement.textContent = "efg";
try {
container.appendChild(divElement);
utils.setupEditingHost("abcd[]");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
// When the <span> element is followed by a <div>, making empty last
// line visible requires an invisible <br> after a line break.
if (!isPreformatted) {
assert_equals(
container.innerHTML,
'<span contenteditable="">abcd<br><br></span><div>efg</div>',
`A <br> and additional <br> should be inserted when ${t.name}`
);
} else {
assert_in_array(
container.innerHTML,
[
`<span contenteditable="">abcd\n<br></span><div>efg</div>`,
`<span contenteditable="">abcd\n\n</span><div>efg</div>`,
],
`A linefeed and additional line break should be inserted when ${t.name}`
);
}
} finally {
divElement.remove();
}
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${
whiteSpace
}">abcd[]</span> followed by a <div> element (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
promise_test(async t => {
editingHost.setAttribute(
"style",
`display:${display};white-space:${whiteSpace}`
);
const text = document.createTextNode("efg");
try {
container.appendChild(text);
utils.setupEditingHost("abcd[]");
await utils.sendEnterKey(modifiers);
editingHost.removeAttribute("style");
// Even if the <span> element is followed by visible text, it does
// not make the new line in the <span> element visible. Therefore,
// inserting additional line break is required in this case too.
if (!isPreformatted) {
assert_equals(
container.innerHTML,
'<span contenteditable="">abcd<br><br></span>efg',
`A <br> and additional <br> should be inserted when ${t.name}`
);
} else {
assert_in_array(
container.innerHTML,
[
`<span contenteditable="">abcd\n<br></span>efg`,
`<span contenteditable="">abcd\n\n</span>efg`,
],
`A linefeed and additional line break should be inserted when ${t.name}`
);
}
} finally {
text.remove();
}
}, `${
testingInsertParagraph ? "insertParagraph" : "insertLineBreak"
} in <span contenteditable style="display:${
display
};white-space:${
whiteSpace
}">abcd[]</span> followed by text (defaultParagraphSeparator=${
defaultParagraphSeparator
})`);
}
</script>