Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/dom/base/test/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 30 kB image not shown  

Quelle  test_mutationobservers.html   Sprache: HTML

 
 products/sources/formale Sprachen/C/Firefox/dom/base/test/test_mutationobservers.html


<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=641821
-->

<head>
  <meta charset="utf-8">
  <title>Test for Bug 641821</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="SpecialPowers.pushPrefEnv({'set': [['dom.mutation_events.enabled', true]]}, 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.includes("PASSED")) {
    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() {
      document.getElementById("log").appendChild(document.createTextNode("DONE"));
    },
    waitForExplicitFinish() {}
  }
}

function then(thenFn) {
  setTimeout(function() {
    if (thenFn) {
      setTimeout(thenFn, 0);
    } else {
      SimpleTest.finish();
    }
  }, 0);
}

var m;
var m2;
var m3;
var m4;

// Checks normal 'this' handling.
// Tests also basic attribute handling.
function runTest() {
  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"] });
  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 });
  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 });

  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.firstChild.remove();
}

function testChildList2() {
  div.innerHTML = "12";
  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 = "foo";
}

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 });
  m.observe(div, { childList: true });

  // 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(testNestedMutations);
      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 testNestedMutations() {
  div.textContent = null;
  div.appendChild(document.createTextNode("foo"));
  var m2WasCalled = false;
  m = new M(function(records, observer) {
    is(records[0].type, "characterData""Should have got characterData");
    observer.disconnect();
    m = null;
    m3 = new M(function(recordsInner, observerInnder) {
      ok(m2WasCalled, "m2 should have been called before m3!");
      is(recordsInner[0].type, "characterData""Should have got characterData");
      observerInnder.disconnect();
      then(testAdoptNode);
      m3 = null;
    });
    m3.observe(div, { characterData: true, subtree: true});
    div.firstChild.data = "foo";
  });
  m2 = new M(function(records, observer) {
    m2WasCalled = true;
    is(records[0].type, "characterData""Should have got characterData");
    observer.disconnect();
    m2 = null;
  });
  m2.observe(div, { characterData: true, subtree: true});
  div.appendChild(document.createTextNode("foo"));
  m.observe(div, { characterData: true, subtree: true });

  div.firstChild.data = "bar";
}

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 = "
1
1
"
;
  d2.outerHTML = "
2
2
"
;
  d3.outerHTML = "
3
3
"
;
  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""
"
);
  d2.insertAdjacentHTML("afterbegin""
"
);
  d3.insertAdjacentHTML("beforeend""
"
);
  d4.insertAdjacentHTML("afterend""
"
);
}


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 = "
hello
"
;
  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 = "12";
  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 });
  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() {
  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() {
  if (!div.attachShadow) {
    todo(false, "Skipping testOutsideShadowDOM and testInsideShadowDOM " +
         "because attachShadow is not supported");
    then(testMarquee);
    return;
  }
  m = new M(function(records, observer) {
    is(records.length, 1);
    is(records[0].type, "attributes""Should have got attributes");
    observer.disconnect();
    then(testMarquee);
  });
  m.observe(div, {
      attributes: true,
      childList: true,
      characterData: true,
      subtree: true
    })
  var sr = div.attachShadow({ mode: "open" });
  sr.innerHTML = " + ">text + "div>";
  sr.firstChild.setAttribute("foo""bar");
  sr.firstChild.firstChild.data = "text2";
  sr.firstChild.appendChild(document.createElement("div"));
  div.setAttribute("foo""bar");
}

function testMarquee() {
  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");
  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.firstChild.setAttribute("foo""bar_1");
  div.firstChild.setAttribute("foo""bar_2");
}

function testAttributeRecordMerging2() {
  ok(true, "testAttributeRecordMerging2");
  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.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");
  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.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");
  m = new M(function(records, observer) {
  });

  div.setAttribute("foo""initial");
  div.innerHTML = "
"
;
  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 chromeOnlyNodes
  try {
    var mo = new M(function(records, observer) { });
    mo.observe(div, { chromeOnlyNodes: 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>

Messung V0.5
C=100 H=100 G=100

¤ Dauer der Verarbeitung: 0.46 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.