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