<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<body>
<script>
function createEditable(markup) {
const node = document.createElement('div');
node.contentEditable = true;
node.setHTMLUnsafe(markup);
return node;
}
assert_true(!!window.testRunner, 'This test requires testRunner');
const root = document.createElement("root");
document.body.appendChild(root);
function testPaste(originalMarkupOrElement, expected, descr) {
const isElement = originalMarkupOrElement instanceof HTMLElement;
descr = descr || (isElement ? originalMarkupOrElement.textContent : originalMarkupOrElement);
test(t => {
// Clear the clipboard to something known, in case copy fails.
const dummy = createEditable("Clear the clipboard");
root.appendChild(dummy);
dummy.focus();
assert_true(document.execCommand("SelectAll", false));
assert_true(document.execCommand("Copy", false));
dummy.remove();
// Create a node containing the test markup.
const node = isElement ? originalMarkupOrElement : createEditable(originalMarkupOrElement);
root.appendChild(node);
node.focus();
assert_true(document.execCommand("SelectAll", false));
assert_true(document.execCommand("Copy", false));
node.remove();
// Paste to a fresh node with known content.
const nodeDest = createEditable("This should be overwritten");
root.appendChild(nodeDest);
nodeDest.focus();
assert_true(document.execCommand("SelectAll", false));
assert_true(document.execCommand("Paste", false));
confirmedMarkup = nodeDest.getHTML({serializableShadowRoots: true});
nodeDest.remove();
assert_equals(confirmedMarkup, expected);
},`Test for "${descr}"`);
}
testPaste("Hello", "Hello");
testPaste("Hello<div></div>", "Hello");
testPaste("<b><i>Hello</i></b>", "<b><i>Hello</i></b>");
testPaste("<div><b><i><span style=\"font-weight: normal\"><b><i>Hello</i></b></span></i></b></div>", "<b><i>Hello</i></b>");
testPaste("<div><div><div>Hello</div></div></div>", "Hello");
testPaste("<div><b><div><i>Hello</i></div></b></div>", "<i style=\"font-weight: 700;\">Hello</i>");
testPaste("<div><div style=\"text-align: center;\"><b>Hello</b></div></div>", "<b style=\"text-align: center;\">Hello</b>");
testPaste("<div><b><i><span style=\"font-weight: normal\"><b><i>hello</i></b></span></i></b></div><div><b><i><span style=\"font-weight: normal\"><b><i>world</i></b></span></i></b></div>",
"<div><b><i>hello</i></b></div><div><b><i>world</i></b></div>");
testPaste("<div><b><i><span style=\"font-weight: normal;\"><b><i>hello1</i></b><b><i> hello2</i></b></span></i></b></div>", "<b><i><span style=\"font-weight: normal;\"><b><i>hello1</i></b><b><i> hello2</i></b></span></i></b>");
testPaste("<i style=\"margin: 10px;\"><b><i style=\"margin: 10px;\">hello</i></b></i>",
"<i style=\"margin: 10px;\"><b><i style=\"margin: 10px;\">hello</i></b></i>");
testPaste("<div><b><i><span style=\"font-weight: normal\"><b><i>Hello <!-- comment -->world</i></b></span></i></b></div>", "<b><i>Hello world</i></b>");
testPaste("<div><b><i><span style=\"font-weight: normal\">plain text<b><i>bold italic text</i></b></span></i></b></div>", "<b><i><span style=\"font-weight: normal;\">plain text<b><i>bold italic text</i></b></span></i></b>");
// Ordinary template gets removed:
testPaste("<span>foo</span><template>Hello</template><span>bar</span>", "foobar");
// Note that an empty <div> is left in the resulting pasted text, which isn't ideal:
testPaste("<span>foo</span><div><template>Hello</template></div><span>bar</span>", "foo<div></div>bar");
// Contained shadow DOM is stripped, but content is retained:
testPaste("<span>foo</span><div><template shadowrootmode='open' serializable>Hello</template></div><span>bar</span>", "foo<div>Hello</div>bar");
testPaste("<span>foo</span><div><template shadowrootmode='open' serializable><slot></slot>DEF</template>ABC</div><span>bar</span>", "foo<div><slot>ABC</slot>DEF</div>bar");
// Make sure regular (non-DSD) template doesn't form a shadow root on paste:
const nodeWithTemplate = createEditable("<span>foo</span><div>ABC<template>Hello</template></div><span>bar</span>");
nodeWithTemplate.querySelector('template').setAttribute('shadowrootmode','open');
testPaste(nodeWithTemplate, "foo<div>ABC</div>bar");
</script>