summaryrefslogtreecommitdiffstats
path: root/dom/base/test/test_mutationobserver_anonymous.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/test/test_mutationobserver_anonymous.html')
-rw-r--r--dom/base/test/test_mutationobserver_anonymous.html265
1 files changed, 265 insertions, 0 deletions
diff --git a/dom/base/test/test_mutationobserver_anonymous.html b/dom/base/test/test_mutationobserver_anonymous.html
new file mode 100644
index 0000000000..191de9a4ea
--- /dev/null
+++ b/dom/base/test/test_mutationobserver_anonymous.html
@@ -0,0 +1,265 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1034110
+-->
+<head>
+ <title>Test for Bug 1034110</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1034110">Mozilla Bug 1034110</a>
+<style type="text/css">
+ #pseudo.before::before { content: "before"; }
+ #pseudo.after::after { content: "after"; }
+</style>
+<div id="pseudo"></div>
+<video id="video"></video>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1034110 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function getWalker(node) {
+ return SpecialPowers.createDOMWalker(node, true);
+}
+
+function getFirstChild(parent) {
+ return SpecialPowers.unwrap(getWalker(parent).firstChild);
+}
+
+function getLastChild(parent) {
+ return SpecialPowers.unwrap(getWalker(parent).lastChild);
+}
+
+function assertSamePseudoElement(which, node1, node2) {
+ is(SpecialPowers.wrap(node1).nodeName, "_moz_generated_content_" + which,
+ "Correct pseudo element type");
+ is(node1, node2,
+ "Referencing the same ::after element");
+}
+
+window.onload = function () {
+ testOneAdded();
+};
+
+function testOneAdded() {
+ let parent = document.getElementById("pseudo");
+ var m = new MutationObserver(function(records, observer) {
+ is(records.length, 1, "Correct number of records");
+ is(records[0].type, "nativeAnonymousChildList", "Correct record type");
+ is(records[0].target, parent, "Correct target");
+
+ is(records[0].addedNodes.length, 1, "Should have got addedNodes");
+ assertSamePseudoElement("before", records[0].addedNodes[0], getFirstChild(parent));
+ is(records[0].removedNodes.length, 0, "Shouldn't have got removedNodes");
+
+ observer.disconnect();
+ testAddedAndRemoved();
+ });
+
+ SpecialPowers.observeMutationEvents(m, parent, true);
+ parent.className = "before";
+}
+
+function testAddedAndRemoved() {
+ let parent = document.getElementById("pseudo");
+ let originalBeforeElement = getFirstChild(parent);
+ var m = new MutationObserver(function(records, observer) {
+ is(records.length, 2, "Correct number of records");
+ is(records[0].type, "nativeAnonymousChildList", "Correct record type (1)");
+ is(records[1].type, "nativeAnonymousChildList", "Correct record type (2)");
+ is(records[0].target, parent, "Correct target (1)");
+ is(records[1].target, parent, "Correct target (2)");
+
+ // Two records are sent - one for removed and one for added.
+ is(records[0].addedNodes.length, 0, "Shouldn't have got addedNodes");
+ is(records[0].removedNodes.length, 1, "Should have got removedNodes");
+ assertSamePseudoElement("before", records[0].removedNodes[0], originalBeforeElement);
+
+ is(records[1].addedNodes.length, 1, "Should have got addedNodes");
+ assertSamePseudoElement("after", records[1].addedNodes[0], getLastChild(parent));
+ is(records[1].removedNodes.length, 0, "Shouldn't have got removedNodes");
+
+ observer.disconnect();
+ testRemoved();
+ });
+
+ SpecialPowers.observeMutationEvents(m, parent, true);
+ parent.className = "after";
+}
+
+function testRemoved() {
+ let parent = document.getElementById("pseudo");
+ let originalAfterElement = getLastChild(parent);
+ var m = new MutationObserver(function(records, observer) {
+ is(records.length, 1, "Correct number of records");
+ is(records[0].type, "nativeAnonymousChildList", "Correct record type");
+ is(records[0].target, parent, "Correct target");
+
+ is(records[0].addedNodes.length, 0, "Shouldn't have got addedNodes");
+ is(records[0].removedNodes.length, 1, "Should have got removedNodes");
+ assertSamePseudoElement("after", records[0].removedNodes[0], originalAfterElement);
+
+ observer.disconnect();
+ testMultipleAdded();
+ });
+
+ SpecialPowers.observeMutationEvents(m, parent, true);
+ parent.className = "";
+}
+
+function testMultipleAdded() {
+ let parent = document.getElementById("pseudo");
+ var m = new MutationObserver(function(records, observer) {
+ is(records.length, 2, "Correct number of records");
+ is(records[0].type, "nativeAnonymousChildList", "Correct record type (1)");
+ is(records[1].type, "nativeAnonymousChildList", "Correct record type (2)");
+ is(records[0].target, parent, "Correct target (1)");
+ is(records[1].target, parent, "Correct target (2)");
+
+ is(records[0].addedNodes.length, 1, "Should have got addedNodes");
+ assertSamePseudoElement("before", records[0].addedNodes[0], getFirstChild(parent));
+ is(records[0].removedNodes.length, 0, "Shouldn't have got removedNodes");
+
+ is(records[1].addedNodes.length, 1, "Should have got addedNodes");
+ assertSamePseudoElement("after", records[1].addedNodes[0], getLastChild(parent));
+ is(records[1].removedNodes.length, 0, "Shouldn't have got removedNodes");
+
+ observer.disconnect();
+ testRemovedDueToDisplay();
+ });
+
+ SpecialPowers.observeMutationEvents(m, parent, true);
+ parent.className = "before after";
+}
+
+function testRemovedDueToDisplay() {
+ let parent = document.getElementById("pseudo");
+ let originalBeforeElement = getFirstChild(parent);
+ let originalAfterElement = getLastChild(parent);
+ var m = new MutationObserver(function(records, observer) {
+ is(records.length, 2, "Correct number of records");
+ is(records[0].type, "nativeAnonymousChildList", "Correct record type (1)");
+ is(records[1].type, "nativeAnonymousChildList", "Correct record type (2)");
+ is(records[0].target, parent, "Correct target (1)");
+ is(records[1].target, parent, "Correct target (2)");
+
+ is(records[0].addedNodes.length, 0, "Shouldn't have got addedNodes");
+ is(records[0].removedNodes.length, 1, "Should have got removedNodes");
+ assertSamePseudoElement("after", records[0].removedNodes[0], originalAfterElement);
+
+ is(records[1].addedNodes.length, 0, "Shouldn't have got addedNodes");
+ is(records[1].removedNodes.length, 1, "Should have got removedNodes");
+ assertSamePseudoElement("before", records[1].removedNodes[0], originalBeforeElement);
+
+ observer.disconnect();
+ testAddedDueToDisplay();
+ });
+
+ SpecialPowers.observeMutationEvents(m, parent, true);
+ parent.style.display = "none";
+}
+
+function testAddedDueToDisplay() {
+ let parent = document.getElementById("pseudo");
+ var m = new MutationObserver(function(records, observer) {
+ is(records.length, 2, "Correct number of records");
+ is(records[0].type, "nativeAnonymousChildList", "Correct record type (1)");
+ is(records[1].type, "nativeAnonymousChildList", "Correct record type (2)");
+ is(records[0].target, parent, "Correct target (1)");
+ is(records[1].target, parent, "Correct target (2)");
+
+ is(records[0].addedNodes.length, 1, "Should have got addedNodes");
+ assertSamePseudoElement("before", records[0].addedNodes[0], getFirstChild(parent));
+ is(records[0].removedNodes.length, 0, "Shouldn't have got removedNodes");
+
+ is(records[1].addedNodes.length, 1, "Should have got addedNodes");
+ assertSamePseudoElement("after", records[1].addedNodes[0], getLastChild(parent));
+ is(records[1].removedNodes.length, 0, "Shouldn't have got removedNodes");
+
+ observer.disconnect();
+ testDifferentTargetNoSubtree();
+ });
+
+ SpecialPowers.observeMutationEvents(m, parent, true);
+ parent.style.display = "block";
+}
+
+function testDifferentTargetNoSubtree() {
+ let parent = document.getElementById("pseudo");
+ var m = new MutationObserver(function(records, observer) {
+ ok(false,
+ "No mutation should fire when observing on a parent without subtree option.");
+ });
+ SpecialPowers.observeMutationEvents(m, document, true);
+ parent.style.display = "none";
+
+ // Wait for the actual mutation to come through, making sure that
+ // the original observer never fires.
+ var m2 = new MutationObserver(function(records, observer) {
+ ok(!getFirstChild(parent), "Pseudo element has been removed, but no mutation");
+ ok(!getLastChild(parent), "Pseudo element has been removed, but no mutation");
+ observer.disconnect();
+ testSubtree();
+ });
+ SpecialPowers.observeMutationEvents(m2, parent, true);
+}
+
+function testSubtree() {
+ let parent = document.getElementById("pseudo");
+ var m = new MutationObserver(function(records, observer) {
+ is(records.length, 2, "Correct number of records");
+ is(records[0].type, "nativeAnonymousChildList", "Correct record type (1)");
+ is(records[1].type, "nativeAnonymousChildList", "Correct record type (2)");
+ is(records[0].target, parent, "Correct target (1)");
+ is(records[1].target, parent, "Correct target (2)");
+
+ is(records[0].addedNodes.length, 1, "Should have got addedNodes");
+ assertSamePseudoElement("before", records[0].addedNodes[0], getFirstChild(parent));
+ is(records[0].removedNodes.length, 0, "Shouldn't have got removedNodes");
+
+ is(records[1].addedNodes.length, 1, "Should have got addedNodes");
+ assertSamePseudoElement("after", records[1].addedNodes[0], getLastChild(parent));
+ is(records[1].removedNodes.length, 0, "Shouldn't have got removedNodes");
+
+ observer.disconnect();
+ testDictionaryWithoutChromePriv();
+ });
+ SpecialPowers.observeMutationEvents(m, document, true, true);
+ parent.style.display = "block";
+}
+
+function testDictionaryWithoutChromePriv()
+{
+ var m = new MutationObserver(function() {});
+ try {
+ m.observe(document, { childList: true, get nativeAnonymousChildList() { throw "Foo1"; } } );
+ ok(true, "Shouldn't throw!");
+ } catch(ex) {
+ ok(false, "Did throw " + ex);
+ }
+
+ try {
+ m.observe(document, { childList: true, get animations() { throw "Foo2"; } } );
+ ok(true, "Shouldn't throw!");
+ } catch(ex) {
+ ok(false, "Did throw " + ex);
+ }
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>