<!DOCTYPE html>
<meta charset="utf-8">
<title>Serialization of script-disabled documents should follow escaping rules</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@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 = '&amp;&nbsp;&lt;&gt;';
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>
