diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/html/syntax/serializing-html-fragments | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/html/syntax/serializing-html-fragments')
5 files changed, 528 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/syntax/serializing-html-fragments/escaping.html b/testing/web-platform/tests/html/syntax/serializing-html-fragments/escaping.html new file mode 100644 index 0000000000..7bbc5566fc --- /dev/null +++ b/testing/web-platform/tests/html/syntax/serializing-html-fragments/escaping.html @@ -0,0 +1,89 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Serialization of script-disabled documents should follow escaping rules</title> +<link rel="author" href="mailto:masonf@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/parsing.html#serialising-html-fragments"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<body> + +<script> +const html_escaped = '& <>'; +const html_unescaped = '& <>'; +function getHtml(deEscapeParse) { + return `<noscript>${deEscapeParse ? html_escaped : html_unescaped}</noscript>`; +} +function testDoc(escapeSerialize, parsedNode) { + const node = parsedNode.firstChild; + const innerText = node.textContent; + assert_equals(innerText, html_unescaped, 'Content should be unescaped'); + const serialized = node.innerHTML; + const expectation = escapeSerialize ? html_escaped : html_unescaped; + assert_equals(serialized, expectation, `Serialization ${escapeSerialize ? 'should' : 'should NOT'} re-escape <noscript> contents`); +} + +test(() => { + const div = document.createElement('div'); + document.body.appendChild(div); + div.innerHTML = getHtml(false); + testDoc(false, div); +}, 'div.innerHTML'); + +test(() => { + const div = document.createElement('div'); + div.insertAdjacentHTML('afterbegin',getHtml(false)); + testDoc(false, div); +}, 'div.insertAdjacentHTML'); + +test(() => { + const id = 'doc-write-1'; + document.write(`<div id=${id} style="display:none">${getHtml(false)}</div>`); + testDoc(false, document.getElementById(id)); +}, 'document.write on main document'); + +test(() => { + const doc = (new DOMParser()).parseFromString(`<body>${getHtml(true)}</body>`, 'text/html'); + testDoc(true, doc.body); +}, 'DOMParser.parseFromString'); + +test(() => { + const template = document.createElement('template'); + document.body.appendChild(template); + template.innerHTML = getHtml(true); + testDoc(true, template.content); +}, 'template.innerHTML'); + +test(() => { + const doc = document.implementation.createHTMLDocument(''); + doc.body.innerHTML=`<pre>${getHtml(true)}</pre>`; + testDoc(true, doc.body.firstChild); +}, 'document.implementation.createHTMLDocument and innerHTML'); + +test(() => { + const doc = document.implementation.createHTMLDocument(''); + let range = doc.createRange(); + range.selectNode(doc.body); + const frag = range.createContextualFragment(getHtml(true)); + testDoc(true, frag); +}, 'document.implementation.createHTMLDocument and createContextualFragment'); + +test(() => { + const id = 'doc-write-2'; + const doc = document.implementation.createHTMLDocument(''); + doc.write(`<div id=${id} style="display:none">${getHtml(false)}</div>`); + testDoc(true, doc.getElementById(id)); +}, 'document.implementation.createHTMLDocument and document.write'); + +async_test((t) => { + let client = new XMLHttpRequest(); + client.addEventListener('load', t.step_func_done(() => { + assert_true(client.status == 200 && client.responseXML != null); + testDoc(true, client.responseXML.body.firstChild); + t.done(); + })); + client.open("GET", `data:text/html,<pre>${getHtml(true)}</pre>`); + client.responseType = 'document'; + client.send(); +}, 'XMLHttpRequest'); +</script> diff --git a/testing/web-platform/tests/html/syntax/serializing-html-fragments/initial-linefeed-pre.html b/testing/web-platform/tests/html/syntax/serializing-html-fragments/initial-linefeed-pre.html new file mode 100644 index 0000000000..d4e30bb60d --- /dev/null +++ b/testing/web-platform/tests/html/syntax/serializing-html-fragments/initial-linefeed-pre.html @@ -0,0 +1,48 @@ +<!doctype html> +<title>innerHTML getter for pre/textarea/listing with initial LF</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div id="outer"> +<div id="inner"> +<pre id="pre1"> +x</pre> +<pre id="pre2"> + +x</pre> +<textarea id="textarea1"> +x</textarea> +<textarea id="textarea2"> + +x</textarea> +<listing id="listing1"> +x</listing> +<listing id="listing2"> + +x</listing> +</div> +</div> + +<script> +var expected_outer = '\n<div id="inner">\n<pre id="pre1">x</pre>\n<pre id="pre2">\nx</pre>\n<textarea id="textarea1">x</textarea>\n<textarea id="textarea2">\nx</textarea>\n<listing id="listing1">x</listing>\n<listing id="listing2">\nx</listing>\n</div>\n'; +var expected_inner = expected_outer.replace('\n<div id="inner">', '').replace('</div>\n', ''); +var expected_1 = 'x'; +var expected_2 = '\nx'; + +test(function() { + assert_equals(outer.innerHTML, expected_outer); +}, 'outer div'); + +test(function() { + assert_equals(inner.innerHTML, expected_inner); +}, 'inner div'); + +['pre', 'textarea', 'listing'].forEach(function(tag) { + test(function() { + assert_equals(document.getElementById(tag + '1').innerHTML, expected_1); + }, tag + '1'); + + test(function() { + assert_equals(document.getElementById(tag + '2').innerHTML, expected_2); + }, tag + '2'); +}); +</script> diff --git a/testing/web-platform/tests/html/syntax/serializing-html-fragments/outerHTML.html b/testing/web-platform/tests/html/syntax/serializing-html-fragments/outerHTML.html new file mode 100644 index 0000000000..491bf9e900 --- /dev/null +++ b/testing/web-platform/tests/html/syntax/serializing-html-fragments/outerHTML.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> + <head> + <title>HTML Test: element.outerHTML to verify HTML fragment serialization algorithm</title> + <link rel="author" title="Intel" href="http://www.intel.com/"> + <link rel="help" href="https://html.spec.whatwg.org/multipage/#html-fragment-serialization-algorithm"> + <link rel="help" href="https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-outerHTML"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="../../resources/common.js"></script> + </head> + <body> + <div id="log"></div> + <script> + test(function() { + const non_void_elements = HTML5_ELEMENTS.filter(el => !HTML5_VOID_ELEMENTS.includes(el)); + non_void_elements.forEach(function(ele) { + test(function() { + var e = document.createElement(ele); + assert_equals(e.outerHTML, "<" + ele + "></" + ele + ">", ele + " node created." ); + }, "Node for " + ele); + }); + HTML5_VOID_ELEMENTS.forEach(function(ele) { + test(function() { + var e = document.createElement(ele); + assert_equals(e.outerHTML, "<" + ele + ">", ele + " node created." ); + }, "Node for " + ele); + }); + }, document.title); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/syntax/serializing-html-fragments/serializing.html b/testing/web-platform/tests/html/syntax/serializing-html-fragments/serializing.html new file mode 100644 index 0000000000..1bccbf5608 --- /dev/null +++ b/testing/web-platform/tests/html/syntax/serializing-html-fragments/serializing.html @@ -0,0 +1,336 @@ +<!DOCTYPE html> +<title>innerHTML in HTML</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> + +<!-- test elments. Each has an expected innerHTML and outerHTML in an array in the <script>--> +<div id="test" style="display:none"> +<span></span> +<span><a></a></span> +<span><a b=c></a></span> +<span><a b='c'></a></span> +<span><a b='&'></a></span> +<span><a b=' '></a></span> +<span><a b='"'></a></span> +<span><a b="<"></a></span> +<span><a b=">"></a></span> +<span><a href="javascript:"<>""></a></span> +<span><svg xlink:href="a"></svg></span> +<span><svg xmlns:svg="test"></svg></span> +<span>a</span> +<span>&</span> +<span> </span> +<span><</span> +<span>></span> +<span>"</span> +<span><style><&></style></span> +<span><script type="test"><&></script></span> +<script type="test"><&></script> +<span><xmp><&></xmp></span> +<span><iframe><&></iframe></span> +<span><noembed><&></noembed></span> +<span><noframes><&></noframes></span> +<span><noscript><&></noscript></span> +<span><!--data--></span> +<span><a><b><c></c></b><d>e</d><f><g>h</g></f></a></span> +<span b=c></span> +</div> +<!-- TODO: template element --> +<script> + +var test_data = document.getElementById("test").children; +var expected = [ +["", "<span></span>"], +["<a></a>", "<span><a></a></span>"], +["<a b=\"c\"></a>", "<span><a b=\"c\"></a></span>"], +["<a b=\"c\"></a>", "<span><a b=\"c\"></a></span>"], +["<a b=\"&\"></a>", "<span><a b=\"&\"></a></span>"], +["<a b=\" \"></a>", "<span><a b=\" \"></a></span>"], +["<a b=\""\"></a>", "<span><a b=\""\"></a></span>"], +["<a b=\"<\"></a>", "<span><a b=\"<\"></a></span>"], +["<a b=\">\"></a>", "<span><a b=\">\"></a></span>"], +["<a href=\"javascript:"<>"\"></a>", "<span><a href=\"javascript:"<>"\"></a></span>"], +["<svg xlink:href=\"a\"></svg>", "<span><svg xlink:href=\"a\"></svg></span>"], +["<svg xmlns:svg=\"test\"></svg>", "<span><svg xmlns:svg=\"test\"></svg></span>"], +["a", "<span>a</span>"], +["&", "<span>&</span>"], +[" ", "<span> </span>"], +["<", "<span><</span>"], +[">", "<span>></span>"], +["\"", "<span>\"</span>"], +["<style><&></style>", "<span><style><&></style></span>"], +["<script type=\"test\"><&><\/script>", "<span><script type=\"test\"><&><\/script></span>"], +["<&>", "<script type=\"test\"><&><\/script>"], +["<xmp><&></xmp>", "<span><xmp><&></xmp></span>"], +["<iframe><&></iframe>", "<span><iframe><&></iframe></span>"], +["<noembed><&></noembed>", "<span><noembed><&></noembed></span>"], +["<noframes><&></noframes>", "<span><noframes><&></noframes></span>"], +["<noscript><&></noscript>", "<span><noscript><&></noscript></span>"], +["<!--data-->", "<span><!--data--></span>"], +["<a><b><c></c></b><d>e</d><f><g>h</g></f></a>", "<span><a><b><c></c></b><d>e</d><f><g>h</g></f></a></span>"], +["", "<span b=\"c\"></span>"] +]; + +var dom_tests = [ + ["Attribute in the XML namespace", + function() { + var span = document.createElement("span"); + var svg = document.createElement("svg"); + svg.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:foo", "test"); + span.appendChild(svg); + return span; + }, + '<svg xml:foo="test"></svg>', + '<span><svg xml:foo="test"></svg></span>'], + + ["Attribute in the XML namespace with the prefix not set to xml:", + function() { + var span = document.createElement("span"); + var svg = document.createElement("svg"); + svg.setAttributeNS("http://www.w3.org/XML/1998/namespace", "abc:foo", "test"); + span.appendChild(svg); + return span; + }, + '<svg xml:foo="test"></svg>', + '<span><svg xml:foo="test"></svg></span>'], + + ["Non-'xmlns' attribute in the xmlns namespace", + function() { + var span = document.createElement("span"); + var svg = document.createElement("svg"); + svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo", "test") + span.appendChild(svg); + return span; + }, + '<svg xmlns:foo="test"></svg>', + '<span><svg xmlns:foo="test"></svg></span>'], + + ["'xmlns' attribute in the xmlns namespace", + function() { + var span = document.createElement("span"); + var svg = document.createElement("svg"); + svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "test") + span.appendChild(svg); + return span; + }, + '<svg xmlns="test"></svg>', + '<span><svg xmlns="test"></svg></span>'], + + ["Attribute in non-standard namespace", + function() { + var span = document.createElement("span"); + var svg = document.createElement("svg"); + svg.setAttributeNS("fake_ns", "abc:def", "test") + span.appendChild(svg); + return span; + }, + '<svg abc:def="test"></svg>', + '<span><svg abc:def="test"></svg></span>'], + + ["<span> starting with U+000A", + function() { + var elem = document.createElement("span"); + elem.appendChild(document.createTextNode("\x0A")); + return elem; + }, + "\x0A", + "<span>\x0A</span>"], + + //TODO: Processing instructions +] + +var text_elements = ["pre", "textarea", "listing"]; + +var text_tests = [ + ["<%text> context starting with U+000A", + function(elem) { + elem.appendChild(document.createTextNode("\x0A")); + return elem; + }, + "\x0A", + "<%text>\x0A</%text>"], + + ["<%text> context not starting with U+000A", + function(elem) { + elem.appendChild(document.createTextNode("a\x0A")); + return elem; + }, + "a\x0A", + "<%text>a\x0A</%text>"], + + ["<%text> non-context starting with U+000A", + function(elem) { + var span = document.createElement("span"); + elem.appendChild(document.createTextNode("\x0A")); + span.appendChild(elem); + return span; + }, + "<%text>\x0A</%text>", + "<span><%text>\x0A</%text></span>"], + + ["<%text> non-context not starting with U+000A", + function(elem) { + var span = document.createElement("span"); + elem.appendChild(document.createTextNode("a\x0A")); + span.appendChild(elem); + return span; + }, + "<%text>a\x0A</%text>", + "<span><%text>a\x0A</%text></span>"], +] + +var void_elements = [ + "area", "base", "basefont", "bgsound", "br", "col", "embed", + "frame", "hr", "img", "input", "keygen", "link", + "meta", "param", "source", "track", "wbr" +]; + +var void_tests = [ + ["Void context node", + function (void_elem) { + return void_elem; + }, + "", + "<%void>" + ], + ["void as first child with following siblings", + function (void_elem) { + var span = document.createElement("span"); + span.appendChild(void_elem); + span.appendChild(document.createElement("a")).appendChild(document.createTextNode("test")); + span.appendChild(document.createElement("b")) + return span + }, + "<%void><a>test</a><b></b>", + "<span><%void><a>test</a><b></b></span>" + ], + ["void as second child with following siblings", + function (void_elem) { + var span = document.createElement("span"); + span.appendChild(document.createElement("a")).appendChild(document.createTextNode("test")); + span.appendChild(void_elem); + span.appendChild(document.createElement("b")) + return span; + }, + "<a>test</a><%void><b></b>", + "<span><a>test</a><%void><b></b></span>" + ], + ["void as last child with preceding siblings", + function (void_elem) { + var span = document.createElement("span"); + span.appendChild(document.createElement("a")).appendChild(document.createTextNode("test")); + span.appendChild(document.createElement("b")) + span.appendChild(void_elem); + return span; + }, + "<a>test</a><b></b><%void>", + "<span><a>test</a><b></b><%void></span>" + ], +] + +function cross_map(a1, a2, f) { + var rv = []; + a1.forEach(function(a1_elem) { + a2.forEach(function(a2_elem) { + rv.push(f(a1_elem, a2_elem)); + }) + }); + return rv; +} + +function innerHTML_test(func, elem, expected) { + assert_equals(func(elem).innerHTML, expected); +} + +function outerHTML_test(func, elem, expected) { + assert_equals(func(elem).outerHTML, expected); +} + + +function make_void(name) { + var rv = document.createElement(name); + rv.appendChild(document.createElement("a")).appendChild(document.createComment("abc")) + rv.appendChild(document.createElement("b")). + appendChild(document.createElement("c")). + appendChild(document.createTextNode("abc")) + return rv; +} + +function make_text(name) { + return document.createElement(name); +} + +generate_tests(innerHTML_test, + expected.map(function(item, i) { + return ["innerHTML " + i + " " + expected[i][0], + function() {return test_data[i]}, + null, + item[0]]; + })) + +generate_tests(outerHTML_test, + expected.map(function(item, i) { + return ["outerHTML " + i + " " + expected[i][1], + function() {return test_data[i]}, + null, + item[1]]; + })) + +generate_tests(innerHTML_test, + dom_tests.map(function(item) { + return ["innerHTML " + item[0], + item[1], + null, + item[2]]; + })) + +generate_tests(outerHTML_test, + dom_tests.map(function(item) { + return ["outerHTML " + item[0], + item[1], + null, + item[3]]; + })) + +generate_tests(innerHTML_test, + cross_map(text_tests, text_elements, + function(test_data, elem_name) { + var rv = ["innerHTML " + test_data[0].replace(/%text/g, elem_name), + test_data[1], + document.createElement(elem_name), + test_data[2].replace(/%text/g, elem_name)]; + return rv; + })) + +generate_tests(outerHTML_test, + cross_map(text_tests, text_elements, + function(test_data, elem_name) { + var rv = ["outerHTML " + test_data[0].replace(/%text/g, elem_name), + test_data[1], + document.createElement(elem_name), + test_data[3].replace(/%text/g, elem_name)]; + return rv; + })) + +generate_tests(innerHTML_test, + cross_map(void_tests, void_elements, + function(test_data, elem_name) { + var rv = ["innerHTML " + test_data[0] + " " + elem_name, + test_data[1], + make_void(elem_name), + test_data[2].replace(/%void/g, elem_name)]; + return rv; + })) + +generate_tests(outerHTML_test, + cross_map(void_tests, void_elements, + function(test_data, elem_name) { + var rv = ["outerHTML " + test_data[0] + " " + elem_name, + test_data[1], + make_void(elem_name), + test_data[3].replace(/%void/g, elem_name)]; + return rv; + })) + +</script> diff --git a/testing/web-platform/tests/html/syntax/serializing-html-fragments/template.html b/testing/web-platform/tests/html/syntax/serializing-html-fragments/template.html new file mode 100644 index 0000000000..ea050384f2 --- /dev/null +++ b/testing/web-platform/tests/html/syntax/serializing-html-fragments/template.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> +test(() => { + document.body.insertAdjacentHTML('afterbegin', '<div><template><table><td></table></template></div>'); + let t = document.querySelector('template'); + assert_equals(t.innerHTML, '<table><tbody><tr><td></td></tr></tbody></table>'); + assert_equals(t.parentNode.innerHTML, '<template><table><tbody><tr><td></td></tr></tbody></table></template>'); +}, 'Template element content is correctly serialized'); + +test(() => { + let t = document.createElement('template'); + let c = t.content.appendChild(document.createElementNS("xx", "div")); + c.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:lang', 'en-us'); + c.setAttributeNS('uri2', 'p:attr', 'v'); + let doc = new Document(); + doc.adoptNode(t.content); + assert_equals(t.innerHTML, '<div xml:lang="en-us" p:attr="v"></div>'); +}, 'HTML fragment serialization algorithm should be applied to the template content'); +</script> +</body> |