From 936d1f091b270658dde16670d12c76d342c66628 Mon Sep 17 00:00:00 2001 From: Joey Arhar <jarhar@chromium.org> Date: Mon, 16 Oct 2023 09:56:49 -0700 Subject: [PATCH] Implement parseHTMLUnsafe and setHTMLUnsafe I am speccing this here: https://github.com/whatwg/html/pull/9538 Bug: 1478969 Change-Id: Ie55827cebdf349aadae13fbf1086baf6177bbff2 --- ...nt-parseHTMLUnsafe-encoding.tentative.html | 35 +++++++++ ...eHTMLUnsafe-style-attribute.tentative.html | 54 +++++++++++++ ...MLUnsafe-url-base-pushstate.tentative.html | 15 ++++ ...nt-parseHTMLUnsafe-url-base.tentative.html | 10 +++ ...rseHTMLUnsafe-url-moretests.tentative.html | 42 ++++++++++ ...rseHTMLUnsafe-url-pushstate.tentative.html | 14 ++++ ...ocument-parseHTMLUnsafe-url.tentative.html | 9 +++ .../Document-parseHTMLUnsafe.tentative.html | 77 +++++++++++++++++++ .../Element-setHTMLUnsafe-04.tentative.html | 25 ++++++ ...parseHTMLUnsafe-iframe-base-pushstate.html | 10 +++ .../parseHTMLUnsafe-iframe-base.html | 6 ++ .../parseHTMLUnsafe-iframe-pushstate.html | 9 +++ .../resources/parseHTMLUnsafe-iframe.html | 4 + .../resources/parseHTMLUnsafe-iframe.js | 3 + .../resources/parseHTMLUnsafe-url-tests.js | 36 +++++++++ .../setHTMLUnsafe.tentative.html | 55 +++++++++++++ .../declarative-shadow-dom-attachment.html | 2 +- .../declarative-shadow-dom-basic.html | 13 ++-- shadow-dom/declarative/support/helpers.js | 4 - 19 files changed, 411 insertions(+), 12 deletions(-) create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-encoding.tentative.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-style-attribute.tentative.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-base-pushstate.tentative.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-base.tentative.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-moretests.tentative.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-pushstate.tentative.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url.tentative.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe.tentative.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Element-setHTMLUnsafe-04.tentative.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-base-pushstate.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-base.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-pushstate.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.html create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.js create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-url-tests.js create mode 100644 html/webappapis/dynamic-markup-insertion/html-unsafe-methods/setHTMLUnsafe.tentative.html delete mode 100644 shadow-dom/declarative/support/helpers.js diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-encoding.tentative.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-encoding.tentative.html new file mode 100644 index 000000000000000..1debcafa3b53402 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-encoding.tentative.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<meta charset="windows-1252"> <!-- intentional to make sure the results are UTF-8 anyway --> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/whatwg/html/pull/9538"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<!-- This was adapted from DOMParser-parseFromString-encoding.html --> + +<script> +function assertEncoding(doc) { + assert_equals(doc.charset, "UTF-8", "document.charset"); + assert_equals(doc.characterSet, "UTF-8", "document.characterSet"); + assert_equals(doc.inputEncoding, "UTF-8", "document.characterSet"); +} + +setup(() => { + assert_equals(document.characterSet, "windows-1252", "the meta charset must be in effect, making the main document windows-1252"); +}); + +test(() => { + const doc = Document.parseHTMLUnsafe(''); + assertEncoding(doc); +}, 'Parse empty string'); + +test(() => { + const doc = Document.parseHTMLUnsafe(`<meta charset="latin2">`); + assertEncoding(doc); +}, "meta charset latin2"); + +test(() => { + const doc = Document.parseHTMLUnsafe(`<?xml version="1.0" encoding="latin2"?><x/>`); + assertEncoding(doc); +}, "XML declaration"); +</script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-style-attribute.tentative.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-style-attribute.tentative.html new file mode 100644 index 000000000000000..cd092a6034602a4 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-style-attribute.tentative.html @@ -0,0 +1,54 @@ +<!doctype html> +<link rel=author href="mailto:jarhar@chromium.org"> +<!-- This test was adapted from style_attribute_html.html --> +<meta charset=utf-8> +<title>Style attribute in HTML</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> + +var div; +setup(function() { + var input = '<div style="color: red">Foo</div>'; + var doc = Document.parseHTMLUnsafe(input); + div = doc.querySelector('div'); +}); + +test(function() { + var style = div.style; + assert_equals(style.cssText, 'color: red;'); + assert_equals(style.color, 'red'); + assert_equals(div.getAttribute("style"), 'color: red', + 'Value of style attribute should match the string value that was set'); +}, 'Parsing of initial style attribute'); + +test(function() { + var style = div.style; + div.setAttribute('style', 'color:: invalid'); + assert_equals(style.cssText, ''); + assert_equals(style.color, ''); + assert_equals(div.getAttribute('style'), 'color:: invalid', + 'Value of style attribute should match the string value that was set'); +}, 'Parsing of invalid style attribute'); + +test(function() { + var style = div.style; + div.setAttribute('style', 'color: green'); + assert_equals(style.cssText, 'color: green;'); + assert_equals(style.color, 'green'); + assert_equals(div.getAttribute('style'), 'color: green', + 'Value of style attribute should match the string value that was set'); +}, 'Parsing of style attribute'); + +test(function() { + var style = div.style; + style.backgroundColor = 'blue'; + assert_equals(style.cssText, 'color: green; background-color: blue;', + 'Should not drop the existing style'); + assert_equals(style.color, 'green', + 'Should not drop the existing style'); + assert_equals(div.getAttribute('style'), 'color: green; background-color: blue;', + 'Should update style attribute'); +}, 'Update style.backgroundColor'); + +</script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-base-pushstate.tentative.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-base-pushstate.tentative.html new file mode 100644 index 000000000000000..a8eab595116f0c6 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-base-pushstate.tentative.html @@ -0,0 +1,15 @@ +<!doctype html> +<link rel=author href="mailto:jarhar@chromium.org"> +<!-- This test was adapted from DOMParser-parseFromString-url-base-pushstate.html --> +<title>parseHTMLUnsafe test of how the document's URL is set (base, pushstate)</title> +<base href="/fake/base-from-outer-frame"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<iframe src="/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-base-pushstate.html" onload="window.resolveLoadPromise();"></iframe> + +<script> +"use strict"; +history.pushState(null, "", "/fake/push-state-from-outer-frame"); +</script> +<script src="/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-url-tests.js"></script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-base.tentative.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-base.tentative.html new file mode 100644 index 000000000000000..62b2c09aaec5ecb --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-base.tentative.html @@ -0,0 +1,10 @@ +<!doctype html> +<link rel=author href="mailto:jarhar@chromium.org"> +<!-- This was adapted from DOMParser-parseFromString-url-base.html --> +<title>parseHTMLUnsafe test of how the document's URL is set (base, no pushstate)</title> +<base href="/fake/base-from-outer-frame"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<iframe src="/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-base.html" onload="window.resolveLoadPromise();"></iframe> +<script src="/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-url-tests.js"></script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-moretests.tentative.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-moretests.tentative.html new file mode 100644 index 000000000000000..41335ef035fae44 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-moretests.tentative.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<!-- This test was adapted from DOMParser-parseFromString-url-moretests.html --> +<meta charset=utf-8> +<title>Document.parseHTMLUnsafe: Document's url</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +async_test(function() { + var iframe = document.createElement("iframe"); + iframe.onload = this.step_func(function() { + var child = iframe.contentWindow; + + test(function() { + var doc = Document.parseHTMLUnsafe("<html></html>"); + assert_equals(doc.URL, "about:blank"); + }, "Parent window"); + + test(function() { + var doc = child.Document.parseHTMLUnsafe("<html></html>"); + assert_equals(doc.URL, "about:blank"); + }, "Child window"); + + var dpBeforeNavigation = child.Document, urlBeforeNavigation = child.document.URL; + iframe.onload = this.step_func_done(function() { + test(function() { + var doc = dpBeforeNavigation.parseHTMLUnsafe("<html></html>"); + assert_equals(doc.URL, "about:blank"); + }, "Child window crossing navigation"); + + test(function() { + var doc = child.Document.parseHTMLUnsafe("<html></html>"); + assert_equals(doc.URL, "about:blank"); + }, "Child window after navigation"); + }); + iframe.src = "/common/blank.html?2"; + }); + iframe.src = "/common/blank.html?1"; + document.body.appendChild(iframe); +}); +</script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-pushstate.tentative.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-pushstate.tentative.html new file mode 100644 index 000000000000000..7930bf0ddbf12a1 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-pushstate.tentative.html @@ -0,0 +1,14 @@ +<!doctype html> +<link rel=author href="mailto:jarhar@chromium.org"> +<!-- This test was adapted from DOMParser-parseFromString-url-pushstate.html --> +<title>parseHTMLUnsafe test of how the document's URL is set (no base, pushstate)</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<iframe src="/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-pushstate.html" onload="window.resolveLoadPromise();"></iframe> + +<script> +"use strict"; +history.pushState(null, "", "/fake/push-state-from-outer-frame"); +</script> +<script src="/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-url-tests.js"></script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url.tentative.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url.tentative.html new file mode 100644 index 000000000000000..911e1837063ab49 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url.tentative.html @@ -0,0 +1,9 @@ +<!doctype html> +<link rel=author href="mailto:jarhar@chromium.org"> +<!-- This test was adapted from DOMParser-parseFromString-url.html --> +<title>parseHTMLUnsafe test of how the document's URL is set (no pushstate, no base)</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<iframe src="resources/parseHTMLUnsafe-iframe.html" onload="window.resolveLoadPromise();"></iframe> +<script src="resources/parseHTMLUnsafe-url-tests.js"></script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe.tentative.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe.tentative.html new file mode 100644 index 000000000000000..2a89370825b6936 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe.tentative.html @@ -0,0 +1,77 @@ +<!doctype html> +<link rel=author href="mailto:jarhar@chromium.org"> +<!-- This was adapted from DOMParser-parseFromString-html.html --> +<title>parseHTMLUnsafe basic test of HTML parsing</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +// |expected| should be an object indicating the expected type of node. +function assert_node(actual, expected) { + assert_true(actual instanceof expected.type, + 'Node type mismatch: actual = ' + actual.constructor.name + ', expected = ' + expected.type.name); + if (typeof(expected.id) !== 'undefined') + assert_equals(actual.id, expected.id, expected.idMessage); +} + +var doc; +setup(function() { + doc = Document.parseHTMLUnsafe('<html id="root"><head></head><body></body></html>'); +}); + +test(function() { + var root = doc.documentElement; + assert_node(root, { type: HTMLHtmlElement, id: 'root', + idMessage: 'documentElement id attribute should be root.' }); +}, 'Parsing of id attribute'); + +test(function() { + assert_equals(doc.contentType, "text/html") +}, 'contentType'); + +test(function() { + assert_equals(doc.compatMode, "BackCompat") +}, 'compatMode'); + +test(function() { + doc = Document.parseHTMLUnsafe('<!DOCTYPE html><html id="root"><head></head><body></body></html>'); + assert_equals(doc.compatMode, "CSS1Compat") +}, 'compatMode for a proper DOCTYPE'); + +// URL- and encoding-related stuff tested separately. + +test(function() { + assert_equals(doc.location, null, + 'The document must have a location value of null.'); +}, 'Location value'); + +test(function() { + var htmldoc = Document.parseHTMLUnsafe("<!DOCTYPE foo></><foo></multiple></>"); + assert_equals(htmldoc.documentElement.localName, "html"); + assert_equals(htmldoc.documentElement.namespaceURI, "http://www.w3.org/1999/xhtml"); +}, "Document.parseHTMLUnsafe parses HTML tag soup with no problems"); + +test(function() { + const doc = Document.parseHTMLUnsafe('<noembed><a></noembed>'); + assert_equals(doc.querySelector('noembed').textContent, '<a>'); +}, 'Document.parseHTMLUnsafe should handle the content of <noembed> as raw text'); + +test(() => { + const doc = Document.parseHTMLUnsafe(` +<html><body> +<style> + @import url(/dummy.css) +</style> +<script>document.x = 8<\/script> +</body></html>`); + + assert_not_equals(doc.querySelector('script'), null, 'script must be found'); + assert_equals(doc.x, undefined, 'script must not be executed on the inner document'); + assert_equals(document.x, undefined, 'script must not be executed on the outer document'); +}, 'script is found synchronously even when there is a css import'); + +test(() => { + const doc = Document.parseHTMLUnsafe(`<body><noscript><p id="test1">test1<p id="test2">test2</noscript>`); + assert_node(doc.body.firstChild.childNodes[0], { type: HTMLParagraphElement, id: 'test1' }); + assert_node(doc.body.firstChild.childNodes[1], { type: HTMLParagraphElement, id: 'test2' }); +}, 'must be parsed with scripting disabled, so noscript works'); +</script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Element-setHTMLUnsafe-04.tentative.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Element-setHTMLUnsafe-04.tentative.html new file mode 100644 index 000000000000000..4a9e300afc2f934 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Element-setHTMLUnsafe-04.tentative.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<title>setHTMLUnsafe in HTML</title> +<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"> +<link rel=author href="mailto:jarhar@chromium.org"> +<!-- This test was adapted from innerhtml-04.html --> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> +function testIsChild(p, c) { + assert_equals(p.firstChild, c); + assert_equals(c.parentNode, p); +} +test(function() { + var p = document.createElement('p'); + var b = p.appendChild(document.createElement('b')); + var t = b.appendChild(document.createTextNode("foo")); + testIsChild(p, b); + testIsChild(b, t); + assert_equals(t.data, "foo"); + p.setHTMLUnsafe(""); + testIsChild(b, t); + assert_equals(t.data, "foo"); +}, "setHTMLUnsafe should leave the removed children alone.") +</script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-base-pushstate.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-base-pushstate.html new file mode 100644 index 000000000000000..53b855968c866e8 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-base-pushstate.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>An iframe that does parseHTMLUnsafe stuff with base and pushstates itself</title> +<base href="/fake/base-from-iframe"> + +<script> +"use strict"; +history.pushState(null, "", "/fake/push-state-from-iframe"); +</script> +<script src="/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.js"></script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-base.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-base.html new file mode 100644 index 000000000000000..6977e938119561a --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-base.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>An iframe that does parseHTMLUnsafe stuff with base</title> +<base href="/fake/base-from-iframe"> + +<script src="/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.js"></script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-pushstate.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-pushstate.html new file mode 100644 index 000000000000000..5e1fae04413cdfa --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe-pushstate.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>An iframe that does parseHTMLUnsafe stuff and pushstates itself</title> + +<script> +"use strict"; +history.pushState(null, "", "/fake/push-state-from-iframe"); +</script> +<script src="/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.js"></script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.html new file mode 100644 index 000000000000000..f47d9605fc85969 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>An iframe that does parseHTMLUnsafe stuff</title> +<script src="parseHTMLUnsafe-iframe.js"></script> diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.js b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.js new file mode 100644 index 000000000000000..4a0b56869beb568 --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-iframe.js @@ -0,0 +1,3 @@ +window.doParse = (html) => { + return Document.parseHTMLUnsafe(html); +}; diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-url-tests.js b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-url-tests.js new file mode 100644 index 000000000000000..88344d127cee3cc --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/resources/parseHTMLUnsafe-url-tests.js @@ -0,0 +1,36 @@ +const loadPromise = new Promise(resolve => { window.resolveLoadPromise = resolve; }); + +function assertURL(doc) { + assert_equals(doc.URL, "about:blank", "document.URL"); + assert_equals(doc.documentURI, "about:blank", "document.documentURI"); + assert_equals(doc.baseURI, "about:blank", "document.baseURI"); +} + +const inputs = { + valid: "<html></html>", + "invalid XML": `<span x:test="testing">1</span>` +}; + +for (const [inputName, input] of Object.entries(inputs)) { + test(() => { + const doc = Document.parseHTMLUnsafe(input); + + assertURL(doc); + }, `${inputName}: created normally`); + + promise_test(async () => { + await loadPromise; + + const doc = frames[0].Document.parseHTMLUnsafe(input); + + assertURL(doc); + }, `${inputName}: created using another iframe's parseHTMLUnsafe from this frame`); + + promise_test(async () => { + await loadPromise; + + const doc = frames[0].doParse(input); + + assertURL(doc); + }, `${inputName}: created using another iframe's parseHTMLUnsafe from that frame`); +} diff --git a/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/setHTMLUnsafe.tentative.html b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/setHTMLUnsafe.tentative.html new file mode 100644 index 000000000000000..1c0b1155691cbcf --- /dev/null +++ b/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/setHTMLUnsafe.tentative.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/whatwg/html/pull/9538"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<body> +<script> +for (const containerType of ['Element', 'ShadowRoot']) { + const createContainer = () => { + if (containerType == 'ShadowRoot') { + return document.createElement('div').attachShadow({mode: 'open'}); + } else if (containerType == 'Element') { + return document.createElement('div'); + } + }; + + test(() => { + const container = createContainer(); + container.setHTMLUnsafe('<span title=hello>world</span>'); + + assert_equals(container.children.length, 1, 'Only one child node should be created.'); + assert_equals(container.firstChild.tagName, 'SPAN', 'The child element should be a span.'); + assert_equals(container.firstChild.getAttribute('title'), 'hello', + 'The title attribute should be set to hello.'); + assert_equals(container.firstChild.childNodes.length, 1, + 'The span should have one child.'); + assert_true(container.firstChild.childNodes[0] instanceof Text, + 'The spans child should be a text node.'); + assert_equals(container.firstChild.textContent, 'world', + 'The spans textContent should be world.'); + }, `${containerType}: setHTMLUnsafe with no shadowdom.`); + + test(() => { + const container = createContainer(); + container.setHTMLUnsafe(`<div><template shadowrootmode=open><div>hello</div></template></div>`); + + assert_equals(container.children.length, 1, 'One child should be created in the container.'); + const shadowRoot = container.firstChild.shadowRoot; + assert_true(!!shadowRoot, 'The containers child should have a ShadowRoot.'); + assert_equals(shadowRoot.children.length, 1, 'One child should be created in the ShadowRoot.'); + assert_equals(shadowRoot.firstChild.textContent, 'hello', + 'The ShadowRoots childs textContent should be hello.'); + }, `${containerType}: setHTMLUnsafe with shadowdom.`); +} + +test(() => { + const template = document.createElement('template'); + template.setHTMLUnsafe('<div>hello world</div>'); + + assert_equals(template.children.length, 0, 'template should not have any child nodes.'); + assert_equals(template.content.children.length, 1, 'template content should have a child div.'); + assert_equals(template.content.children[0].textContent, 'hello world', 'text content should be set.'); +}, 'template.setHTMLUnsafe() should modify template content fragment rather than actual children.'); +</script> diff --git a/shadow-dom/declarative/declarative-shadow-dom-attachment.html b/shadow-dom/declarative/declarative-shadow-dom-attachment.html index d752b62d31d47fd..dcee6cf8a103ac5 100644 --- a/shadow-dom/declarative/declarative-shadow-dom-attachment.html +++ b/shadow-dom/declarative/declarative-shadow-dom-attachment.html @@ -19,7 +19,7 @@ const declarativeString = `<${elementType} id=theelement>${getDeclarativeContent(mode, delegatesFocus)} <span class='lightdom'>${lightDomTextContent}</span></${elementType}>`; const wrapper = document.createElement('div'); - setInnerHTML(wrapper, declarativeString); + wrapper.setHTMLUnsafe(declarativeString); const element = wrapper.querySelector('#theelement'); return {wrapper: wrapper, element: element}; } diff --git a/shadow-dom/declarative/declarative-shadow-dom-basic.html b/shadow-dom/declarative/declarative-shadow-dom-basic.html index b71f7d1a3778e72..5d59c9bb2f70c37 100644 --- a/shadow-dom/declarative/declarative-shadow-dom-basic.html +++ b/shadow-dom/declarative/declarative-shadow-dom-basic.html @@ -5,7 +5,6 @@ <link rel="help" href="https://github.com/whatwg/dom/issues/831"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="support/helpers.js"></script> <div id="host" style="display:none"> <template shadowrootmode="open"> @@ -47,7 +46,7 @@ test(() => { const div = document.createElement('div'); - setInnerHTML(div,` + div.setHTMLUnsafe(` <div id="host"> <template shadowrootmode="open"> <slot id="s1" name="slot1"></slot> @@ -68,7 +67,7 @@ test(() => { const div = document.createElement('div'); - setInnerHTML(div,` + div.setHTMLUnsafe(` <div id="host"> <template shadowrootmode="invalid"> </template> @@ -84,7 +83,7 @@ test(() => { const div = document.createElement('div'); - setInnerHTML(div,` + div.setHTMLUnsafe(` <div id="host"> <template shadowrootmode="closed"> </template> @@ -97,7 +96,7 @@ test(() => { const div = document.createElement('div'); - setInnerHTML(div,` + div.setHTMLUnsafe(` <div id="host"> <template shadowrootmode="open"> <slot id="s1" name="slot1"></slot> @@ -113,7 +112,7 @@ test(() => { const div = document.createElement('div'); - setInnerHTML(div,` + div.setHTMLUnsafe(` <div id="host"> <template shadowrootmode="open" shadowrootdelegatesfocus> </template> @@ -122,7 +121,7 @@ var host = div.querySelector('#host'); assert_true(!!host.shadowRoot,"No shadow root found"); assert_true(host.shadowRoot.delegatesFocus,"delegatesFocus should be true"); - setInnerHTML(div,` + div.setHTMLUnsafe(` <div id="host"> <template shadowrootmode="open"> </template> diff --git a/shadow-dom/declarative/support/helpers.js b/shadow-dom/declarative/support/helpers.js deleted file mode 100644 index 0be3add620065a9..000000000000000 --- a/shadow-dom/declarative/support/helpers.js +++ /dev/null @@ -1,4 +0,0 @@ -function setInnerHTML(el,content) { - const fragment = (new DOMParser()).parseFromString(`<pre>${content}</pre>`, 'text/html', {includeShadowRoots: true}); - (el instanceof HTMLTemplateElement ? el.content : el).replaceChildren(...fragment.body.firstChild.childNodes); -}