522 lines
17 KiB
HTML
522 lines
17 KiB
HTML
<!doctype html>
|
|
<meta chareset="utf-8">
|
|
<meta name="timeout" content="long">
|
|
<title>Cloning attributes at splitting an element in contenteditable</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 contenteditable></div>
|
|
<script>
|
|
"use strict";
|
|
|
|
document.execCommand("defaultParagraphSeparator", false, "div");
|
|
const utils =
|
|
new EditorTestUtils(document.querySelector("div[contenteditable]"));
|
|
|
|
// DO NOT USE multi-line comment in this file, then, you can comment out
|
|
// unnecessary tests when you need to attach the browser with a debugger.
|
|
|
|
// When an element is being split, all attributes except id attribute should be
|
|
// cloned to the new element.
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<div id="splittee">abc[]def</div>`);
|
|
const splittee = document.getElementById("splittee");
|
|
await utils.sendEnterKey();
|
|
test(() => {
|
|
assert_equals(
|
|
document.getElementById("splittee"),
|
|
splittee,
|
|
`The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
document.querySelectorAll("[id=splittee]").length,
|
|
1,
|
|
`The new element created by splitting an element shouldn't have same id attribute value (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <div id=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<div class="splittee">abc[]def</div>`);
|
|
await utils.sendEnterKey();
|
|
const leftNode = utils.editingHost.querySelector("div");
|
|
const rightNode = utils.editingHost.querySelector("div + div");
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("class"),
|
|
"splittee",
|
|
`The left element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("class"),
|
|
"splittee",
|
|
`The right element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <div class=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<div data-foo="1" data-bar="2">abc[]def</div>`);
|
|
await utils.sendEnterKey();
|
|
const leftNode = utils.editingHost.querySelector("div");
|
|
const rightNode = utils.editingHost.querySelector("div + div");
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("data-foo"),
|
|
"1",
|
|
`The left element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
leftNode.getAttribute("data-bar"),
|
|
"2",
|
|
`The left element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("data-foo"),
|
|
"1",
|
|
`The right element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
rightNode.getAttribute("data-bar"),
|
|
"2",
|
|
`The right element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <div data-foo=\"1\" data-bar=\"2\">");
|
|
|
|
// Same tests for list items since browsers may use different path to handle
|
|
// splitting a list item.
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<ul><li id="splittee">abc[]def</li></ul>`);
|
|
const splittee = document.getElementById("splittee");
|
|
await utils.sendEnterKey();
|
|
test(() => {
|
|
assert_equals(
|
|
document.getElementById("splittee"),
|
|
splittee,
|
|
`The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
document.querySelectorAll("[id=splittee]").length,
|
|
1,
|
|
`The new element created by splitting an element shouldn't have same id attribute value (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <li id=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<ul><li class="splittee">abc[]def</li></ul>`);
|
|
await utils.sendEnterKey();
|
|
const leftNode = utils.editingHost.querySelector("li");
|
|
const rightNode = utils.editingHost.querySelector("li + li");
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("class"),
|
|
"splittee",
|
|
`The left element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("class"),
|
|
"splittee",
|
|
`The right element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <li class=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<ul><li data-foo="1" data-bar="2">abc[]def</li></ul>`);
|
|
await utils.sendEnterKey();
|
|
const leftNode = utils.editingHost.querySelector("li");
|
|
const rightNode = utils.editingHost.querySelector("li + li");
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("data-foo"),
|
|
"1",
|
|
`The left element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
leftNode.getAttribute("data-bar"),
|
|
"2",
|
|
`The left element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("data-foo"),
|
|
"1",
|
|
`The right element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
rightNode.getAttribute("data-bar"),
|
|
"2",
|
|
`The right element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <li data-foo=\"1\" data-bar=\"2\">");
|
|
|
|
// Same tests for heading since browsers may use different path to handle
|
|
// splitting a heading element.
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<h3 id="p">abc[]def</h3>`);
|
|
const splittee = document.getElementById("splittee");
|
|
await utils.sendEnterKey();
|
|
test(() => {
|
|
assert_equals(
|
|
document.getElementById("splittee"),
|
|
splittee,
|
|
`The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
document.querySelectorAll("[id=p]").length,
|
|
1,
|
|
`The new element created by splitting an element shouldn't have same id attribute value (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <h3 id=\"p\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<h3 class="splittee">abc[]def</h3>`);
|
|
await utils.sendEnterKey();
|
|
const leftNode = utils.editingHost.querySelector("h3");
|
|
const rightNode = leftNode.nextSibling;
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("class"),
|
|
"splittee",
|
|
`The left element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("class"),
|
|
"splittee",
|
|
`The right element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <h3 class=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<h3 data-foo="1" data-bar="2">abc[]def</h3>`);
|
|
await utils.sendEnterKey();
|
|
const leftNode = utils.editingHost.querySelector("h3");
|
|
const rightNode = leftNode.nextSibling;
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("data-foo"),
|
|
"1",
|
|
`The left element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
leftNode.getAttribute("data-bar"),
|
|
"2",
|
|
`The left element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("data-foo"),
|
|
"1",
|
|
`The right element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
rightNode.getAttribute("data-bar"),
|
|
"2",
|
|
`The right element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <h3 data-foo=\"1\" data-bar=\"2\">");
|
|
|
|
// Same tests for <dt> since browsers may use different path to handle
|
|
// splitting a <dt>.
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<dl><dt id="splittee">abc[]def</dt></dl>`);
|
|
const splittee = document.getElementById("splittee");
|
|
await utils.sendEnterKey();
|
|
test(() => {
|
|
assert_equals(
|
|
document.getElementById("splittee"),
|
|
splittee,
|
|
`The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
document.querySelectorAll("[id=splittee]").length,
|
|
1,
|
|
`The new element created by splitting an element shouldn't have same id attribute value (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <dt id=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<dl><dt class="splittee">abc[]def</dt></dl>`);
|
|
await utils.sendEnterKey();
|
|
const leftNode = utils.editingHost.querySelector("dt");
|
|
const rightNode = leftNode.nextSibling;
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("class"),
|
|
"splittee",
|
|
`The left element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("class"),
|
|
"splittee",
|
|
`The right element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <dt class=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<dl><dt data-foo="1" data-bar="2">abc[]def</dt></dl>`);
|
|
await utils.sendEnterKey();
|
|
const leftNode = utils.editingHost.querySelector("dt");
|
|
const rightNode = leftNode.nextSibling;
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("data-foo"),
|
|
"1",
|
|
`The left element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
leftNode.getAttribute("data-bar"),
|
|
"2",
|
|
`The left element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("data-foo"),
|
|
"1",
|
|
`The right element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
rightNode.getAttribute("data-bar"),
|
|
"2",
|
|
`The right element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <dt data-foo=\"1\" data-bar=\"2\">");
|
|
|
|
// Same tests for <dd> since browsers may use different path to handle
|
|
// splitting a <dd>.
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<dl><dd id="splittee">abc[]def</dd></dl>`);
|
|
const splittee = document.getElementById("splittee");
|
|
await utils.sendEnterKey();
|
|
test(() => {
|
|
assert_equals(
|
|
document.getElementById("splittee"),
|
|
splittee,
|
|
`The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
document.querySelectorAll("[id=splittee]").length,
|
|
1,
|
|
`The new element created by splitting an element shouldn't have same id attribute value (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <dd id=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<dl><dd class="splittee">abc[]def</dd></dl>`);
|
|
await utils.sendEnterKey();
|
|
const leftNode = utils.editingHost.querySelector("dd");
|
|
const rightNode = leftNode.nextSibling;
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("class"),
|
|
"splittee",
|
|
`The left element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("class"),
|
|
"splittee",
|
|
`The right element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <dd class=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<dl><dd data-foo="1" data-bar="2">abc[]def</dd></dl>`);
|
|
await utils.sendEnterKey();
|
|
const leftNode = utils.editingHost.querySelector("dd");
|
|
const rightNode = leftNode.nextSibling;
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("data-foo"),
|
|
"1",
|
|
`The left element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
leftNode.getAttribute("data-bar"),
|
|
"2",
|
|
`The left element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("data-foo"),
|
|
"1",
|
|
`The right element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
rightNode.getAttribute("data-bar"),
|
|
"2",
|
|
`The right element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <dd data-foo=\"1\" data-bar=\"2\">");
|
|
|
|
// Same tests for inline elements.
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<div id="splittee-parent"><span id="splittee">abc[]def</span></div>`);
|
|
const splittee = document.getElementById("splittee");
|
|
const splitteeParent = document.getElementById("splittee-parent");
|
|
await utils.sendEnterKey();
|
|
test(() => {
|
|
assert_equals(
|
|
document.getElementById("splittee"),
|
|
splittee,
|
|
`The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
document.getElementById("splittee-parent"),
|
|
splitteeParent,
|
|
`The element instance returned by Document.getElementById shouldn't be changed after splitting the element (splittee-parent) (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
document.querySelectorAll("[id=splittee]").length,
|
|
1,
|
|
`The new element created by splitting an element shouldn't have same id attribute value (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
document.querySelectorAll("[id=splittee-parent]").length,
|
|
1,
|
|
`The new element created by splitting an element shouldn't have same id attribute value (splittee-parent) (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <div id=\"splittee-parent\"> and <span id=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<div class="splittee-parent"><span class="splittee">abc[]def</span></div>`);
|
|
await utils.sendEnterKey();
|
|
const leftParent = utils.editingHost.querySelector("div");
|
|
const leftNode = leftParent.querySelector("span");
|
|
const rightParent = utils.editingHost.querySelector("div + div");
|
|
const rightNode = rightParent.querySelector("span");
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("class"),
|
|
"splittee",
|
|
`The left element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
leftParent.getAttribute("class"),
|
|
"splittee-parent",
|
|
`The left element should keep having the class attribute (splittee-parent) (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("class"),
|
|
"splittee",
|
|
`The right element should keep having the class attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightParent.getAttribute("class"),
|
|
"splittee-parent",
|
|
`The right element should keep having the class attribute (splittee-parent) (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <div class=\"splittee-parent\"> and <span class=\"splittee\">");
|
|
|
|
promise_test(async t => {
|
|
utils.setupEditingHost(`<div data-foo="1" data-bar="2"><span data-foo="3" data-bar="4">abc[]def</span></div>`);
|
|
await utils.sendEnterKey();
|
|
const leftParent = utils.editingHost.querySelector("div");
|
|
const leftNode = leftParent.querySelector("span");
|
|
const rightParent = utils.editingHost.querySelector("div + div");
|
|
const rightNode = rightParent.querySelector("span");
|
|
test(() => {
|
|
assert_equals(
|
|
leftNode.getAttribute("data-foo"),
|
|
"3",
|
|
`The left element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
leftNode.getAttribute("data-bar"),
|
|
"4",
|
|
`The left element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
leftParent.getAttribute("data-foo"),
|
|
"1",
|
|
`The left element should keep having the data-foo attribute (splittee-parent) (${t.name})`
|
|
);
|
|
assert_equals(
|
|
leftParent.getAttribute("data-bar"),
|
|
"2",
|
|
`The left element should keep having the data-bar attribute (splittee-parent) (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightNode.getAttribute("data-foo"),
|
|
"3",
|
|
`The right element should keep having the data-foo attribute (${t.name})`
|
|
);
|
|
assert_equals(
|
|
rightNode.getAttribute("data-bar"),
|
|
"4",
|
|
`The right element should keep having the data-bar attribute (${t.name})`
|
|
);
|
|
});
|
|
test(() => {
|
|
assert_equals(
|
|
rightParent.getAttribute("data-foo"),
|
|
"1",
|
|
`The right element should keep having the data-foo attribute (splittee-parent) (${t.name})`
|
|
);
|
|
assert_equals(
|
|
rightParent.getAttribute("data-bar"),
|
|
"2",
|
|
`The right element should keep having the data-bar attribute (splittee-parent) (${t.name})`
|
|
);
|
|
});
|
|
}, "Splitting <div data-foo=\"1\" data-bar=\"2\"> and <span data-foo=\"3\" data-bar=\"4\">");
|
|
|
|
</script>
|