summaryrefslogtreecommitdiffstats
path: root/dom/base/test/test_mutationobservers.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/test/test_mutationobservers.html')
-rw-r--r--dom/base/test/test_mutationobservers.html913
1 files changed, 0 insertions, 913 deletions
diff --git a/dom/base/test/test_mutationobservers.html b/dom/base/test/test_mutationobservers.html
deleted file mode 100644
index a6de89595..000000000
--- a/dom/base/test/test_mutationobservers.html
+++ /dev/null
@@ -1,913 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=641821
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 641821</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onload="runTest()">
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=641821">Mozilla Bug 641821</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 641821 **/
-
-SimpleTest.requestFlakyTimeout("requestFlakyTimeout is silly. (But make sure marquee has time to initialize itself.)");
-
-var div = document.createElement("div");
-
-var M;
-if ("MozMutationObserver" in window) {
- M = window.MozMutationObserver;
-} else if ("WebKitMutationObserver" in window) {
- M = window.WebKitMutationObserver;
-} else {
- M = window.MutationObserver;
-}
-
-function log(str) {
- var d = document.createElement("div");
- d.textContent = str;
- if (str.indexOf("PASSED") >= 0) {
- d.setAttribute("style", "color: green;");
- } else {
- d.setAttribute("style", "color: red;");
- }
- document.getElementById("log").appendChild(d);
-}
-
-// Some helper functions so that this test runs also outside mochitest.
-if (!("ok" in window)) {
- window.ok = function(val, str) {
- log(str + (val ? " PASSED\n" : " FAILED\n"));
- }
-}
-
-if (!("is" in window)) {
- window.is = function(val, refVal, str) {
- log(str + (val == refVal? " PASSED " : " FAILED ") +
- (val != refVal ? "expected " + refVal + " got " + val + "\n" : "\n"));
- }
-}
-
-if (!("isnot" in window)) {
- window.isnot = function(val, refVal, str) {
- log(str + (val != refVal? " PASSED " : " FAILED ") +
- (val == refVal ? "Didn't expect " + refVal + "\n" : "\n"));
- }
-}
-
-if (!("SimpleTest" in window)) {
- window.SimpleTest =
- {
- finish: function() {
- document.getElementById("log").appendChild(document.createTextNode("DONE"));
- },
- waitForExplicitFinish: function() {}
- }
-}
-
-function then(thenFn) {
- setTimeout(function() {
- if (thenFn) {
- setTimeout(thenFn, 0);
- } else {
- SimpleTest.finish();
- }
- }, 0);
-}
-
-var m;
-var m2;
-var m3;
-var m4;
-
-// Checks basic parameter validation and normal 'this' handling.
-// Tests also basic attribute handling.
-function runTest() {
- m = new M(function(){});
- ok(m, "MutationObserver supported");
-
- var e = null;
- try {
- m.observe(document, {});
- } catch (ex) {
- e = ex;
- }
- ok(e, "Should have thrown an exception");
- is(e.name, "TypeError", "Should have thrown TypeError");
-
- e = null;
- try {
- m.observe(document, { childList: true, attributeOldValue: true });
- } catch (ex) {
- e = ex;
- }
- ok(!e, "Shouldn't have thrown an exception");
-
- e = null;
- try {
- m.observe(document, { childList: true, attributeFilter: ["foo"] });
- } catch (ex) {
- e = ex;
- }
- ok(!e, "Shouldn't have thrown an exception");
-
- e = null;
- try {
- m.observe(document, { childList: true, characterDataOldValue: true });
- } catch (ex) {
- e = ex;
- }
- ok(!e, "Shouldn't have thrown an exception");
-
- e = null;
- try {
- m.observe(document);
- } catch (ex) {
- e = ex;
- }
- ok(e, "Should have thrown an exception");
-
- m = new M(function(records, observer) {
- is(observer, m, "2nd parameter should be the mutation observer");
- is(observer, this, "2nd parameter should be 'this'");
- is(records.length, 1, "Should have one record.");
- is(records[0].type, "attributes", "Should have got attributes record");
- is(records[0].target, div, "Should have got div as target");
- is(records[0].attributeName, "foo", "Should have got record about foo attribute");
- observer.disconnect();
- then(testThisBind);
- m = null;
- });
- m.observe(div, { attributes: true, attributeFilter: ["foo"] });
- is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].attributes, true);
- is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].attributeFilter.length, 1)
- is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].attributeFilter[0], "foo")
- div.setAttribute("foo", "bar");
-}
-
-// 'this' handling when fn.bind() is used.
-function testThisBind() {
- var child = div.appendChild(document.createElement("div"));
- var gchild = child.appendChild(document.createElement("div"));
- m = new M((function(records, observer) {
- is(observer, m, "2nd parameter should be the mutation observer");
- isnot(observer, this, "2nd parameter should be 'this'");
- is(records.length, 3, "Should have one record.");
- is(records[0].type, "attributes", "Should have got attributes record");
- is(records[0].target, div, "Should have got div as target");
- is(records[0].attributeName, "foo", "Should have got record about foo attribute");
- is(records[0].oldValue, "bar", "oldValue should be bar");
- is(records[1].type, "attributes", "Should have got attributes record");
- is(records[1].target, div, "Should have got div as target");
- is(records[1].attributeName, "foo", "Should have got record about foo attribute");
- is(records[1].oldValue, "bar2", "oldValue should be bar2");
- is(records[2].type, "attributes", "Should have got attributes record");
- is(records[2].target, gchild, "Should have got div as target");
- is(records[2].attributeName, "foo", "Should have got record about foo attribute");
- is(records[2].oldValue, null, "oldValue should be bar2");
- observer.disconnect();
- then(testCharacterData);
- m = null;
- }).bind(window));
- m.observe(div, { attributes: true, attributeOldValue: true, subtree: true });
- is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].attributes, true)
- is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].attributeOldValue, true)
- is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].subtree, true)
- div.setAttribute("foo", "bar2");
- div.removeAttribute("foo");
- div.removeChild(child);
- child.removeChild(gchild);
- div.appendChild(gchild);
- div.removeChild(gchild);
- gchild.setAttribute("foo", "bar");
-}
-
-function testCharacterData() {
- m = new M(function(records, observer) {
- is(records[0].type, "characterData", "Should have got characterData");
- is(records[0].oldValue, null, "Shouldn't have got oldData");
- observer.disconnect();
- m = null;
- });
- m2 = new M(function(records, observer) {
- is(records[0].type, "characterData", "Should have got characterData");
- is(records[0].oldValue, "foo", "Should have got oldData");
- observer.disconnect();
- m2 = null;
- });
- m3 = new M(function(records, observer) {
- ok(false, "This should not be called!");
- observer.disconnect();
- m3 = null;
- });
- m4 = new M(function(records, observer) {
- is(records[0].oldValue, null, "Shouldn't have got oldData");
- observer.disconnect();
- m3.disconnect();
- m3 = null;
- then(testChildList);
- m4 = null;
- });
-
- div.appendChild(document.createTextNode("foo"));
- m.observe(div, { characterData: true, subtree: true });
- m2.observe(div, { characterData: true, characterDataOldValue: true, subtree: true});
- // If observing the same node twice, only the latter option should apply.
- m3.observe(div, { characterData: true, subtree: true });
- m3.observe(div, { characterData: true, subtree: false });
- m4.observe(div.firstChild, { characterData: true, subtree: false });
-
- is(SpecialPowers.wrap(div).getBoundMutationObservers().length, 3)
- is(SpecialPowers.wrap(div).getBoundMutationObservers()[2].getObservingInfo()[0].characterData, true)
- is(SpecialPowers.wrap(div).getBoundMutationObservers()[2].getObservingInfo()[0].subtree, false)
-
- div.firstChild.data = "bar";
-}
-
-function testChildList() {
- var fc = div.firstChild;
- m = new M(function(records, observer) {
- is(records[0].type, "childList", "Should have got childList");
- is(records[0].addedNodes.length, 0, "Shouldn't have got addedNodes");
- is(records[0].removedNodes.length, 1, "Should have got removedNodes");
- is(records[0].removedNodes[0], fc, "Should have removed a text node");
- observer.disconnect();
- then(testChildList2);
- m = null;
- });
- m.observe(div, { childList: true});
- div.removeChild(div.firstChild);
-}
-
-function testChildList2() {
- div.innerHTML = "<span>1</span><span>2</span>";
- m = new M(function(records, observer) {
- is(records[0].type, "childList", "Should have got childList");
- is(records[0].removedNodes.length, 2, "Should have got removedNodes");
- is(records[0].addedNodes.length, 1, "Should have got addedNodes");
- observer.disconnect();
- then(testChildList3);
- m = null;
- });
- m.observe(div, { childList: true });
- div.innerHTML = "<span><span>foo</span></span>";
-}
-
-function testChildList3() {
- m = new M(function(records, observer) {
- is(records[0].type, "childList", "Should have got childList");
- is(records[0].removedNodes.length, 1, "Should have got removedNodes");
- is(records[0].addedNodes.length, 1, "Should have got addedNodes");
- observer.disconnect();
- then(testChildList4);
- m = null;
- });
- m.observe(div, { childList: true });
- div.textContent = "hello";
-}
-
-function testChildList4() {
- div.textContent = null;
- var df = document.createDocumentFragment();
- var t1 = df.appendChild(document.createTextNode("Hello "));
- var t2 = df.appendChild(document.createTextNode("world!"));
- var s1 = div.appendChild(document.createElement("span"));
- s1.textContent = "foo";
- var s2 = div.appendChild(document.createElement("span"));
- function callback(records, observer) {
- is(records.length, 3, "Should have got one record for removing nodes from document fragment and one record for adding them to div");
- is(records[0].removedNodes.length, 2, "Should have got removedNodes");
- is(records[0].removedNodes[0], t1, "Should be the 1st textnode");
- is(records[0].removedNodes[1], t2, "Should be the 2nd textnode");
- is(records[1].addedNodes.length, 2, "Should have got addedNodes");
- is(records[1].addedNodes[0], t1, "Should be the 1st textnode");
- is(records[1].addedNodes[1], t2, "Should be the 2nd textnode");
- is(records[1].previousSibling, s1, "Should have previousSibling");
- is(records[1].nextSibling, s2, "Should have nextSibling");
- is(records[2].type, "characterData", "3rd record should be characterData");
- is(records[2].target, t1, "target should be the textnode");
- is(records[2].oldValue, "Hello ", "oldValue was 'Hello '");
- observer.disconnect();
- then(testChildList5);
- m = null;
- };
- m = new M(callback);
- m.observe(df, { childList: true, characterData: true, characterDataOldValue: true, subtree: true });
- is(SpecialPowers.wrap(df).getBoundMutationObservers()[0].getObservingInfo()[0].childList, true)
- is(SpecialPowers.wrap(df).getBoundMutationObservers()[0].getObservingInfo()[0].characterData, true)
- is(SpecialPowers.wrap(df).getBoundMutationObservers()[0].getObservingInfo()[0].characterDataOldValue, true)
- is(SpecialPowers.wrap(df).getBoundMutationObservers()[0].getObservingInfo()[0].subtree, true)
- ok(SpecialPowers.compare(SpecialPowers.wrap(df).getBoundMutationObservers()[0].mutationCallback, callback))
- m.observe(div, { childList: true });
- is(SpecialPowers.wrap(df).getBoundMutationObservers()[0].getObservingInfo().length, 2)
-
- // Make sure transient observers aren't leaked.
- var leakTest = new M(function(){});
- leakTest.observe(div, { characterData: true, subtree: true });
-
- div.insertBefore(df, s2);
- s1.firstChild.data = "bar"; // This should *not* create a record.
- t1.data = "Hello the whole "; // This should create a record.
-}
-
-function testChildList5() {
- div.textContent = null;
- var c1 = div.appendChild(document.createElement("div"));
- var c2 = document.createElement("div");
- var div2 = document.createElement("div");
- var c3 = div2.appendChild(document.createElement("div"));
- var c4 = document.createElement("div");
- var c5 = document.createElement("div");
- var df = document.createDocumentFragment();
- var emptyDF = document.createDocumentFragment();
- var dfc1 = df.appendChild(document.createElement("div"));
- var dfc2 = df.appendChild(document.createElement("div"));
- var dfc3 = df.appendChild(document.createElement("div"));
- m = new M(function(records, observer) {
- is(records.length, 6 , "");
- is(records[0].removedNodes.length, 1, "Should have got removedNodes");
- is(records[0].removedNodes[0], c1, "");
- is(records[0].addedNodes.length, 1, "Should have got addedNodes");
- is(records[0].addedNodes[0], c2, "");
- is(records[0].previousSibling, null, "");
- is(records[0].nextSibling, null, "");
- is(records[1].removedNodes.length, 1, "Should have got removedNodes");
- is(records[1].removedNodes[0], c3, "");
- is(records[1].addedNodes.length, 0, "Shouldn't have got addedNodes");
- is(records[1].previousSibling, null, "");
- is(records[1].nextSibling, null, "");
- is(records[2].removedNodes.length, 1, "Should have got removedNodes");
- is(records[2].removedNodes[0], c2, "");
- is(records[2].addedNodes.length, 1, "Should have got addedNodes");
- is(records[2].addedNodes[0], c3, "");
- is(records[2].previousSibling, null, "");
- is(records[2].nextSibling, null, "");
- // Check document fragment handling
- is(records[5].removedNodes.length, 1, "");
- is(records[5].removedNodes[0], c4, "");
- is(records[5].addedNodes.length, 3, "");
- is(records[5].addedNodes[0], dfc1, "");
- is(records[5].addedNodes[1], dfc2, "");
- is(records[5].addedNodes[2], dfc3, "");
- is(records[5].previousSibling, c3, "");
- is(records[5].nextSibling, c5, "");
- observer.disconnect();
- then(testAdoptNode);
- m = null;
- });
- m.observe(div, { childList: true, subtree: true });
- m.observe(div2, { childList: true, subtree: true });
- div.replaceChild(c2, c1);
- div.replaceChild(c3, c2);
- div.appendChild(c4);
- div.appendChild(c5);
- div.replaceChild(df, c4);
- div.appendChild(emptyDF); // empty document shouldn't cause mutation records
-}
-
-function testAdoptNode() {
- var d1 = document.implementation.createHTMLDocument(null);
- var d2 = document.implementation.createHTMLDocument(null);
- var addedNode;
- m = new M(function(records, observer) {
- is(records.length, 3, "Should have 2 records");
- is(records[0].target.ownerDocument, d1, "ownerDocument should be the initial document")
- is(records[1].target.ownerDocument, d2, "ownerDocument should be the new document");
- is(records[2].type, "attributes", "Should have got attribute mutation")
- is(records[2].attributeName, "foo", "Should have got foo attribute mutation")
- observer.disconnect();
- then(testOuterHTML);
- m = null;
- });
- m.observe(d1, { childList: true, subtree: true, attributes: true });
- d2.body.appendChild(d1.body);
- addedNode = d2.body.lastChild.appendChild(d2.createElement("div"));
- addedNode.setAttribute("foo", "bar");
-}
-
-function testOuterHTML() {
- var doc = document.implementation.createHTMLDocument(null);
- var d1 = doc.body.appendChild(document.createElement("div"));
- var d2 = doc.body.appendChild(document.createElement("div"));
- var d3 = doc.body.appendChild(document.createElement("div"));
- var d4 = doc.body.appendChild(document.createElement("div"));
- m = new M(function(records, observer) {
- is(records.length, 4, "Should have 1 record");
- is(records[0].removedNodes.length, 1, "Should have 1 removed nodes");
- is(records[0].addedNodes.length, 2, "Should have 2 added nodes");
- is(records[0].previousSibling, null, "");
- is(records[0].nextSibling, d2, "");
- is(records[1].removedNodes.length, 1, "Should have 1 removed nodes");
- is(records[1].addedNodes.length, 2, "Should have 2 added nodes");
- is(records[1].previousSibling, records[0].addedNodes[1], "");
- is(records[1].nextSibling, d3, "");
- is(records[2].removedNodes.length, 1, "Should have 1 removed nodes");
- is(records[2].addedNodes.length, 2, "Should have 2 added nodes");
- is(records[2].previousSibling, records[1].addedNodes[1], "");
- is(records[2].nextSibling, d4, "");
- is(records[3].removedNodes.length, 1, "Should have 1 removed nodes");
- is(records[3].addedNodes.length, 0);
- is(records[3].previousSibling, records[2].addedNodes[1], "");
- is(records[3].nextSibling, null, "");
- observer.disconnect();
- then(testInsertAdjacentHTML);
- m = null;
- });
- m.observe(doc, { childList: true, subtree: true });
- d1.outerHTML = "<div>1</div><div>1</div>";
- d2.outerHTML = "<div>2</div><div>2</div>";
- d3.outerHTML = "<div>3</div><div>3</div>";
- d4.outerHTML = "";
-}
-
-function testInsertAdjacentHTML() {
- var doc = document.implementation.createHTMLDocument(null);
- var d1 = doc.body.appendChild(document.createElement("div"));
- var d2 = doc.body.appendChild(document.createElement("div"));
- var d3 = doc.body.appendChild(document.createElement("div"));
- var d4 = doc.body.appendChild(document.createElement("div"));
- m = new M(function(records, observer) {
- is(records.length, 4, "");
- is(records[0].target, doc.body, "");
- is(records[0].previousSibling, null, "");
- is(records[0].nextSibling, d1, "");
- is(records[1].target, d2, "");
- is(records[1].previousSibling, null, "");
- is(records[1].nextSibling, null, "");
- is(records[2].target, d3, "");
- is(records[2].previousSibling, null, "");
- is(records[2].nextSibling, null, "");
- is(records[3].target, doc.body, "");
- is(records[3].previousSibling, d4, "");
- is(records[3].nextSibling, null, "");
- observer.disconnect();
- then(testSyncXHR);
- m = null;
- });
- m.observe(doc, { childList: true, subtree: true });
- d1.insertAdjacentHTML("beforebegin", "<div></div><div></div>");
- d2.insertAdjacentHTML("afterbegin", "<div></div><div></div>");
- d3.insertAdjacentHTML("beforeend", "<div></div><div></div>");
- d4.insertAdjacentHTML("afterend", "<div></div><div></div>");
-}
-
-
-var callbackHandled = false;
-
-function testSyncXHR() {
- div.textContent = null;
- m = new M(function(records, observer) {
- is(records.length, 1, "");
- is(records[0].addedNodes.length, 1, "");
- callbackHandled = true;
- observer.disconnect();
- m = null;
- });
- m.observe(div, { childList: true, subtree: true });
- div.innerHTML = "<div>hello</div>";
- var x = new XMLHttpRequest();
- x.open("GET", window.location, false);
- x.send();
- ok(!callbackHandled, "Shouldn't have called the mutation callback!");
- setTimeout(testSyncXHR2, 0);
-}
-
-function testSyncXHR2() {
- ok(callbackHandled, "Should have called the mutation callback!");
- then(testTakeRecords);
-}
-
-function testTakeRecords() {
- var s = "<span>1</span><span>2</span>";
- div.innerHTML = s;
- var takenRecords;
- m = new M(function(records, observer) {
- is(records.length, 3, "Should have got 3 records");
-
- is(records[0].type, "attributes", "Should have got attributes");
- is(records[0].attributeName, "foo", "");
- is(records[0].attributeNamespace, null, "");
- is(records[0].prevValue, null, "");
- is(records[1].type, "childList", "Should have got childList");
- is(records[1].removedNodes.length, 2, "Should have got removedNodes");
- is(records[1].addedNodes.length, 2, "Should have got addedNodes");
- is(records[2].type, "attributes", "Should have got attributes");
- is(records[2].attributeName, "foo", "");
-
- is(records.length, takenRecords.length, "Should have had similar mutations");
- is(records[0].type, takenRecords[0].type, "Should have had similar mutations");
- is(records[1].type, takenRecords[1].type, "Should have had similar mutations");
- is(records[2].type, takenRecords[2].type, "Should have had similar mutations");
-
- is(records[1].removedNodes.length, takenRecords[1].removedNodes.length, "Should have had similar mutations");
- is(records[1].addedNodes.length, takenRecords[1].addedNodes.length, "Should have had similar mutations");
-
- is(m.takeRecords().length, 0, "Shouldn't have any records");
- observer.disconnect();
- then(testMutationObserverAndEvents);
- m = null;
- });
- m.observe(div, { childList: true, attributes: true });
- div.setAttribute("foo", "bar");
- div.innerHTML = s;
- div.removeAttribute("foo");
- takenRecords = m.takeRecords();
- div.setAttribute("foo", "bar");
- div.innerHTML = s;
- div.removeAttribute("foo");
-}
-
-function testTakeRecords() {
- function mutationListener(e) {
- ++mutationEventCount;
- is(e.attrChange, MutationEvent.ADDITION, "unexpected change");
- }
-
- m = new M(function(records, observer) {
- is(records.length, 2, "Should have got 2 records");
- is(records[0].type, "attributes", "Should have got attributes");
- is(records[0].attributeName, "foo", "");
- is(records[0].oldValue, null, "");
- is(records[1].type, "attributes", "Should have got attributes");
- is(records[1].attributeName, "foo", "");
- is(records[1].oldValue, "bar", "");
- observer.disconnect();
- div.removeEventListener("DOMAttrModified", mutationListener);
- then(testExpandos);
- m = null;
- });
- m.observe(div, { attributes: true, attributeOldValue: true });
- // Note, [0] points to a mutation observer which is there for a leak test!
- ok(SpecialPowers.compare(SpecialPowers.wrap(div).getBoundMutationObservers()[1], m));
- var mutationEventCount = 0;
- div.addEventListener("DOMAttrModified", mutationListener);
- div.setAttribute("foo", "bar");
- div.setAttribute("foo", "bar");
- is(mutationEventCount, 1, "Should have got only one mutation event!");
-}
-
-function testExpandos() {
- var m2 = new M(function(records, observer) {
- is(observer.expandoProperty, true);
- observer.disconnect();
- then(testOutsideShadowDOM);
- });
- m2.expandoProperty = true;
- m2.observe(div, { attributes: true });
- m2 = null;
- if (SpecialPowers) {
- // Run GC several times to see if the expando property disappears.
-
- SpecialPowers.gc();
- SpecialPowers.gc();
- SpecialPowers.gc();
- SpecialPowers.gc();
- }
- div.setAttribute("foo", "bar2");
-}
-
-function testOutsideShadowDOM() {
- var m = new M(function(records, observer) {
- is(records.length, 1);
- is(records[0].type, "attributes", "Should have got attributes");
- observer.disconnect();
- then(testInsideShadowDOM);
- });
- m.observe(div, {
- attributes: true,
- childList: true,
- characterData: true,
- subtree: true
- })
- var sr = div.createShadowRoot();
- sr.innerHTML = "<div" + ">text</" + "div>";
- sr.firstChild.setAttribute("foo", "bar");
- sr.firstChild.firstChild.data = "text2";
- sr.firstChild.appendChild(document.createElement("div"));
- div.setAttribute("foo", "bar");
-}
-
-function testInsideShadowDOM() {
- var m = new M(function(records, observer) {
- is(records.length, 4);
- is(records[0].type, "childList");
- is(records[1].type, "attributes");
- is(records[2].type, "characterData");
- is(records[3].type, "childList");
- observer.disconnect();
- then(testMarquee);
- });
- var sr = div.createShadowRoot();
- m.observe(sr, {
- attributes: true,
- childList: true,
- characterData: true,
- subtree: true
- });
-
- sr.innerHTML = "<div" + ">text</" + "div>";
- sr.firstChild.setAttribute("foo", "bar");
- sr.firstChild.firstChild.data = "text2";
- sr.firstChild.appendChild(document.createElement("div"));
- div.setAttribute("foo", "bar2");
-
-}
-
-function testMarquee() {
- var m = new M(function(records, observer) {
- is(records.length, 1);
- is(records[0].type, "attributes");
- is(records[0].attributeName, "ok");
- is(records[0].oldValue, null);
- observer.disconnect();
- then(testStyleCreate);
- });
- var marquee = document.createElement("marquee");
- m.observe(marquee, {
- attributes: true,
- attributeOldValue: true,
- childList: true,
- characterData: true,
- subtree: true
- });
- document.body.appendChild(marquee);
- setTimeout(function() {marquee.setAttribute("ok", "ok")}, 500);
-}
-
-function testStyleCreate() {
- m = new M(function(records, observer) {
- is(records.length, 1, "number of records");
- is(records[0].type, "attributes", "record.type");
- is(records[0].attributeName, "style", "record.attributeName");
- is(records[0].oldValue, null, "record.oldValue");
- isnot(div.getAttribute("style"), null, "style attribute after creation");
- observer.disconnect();
- m = null;
- div.removeAttribute("style");
- then(testStyleModify);
- });
- m.observe(div, { attributes: true, attributeOldValue: true });
- is(div.getAttribute("style"), null, "style attribute before creation");
- div.style.color = "blue";
-}
-
-function testStyleModify() {
- div.style.color = "yellow";
- m = new M(function(records, observer) {
- is(records.length, 1, "number of records");
- is(records[0].type, "attributes", "record.type");
- is(records[0].attributeName, "style", "record.attributeName");
- isnot(div.getAttribute("style"), null, "style attribute after modification");
- observer.disconnect();
- m = null;
- div.removeAttribute("style");
- then(testStyleRead);
- });
- m.observe(div, { attributes: true });
- isnot(div.getAttribute("style"), null, "style attribute before modification");
- div.style.color = "blue";
-}
-
-function testStyleRead() {
- m = new M(function(records, observer) {
- is(records.length, 1, "number of records");
- is(records[0].type, "attributes", "record.type");
- is(records[0].attributeName, "data-test", "record.attributeName");
- is(div.getAttribute("style"), null, "style attribute after read");
- observer.disconnect();
- div.removeAttribute("data-test");
- m = null;
- then(testStyleRemoveProperty);
- });
- m.observe(div, { attributes: true });
- is(div.getAttribute("style"), null, "style attribute before read");
- var value = div.style.color; // shouldn't generate any mutation records
- div.setAttribute("data-test", "a");
-}
-
-function testStyleRemoveProperty() {
- div.style.color = "blue";
- m = new M(function(records, observer) {
- is(records.length, 1, "number of records");
- is(records[0].type, "attributes", "record.type");
- is(records[0].attributeName, "style", "record.attributeName");
- isnot(div.getAttribute("style"), null, "style attribute after successful removeProperty");
- observer.disconnect();
- m = null;
- div.removeAttribute("style");
- then(testStyleRemoveProperty2);
- });
- m.observe(div, { attributes: true });
- isnot(div.getAttribute("style"), null, "style attribute before successful removeProperty");
- div.style.removeProperty("color");
-}
-
-function testStyleRemoveProperty2() {
- m = new M(function(records, observer) {
- is(records.length, 1, "number of records");
- is(records[0].type, "attributes", "record.type");
- is(records[0].attributeName, "data-test", "record.attributeName");
- is(div.getAttribute("style"), null, "style attribute after unsuccessful removeProperty");
- observer.disconnect();
- m = null;
- div.removeAttribute("data-test");
- then(testAttributeRecordMerging1);
- });
- m.observe(div, { attributes: true });
- is(div.getAttribute("style"), null, "style attribute before unsuccessful removeProperty");
- div.style.removeProperty("color"); // shouldn't generate any mutation records
- div.setAttribute("data-test", "a");
-}
-
-function testAttributeRecordMerging1() {
- ok(true, "testAttributeRecordMerging1");
- var m = new M(function(records, observer) {
- is(records.length, 2);
- is(records[0].type, "attributes");
- is(records[0].target, div);
- is(records[0].attributeName, "foo");
- is(records[0].attributeNamespace, null);
- is(records[0].oldValue, null);
-
- is(records[1].type, "attributes");
- is(records[1].target, div.firstChild);
- is(records[1].attributeName, "foo");
- is(records[1].attributeNamespace, null);
- is(records[1].oldValue, null);
- observer.disconnect();
- div.innerHTML = "";
- div.removeAttribute("foo");
- then(testAttributeRecordMerging2);
- });
- m.observe(div, {
- attributes: true,
- subtree: true
- });
- SpecialPowers.wrap(m).mergeAttributeRecords = true;
-
- div.setAttribute("foo", "bar_1");
- div.setAttribute("foo", "bar_2");
- div.innerHTML = "<div></div>";
- div.firstChild.setAttribute("foo", "bar_1");
- div.firstChild.setAttribute("foo", "bar_2");
-}
-
-function testAttributeRecordMerging2() {
- ok(true, "testAttributeRecordMerging2");
- var m = new M(function(records, observer) {
- is(records.length, 2);
- is(records[0].type, "attributes");
- is(records[0].target, div);
- is(records[0].attributeName, "foo");
- is(records[0].attributeNamespace, null);
- is(records[0].oldValue, "initial");
-
- is(records[1].type, "attributes");
- is(records[1].target, div.firstChild);
- is(records[1].attributeName, "foo");
- is(records[1].attributeNamespace, null);
- is(records[1].oldValue, "initial");
- observer.disconnect();
- div.innerHTML = "";
- div.removeAttribute("foo");
- then(testAttributeRecordMerging3);
- });
-
- div.setAttribute("foo", "initial");
- div.innerHTML = "<div></div>";
- div.firstChild.setAttribute("foo", "initial");
- m.observe(div, {
- attributes: true,
- subtree: true,
- attributeOldValue: true
- });
- SpecialPowers.wrap(m).mergeAttributeRecords = true;
-
- div.setAttribute("foo", "bar_1");
- div.setAttribute("foo", "bar_2");
- div.firstChild.setAttribute("foo", "bar_1");
- div.firstChild.setAttribute("foo", "bar_2");
-}
-
-function testAttributeRecordMerging3() {
- ok(true, "testAttributeRecordMerging3");
- var m = new M(function(records, observer) {
- is(records.length, 4);
- is(records[0].type, "attributes");
- is(records[0].target, div);
- is(records[0].attributeName, "foo");
- is(records[0].attributeNamespace, null);
- is(records[0].oldValue, "initial");
-
- is(records[1].type, "attributes");
- is(records[1].target, div.firstChild);
- is(records[1].attributeName, "foo");
- is(records[1].attributeNamespace, null);
- is(records[1].oldValue, "initial");
-
- is(records[2].type, "attributes");
- is(records[2].target, div);
- is(records[2].attributeName, "foo");
- is(records[2].attributeNamespace, null);
- is(records[2].oldValue, "bar_1");
-
- is(records[3].type, "attributes");
- is(records[3].target, div.firstChild);
- is(records[3].attributeName, "foo");
- is(records[3].attributeNamespace, null);
- is(records[3].oldValue, "bar_1");
-
- observer.disconnect();
- div.innerHTML = "";
- div.removeAttribute("foo");
- then(testAttributeRecordMerging4);
- });
-
- div.setAttribute("foo", "initial");
- div.innerHTML = "<div></div>";
- div.firstChild.setAttribute("foo", "initial");
- m.observe(div, {
- attributes: true,
- subtree: true,
- attributeOldValue: true
- });
- SpecialPowers.wrap(m).mergeAttributeRecords = true;
-
- // No merging should happen.
- div.setAttribute("foo", "bar_1");
- div.firstChild.setAttribute("foo", "bar_1");
- div.setAttribute("foo", "bar_2");
- div.firstChild.setAttribute("foo", "bar_2");
-}
-
-function testAttributeRecordMerging4() {
- ok(true, "testAttributeRecordMerging4");
- var m = new M(function(records, observer) {
- });
-
- div.setAttribute("foo", "initial");
- div.innerHTML = "<div></div>";
- div.firstChild.setAttribute("foo", "initial");
- m.observe(div, {
- attributes: true,
- subtree: true,
- attributeOldValue: true
- });
- SpecialPowers.wrap(m).mergeAttributeRecords = true;
-
- div.setAttribute("foo", "bar_1");
- div.setAttribute("foo", "bar_2");
- div.firstChild.setAttribute("foo", "bar_1");
- div.firstChild.setAttribute("foo", "bar_2");
-
- var records = m.takeRecords();
-
- is(records.length, 2);
- is(records[0].type, "attributes");
- is(records[0].target, div);
- is(records[0].attributeName, "foo");
- is(records[0].attributeNamespace, null);
- is(records[0].oldValue, "initial");
-
- is(records[1].type, "attributes");
- is(records[1].target, div.firstChild);
- is(records[1].attributeName, "foo");
- is(records[1].attributeNamespace, null);
- is(records[1].oldValue, "initial");
- m.disconnect();
- div.innerHTML = "";
- div.removeAttribute("foo");
- then(testChromeOnly);
-}
-
-function testChromeOnly() {
- // Content can't access nativeAnonymousChildList
- try {
- var mo = new M(function(records, observer) { });
- mo.observe(div, { nativeAnonymousChildList: true });
- ok(false, "Should have thrown when trying to observe with chrome-only init");
- } catch (e) {
- ok(true, "Throws when trying to observe with chrome-only init");
- }
-
- then();
-}
-
-SimpleTest.waitForExplicitFinish();
-
-</script>
-</pre>
-<div id="log">
-</div>
-</body>
-</html>