Commit 8567fa97 authored by Mason Freed's avatar Mason Freed Committed by Commit Bot

Update paste-and-sanitize test to testharness, and add more tests

This was an old test, so this updates it to use testharness.js. It also
fixes a few issues with the test, primarily the fact that it used to
copy and paste from the same control, and errors in copying or pasting
would leave the existing markup in place.

Along with this update, I added testing of both "normal" template
elements in copied content, in addition to declarative Shadow DOM.
And a test that <template shadowroot=open> doesn't get round-tripped
back into a declarative Shadow Root.

Note that one "flaw" is baked into this test:
  ABC<div><template></template></div>DEF
will get left as ABC<div></div>DEF, rather than just ABCDEF.

Bug: 1042130
Change-Id: I870d4a518d722c6f10a9ca2d20aab0d6334b8589
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2561273
Auto-Submit: Mason Freed <masonfreed@chromium.org>
Commit-Queue: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#831199}
parent 2b9c5c7c
This test checks that the paste operation trims the pasted fragment to reduce the verbosity of the markup without affecting the style.
PASS confirmedMarkup is 'Hello'
PASS confirmedMarkup is '<b><i>Hello</i></b>'
PASS confirmedMarkup is '<b><i>Hello</i></b>'
PASS confirmedMarkup is 'Hello'
PASS confirmedMarkup is '<i style="font-weight: 700;">Hello</i>'
PASS confirmedMarkup is '<div style="text-align: center;"><b>Hello</b></div>'
PASS confirmedMarkup is '<div><b><i>hello</i></b></div><div><b><i>world</i></b></div>'
PASS confirmedMarkup is '<b><i><span style="font-weight: normal;"><b><i>hello1</i></b><b><i>&nbsp;hello2</i></b></span></i></b>'
PASS confirmedMarkup is '<i style="margin: 10px;"><b><i style="margin: 10px;">hello</i></b></i>'
PASS confirmedMarkup is '<b><i>Hello&nbsp;world</i></b>'
PASS confirmedMarkup is '<b><i><span style="font-weight: normal;">plain text<b><i>bold italic text</i></b></span></i></b>'
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test.js"></script>
</head>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<body>
<p id="description">This test checks that the paste operation trims the pasted fragment to reduce the verbosity of the markup without affecting the style. </p>
<div id="console"></div>
<script>
function setInnerHTML(el,content) {
const fragment = (new DOMParser()).parseFromString(`<pre>${content}</pre>`, 'text/html', {includeShadowRoots: true});
el.replaceChildren(...fragment.body.firstChild.childNodes);
}
var sel = document.getSelection();
var root = document.createElement("root");
function createEditable(markup) {
const node = document.createElement('div');
node.contentEditable = true;
setInnerHTML(node,markup);
return node;
}
assert_true(!!window.testRunner, 'This test requires testRunner');
const root = document.createElement("root");
document.body.appendChild(root);
function testPaste(originalMarkupOrElement, expected) {
const isElement = originalMarkupOrElement instanceof HTMLElement;
const 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();
function createEditable(tagName, markup) {
var node = document.createElement(tagName);
node.contentEditable = true;
node.innerHTML = markup;
return node;
}
function testPaste(tagName, originalMarkup, expected) {
var node = createEditable(tagName, originalMarkup);
// Create a node containing the test markup.
const node = isElement ? originalMarkupOrElement : createEditable(originalMarkupOrElement);
root.appendChild(node);
node.focus();
document.execCommand("SelectAll", false);
document.execCommand("Copy", false);
document.execCommand("Paste", false);
assert_true(document.execCommand("SelectAll", false));
assert_true(document.execCommand("Copy", false));
node.remove();
confirmedMarkup = node.innerHTML;
// 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.getInnerHTML({includeShadowRoots: true});
nodeDest.remove();
shouldBe("confirmedMarkup", "'" + expected + "'");
assert_equals(confirmedMarkup, expected);
},`Test for "${descr}"`);
}
testPaste("div", "Hello", "Hello");
testPaste("div", "<b><i>Hello</i></b>", "<b><i>Hello</i></b>");
testPaste("div", "<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><div>Hello</div></div></div>", "Hello");
testPaste("div", "<div><b><div><i>Hello</i></div></b></div>", "<i style=\"font-weight: 700;\">Hello</i>");
testPaste("div", "<div><div style=\"text-align: center;\"><b>Hello</b></div></div>", "<div style=\"text-align: center;\"><b>Hello</b></div>");
testPaste("div", "<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>",
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", "<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>&nbsp;hello2</i></b></span></i></b>");
testPaste("div", "<i style=\"margin: 10px;\"><b><i style=\"margin: 10px;\">hello</i></b></i>",
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>&nbsp;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", "<div><b><i><span style=\"font-weight: normal\"><b><i>Hello <!-- comment -->world</i></b></span></i></b></div>", "<b><i>Hello&nbsp;world</i></b>");
testPaste("div", "<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>");
root.style.display = "none";
testPaste("<div><b><i><span style=\"font-weight: normal\"><b><i>Hello <!-- comment -->world</i></b></span></i></b></div>", "<b><i>Hello&nbsp;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 shadowroot='open'>Hello</template></div><span>bar</span>", "foo<div>Hello</div>bar");
testPaste("<span>foo</span><div><template shadowroot='open'><slot></slot>DEF</template>ABC</div><span>bar</span>", "foo<div><slot>ABC</slot>DEF</div>bar");
// Make sure non-declarative <template shadowroot> 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('shadowroot','open');
testPaste(nodeWithTemplate, "foo<div>ABC</div>bar");
</script>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment