1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Custom Element Base Delayed Connected"
onload="runTests();"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
<script type="application/javascript"><![CDATA[
let nativeDOMContentLoadedFired = false;
document.addEventListener("DOMContentLoaded", () => {
nativeDOMContentLoadedFired = true;
}, { once: true });
// To test `delayConnectedCallback` and `isConnectedAndReady` we have to run this before
// DOMContentLoaded, which is why this is done in a separate script that runs
// immediately and not in `runTests`.
let delayedConnectionPromise = new Promise(resolve => {
let numSkippedAttributeChanges = 0;
let numDelayedConnections = 0;
let numDelayedDisconnections = 0;
let finishedWaitingForDOMReady = false;
// Register this custom element before DOMContentLoaded has fired and before it's parsed in
// the markup:
customElements.define("delayed-connection", class DelayedConnection extends MozXULElement {
static get observedAttributes() { return ["foo"]; }
attributeChangedCallback() {
ok(!this.isConnectedAndReady,
"attributeChangedCallback fires before isConnectedAndReady");
ok(!nativeDOMContentLoadedFired,
"attributeChangedCallback fires before nativeDOMContentLoadedFired");
numSkippedAttributeChanges++;
}
connectedCallback() {
if (this.delayConnectedCallback()) {
ok(!finishedWaitingForDOMReady,
"connectedCallback with delayConnectedCallback fires before finishedWaitingForDOMReady");
ok(!this.isConnectedAndReady,
"connectedCallback with delayConnectedCallback fires before isConnectedAndReady");
ok(!nativeDOMContentLoadedFired,
"connectedCallback with delayConnectedCallback fires before nativeDOMContentLoadedFired");
numDelayedConnections++;
return;
}
ok(!finishedWaitingForDOMReady,
"connectedCallback only fires once when DOM is ready");
ok(this.isConnectedAndReady,
"isConnectedAndReady during connectedCallback");
ok(!nativeDOMContentLoadedFired,
"delayed connectedCallback fires before nativeDOMContentLoadedFired");
is(numSkippedAttributeChanges, 2,
"Correct number of skipped attribute changes");
is(numDelayedConnections, 2,
"Correct number of delayed connections");
is(numDelayedDisconnections, 1,
"Correct number of delated disconnections");
finishedWaitingForDOMReady = true;
resolve();
}
disconnectedCallback() {
ok(this.delayConnectedCallback(),
"disconnectedCallback while DOM not ready");
is(numDelayedDisconnections, 0,
"disconnectedCallback fired only once");
numDelayedDisconnections++;
}
});
});
// This should be called after the element is parsed below this.
function mutateDelayedConnection() {
// Fire connectedCallback and attributeChangedCallback twice before DOMContentLoaded
// fires. The first connectedCallback is due to the parse and the second due to re-appending.
let delayedConnection = document.querySelector("delayed-connection");
delayedConnection.setAttribute("foo", "bar");
delayedConnection.remove();
delayedConnection.setAttribute("foo", "bat");
document.documentElement.append(delayedConnection);
}
]]>
</script>
<delayed-connection></delayed-connection>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SimpleTest.waitForExplicitFinish();
mutateDelayedConnection();
async function runTests() {
info("Waiting for delayed connection to fire");
ok(nativeDOMContentLoadedFired,
"nativeDOMContentLoadedFired is true in runTests");
await delayedConnectionPromise;
SimpleTest.finish();
}
]]>
</script>
</window>
|