summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/editing/other/join-pre-and-other-block.html
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/editing/other/join-pre-and-other-block.html')
-rw-r--r--testing/web-platform/tests/editing/other/join-pre-and-other-block.html329
1 files changed, 329 insertions, 0 deletions
diff --git a/testing/web-platform/tests/editing/other/join-pre-and-other-block.html b/testing/web-platform/tests/editing/other/join-pre-and-other-block.html
new file mode 100644
index 0000000000..39e455a848
--- /dev/null
+++ b/testing/web-platform/tests/editing/other/join-pre-and-other-block.html
@@ -0,0 +1,329 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<meta name="variant" content="?method=backspace&block=div">
+<meta name="variant" content="?method=backspace&block=p">
+<meta name="variant" content="?method=backspace&block=blockquote">
+<meta name="variant" content="?method=forwarddelete&block=div">
+<meta name="variant" content="?method=forwarddelete&block=p">
+<meta name="variant" content="?method=forwarddelete&block=blockquote">
+<meta name="variant" content="?method=select-boundary&block=div">
+<meta name="variant" content="?method=select-boundary&block=p">
+<meta name="variant" content="?method=select-boundary&block=blockquote">
+<title>Tests for joining pre and other block element</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>
+</head>
+<body>
+<div contenteditable></div>
+<script>
+"use strict";
+
+const searchParams = new URLSearchParams(document.location.search);
+const testingBackspace = searchParams.get("method") == "backspace";
+const testingSelectBoundary = searchParams.get("method") == "select-boundary";
+const commandName =
+ testingBackspace || testingSelectBoundary ? "delete" : "forwarddelete";
+const editingHost = document.querySelector("div[contenteditable]");
+const caretInLeft = (() => {
+ if (testingSelectBoundary) {
+ return "[";
+ }
+ return testingBackspace ? "" : "[]";
+})();
+const caretInRight = (() => {
+ if (testingSelectBoundary) {
+ return "]";
+ }
+ return testingBackspace ? "[]" : "";
+})();
+const tag = searchParams.get("block");
+
+// These expectations are odd because they don't preserve white-space style
+// coming from another element. However, this is traditional behavior so that
+// browsers should not change the behavior.
+const tests = [
+ {
+ initialHTML:
+ `<pre>abc${caretInLeft}</pre>` +
+ `<${tag}>${caretInRight}def</${tag}>`,
+ expectedHTML: [
+ "<pre>abcdef</pre>",
+ ],
+ },
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre>${caretInRight}def</pre>`,
+ expectedHTML: [
+ `<${tag}>abcdef</${tag}>`,
+ ],
+ expectedHTMLWithStyledPre: [
+ `<${tag}>abc<span style="white-space:pre">def</span></${tag}>`,
+ ],
+ },
+ {
+ initialHTML:
+ `<pre>abc${caretInLeft}</pre>` +
+ `<${tag}>${caretInRight}def<br>ghi</${tag}>`,
+ expectedHTML: [
+ `<pre>abcdef</pre>` +
+ `<${tag}>ghi</${tag}>`,
+ ],
+ },
+ {
+ initialHTML:
+ `<pre>abc${caretInLeft}</pre>` +
+ `<${tag}>${caretInRight}def<div>ghi</div></${tag}>`,
+ expectedHTML: [
+ "<pre>abcdef</pre>" +
+ `<${tag}><div>ghi</div></${tag}>`,
+ ],
+ skip: tag == "p",
+ },
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre>${caretInRight}def\nghi</pre>`,
+ expectedHTML: [
+ `<${tag}>abcdef</${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ expectedHTMLWithStyledPre: [
+ `<${tag}>abc<span style="white-space:pre">def</span></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ },
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre>${caretInRight}def<br>ghi</pre>`,
+ expectedHTML: [
+ `<${tag}>abcdef</${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ expectedHTMLWithStyledPre: [
+ `<${tag}>abc<span style="white-space:pre">def</span></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ },
+ {
+ initialHTML:
+ `<pre>abc${caretInLeft}</pre>` +
+ `<${tag}><b>${caretInRight}def</b></${tag}>`,
+ expectedHTML: [
+ "<pre>abc<b>def</b></pre>",
+ ],
+ },
+ {
+ initialHTML:
+ `<pre>abc${caretInLeft}</pre>` +
+ `<${tag}><b>${caretInRight}def<br>ghi</b></${tag}>`,
+ expectedHTML: [
+ "<pre>abc<b>def</b></pre>" +
+ `<${tag}><b>ghi</b></${tag}>`,
+ ],
+ },
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre><b>${caretInRight}def\nghi</b></pre>`,
+ expectedHTML: [
+ `<${tag}>abc<b>def</b></${tag}>` +
+ "<pre><b>ghi</b></pre>",
+ ],
+ expectedHTMLWithStyledPre: [
+ `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` +
+ "<pre><b>ghi</b></pre>",
+ `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` +
+ "<pre><b>ghi</b></pre>",
+ ],
+ },
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre><b>${caretInRight}def<br>ghi</b></pre>`,
+ expectedHTML: [
+ `<${tag}>abc<b>def</b></${tag}>` +
+ "<pre><b>ghi</b></pre>",
+ ],
+ expectedHTMLWithStyledPre: [
+ `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` +
+ "<pre><b>ghi</b></pre>",
+ `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` +
+ "<pre><b>ghi</b></pre>",
+ ],
+ },
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre><b>${caretInRight}def</b>\nghi</pre>`,
+ expectedHTML: [
+ `<${tag}>abc<b>def</b></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ expectedHTMLWithStyledPre: [
+ `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` +
+ "<pre>ghi</pre>",
+ `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ },
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre><b>${caretInRight}def</b><br>ghi</pre>`,
+ expectedHTML: [
+ `<${tag}>abc<b>def</b></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ expectedHTMLWithStyledPre: [
+ `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` +
+ "<pre>ghi</pre>",
+ `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ },
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre><b>${caretInRight}def\n</b>ghi</pre>`,
+ expectedHTML: [
+ `<${tag}>abc<b>def</b></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ expectedHTMLWithStyledPre: [
+ `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` +
+ `<pre>ghi</pre>`,
+ `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ },
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre><b>${caretInRight}def<br></b>ghi</pre>`,
+ expectedHTML: [
+ `<${tag}>abc<b>def</b></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ expectedHTMLWithStyledPre: [
+ `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` +
+ "<pre>ghi</pre>",
+ `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ },
+ // One linefeed at start of <pre> should be ignored.
+ // Note that if setupEditingHost() does not touch the text node in <pre>,
+ // the leading line break is ignored, but if it touches the text node,
+ // the value is set to as-is. Therefore, the following tests can work
+ // with empty caretInRight value.
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre>\ndef\nghi</pre>`,
+ expectedHTML: [
+ `<${tag}>abcdef</${tag}>` +
+ `<pre>ghi</pre>`,
+ ],
+ expectedHTMLWithStyledPre: [
+ `<${tag}>abc<span style="white-space:pre">def</span></${tag}>` +
+ "<pre>ghi</pre>",
+ ],
+ skip: caretInRight !== "",
+ },
+ // When there are two line breaks at start of <pre>, the first one should be
+ // ignored by the parser but the second one should make empty first line.
+ // Therefore, the first empty line should be removed.
+ {
+ initialHTML:
+ `<${tag}>abc${caretInLeft}</${tag}>` +
+ `<pre>\n\ndef\nghi</pre>`,
+ expectedHTML: [
+ `<${tag}>abc</${tag}>` +
+ "<pre>def\nghi</pre>",
+ ],
+ skip: caretInRight !== "",
+ },
+];
+const utils = new EditorTestUtils(editingHost);
+
+const betweenBlockAndPre = new RegExp(`</${tag}><pre>`);
+const betweenPreAndBlock = new RegExp(`</pre><${tag}>`);
+function putStyleElement() {
+ const styleElement = document.createElement("style");
+ styleElement.textContent = "pre { white-space: pre; }";
+ document.head.appendChild(styleElement);
+}
+
+for (const specifyPreStyle of [false, true]) {
+ for (const t of tests) {
+ if (t.skip) {
+ continue;
+ }
+ if (specifyPreStyle && !t.expectedHTMLWithStyledPre) {
+ continue;
+ }
+ promise_test(async () => {
+ if (specifyPreStyle) {
+ putStyleElement();
+ }
+ try {
+ utils.setupEditingHost(t.initialHTML);
+ await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey());
+ utils.normalizeStyleAttributeValues();
+ assert_in_array(
+ editingHost.innerHTML,
+ specifyPreStyle ? t.expectedHTMLWithStyledPre : t.expectedHTML,
+ `white-space should${
+ !specifyPreStyle ? " not" : ""
+ } be preserved by <span> elements`
+ );
+ } finally {
+ if (specifyPreStyle) {
+ document.querySelector("style")?.remove();
+ }
+ }
+ }, `${commandName} at ${t.initialHTML.replace(/\n/g, "\\n")}${
+ specifyPreStyle ? " (with <style>pre { white-space: pre; }</style>)" : ""
+ }`);
+
+ // Repeat same tests with inserting a line break between the paragraphs.
+ const initialHTMLWithLineBreak =
+ t.initialHTML
+ .replace(betweenBlockAndPre, `</${tag}>\n<pre>`)
+ .replace(betweenPreAndBlock, `</pre>\n<${tag}>`);
+ promise_test(async () => {
+ if (specifyPreStyle) {
+ putStyleElement();
+ }
+ try {
+ utils.setupEditingHost(initialHTMLWithLineBreak);
+ await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey());
+ utils.normalizeStyleAttributeValues();
+ assert_in_array(
+ editingHost.innerHTML,
+ specifyPreStyle ? t.expectedHTMLWithStyledPre : t.expectedHTML,
+ `white-space should${
+ !specifyPreStyle ? " not" : ""
+ } be preserved by <span> elements (testing with a line break between paragraphs)`
+ );
+ } finally {
+ if (specifyPreStyle) {
+ document.querySelector("style")?.remove();
+ }
+ }
+ }, `${commandName} at ${initialHTMLWithLineBreak.replace(/\n/g, "\\n")}${
+ specifyPreStyle ? " (with <style>pre { white-space: pre; }</style>)" : ""
+ }`);
+ }
+}
+</script>
+</body>
+</html>