| <!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> |