Blame dom/base/test/test_blockParsing.html

Packit f0b94e
Packit f0b94e
<html>
Packit f0b94e
<head>
Packit f0b94e
  <title>Test for document.blockParsing</title>
Packit f0b94e
  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
Packit f0b94e
  <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
Packit f0b94e
  <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css">
Packit f0b94e
</head>
Packit f0b94e
<body>
Packit f0b94e
<script>
Packit f0b94e
ChromeUtils.import("resource://testing-common/TestUtils.jsm");
Packit f0b94e
Packit f0b94e
async function runTest(url, initialHTML, finalHTML) {
Packit f0b94e
  let iframe = document.createElement("iframe");
Packit f0b94e
  iframe.src = url;
Packit f0b94e
Packit f0b94e
  let blockerPromise;
Packit f0b94e
  let promise = TestUtils.topicObserved("document-element-inserted", document => {
Packit f0b94e
    blockerPromise = new Promise(resolve => {
Packit f0b94e
      setTimeout(resolve, 0);
Packit f0b94e
    }).then(() => {
Packit f0b94e
      return new Promise(resolve => setTimeout(resolve, 0));
Packit f0b94e
    }).then(() => {
Packit f0b94e
      return new Promise(resolve => setTimeout(resolve, 0));
Packit f0b94e
    });
Packit f0b94e
Packit f0b94e
    is(document.documentElement.outerHTML, initialHTML,
Packit f0b94e
       "Should have initial HTML during document-element-inserted");
Packit f0b94e
    is(document.defaultView.wrappedJSObject.scriptRan, undefined,
Packit f0b94e
       "Script node should not have run");
Packit f0b94e
Packit f0b94e
    document.blockParsing(blockerPromise);
Packit f0b94e
Packit f0b94e
    return true;
Packit f0b94e
  }).then(([document]) => {
Packit f0b94e
    return document;
Packit f0b94e
  });
Packit f0b94e
Packit f0b94e
  document.body.appendChild(iframe);
Packit f0b94e
Packit f0b94e
  // Wait for document-element-inserted to fire.
Packit f0b94e
  let doc = await promise;
Packit f0b94e
  let win = doc.defaultView.wrappedJSObject;
Packit f0b94e
  let root = doc.documentElement;
Packit f0b94e
Packit f0b94e
  // At this point, if the parser was successfully blocked, we should still
Packit f0b94e
  // have the initial skeleton HTML for the page.
Packit f0b94e
  is(root.outerHTML, initialHTML, "Should have initial HTML after document-element-inserted returns");
Packit f0b94e
  is(win.scriptRan, undefined, "Script node should still not have run");
Packit f0b94e
Packit f0b94e
  await blockerPromise;
Packit f0b94e
Packit f0b94e
  // Just after the promise that's blocking the parser fires, we shouldn't have
Packit f0b94e
  // returned to the main event loop, so we should still have the initial HTML.
Packit f0b94e
  is(root.outerHTML, initialHTML, "Should still have initial HTML");
Packit f0b94e
  is(win.scriptRan, undefined, "Script node should still not have run");
Packit f0b94e
Packit f0b94e
  await new Promise(resolve => win.addEventListener("DOMContentLoaded", resolve, {once: true}));
Packit f0b94e
Packit f0b94e
  // Parsing should have resumed, and we should have finished loading the document.
Packit f0b94e
  is(root.outerHTML, finalHTML, "Should have final HTML");
Packit f0b94e
  is(win.scriptRan, true, "Script node should have run");
Packit f0b94e
Packit f0b94e
  iframe.remove();
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
add_task(async function() {
Packit f0b94e
  await runTest("http://mochi.test:8888/chrome/dom/base/test/file_inline_script.html",
Packit f0b94e
                '<html lang="en"></html>',
Packit f0b94e
                '<html lang="en"><head>\n  <script>window.scriptRan = true;<\/script>\n  <meta charset="utf-8">\n  <title></title>\n</head>\n<body>\n  

Hello Mochitest

\n\n\n</body></html>');
Packit f0b94e
Packit f0b94e
  await runTest("http://mochi.test:8888/chrome/dom/base/test/file_inline_script.xhtml",
Packit f0b94e
                '<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"></html>',
Packit f0b94e
                '<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">\n<head>\n  <script>window.scriptRan = true;<\/script>\n  <title></title>\n</head>\n<body>\n  

Hello Mochitest

\n</body>\n</html>');
Packit f0b94e
Packit f0b94e
  await runTest("http://mochi.test:8888/chrome/dom/base/test/file_external_script.html",
Packit f0b94e
                '<html lang="en"></html>',
Packit f0b94e
                '<html lang="en"><head>\n  <script src="file_script.js"><\/script>\n  <meta charset="utf-8">\n  <title></title>\n</head>\n<body>\n  

Hello Mochitest

\n\n\n</body></html>');
Packit f0b94e
Packit f0b94e
  await runTest("http://mochi.test:8888/chrome/dom/base/test/file_external_script.xhtml",
Packit f0b94e
                '<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"></html>',
Packit f0b94e
                '<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">\n<head>\n  <script src="file_script.js"><\/script>\n  <title></title>\n</head>\n<body>\n  

Hello Mochitest

\n</body>\n</html>');
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_cleanup() {
Packit f0b94e
  const TOPIC = "blocking-promise-destroyed";
Packit f0b94e
Packit f0b94e
  const finalizationWitness = Cc["@mozilla.org/toolkit/finalizationwitness;1"]
Packit f0b94e
      .getService(Ci.nsIFinalizationWitnessService);
Packit f0b94e
Packit f0b94e
  for (let url of ["http://mochi.test:8888/chrome/dom/base/test/file_inline_script.html",
Packit f0b94e
                   "http://mochi.test:8888/chrome/dom/base/test/file_inline_script.xhtml"]) {
Packit f0b94e
    let iframe = document.createElement("iframe");
Packit f0b94e
    iframe.src = url;
Packit f0b94e
Packit f0b94e
    // Create a promise that never resolves.
Packit f0b94e
    let blockerPromise = new Promise(() => {});
Packit f0b94e
Packit f0b94e
    // Create a finalization witness so we can be sure that the promises
Packit f0b94e
    // have been collected before the end of the test.
Packit f0b94e
    let destroyedPromise = TestUtils.topicObserved(TOPIC);
Packit f0b94e
    let witness = finalizationWitness.make(TOPIC, url);
Packit f0b94e
    blockerPromise.witness = witness;
Packit f0b94e
Packit f0b94e
    let insertedPromise = TestUtils.topicObserved("document-element-inserted", document => {
Packit f0b94e
      document.blockParsing(blockerPromise).witness = witness;
Packit f0b94e
Packit f0b94e
      return true;
Packit f0b94e
    });
Packit f0b94e
Packit f0b94e
    document.body.appendChild(iframe);
Packit f0b94e
    await insertedPromise;
Packit f0b94e
Packit f0b94e
    // Clear the promise reference, destroy the document, and force GC/CC. This should
Packit f0b94e
    // trigger any potential leaks or cleanup issues.
Packit f0b94e
    blockerPromise = null;
Packit f0b94e
    witness = null;
Packit f0b94e
    iframe.remove();
Packit f0b94e
Packit f0b94e
    Cu.forceGC();
Packit f0b94e
    Cu.forceCC();
Packit f0b94e
    Cu.forceGC();
Packit f0b94e
Packit f0b94e
    // Make sure the blocker promise has been collected.
Packit f0b94e
    let [, data] = await destroyedPromise;
Packit f0b94e
    is(data, url, "Should have correct finalizer URL");
Packit f0b94e
  }
Packit f0b94e
});
Packit f0b94e
</script>
Packit f0b94e
</body>
Packit f0b94e
</html>