mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1914513 - Add a pref to disable mutation events, r=masayuki
Differential Revision: https://phabricator.services.mozilla.com/D219934
This commit is contained in:
parent
b4ad683950
commit
e1fad67026
@ -2,20 +2,24 @@
|
||||
<head>
|
||||
<title>testcase2 Bug 432114 <20> Crash [@ PL_DHashTableOperate] with DOMNodeInserted event listener removing window and frameset contenteditable</title>
|
||||
</head>
|
||||
<body>
|
||||
<body onload="SpecialPowers.pushPrefEnv({'set': [['dom.mutation_events.enabled', true]]}, run);">
|
||||
<script>
|
||||
window.addEventListener("DOMNodeRemoved", function() {
|
||||
setTimeout(function() {
|
||||
document.documentElement.removeAttribute("class");
|
||||
}, 0);
|
||||
});
|
||||
var iframe = document.getElementById("content");
|
||||
iframe.onload=function() {
|
||||
dump("iframe onload\n");
|
||||
console.log("iframe onload");
|
||||
};
|
||||
|
||||
function run() {
|
||||
var iframe = document.getElementById("content");
|
||||
iframe.onload=function() {
|
||||
dump("iframe onload\n");
|
||||
console.log("iframe onload");
|
||||
};
|
||||
iframe.src = "file_432114-2.xhtml";
|
||||
}
|
||||
</script>
|
||||
<iframe id="content" src="file_432114-2.xhtml" style="width:1000px;height: 200px;"></iframe>
|
||||
<iframe id="content" style="width:1000px;height: 200px;"></iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -7908,6 +7908,14 @@ void Document::SetScopeObject(nsIGlobalObject* aGlobal) {
|
||||
#ifdef DEBUG
|
||||
AssertDocGroupMatchesKey();
|
||||
#endif
|
||||
|
||||
// Update data document's mMutationEventsEnabled early on so that
|
||||
// we can avoid extra IsURIInPrefList calls.
|
||||
if (mMutationEventsEnabled.isNothing()) {
|
||||
mMutationEventsEnabled.emplace(
|
||||
window->GetExtantDoc()->MutationEventsEnabled());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -19595,4 +19603,15 @@ already_AddRefed<Document> Document::ParseHTMLUnsafe(GlobalObject& aGlobal,
|
||||
return doc.forget();
|
||||
}
|
||||
|
||||
bool Document::MutationEventsEnabled() {
|
||||
if (StaticPrefs::dom_mutation_events_enabled()) {
|
||||
return true;
|
||||
}
|
||||
if (mMutationEventsEnabled.isNothing()) {
|
||||
mMutationEventsEnabled.emplace(
|
||||
NodePrincipal()->IsURIInPrefList("dom.mutation_events.forceEnable"));
|
||||
}
|
||||
return mMutationEventsEnabled.value();
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
@ -3656,6 +3656,10 @@ class Document : public nsINode,
|
||||
bool FireMutationEvents() const { return mFireMutationEvents; }
|
||||
void SetFireMutationEvents(bool aFire) { mFireMutationEvents = aFire; }
|
||||
|
||||
// Even if mutation events are disabled by default,
|
||||
// dom.mutation_events.forceEnable can be used to enable them per site.
|
||||
bool MutationEventsEnabled();
|
||||
|
||||
// This should be called when this document receives events which are likely
|
||||
// to be user interaction with the document, rather than the byproduct of
|
||||
// interaction with the browser (i.e. a keypress to scroll the view port,
|
||||
@ -4924,6 +4928,8 @@ class Document : public nsINode,
|
||||
|
||||
bool mFireMutationEvents : 1;
|
||||
|
||||
Maybe<bool> mMutationEventsEnabled;
|
||||
|
||||
// The fingerprinting protections overrides for this document. The value will
|
||||
// override the default enabled fingerprinting protections for this document.
|
||||
// This will only get populated if these is one that comes from the local
|
||||
|
@ -25,7 +25,7 @@ function boom()
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="setTimeout(boom, 30)">
|
||||
<body onload="SpecialPowers.pushPrefEnv({'set': [['dom.mutation_events.enabled', true]]}, () => setTimeout(boom, 30))">
|
||||
|
||||
<div id="n"></div>
|
||||
|
||||
|
@ -5205,6 +5205,10 @@ bool nsContentUtils::HasNonEmptyAttr(const nsIContent* aContent,
|
||||
bool nsContentUtils::WantMutationEvents(nsINode* aNode, uint32_t aType,
|
||||
nsINode* aTargetForSubtreeModified) {
|
||||
Document* doc = aNode->OwnerDoc();
|
||||
if (!doc->MutationEventsEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!doc->FireMutationEvents()) {
|
||||
return false;
|
||||
}
|
||||
@ -11283,13 +11287,13 @@ bool nsContentUtils::IsURIInList(nsIURI* aURI, const nsCString& aList) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoCString scheme;
|
||||
aURI->GetScheme(scheme);
|
||||
if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("https")) {
|
||||
if (aList.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aList.IsEmpty()) {
|
||||
nsAutoCString scheme;
|
||||
aURI->GetScheme(scheme);
|
||||
if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("https")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1075702
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1075702 **/
|
||||
function test() {
|
||||
// test: Element.removeAttributeNode()
|
||||
|
||||
var a1 = document.createAttribute("aa");
|
||||
@ -71,7 +72,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1075702
|
||||
}
|
||||
|
||||
testremoveNamedItem();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
<script>
|
||||
add_task(t => {
|
||||
function test() {
|
||||
let root = document.createElement("div");
|
||||
root.innerHTML = "<div id='a'>text<div id='b'>text2</div></div>";
|
||||
const a = root.firstChild;
|
||||
@ -66,7 +66,11 @@
|
||||
is(events[2].relatedNode, b);
|
||||
is(events[3].target, dfChild2);
|
||||
is(events[3].relatedNode, b);
|
||||
});
|
||||
SimpleTest.finish();
|
||||
};
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test));
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -18,8 +18,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=339494
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 339494 **/
|
||||
|
||||
/** Test for Bug 339494 **/
|
||||
function test() {
|
||||
var d = document.getElementById("d");
|
||||
|
||||
d.setAttribute("hhh", "testvalue");
|
||||
@ -51,6 +51,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=339494
|
||||
isnot(s.getAttribute("ggg"), "testvalue", "Value check 4");
|
||||
is(s.getAttribute("ggg"), "othervalue", "Value check 5");
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -18,7 +18,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=339494
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 339494 **/
|
||||
|
||||
function test() {
|
||||
var d = document.getElementById("d");
|
||||
|
||||
d.setAttribute("hhh", "testvalue");
|
||||
@ -50,6 +50,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=339494
|
||||
isnot(s.getAttribute("ggg"), "testvalue", "Value check 4");
|
||||
is(s.getAttribute("ggg"), "othervalue", "Value check 5");
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -64,9 +64,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=362391
|
||||
expected = "null";
|
||||
document.getElementById("test4")
|
||||
.removeAttribute("attr");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
test();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test);
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
|
@ -35,9 +35,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=364092
|
||||
test1.addEventListener("DOMAttrModified", mutationHandler, true);
|
||||
test1.removeAttributeNode(attrNode);
|
||||
test1.removeEventListener("DOMAttrModified", mutationHandler, true);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
runTest();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, runTest);
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
|
@ -37,9 +37,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=364413
|
||||
test1.addEventListener("DOMAttrModified", mutationHandler, true);
|
||||
test1.setAttributeNodeNS(attrNode);
|
||||
test1.removeEventListener("DOMAttrModified", mutationHandler, true);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
runTest();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, runTest);
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
|
@ -18,27 +18,32 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=367164
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 367164 **/
|
||||
function test() {
|
||||
var span = document.createElement("span");
|
||||
|
||||
var span = document.createElement("span");
|
||||
var ins1 = false;
|
||||
var ins2 = false;
|
||||
var rem1 = false;
|
||||
var rem2 = false;
|
||||
|
||||
var ins1 = false;
|
||||
var ins2 = false;
|
||||
var rem1 = false;
|
||||
var rem2 = false;
|
||||
span.addEventListener("DOMNodeInserted", function() { ins1 = true; }, true);
|
||||
span.addEventListener("DOMNodeInserted", function() { ins2 = true; });
|
||||
span.addEventListener("DOMNodeRemoved", function() { rem1 = true; }, true);
|
||||
span.addEventListener("DOMNodeRemoved", function() { rem2 = true; });
|
||||
|
||||
span.addEventListener("DOMNodeInserted", function() { ins1 = true; }, true);
|
||||
span.addEventListener("DOMNodeInserted", function() { ins2 = true; });
|
||||
span.addEventListener("DOMNodeRemoved", function() { rem1 = true; }, true);
|
||||
span.addEventListener("DOMNodeRemoved", function() { rem2 = true; });
|
||||
$("content").appendChild(span);
|
||||
$("content").removeChild(span);
|
||||
|
||||
$("content").appendChild(span);
|
||||
$("content").removeChild(span);
|
||||
is(ins1, true, "Capturing DOMNodeInserted listener");
|
||||
is(ins2, true, "Bubbling DOMNodeInserted listener");
|
||||
is(rem1, true, "Capturing DOMNodeRemoved listener");
|
||||
is(rem2, true, "Bubbling DOMNodeRemoved listener");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test);
|
||||
|
||||
is(ins1, true, "Capturing DOMNodeInserted listener");
|
||||
is(ins2, true, "Bubbling DOMNodeInserted listener");
|
||||
is(rem1, true, "Capturing DOMNodeRemoved listener");
|
||||
is(rem2, true, "Bubbling DOMNodeRemoved listener");
|
||||
|
||||
</script>
|
||||
|
||||
</pre>
|
||||
|
@ -34,12 +34,12 @@ function do_test()
|
||||
ns.appendChild(nt);
|
||||
dE.appendChild(ns);
|
||||
ok(true, "Test is successful if we get here without crashing");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(do_test);
|
||||
addLoadEvent(() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, do_test));
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -41,9 +41,8 @@ function runTests() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(runTests);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, runTests));
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -52,251 +52,256 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=564863
|
||||
<script class="testbody" type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
root = $('root');
|
||||
div = root.children[0];
|
||||
a = root.children[1];
|
||||
svg = root.children[2].firstChild;
|
||||
nsx = root.children[3];
|
||||
function test() {
|
||||
root = $('root');
|
||||
div = root.children[0];
|
||||
a = root.children[1];
|
||||
svg = root.children[2].firstChild;
|
||||
nsx = root.children[3];
|
||||
|
||||
var div_cs = getComputedStyle(div, "");
|
||||
var a_cs = getComputedStyle(a, "");
|
||||
var svg_cs = getComputedStyle(svg, "");
|
||||
var nsx_cs = getComputedStyle(nsx, "");
|
||||
var div_cs = getComputedStyle(div, "");
|
||||
var a_cs = getComputedStyle(a, "");
|
||||
var svg_cs = getComputedStyle(svg, "");
|
||||
var nsx_cs = getComputedStyle(nsx, "");
|
||||
|
||||
function checkHasId(test) {
|
||||
// Check computed style first to avoid flushes from hiding problems
|
||||
checkHasIdNoGEBI(test);
|
||||
function checkHasId(test) {
|
||||
// Check computed style first to avoid flushes from hiding problems
|
||||
checkHasIdNoGEBI(test);
|
||||
|
||||
is($("div_id"), div, "div getElementById " + test);
|
||||
is($("a_id"), a, "a getElementById " + test);
|
||||
is($("svg_id"), svg, "svg getElementById " + test);
|
||||
is($("ns_id"), nsx, "ns getElementById " + test);
|
||||
}
|
||||
is($("div_id"), div, "div getElementById " + test);
|
||||
is($("a_id"), a, "a getElementById " + test);
|
||||
is($("svg_id"), svg, "svg getElementById " + test);
|
||||
is($("ns_id"), nsx, "ns getElementById " + test);
|
||||
}
|
||||
|
||||
function checkHasIdNoGEBI(test) {
|
||||
const connected = test != "removed node";
|
||||
is(div_cs.color, connected ? "rgb(10, 10, 10)" : "", "div color " + test);
|
||||
is(a_cs.color, connected ? "rgb(20, 20, 20)" : "", "a color " + test);
|
||||
is(svg_cs.color, connected ? "rgb(40, 40, 40)" : "", "svg color " + test);
|
||||
is(nsx_cs.color, connected ? "rgb(50, 50, 50)" : "", "nsx color " + test);
|
||||
function checkHasIdNoGEBI(test) {
|
||||
const connected = test != "removed node";
|
||||
is(div_cs.color, connected ? "rgb(10, 10, 10)" : "", "div color " + test);
|
||||
is(a_cs.color, connected ? "rgb(20, 20, 20)" : "", "a color " + test);
|
||||
is(svg_cs.color, connected ? "rgb(40, 40, 40)" : "", "svg color " + test);
|
||||
is(nsx_cs.color, connected ? "rgb(50, 50, 50)" : "", "nsx color " + test);
|
||||
|
||||
is(div.id, "div_id", "div id " + test);
|
||||
is(a.id, "a_id", "a id " + test);
|
||||
is(svg.id, "svg_id", "svg id " + test);
|
||||
is (nsx.getAttribute("id"), "ns_id", "ns id " + test);
|
||||
}
|
||||
is(div.id, "div_id", "div id " + test);
|
||||
is(a.id, "a_id", "a id " + test);
|
||||
is(svg.id, "svg_id", "svg id " + test);
|
||||
is (nsx.getAttribute("id"), "ns_id", "ns id " + test);
|
||||
}
|
||||
|
||||
function checkHasNoId(removed, test) {
|
||||
is(div_cs.color, "rgb(0, 0, 0)", "div color " + test);
|
||||
is(a_cs.color, "rgb(0, 0, 0)", "a color " + test);
|
||||
is(svg_cs.color, "rgb(0, 0, 0)", "svg color " + test);
|
||||
is(nsx_cs.color, "rgb(0, 0, 0)", "nsx color " + test);
|
||||
function checkHasNoId(removed, test) {
|
||||
is(div_cs.color, "rgb(0, 0, 0)", "div color " + test);
|
||||
is(a_cs.color, "rgb(0, 0, 0)", "a color " + test);
|
||||
is(svg_cs.color, "rgb(0, 0, 0)", "svg color " + test);
|
||||
is(nsx_cs.color, "rgb(0, 0, 0)", "nsx color " + test);
|
||||
|
||||
attrValue = removed ? null : "";
|
||||
attrValue = removed ? null : "";
|
||||
|
||||
is(div.id, "", "div id " + test);
|
||||
is(a.id, "", "a id " + test);
|
||||
is(svg.id, "", "svg id " + test);
|
||||
is(div.id, "", "div id " + test);
|
||||
is(a.id, "", "a id " + test);
|
||||
is(svg.id, "", "svg id " + test);
|
||||
|
||||
is(div.getAttribute("id"), attrValue, "div getAttribute " + test);
|
||||
is(a.getAttribute("id"), attrValue, "a getAttribute " + test);
|
||||
is(svg.getAttribute("id"), attrValue, "svg getAttribute " + test);
|
||||
is(nsx.getAttribute("id"), attrValue, "ns getAttribute " + test);
|
||||
is(div.getAttribute("id"), attrValue, "div getAttribute " + test);
|
||||
is(a.getAttribute("id"), attrValue, "a getAttribute " + test);
|
||||
is(svg.getAttribute("id"), attrValue, "svg getAttribute " + test);
|
||||
is(nsx.getAttribute("id"), attrValue, "ns getAttribute " + test);
|
||||
|
||||
is($("div_id"), null, "div getElementById " + test);
|
||||
is($("a_id"), null, "a getElementById " + test);
|
||||
is($("svg_id"), null, "svg getElementById " + test);
|
||||
is($("ns_id"), null, "ns getElementById " + test);
|
||||
}
|
||||
is($("div_id"), null, "div getElementById " + test);
|
||||
is($("a_id"), null, "a getElementById " + test);
|
||||
is($("svg_id"), null, "svg getElementById " + test);
|
||||
is($("ns_id"), null, "ns getElementById " + test);
|
||||
}
|
||||
|
||||
// Check that dynamic modifications of attribute work
|
||||
// Check that dynamic modifications of attribute work
|
||||
|
||||
checkHasId("in markup");
|
||||
checkHasId("in markup");
|
||||
|
||||
div.id = "";
|
||||
a.id = "";
|
||||
svg.id = "";
|
||||
nsx.setAttribute("id", "");
|
||||
div.id = "";
|
||||
a.id = "";
|
||||
svg.id = "";
|
||||
nsx.setAttribute("id", "");
|
||||
|
||||
checkHasNoId(false, "set to empty");
|
||||
checkHasNoId(false, "set to empty");
|
||||
|
||||
div.id = "div_id";
|
||||
a.id = "a_id";
|
||||
svg.id = "svg_id";
|
||||
nsx.setAttribute("id", "ns_id");
|
||||
div.id = "div_id";
|
||||
a.id = "a_id";
|
||||
svg.id = "svg_id";
|
||||
nsx.setAttribute("id", "ns_id");
|
||||
|
||||
checkHasId("set using .id");
|
||||
checkHasId("set using .id");
|
||||
|
||||
div.setAttribute("id", "");
|
||||
a.setAttribute("id", "");
|
||||
svg.setAttribute("id", "");
|
||||
nsx.setAttribute("id", "");
|
||||
div.setAttribute("id", "");
|
||||
a.setAttribute("id", "");
|
||||
svg.setAttribute("id", "");
|
||||
nsx.setAttribute("id", "");
|
||||
|
||||
checkHasNoId(false, "setAttribute to empty");
|
||||
checkHasNoId(false, "setAttribute to empty");
|
||||
|
||||
div.id = "div_id";
|
||||
a.id = "a_id";
|
||||
svg.id = "svg_id";
|
||||
nsx.setAttribute("id", "ns_id");
|
||||
div.id = "div_id";
|
||||
a.id = "a_id";
|
||||
svg.id = "svg_id";
|
||||
nsx.setAttribute("id", "ns_id");
|
||||
|
||||
checkHasId("set again using .id");
|
||||
checkHasId("set again using .id");
|
||||
|
||||
div.removeAttribute("id");
|
||||
a.removeAttribute("id");
|
||||
svg.removeAttribute("id");
|
||||
nsx.removeAttribute("id");
|
||||
div.removeAttribute("id");
|
||||
a.removeAttribute("id");
|
||||
svg.removeAttribute("id");
|
||||
nsx.removeAttribute("id");
|
||||
|
||||
checkHasNoId(true, "removed attribute");
|
||||
checkHasNoId(true, "removed attribute");
|
||||
|
||||
div.setAttribute("id", "div_id");
|
||||
a.setAttribute("id", "a_id");
|
||||
svg.setAttribute("id", "svg_id");
|
||||
nsx.setAttribute("id", "ns_id");
|
||||
div.setAttribute("id", "div_id");
|
||||
a.setAttribute("id", "a_id");
|
||||
svg.setAttribute("id", "svg_id");
|
||||
nsx.setAttribute("id", "ns_id");
|
||||
|
||||
checkHasId("set using setAttribute");
|
||||
checkHasId("set using setAttribute");
|
||||
|
||||
t1 = document.createElement("div");
|
||||
t1.id = "div_id";
|
||||
t2 = document.createElement("a");
|
||||
t2.id = "a_id";
|
||||
t4 = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
||||
t4.id = "svg_id";
|
||||
t5 = document.createElementNS("urn:namespace", "ns:x");
|
||||
t5.setAttribute("id", "ns_id");
|
||||
t1 = document.createElement("div");
|
||||
t1.id = "div_id";
|
||||
t2 = document.createElement("a");
|
||||
t2.id = "a_id";
|
||||
t4 = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
||||
t4.id = "svg_id";
|
||||
t5 = document.createElementNS("urn:namespace", "ns:x");
|
||||
t5.setAttribute("id", "ns_id");
|
||||
|
||||
// Check that inserting elements before/after existing work
|
||||
// Check that inserting elements before/after existing work
|
||||
|
||||
function insertAfter(newChild, existing) {
|
||||
existing.parentNode.insertBefore(newChild, existing.nextSibling);
|
||||
}
|
||||
function insertBefore(newChild, existing) {
|
||||
existing.parentNode.insertBefore(newChild, existing);
|
||||
}
|
||||
function removeNode(child) {
|
||||
child.remove();
|
||||
}
|
||||
function insertAfter(newChild, existing) {
|
||||
existing.parentNode.insertBefore(newChild, existing.nextSibling);
|
||||
}
|
||||
function insertBefore(newChild, existing) {
|
||||
existing.parentNode.insertBefore(newChild, existing);
|
||||
}
|
||||
function removeNode(child) {
|
||||
child.remove();
|
||||
}
|
||||
|
||||
insertAfter(t1, div);
|
||||
insertAfter(t2, a);
|
||||
insertAfter(t4, svg);
|
||||
insertAfter(t5, nsx);
|
||||
insertAfter(t1, div);
|
||||
insertAfter(t2, a);
|
||||
insertAfter(t4, svg);
|
||||
insertAfter(t5, nsx);
|
||||
|
||||
checkHasId("inserted after");
|
||||
checkHasId("inserted after");
|
||||
|
||||
insertBefore(t1, div);
|
||||
insertBefore(t2, a);
|
||||
insertBefore(t4, svg);
|
||||
insertBefore(t5, nsx);
|
||||
insertBefore(t1, div);
|
||||
insertBefore(t2, a);
|
||||
insertBefore(t4, svg);
|
||||
insertBefore(t5, nsx);
|
||||
|
||||
checkHasIdNoGEBI("inserted before");
|
||||
is($("div_id"), t1, "div getElementById inserted before");
|
||||
is($("a_id"), t2, "a getElementById inserted before");
|
||||
is($("svg_id"), t4, "svg getElementById inserted before");
|
||||
is($("ns_id"), t5, "ns getElementById inserted before");
|
||||
checkHasIdNoGEBI("inserted before");
|
||||
is($("div_id"), t1, "div getElementById inserted before");
|
||||
is($("a_id"), t2, "a getElementById inserted before");
|
||||
is($("svg_id"), t4, "svg getElementById inserted before");
|
||||
is($("ns_id"), t5, "ns getElementById inserted before");
|
||||
|
||||
t1.removeAttribute("id");
|
||||
t2.removeAttribute("id");
|
||||
t4.removeAttribute("id");
|
||||
t5.removeAttribute("id");
|
||||
t1.removeAttribute("id");
|
||||
t2.removeAttribute("id");
|
||||
t4.removeAttribute("id");
|
||||
t5.removeAttribute("id");
|
||||
|
||||
checkHasId("removed tx attribute");
|
||||
checkHasId("removed tx attribute");
|
||||
|
||||
t1.setAttribute("id", "div_id");
|
||||
t2.setAttribute("id", "a_id");
|
||||
t4.setAttribute("id", "svg_id");
|
||||
t5.setAttribute("id", "ns_id");
|
||||
t1.setAttribute("id", "div_id");
|
||||
t2.setAttribute("id", "a_id");
|
||||
t4.setAttribute("id", "svg_id");
|
||||
t5.setAttribute("id", "ns_id");
|
||||
|
||||
checkHasIdNoGEBI("setAttribute before");
|
||||
is($("div_id"), t1, "div getElementById setAttribute before");
|
||||
is($("a_id"), t2, "a getElementById setAttribute before");
|
||||
is($("svg_id"), t4, "svg getElementById setAttribute before");
|
||||
is($("ns_id"), t5, "ns getElementById setAttribute before");
|
||||
checkHasIdNoGEBI("setAttribute before");
|
||||
is($("div_id"), t1, "div getElementById setAttribute before");
|
||||
is($("a_id"), t2, "a getElementById setAttribute before");
|
||||
is($("svg_id"), t4, "svg getElementById setAttribute before");
|
||||
is($("ns_id"), t5, "ns getElementById setAttribute before");
|
||||
|
||||
removeNode(t1);
|
||||
removeNode(t2);
|
||||
removeNode(t4);
|
||||
removeNode(t5);
|
||||
removeNode(t1);
|
||||
removeNode(t2);
|
||||
removeNode(t4);
|
||||
removeNode(t5);
|
||||
|
||||
checkHasId("removed temporaries");
|
||||
|
||||
removeNode(div);
|
||||
removeNode(a);
|
||||
removeNode(svg);
|
||||
removeNode(nsx);
|
||||
|
||||
checkHasIdNoGEBI("removed node");
|
||||
|
||||
// Check that removing an element during UnsetAttr works
|
||||
is(div.id, "div_id", "div still has id set");
|
||||
var mutateFired = false;
|
||||
root.appendChild(div);
|
||||
div.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, div, "target is div");
|
||||
is(div.id, "", "div no longer has id");
|
||||
is(div.getAttribute("id"), null, "div no longer has id attr");
|
||||
checkHasId("removed temporaries");
|
||||
|
||||
removeNode(div);
|
||||
is(div.parentNode, null, "div was removed");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
div.removeAttribute("id");
|
||||
ok(mutateFired, "mutation event fired");
|
||||
|
||||
// Check same for XML elements
|
||||
is(nsx.getAttribute("id"), "ns_id", "nsx still has id set");
|
||||
mutateFired = false;
|
||||
root.appendChild(nsx);
|
||||
nsx.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, nsx, "target is nsx");
|
||||
is(nsx.getAttribute("id"), null, "nsx no longer has id attr");
|
||||
removeNode(a);
|
||||
removeNode(svg);
|
||||
removeNode(nsx);
|
||||
is(nsx.parentNode, null, "nsx was removed");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
nsx.removeAttribute("id");
|
||||
ok(mutateFired, "mutation event fired");
|
||||
|
||||
checkHasIdNoGEBI("removed node");
|
||||
|
||||
// Re-add the id inside a mutation event on a XML element
|
||||
is($("ns_id"), null, "no nsx");
|
||||
is($("ns2_id"), null, "no nsx");
|
||||
nsx = document.createElementNS("urn:namespace", "ns:x");
|
||||
nsx.setAttribute("id", "ns_id");
|
||||
root.appendChild(nsx);
|
||||
is($("ns_id"), nsx, "new nsx is set up");
|
||||
mutateFired = false;
|
||||
nsx.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, nsx, "target is nsx");
|
||||
is(nsx.getAttribute("id"), null, "nsx no longer has id attr");
|
||||
nsx.setAttribute("id", "other_id");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
nsx.removeAttribute("id");
|
||||
ok(mutateFired, "mutation event fired");
|
||||
is($("ns_id"), null, "ns_id was removed from table");
|
||||
is($("other_id"), nsx, "other_id was added");
|
||||
removeNode(nsx);
|
||||
is($("other_id"), null, "other_id was removed");
|
||||
// Check that removing an element during UnsetAttr works
|
||||
is(div.id, "div_id", "div still has id set");
|
||||
var mutateFired = false;
|
||||
root.appendChild(div);
|
||||
div.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, div, "target is div");
|
||||
is(div.id, "", "div no longer has id");
|
||||
is(div.getAttribute("id"), null, "div no longer has id attr");
|
||||
removeNode(div);
|
||||
is(div.parentNode, null, "div was removed");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
div.removeAttribute("id");
|
||||
ok(mutateFired, "mutation event fired");
|
||||
|
||||
// Re-add the id inside a mutation event on a HTML element
|
||||
is($("div_id"), null, "no div");
|
||||
div = document.createElement("div");
|
||||
div.id = "div_id";
|
||||
root.appendChild(div);
|
||||
is($("div_id"), div, "new div is set up");
|
||||
mutateFired = false;
|
||||
div.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, div, "target is div");
|
||||
is(div.getAttribute("id"), null, "div no longer has id attr");
|
||||
is(div.id, "", "div no longer has id");
|
||||
div.id = "other_div_id";
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
div.removeAttribute("id");
|
||||
ok(mutateFired, "mutation event fired");
|
||||
is($("div_id"), null, "div_id was removed from table");
|
||||
is($("other_div_id"), div, "other_div_id was added");
|
||||
removeNode(div);
|
||||
is($("other_div_id"), null, "other_div_id was removed");
|
||||
// Check same for XML elements
|
||||
is(nsx.getAttribute("id"), "ns_id", "nsx still has id set");
|
||||
mutateFired = false;
|
||||
root.appendChild(nsx);
|
||||
nsx.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, nsx, "target is nsx");
|
||||
is(nsx.getAttribute("id"), null, "nsx no longer has id attr");
|
||||
removeNode(nsx);
|
||||
is(nsx.parentNode, null, "nsx was removed");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
nsx.removeAttribute("id");
|
||||
ok(mutateFired, "mutation event fired");
|
||||
|
||||
// Re-add the id inside a mutation event on a XML element
|
||||
is($("ns_id"), null, "no nsx");
|
||||
is($("ns2_id"), null, "no nsx");
|
||||
nsx = document.createElementNS("urn:namespace", "ns:x");
|
||||
nsx.setAttribute("id", "ns_id");
|
||||
root.appendChild(nsx);
|
||||
is($("ns_id"), nsx, "new nsx is set up");
|
||||
mutateFired = false;
|
||||
nsx.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, nsx, "target is nsx");
|
||||
is(nsx.getAttribute("id"), null, "nsx no longer has id attr");
|
||||
nsx.setAttribute("id", "other_id");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
nsx.removeAttribute("id");
|
||||
ok(mutateFired, "mutation event fired");
|
||||
is($("ns_id"), null, "ns_id was removed from table");
|
||||
is($("other_id"), nsx, "other_id was added");
|
||||
removeNode(nsx);
|
||||
is($("other_id"), null, "other_id was removed");
|
||||
|
||||
// Re-add the id inside a mutation event on a HTML element
|
||||
is($("div_id"), null, "no div");
|
||||
div = document.createElement("div");
|
||||
div.id = "div_id";
|
||||
root.appendChild(div);
|
||||
is($("div_id"), div, "new div is set up");
|
||||
mutateFired = false;
|
||||
div.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, div, "target is div");
|
||||
is(div.getAttribute("id"), null, "div no longer has id attr");
|
||||
is(div.id, "", "div no longer has id");
|
||||
div.id = "other_div_id";
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
div.removeAttribute("id");
|
||||
ok(mutateFired, "mutation event fired");
|
||||
is($("div_id"), null, "div_id was removed from table");
|
||||
is($("other_div_id"), div, "other_div_id was added");
|
||||
removeNode(div);
|
||||
is($("other_div_id"), null, "other_div_id was removed");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test);
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
@ -22,309 +22,314 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=588990
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
root = $('root');
|
||||
i1_1 = root.children[0];
|
||||
i2_1 = root.children[1];
|
||||
i2_2 = root.children[2];
|
||||
i3_1 = root.children[3];
|
||||
i3_2 = root.children[4];
|
||||
i3_3 = root.children[5];
|
||||
function test() {
|
||||
root = $('root');
|
||||
i1_1 = root.children[0];
|
||||
i2_1 = root.children[1];
|
||||
i2_2 = root.children[2];
|
||||
i3_1 = root.children[3];
|
||||
i3_2 = root.children[4];
|
||||
i3_3 = root.children[5];
|
||||
|
||||
function checkHasName(test) {
|
||||
// Check name first to avoid flushes from hiding problems
|
||||
checkHasNameNoDocProp(test);
|
||||
function checkHasName(test) {
|
||||
// Check name first to avoid flushes from hiding problems
|
||||
checkHasNameNoDocProp(test);
|
||||
|
||||
is(document.n1, i1_1, "i1_1 doc.name " + test);
|
||||
is(document.n2[0], i2_1, "i2_1 doc.name " + test);
|
||||
is(document.n2[1], i2_2, "i2_2 doc.name " + test);
|
||||
is(document.n2.length, 2, "doc.name.length " + test);
|
||||
is(document.n3[0], i3_1, "i3_1 doc.name " + test);
|
||||
is(document.n3[1], i3_2, "i3_2 doc.name " + test);
|
||||
is(document.n3[2], i3_3, "i3_3 doc.name " + test);
|
||||
is(document.n3.length, 3, "doc.name.length " + test);
|
||||
}
|
||||
is(document.n1, i1_1, "i1_1 doc.name " + test);
|
||||
is(document.n2[0], i2_1, "i2_1 doc.name " + test);
|
||||
is(document.n2[1], i2_2, "i2_2 doc.name " + test);
|
||||
is(document.n2.length, 2, "doc.name.length " + test);
|
||||
is(document.n3[0], i3_1, "i3_1 doc.name " + test);
|
||||
is(document.n3[1], i3_2, "i3_2 doc.name " + test);
|
||||
is(document.n3[2], i3_3, "i3_3 doc.name " + test);
|
||||
is(document.n3.length, 3, "doc.name.length " + test);
|
||||
}
|
||||
|
||||
function checkHasNameNoDocProp(test) {
|
||||
is(i1_1.name, "n1", "i1_1 name " + test);
|
||||
is(i2_1.name, "n2", "i2_1 name " + test);
|
||||
is(i2_2.name, "n2", "i2_2 name " + test);
|
||||
is(i3_1.name, "n3", "i3_1 name " + test);
|
||||
is(i3_2.name, "n3", "i3_2 name " + test);
|
||||
is(i3_3.name, "n3", "i3_3 name " + test);
|
||||
}
|
||||
function checkHasNameNoDocProp(test) {
|
||||
is(i1_1.name, "n1", "i1_1 name " + test);
|
||||
is(i2_1.name, "n2", "i2_1 name " + test);
|
||||
is(i2_2.name, "n2", "i2_2 name " + test);
|
||||
is(i3_1.name, "n3", "i3_1 name " + test);
|
||||
is(i3_2.name, "n3", "i3_2 name " + test);
|
||||
is(i3_3.name, "n3", "i3_3 name " + test);
|
||||
}
|
||||
|
||||
function checkHasNoName(removed, test) {
|
||||
is(i1_1.name, "", "i1_1 name " + test);
|
||||
is(i2_1.name, "", "i2_1 name " + test);
|
||||
is(i2_2.name, "", "i2_2 name " + test);
|
||||
is(i3_1.name, "", "i3_1 name " + test);
|
||||
is(i3_2.name, "", "i3_2 name " + test);
|
||||
is(i3_3.name, "", "i3_3 name " + test);
|
||||
function checkHasNoName(removed, test) {
|
||||
is(i1_1.name, "", "i1_1 name " + test);
|
||||
is(i2_1.name, "", "i2_1 name " + test);
|
||||
is(i2_2.name, "", "i2_2 name " + test);
|
||||
is(i3_1.name, "", "i3_1 name " + test);
|
||||
is(i3_2.name, "", "i3_2 name " + test);
|
||||
is(i3_3.name, "", "i3_3 name " + test);
|
||||
|
||||
var attrValue = removed ? null : "";
|
||||
is(i1_1.getAttribute("name"), attrValue, "i1_1 getAttribute " + test);
|
||||
is(i2_1.getAttribute("name"), attrValue, "i2_1 getAttribute " + test);
|
||||
is(i2_2.getAttribute("name"), attrValue, "i2_2 getAttribute " + test);
|
||||
is(i3_1.getAttribute("name"), attrValue, "i3_1 getAttribute " + test);
|
||||
is(i3_2.getAttribute("name"), attrValue, "i3_2 getAttribute " + test);
|
||||
is(i3_3.getAttribute("name"), attrValue, "i3_3 getAttribute " + test);
|
||||
|
||||
is(document.n1, undefined, "doc.n1 " + test);
|
||||
is(document.n2, undefined, "doc.n2 " + test);
|
||||
is(document.n3, undefined, "doc.n3 " + test);
|
||||
}
|
||||
var attrValue = removed ? null : "";
|
||||
is(i1_1.getAttribute("name"), attrValue, "i1_1 getAttribute " + test);
|
||||
is(i2_1.getAttribute("name"), attrValue, "i2_1 getAttribute " + test);
|
||||
is(i2_2.getAttribute("name"), attrValue, "i2_2 getAttribute " + test);
|
||||
is(i3_1.getAttribute("name"), attrValue, "i3_1 getAttribute " + test);
|
||||
is(i3_2.getAttribute("name"), attrValue, "i3_2 getAttribute " + test);
|
||||
is(i3_3.getAttribute("name"), attrValue, "i3_3 getAttribute " + test);
|
||||
|
||||
// Check that dynamic modifications of attribute work
|
||||
is(document.n1, undefined, "doc.n1 " + test);
|
||||
is(document.n2, undefined, "doc.n2 " + test);
|
||||
is(document.n3, undefined, "doc.n3 " + test);
|
||||
}
|
||||
|
||||
checkHasName("in markup");
|
||||
// Check that dynamic modifications of attribute work
|
||||
|
||||
i1_1.name = "";
|
||||
i2_1.name = "";
|
||||
i2_2.name = "";
|
||||
i3_1.name = "";
|
||||
i3_2.name = "";
|
||||
i3_3.name = "";
|
||||
checkHasName("in markup");
|
||||
|
||||
checkHasNoName(false, "set to empty");
|
||||
i1_1.name = "";
|
||||
i2_1.name = "";
|
||||
i2_2.name = "";
|
||||
i3_1.name = "";
|
||||
i3_2.name = "";
|
||||
i3_3.name = "";
|
||||
|
||||
i1_1.name = "n1";
|
||||
i2_1.name = "n2";
|
||||
i2_2.name = "n2";
|
||||
i3_1.name = "n3";
|
||||
i3_2.name = "n3";
|
||||
i3_3.name = "n3";
|
||||
checkHasNoName(false, "set to empty");
|
||||
|
||||
checkHasName("set using .name");
|
||||
|
||||
i1_1.setAttribute("name", "");
|
||||
i2_1.setAttribute("name", "");
|
||||
i2_2.setAttribute("name", "");
|
||||
i3_1.setAttribute("name", "");
|
||||
i3_2.setAttribute("name", "");
|
||||
i3_3.setAttribute("name", "");
|
||||
|
||||
checkHasNoName(false, "setAttribute to empty");
|
||||
|
||||
i1_1.name = "n1";
|
||||
i2_1.name = "n2";
|
||||
i2_2.name = "n2";
|
||||
i3_1.name = "n3";
|
||||
i3_2.name = "n3";
|
||||
i3_3.name = "n3";
|
||||
|
||||
checkHasName("set again using .name");
|
||||
|
||||
i1_1.removeAttribute("name");
|
||||
i2_1.removeAttribute("name");
|
||||
i2_2.removeAttribute("name");
|
||||
i3_1.removeAttribute("name");
|
||||
i3_2.removeAttribute("name");
|
||||
i3_3.removeAttribute("name");
|
||||
|
||||
checkHasNoName(true, "removed attribute");
|
||||
|
||||
i1_1.setAttribute("name", "n1");
|
||||
i2_1.setAttribute("name", "n2");
|
||||
i2_2.setAttribute("name", "n2");
|
||||
i3_1.setAttribute("name", "n3");
|
||||
i3_2.setAttribute("name", "n3");
|
||||
i3_3.setAttribute("name", "n3");
|
||||
|
||||
checkHasName("set using setAttribute");
|
||||
|
||||
t1 = document.createElement("img");
|
||||
t1.name = "n1";
|
||||
t2 = document.createElement("img");
|
||||
t2.name = "n2";
|
||||
t3 = document.createElement("img");
|
||||
t3.name = "n2";
|
||||
t4 = document.createElement("img");
|
||||
t4.name = "n3";
|
||||
t5 = document.createElement("img");
|
||||
t5.name = "n3";
|
||||
t6 = document.createElement("img");
|
||||
t6.name = "n3";
|
||||
|
||||
// Check that inserting elements before/after existing work
|
||||
|
||||
function insertAfter(newChild, existing) {
|
||||
existing.parentNode.insertBefore(newChild, existing.nextSibling);
|
||||
}
|
||||
function insertBefore(newChild, existing) {
|
||||
existing.parentNode.insertBefore(newChild, existing);
|
||||
}
|
||||
function removeNode(child) {
|
||||
child.remove();
|
||||
}
|
||||
|
||||
insertAfter(t1, i1_1);
|
||||
insertAfter(t2, i2_1);
|
||||
insertAfter(t3, i2_2);
|
||||
insertAfter(t4, i3_1);
|
||||
insertAfter(t5, i3_2);
|
||||
insertAfter(t6, i3_3);
|
||||
|
||||
checkHasNameNoDocProp("inserted after");
|
||||
is(document.n1[0], i1_1, "i1_1 doc.name inserted after");
|
||||
is(document.n1[1], t1, "t1 doc.name inserted after");
|
||||
is(document.n1.length, 2, "doc.name1.length inserted after");
|
||||
is(document.n2[0], i2_1, "i2_1 doc.name inserted after");
|
||||
todo_is(document.n2[1], t2, "This is where t2 should show up. The elements in here should be in order-in-document rather than order-of-insertion");
|
||||
is(document.n2[1], i2_2, "i2_2 doc.name inserted after");
|
||||
is(document.n2[2], t2, "t2 doc.name inserted after");
|
||||
is(document.n2[3], t3, "t3 doc.name inserted after");
|
||||
is(document.n2.length, 4, "doc.name2.length inserted after");
|
||||
is(document.n3[0], i3_1, "i3_1 doc.name inserted after");
|
||||
is(document.n3[1], i3_2, "i3_3 doc.name inserted after");
|
||||
is(document.n3[2], i3_3, "i3_2 doc.name inserted after");
|
||||
is(document.n3[3], t4, "t4 doc.name inserted after");
|
||||
is(document.n3[4], t5, "t5 doc.name inserted after");
|
||||
is(document.n3[5], t6, "t6 doc.name inserted after");
|
||||
is(document.n3.length, 6, "doc.name3.length inserted after");
|
||||
|
||||
|
||||
insertBefore(t1, i1_1);
|
||||
insertBefore(t2, i2_1);
|
||||
insertBefore(t3, i2_2);
|
||||
insertBefore(t4, i3_1);
|
||||
insertBefore(t5, i3_2);
|
||||
insertBefore(t6, i3_3);
|
||||
|
||||
checkHasNameNoDocProp("inserted before");
|
||||
is(document.n1[0], i1_1, "i1_1 doc.name inserted before");
|
||||
is(document.n1[1], t1, "t1 doc.name inserted before");
|
||||
is(document.n1.length, 2, "doc.name1.length inserted before");
|
||||
is(document.n2[0], i2_1, "i2_1 doc.name inserted before");
|
||||
is(document.n2[1], i2_2, "i2_2 doc.name inserted before");
|
||||
is(document.n2[2], t2, "t2 doc.name inserted before");
|
||||
is(document.n2[3], t3, "t3 doc.name inserted before");
|
||||
is(document.n2.length, 4, "doc.name2.length inserted before");
|
||||
is(document.n3[0], i3_1, "i3_1 doc.name inserted before");
|
||||
is(document.n3[1], i3_2, "i3_3 doc.name inserted before");
|
||||
is(document.n3[2], i3_3, "i3_2 doc.name inserted before");
|
||||
is(document.n3[3], t4, "t4 doc.name inserted before");
|
||||
is(document.n3[4], t5, "t5 doc.name inserted before");
|
||||
is(document.n3[5], t6, "t6 doc.name inserted before");
|
||||
is(document.n3.length, 6, "doc.name3.length inserted before");
|
||||
|
||||
t1.removeAttribute("name");
|
||||
t2.removeAttribute("name");
|
||||
t3.removeAttribute("name");
|
||||
t4.removeAttribute("name");
|
||||
t5.removeAttribute("name");
|
||||
t6.removeAttribute("name");
|
||||
|
||||
checkHasName("removed tx attribute");
|
||||
|
||||
t1.setAttribute("name", "n1");
|
||||
t2.setAttribute("name", "n2");
|
||||
t3.setAttribute("name", "n2");
|
||||
t4.setAttribute("name", "n3");
|
||||
t5.setAttribute("name", "n3");
|
||||
t6.setAttribute("name", "n3");
|
||||
|
||||
checkHasNameNoDocProp("inserted before");
|
||||
is(document.n1[0], i1_1, "i1_1 doc.name inserted before");
|
||||
is(document.n1[1], t1, "t1 doc.name inserted before");
|
||||
is(document.n1.length, 2, "doc.name1.length inserted before");
|
||||
is(document.n2[0], i2_1, "i2_1 doc.name inserted before");
|
||||
is(document.n2[1], i2_2, "i2_2 doc.name inserted before");
|
||||
is(document.n2[2], t2, "t2 doc.name inserted before");
|
||||
is(document.n2[3], t3, "t3 doc.name inserted before");
|
||||
is(document.n2.length, 4, "doc.name2.length inserted before");
|
||||
is(document.n3[0], i3_1, "i3_1 doc.name inserted before");
|
||||
is(document.n3[1], i3_2, "i3_3 doc.name inserted before");
|
||||
is(document.n3[2], i3_3, "i3_2 doc.name inserted before");
|
||||
is(document.n3[3], t4, "t4 doc.name inserted before");
|
||||
is(document.n3[4], t5, "t5 doc.name inserted before");
|
||||
is(document.n3[5], t6, "t6 doc.name inserted before");
|
||||
is(document.n3.length, 6, "doc.name3.length inserted before");
|
||||
|
||||
removeNode(t1);
|
||||
removeNode(t2);
|
||||
removeNode(t3);
|
||||
removeNode(t4);
|
||||
removeNode(t5);
|
||||
removeNode(t6);
|
||||
|
||||
checkHasName("removed temporaries");
|
||||
|
||||
removeNode(i1_1);
|
||||
removeNode(i2_1);
|
||||
removeNode(i2_2);
|
||||
removeNode(i3_1);
|
||||
removeNode(i3_2);
|
||||
removeNode(i3_3);
|
||||
|
||||
checkHasNameNoDocProp("removed node");
|
||||
|
||||
// Check that removing an element during UnsetAttr works
|
||||
is(i1_1.name, "n1", "i1_1 has name set");
|
||||
var mutateFired = false;
|
||||
root.appendChild(i1_1);
|
||||
i1_1.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, i1_1, "target is i1_1");
|
||||
is(i1_1.name, "", "i1_1 no longer has name");
|
||||
is(i1_1.getAttribute("name"), null, "i1_1 no longer has name attr");
|
||||
removeNode(i1_1);
|
||||
is(i1_1.parentNode, null, "i1_1 was removed");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
i1_1.removeAttribute("name");
|
||||
ok(mutateFired, "mutation event fired");
|
||||
SpecialPowers.gc();
|
||||
|
||||
// Check that removing an element during SetAttr works
|
||||
i2_1.name = "";
|
||||
mutateFired = false;
|
||||
root.appendChild(i2_1);
|
||||
i2_1.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, i2_1, "target is i2_1");
|
||||
is(i2_1.name, "n2", "i2_1 no longer has name");
|
||||
is(i2_1.getAttribute("name"), "n2", "i2_1 no longer has name attr");
|
||||
removeNode(i2_1);
|
||||
is(i2_1.parentNode, null, "i2_1 was removed");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
i2_1.name = "n2";
|
||||
ok(mutateFired, "mutation event fired");
|
||||
SpecialPowers.gc();
|
||||
|
||||
// Re-add the name inside a mutation event on a HTML element
|
||||
is(i2_2.name, "n2", "i2_2 has name set");
|
||||
root.appendChild(i2_2);
|
||||
mutateFired = false;
|
||||
root.appendChild(i2_2);
|
||||
i2_2.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, i2_2, "target is i2_2");
|
||||
is(i2_2.name, "", "i2_2 no longer has name");
|
||||
is(i2_2.getAttribute("name"), "", "i2_2 has empty name attr");
|
||||
i1_1.name = "n1";
|
||||
i2_1.name = "n2";
|
||||
i2_2.name = "n2";
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
i2_2.name = "";
|
||||
ok(mutateFired, "mutation event fired");
|
||||
is(document.n2, i2_2, "named was readded during mutation");
|
||||
removeNode(i2_2);
|
||||
SpecialPowers.gc();
|
||||
i3_1.name = "n3";
|
||||
i3_2.name = "n3";
|
||||
i3_3.name = "n3";
|
||||
|
||||
// Re-remove the name inside a mutation event on a HTML element
|
||||
i3_1.name = "";
|
||||
root.appendChild(i3_1);
|
||||
mutateFired = false;
|
||||
root.appendChild(i3_1);
|
||||
i3_1.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, i3_1, "target is i3_1");
|
||||
is(i3_1.name, "n3", "i3_1 no longer has name");
|
||||
is(i3_1.getAttribute("name"), "n3", "i3_1 has empty name attr");
|
||||
checkHasName("set using .name");
|
||||
|
||||
i1_1.setAttribute("name", "");
|
||||
i2_1.setAttribute("name", "");
|
||||
i2_2.setAttribute("name", "");
|
||||
i3_1.setAttribute("name", "");
|
||||
i3_2.setAttribute("name", "");
|
||||
i3_3.setAttribute("name", "");
|
||||
|
||||
checkHasNoName(false, "setAttribute to empty");
|
||||
|
||||
i1_1.name = "n1";
|
||||
i2_1.name = "n2";
|
||||
i2_2.name = "n2";
|
||||
i3_1.name = "n3";
|
||||
i3_2.name = "n3";
|
||||
i3_3.name = "n3";
|
||||
|
||||
checkHasName("set again using .name");
|
||||
|
||||
i1_1.removeAttribute("name");
|
||||
i2_1.removeAttribute("name");
|
||||
i2_2.removeAttribute("name");
|
||||
i3_1.removeAttribute("name");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
i3_1.name = "n3";
|
||||
ok(mutateFired, "mutation event fired");
|
||||
is(document.n3, undefined, "named was readded during mutation");
|
||||
removeNode(i3_1);
|
||||
SpecialPowers.gc();
|
||||
i3_2.removeAttribute("name");
|
||||
i3_3.removeAttribute("name");
|
||||
|
||||
checkHasNoName(true, "removed attribute");
|
||||
|
||||
i1_1.setAttribute("name", "n1");
|
||||
i2_1.setAttribute("name", "n2");
|
||||
i2_2.setAttribute("name", "n2");
|
||||
i3_1.setAttribute("name", "n3");
|
||||
i3_2.setAttribute("name", "n3");
|
||||
i3_3.setAttribute("name", "n3");
|
||||
|
||||
checkHasName("set using setAttribute");
|
||||
|
||||
t1 = document.createElement("img");
|
||||
t1.name = "n1";
|
||||
t2 = document.createElement("img");
|
||||
t2.name = "n2";
|
||||
t3 = document.createElement("img");
|
||||
t3.name = "n2";
|
||||
t4 = document.createElement("img");
|
||||
t4.name = "n3";
|
||||
t5 = document.createElement("img");
|
||||
t5.name = "n3";
|
||||
t6 = document.createElement("img");
|
||||
t6.name = "n3";
|
||||
|
||||
// Check that inserting elements before/after existing work
|
||||
|
||||
function insertAfter(newChild, existing) {
|
||||
existing.parentNode.insertBefore(newChild, existing.nextSibling);
|
||||
}
|
||||
function insertBefore(newChild, existing) {
|
||||
existing.parentNode.insertBefore(newChild, existing);
|
||||
}
|
||||
function removeNode(child) {
|
||||
child.remove();
|
||||
}
|
||||
|
||||
insertAfter(t1, i1_1);
|
||||
insertAfter(t2, i2_1);
|
||||
insertAfter(t3, i2_2);
|
||||
insertAfter(t4, i3_1);
|
||||
insertAfter(t5, i3_2);
|
||||
insertAfter(t6, i3_3);
|
||||
|
||||
checkHasNameNoDocProp("inserted after");
|
||||
is(document.n1[0], i1_1, "i1_1 doc.name inserted after");
|
||||
is(document.n1[1], t1, "t1 doc.name inserted after");
|
||||
is(document.n1.length, 2, "doc.name1.length inserted after");
|
||||
is(document.n2[0], i2_1, "i2_1 doc.name inserted after");
|
||||
todo_is(document.n2[1], t2, "This is where t2 should show up. The elements in here should be in order-in-document rather than order-of-insertion");
|
||||
is(document.n2[1], i2_2, "i2_2 doc.name inserted after");
|
||||
is(document.n2[2], t2, "t2 doc.name inserted after");
|
||||
is(document.n2[3], t3, "t3 doc.name inserted after");
|
||||
is(document.n2.length, 4, "doc.name2.length inserted after");
|
||||
is(document.n3[0], i3_1, "i3_1 doc.name inserted after");
|
||||
is(document.n3[1], i3_2, "i3_3 doc.name inserted after");
|
||||
is(document.n3[2], i3_3, "i3_2 doc.name inserted after");
|
||||
is(document.n3[3], t4, "t4 doc.name inserted after");
|
||||
is(document.n3[4], t5, "t5 doc.name inserted after");
|
||||
is(document.n3[5], t6, "t6 doc.name inserted after");
|
||||
is(document.n3.length, 6, "doc.name3.length inserted after");
|
||||
|
||||
insertBefore(t1, i1_1);
|
||||
insertBefore(t2, i2_1);
|
||||
insertBefore(t3, i2_2);
|
||||
insertBefore(t4, i3_1);
|
||||
insertBefore(t5, i3_2);
|
||||
insertBefore(t6, i3_3);
|
||||
|
||||
checkHasNameNoDocProp("inserted before");
|
||||
is(document.n1[0], i1_1, "i1_1 doc.name inserted before");
|
||||
is(document.n1[1], t1, "t1 doc.name inserted before");
|
||||
is(document.n1.length, 2, "doc.name1.length inserted before");
|
||||
is(document.n2[0], i2_1, "i2_1 doc.name inserted before");
|
||||
is(document.n2[1], i2_2, "i2_2 doc.name inserted before");
|
||||
is(document.n2[2], t2, "t2 doc.name inserted before");
|
||||
is(document.n2[3], t3, "t3 doc.name inserted before");
|
||||
is(document.n2.length, 4, "doc.name2.length inserted before");
|
||||
is(document.n3[0], i3_1, "i3_1 doc.name inserted before");
|
||||
is(document.n3[1], i3_2, "i3_3 doc.name inserted before");
|
||||
is(document.n3[2], i3_3, "i3_2 doc.name inserted before");
|
||||
is(document.n3[3], t4, "t4 doc.name inserted before");
|
||||
is(document.n3[4], t5, "t5 doc.name inserted before");
|
||||
is(document.n3[5], t6, "t6 doc.name inserted before");
|
||||
is(document.n3.length, 6, "doc.name3.length inserted before");
|
||||
|
||||
t1.removeAttribute("name");
|
||||
t2.removeAttribute("name");
|
||||
t3.removeAttribute("name");
|
||||
t4.removeAttribute("name");
|
||||
t5.removeAttribute("name");
|
||||
t6.removeAttribute("name");
|
||||
|
||||
checkHasName("removed tx attribute");
|
||||
|
||||
t1.setAttribute("name", "n1");
|
||||
t2.setAttribute("name", "n2");
|
||||
t3.setAttribute("name", "n2");
|
||||
t4.setAttribute("name", "n3");
|
||||
t5.setAttribute("name", "n3");
|
||||
t6.setAttribute("name", "n3");
|
||||
|
||||
checkHasNameNoDocProp("inserted before");
|
||||
is(document.n1[0], i1_1, "i1_1 doc.name inserted before");
|
||||
is(document.n1[1], t1, "t1 doc.name inserted before");
|
||||
is(document.n1.length, 2, "doc.name1.length inserted before");
|
||||
is(document.n2[0], i2_1, "i2_1 doc.name inserted before");
|
||||
is(document.n2[1], i2_2, "i2_2 doc.name inserted before");
|
||||
is(document.n2[2], t2, "t2 doc.name inserted before");
|
||||
is(document.n2[3], t3, "t3 doc.name inserted before");
|
||||
is(document.n2.length, 4, "doc.name2.length inserted before");
|
||||
is(document.n3[0], i3_1, "i3_1 doc.name inserted before");
|
||||
is(document.n3[1], i3_2, "i3_3 doc.name inserted before");
|
||||
is(document.n3[2], i3_3, "i3_2 doc.name inserted before");
|
||||
is(document.n3[3], t4, "t4 doc.name inserted before");
|
||||
is(document.n3[4], t5, "t5 doc.name inserted before");
|
||||
is(document.n3[5], t6, "t6 doc.name inserted before");
|
||||
is(document.n3.length, 6, "doc.name3.length inserted before");
|
||||
|
||||
removeNode(t1);
|
||||
removeNode(t2);
|
||||
removeNode(t3);
|
||||
removeNode(t4);
|
||||
removeNode(t5);
|
||||
removeNode(t6);
|
||||
|
||||
checkHasName("removed temporaries");
|
||||
|
||||
removeNode(i1_1);
|
||||
removeNode(i2_1);
|
||||
removeNode(i2_2);
|
||||
removeNode(i3_1);
|
||||
removeNode(i3_2);
|
||||
removeNode(i3_3);
|
||||
|
||||
checkHasNameNoDocProp("removed node");
|
||||
|
||||
// Check that removing an element during UnsetAttr works
|
||||
is(i1_1.name, "n1", "i1_1 has name set");
|
||||
var mutateFired = false;
|
||||
root.appendChild(i1_1);
|
||||
i1_1.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, i1_1, "target is i1_1");
|
||||
is(i1_1.name, "", "i1_1 no longer has name");
|
||||
is(i1_1.getAttribute("name"), null, "i1_1 no longer has name attr");
|
||||
removeNode(i1_1);
|
||||
is(i1_1.parentNode, null, "i1_1 was removed");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
i1_1.removeAttribute("name");
|
||||
ok(mutateFired, "mutation event fired");
|
||||
SpecialPowers.gc();
|
||||
|
||||
// Check that removing an element during SetAttr works
|
||||
i2_1.name = "";
|
||||
mutateFired = false;
|
||||
root.appendChild(i2_1);
|
||||
i2_1.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, i2_1, "target is i2_1");
|
||||
is(i2_1.name, "n2", "i2_1 no longer has name");
|
||||
is(i2_1.getAttribute("name"), "n2", "i2_1 no longer has name attr");
|
||||
removeNode(i2_1);
|
||||
is(i2_1.parentNode, null, "i2_1 was removed");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
i2_1.name = "n2";
|
||||
ok(mutateFired, "mutation event fired");
|
||||
SpecialPowers.gc();
|
||||
|
||||
// Re-add the name inside a mutation event on a HTML element
|
||||
is(i2_2.name, "n2", "i2_2 has name set");
|
||||
root.appendChild(i2_2);
|
||||
mutateFired = false;
|
||||
root.appendChild(i2_2);
|
||||
i2_2.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, i2_2, "target is i2_2");
|
||||
is(i2_2.name, "", "i2_2 no longer has name");
|
||||
is(i2_2.getAttribute("name"), "", "i2_2 has empty name attr");
|
||||
i2_2.name = "n2";
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
i2_2.name = "";
|
||||
ok(mutateFired, "mutation event fired");
|
||||
is(document.n2, i2_2, "named was readded during mutation");
|
||||
removeNode(i2_2);
|
||||
SpecialPowers.gc();
|
||||
|
||||
// Re-remove the name inside a mutation event on a HTML element
|
||||
i3_1.name = "";
|
||||
root.appendChild(i3_1);
|
||||
mutateFired = false;
|
||||
root.appendChild(i3_1);
|
||||
i3_1.addEventListener("DOMAttrModified", function(e) {
|
||||
is(e.target, i3_1, "target is i3_1");
|
||||
is(i3_1.name, "n3", "i3_1 no longer has name");
|
||||
is(i3_1.getAttribute("name"), "n3", "i3_1 has empty name attr");
|
||||
i3_1.removeAttribute("name");
|
||||
mutateFired = true;
|
||||
}, {once: true});
|
||||
i3_1.name = "n3";
|
||||
ok(mutateFired, "mutation event fired");
|
||||
is(document.n3, undefined, "named was readded during mutation");
|
||||
removeNode(i3_1);
|
||||
SpecialPowers.gc();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -40,7 +40,7 @@ function boom()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(boom);
|
||||
addLoadEvent(() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, boom));
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -9,7 +9,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=641821
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="runTest()">
|
||||
<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">
|
||||
|
@ -17,7 +17,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1127588
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
window.onload = function () {
|
||||
window.onload = function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test);
|
||||
}
|
||||
|
||||
function test() {
|
||||
let insertedEventCount = 0;
|
||||
let insertedListener = function() {
|
||||
insertedEventCount++;
|
||||
|
@ -90,11 +90,11 @@ function doTest() {
|
||||
subtree.normalize();
|
||||
is(subtreeModifiedCount, 1,
|
||||
"Calling normalize() should have dispatched a DOMSubtreeModified event");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
addLoadEvent(SimpleTest.finish);
|
||||
addLoadEvent(() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, doTest));
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -126,7 +126,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=328885
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestFlakyTimeout("untriaged");
|
||||
addLoadEvent(doTest);
|
||||
addLoadEvent(() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, doTest));
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -38,11 +38,12 @@ function doTest() {
|
||||
i2.contentDocument.adoptNode(pre);
|
||||
i2.contentDocument.body.appendChild(pre);
|
||||
ok(eventCounter == 2, "DOMNodeInserted should have been dispatched in the new document");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
addLoadEvent(SimpleTest.finish);
|
||||
addLoadEvent(() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, doTest));
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -17,197 +17,203 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650493
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function getNodes() {
|
||||
var walker = document.createTreeWalker($('content'), NodeFilter.SHOW_ALL, null);
|
||||
var nodes = [];
|
||||
do {
|
||||
nodes.push(walker.currentNode);
|
||||
} while(walker.nextNode());
|
||||
function test() {
|
||||
function getNodes() {
|
||||
var walker = document.createTreeWalker($('content'), NodeFilter.SHOW_ALL, null);
|
||||
var nodes = [];
|
||||
do {
|
||||
nodes.push(walker.currentNode);
|
||||
} while(walker.nextNode());
|
||||
|
||||
return nodes;
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
function check() {
|
||||
var current = getNodes();
|
||||
is(nodes.length, current.length, "length after " + testName);
|
||||
nodes.forEach(function(val, index) {
|
||||
ok(current.indexOf(val) > -1, "nodes[" + index + "] (" + val + ") shouldn't exist after " + testName);
|
||||
function check() {
|
||||
var current = getNodes();
|
||||
is(nodes.length, current.length, "length after " + testName);
|
||||
nodes.forEach(function(val, index) {
|
||||
ok(current.indexOf(val) > -1, "nodes[" + index + "] (" + val + ") shouldn't exist after " + testName);
|
||||
});
|
||||
}
|
||||
|
||||
var nodes = getNodes();
|
||||
var testName = "empty";
|
||||
var mutateCount = 0;
|
||||
|
||||
check();
|
||||
|
||||
// Set up listeners
|
||||
root = $('content');
|
||||
root.addEventListener("DOMNodeInserted", function(e) {
|
||||
mutateCount++;
|
||||
is(e.isTrusted, true, "untrusted mutation event");
|
||||
var w = document.createTreeWalker(e.target, NodeFilter.SHOW_ALL, null);
|
||||
do {
|
||||
is(nodes.indexOf(w.currentNode), -1, "already have inserted node (" + w.currentNode + ") when " + testName);
|
||||
nodes.push(w.currentNode);
|
||||
} while(w.nextNode());
|
||||
});
|
||||
root.addEventListener("DOMNodeRemoved", function(e) {
|
||||
mutateCount++;
|
||||
is(e.isTrusted, true, "untrusted mutation event");
|
||||
var w = document.createTreeWalker(e.target, NodeFilter.SHOW_ALL, null);
|
||||
do {
|
||||
var index = nodes.indexOf(w.currentNode);
|
||||
ok(index != -1, "missing removed node (" + w.currentNode + ") when " + testName);
|
||||
nodes.splice(index, 1);
|
||||
} while(w.nextNode());
|
||||
});
|
||||
|
||||
testName = "text-only innerHTML";
|
||||
root.innerHTML = "hello world";
|
||||
check();
|
||||
|
||||
testName = "innerHTML with <b>";
|
||||
root.innerHTML = "<b>bold</b> world";
|
||||
check();
|
||||
|
||||
testName = "complex innerHTML";
|
||||
root.innerHTML = "<b>b<span>old</span></b> <strong>world";
|
||||
check();
|
||||
|
||||
testName = "replacing using .textContent";
|
||||
root.textContent = "i'm just a plain text minding my own business";
|
||||
check();
|
||||
|
||||
testName = "clearing using .textContent";
|
||||
root.textContent = "";
|
||||
check();
|
||||
|
||||
testName = "inserting using .textContent";
|
||||
root.textContent = "i'm new text!!";
|
||||
check();
|
||||
|
||||
testName = "inserting using .textContent";
|
||||
root.textContent = "i'm new text!!";
|
||||
check();
|
||||
|
||||
testName = "preparing to normalize";
|
||||
root.innerHTML = "<u><b>foo</b></u> ";
|
||||
var u = root.firstChild;
|
||||
is(u.nodeName, "U", "got the right node");
|
||||
var b = u.firstChild;
|
||||
is(b.nodeName, "B", "got the right node");
|
||||
b.insertBefore(document.createTextNode(""), b.firstChild);
|
||||
b.insertBefore(document.createTextNode(""), b.firstChild);
|
||||
b.appendChild(document.createTextNode(""));
|
||||
b.appendChild(document.createTextNode("hello"));
|
||||
b.appendChild(document.createTextNode("world"));
|
||||
u.appendChild(document.createTextNode("foo"));
|
||||
u.appendChild(document.createTextNode(""));
|
||||
u.appendChild(document.createTextNode("bar"));
|
||||
check();
|
||||
|
||||
testName = "normalizing";
|
||||
root.normalize();
|
||||
check();
|
||||
|
||||
testName = "self replace firstChild";
|
||||
mutateCount = 0;
|
||||
root.replaceChild(root.firstChild, root.firstChild);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "self replace second child";
|
||||
mutateCount = 0;
|
||||
root.replaceChild(root.firstChild.nextSibling, root.firstChild.nextSibling);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "self replace lastChild";
|
||||
mutateCount = 0;
|
||||
root.replaceChild(root.lastChild, root.lastChild);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "self insertBefore firstChild";
|
||||
mutateCount = 0;
|
||||
root.insertBefore(root.firstChild, root.firstChild);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "self insertBefore second child";
|
||||
mutateCount = 0;
|
||||
root.insertBefore(root.firstChild.nextSibling, root.firstChild.nextSibling);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "self insertBefore lastChild";
|
||||
mutateCount = 0;
|
||||
root.insertBefore(root.lastChild, root.lastChild);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "appendChild last";
|
||||
mutateCount = 0;
|
||||
root.appendChild(root.lastChild);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "prepare script/style";
|
||||
script = document.createElement("script");
|
||||
script.appendChild(document.createTextNode("void(0);"));
|
||||
root.appendChild(script);
|
||||
style = document.createElement("style");
|
||||
root.appendChild(style);
|
||||
check();
|
||||
|
||||
testName = "set something in script";
|
||||
script.text = "something";
|
||||
check();
|
||||
|
||||
testName = "set something in style";
|
||||
style.innerHTML = "something { dislay: none; }";
|
||||
check();
|
||||
|
||||
testName = "moving style";
|
||||
root.insertBefore(style, root.firstChild);
|
||||
check();
|
||||
|
||||
testName = "replacing script";
|
||||
root.replaceChild(b, script);
|
||||
check();
|
||||
|
||||
testName = "doc-fragment insert in the middle";
|
||||
frag = document.createDocumentFragment();
|
||||
frag.addEventListener("DOMNodeRemoved", function(e) {
|
||||
var index = children.indexOf(e.target);
|
||||
ok(index != -1, "unknown child removed from fragment");
|
||||
children.splice(index, 1);
|
||||
});
|
||||
var children = [];
|
||||
children.push(document.createTextNode("foo"));
|
||||
children.push(document.createTextNode("bar"));
|
||||
children.push(document.createElement("span"));
|
||||
children.push(document.createElement("b"));
|
||||
children[2].appendChild(document.createElement("i"));
|
||||
children.forEach(function(child) { frag.appendChild(child); });
|
||||
ok(root.firstChild, "need to have children in order to test inserting before end");
|
||||
root.replaceChild(frag, root.firstChild);
|
||||
check();
|
||||
is(children.length, 0, "should have received DOMNodeRemoved for all frag children when inserting");
|
||||
is(frag.childNodes.length, 0, "fragment should be empty when inserting");
|
||||
|
||||
testName = "doc-fragment append at the end";
|
||||
children.push(document.createTextNode("foo"));
|
||||
children.push(document.createTextNode("bar"));
|
||||
children.push(document.createElement("span"));
|
||||
children.push(document.createElement("b"));
|
||||
children[2].appendChild(document.createElement("i"));
|
||||
children.forEach(function(child) { frag.appendChild(child); });
|
||||
root.appendChild(frag);
|
||||
check();
|
||||
is(children.length, 0, "should have received DOMNodeRemoved for all frag children when appending");
|
||||
is(frag.childNodes.length, 0, "fragment should be empty when appending");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
var nodes = getNodes();
|
||||
var testName = "empty";
|
||||
var mutateCount = 0;
|
||||
|
||||
check();
|
||||
|
||||
// Set up listeners
|
||||
root = $('content');
|
||||
root.addEventListener("DOMNodeInserted", function(e) {
|
||||
mutateCount++;
|
||||
is(e.isTrusted, true, "untrusted mutation event");
|
||||
var w = document.createTreeWalker(e.target, NodeFilter.SHOW_ALL, null);
|
||||
do {
|
||||
is(nodes.indexOf(w.currentNode), -1, "already have inserted node (" + w.currentNode + ") when " + testName);
|
||||
nodes.push(w.currentNode);
|
||||
} while(w.nextNode());
|
||||
});
|
||||
root.addEventListener("DOMNodeRemoved", function(e) {
|
||||
mutateCount++;
|
||||
is(e.isTrusted, true, "untrusted mutation event");
|
||||
var w = document.createTreeWalker(e.target, NodeFilter.SHOW_ALL, null);
|
||||
do {
|
||||
var index = nodes.indexOf(w.currentNode);
|
||||
ok(index != -1, "missing removed node (" + w.currentNode + ") when " + testName);
|
||||
nodes.splice(index, 1);
|
||||
} while(w.nextNode());
|
||||
});
|
||||
|
||||
testName = "text-only innerHTML";
|
||||
root.innerHTML = "hello world";
|
||||
check();
|
||||
|
||||
testName = "innerHTML with <b>";
|
||||
root.innerHTML = "<b>bold</b> world";
|
||||
check();
|
||||
|
||||
testName = "complex innerHTML";
|
||||
root.innerHTML = "<b>b<span>old</span></b> <strong>world";
|
||||
check();
|
||||
|
||||
testName = "replacing using .textContent";
|
||||
root.textContent = "i'm just a plain text minding my own business";
|
||||
check();
|
||||
|
||||
testName = "clearing using .textContent";
|
||||
root.textContent = "";
|
||||
check();
|
||||
|
||||
testName = "inserting using .textContent";
|
||||
root.textContent = "i'm new text!!";
|
||||
check();
|
||||
|
||||
testName = "inserting using .textContent";
|
||||
root.textContent = "i'm new text!!";
|
||||
check();
|
||||
|
||||
testName = "preparing to normalize";
|
||||
root.innerHTML = "<u><b>foo</b></u> ";
|
||||
var u = root.firstChild;
|
||||
is(u.nodeName, "U", "got the right node");
|
||||
var b = u.firstChild;
|
||||
is(b.nodeName, "B", "got the right node");
|
||||
b.insertBefore(document.createTextNode(""), b.firstChild);
|
||||
b.insertBefore(document.createTextNode(""), b.firstChild);
|
||||
b.appendChild(document.createTextNode(""));
|
||||
b.appendChild(document.createTextNode("hello"));
|
||||
b.appendChild(document.createTextNode("world"));
|
||||
u.appendChild(document.createTextNode("foo"));
|
||||
u.appendChild(document.createTextNode(""));
|
||||
u.appendChild(document.createTextNode("bar"));
|
||||
check();
|
||||
|
||||
testName = "normalizing";
|
||||
root.normalize();
|
||||
check();
|
||||
|
||||
testName = "self replace firstChild";
|
||||
mutateCount = 0;
|
||||
root.replaceChild(root.firstChild, root.firstChild);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "self replace second child";
|
||||
mutateCount = 0;
|
||||
root.replaceChild(root.firstChild.nextSibling, root.firstChild.nextSibling);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "self replace lastChild";
|
||||
mutateCount = 0;
|
||||
root.replaceChild(root.lastChild, root.lastChild);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "self insertBefore firstChild";
|
||||
mutateCount = 0;
|
||||
root.insertBefore(root.firstChild, root.firstChild);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "self insertBefore second child";
|
||||
mutateCount = 0;
|
||||
root.insertBefore(root.firstChild.nextSibling, root.firstChild.nextSibling);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "self insertBefore lastChild";
|
||||
mutateCount = 0;
|
||||
root.insertBefore(root.lastChild, root.lastChild);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "appendChild last";
|
||||
mutateCount = 0;
|
||||
root.appendChild(root.lastChild);
|
||||
check();
|
||||
is(mutateCount, 2, "should remove and reinsert " + testName);
|
||||
|
||||
testName = "prepare script/style";
|
||||
script = document.createElement("script");
|
||||
script.appendChild(document.createTextNode("void(0);"));
|
||||
root.appendChild(script);
|
||||
style = document.createElement("style");
|
||||
root.appendChild(style);
|
||||
check();
|
||||
|
||||
testName = "set something in script";
|
||||
script.text = "something";
|
||||
check();
|
||||
|
||||
testName = "set something in style";
|
||||
style.innerHTML = "something { dislay: none; }";
|
||||
check();
|
||||
|
||||
testName = "moving style";
|
||||
root.insertBefore(style, root.firstChild);
|
||||
check();
|
||||
|
||||
testName = "replacing script";
|
||||
root.replaceChild(b, script);
|
||||
check();
|
||||
|
||||
testName = "doc-fragment insert in the middle";
|
||||
frag = document.createDocumentFragment();
|
||||
frag.addEventListener("DOMNodeRemoved", function(e) {
|
||||
var index = children.indexOf(e.target);
|
||||
ok(index != -1, "unknown child removed from fragment");
|
||||
children.splice(index, 1);
|
||||
});
|
||||
var children = [];
|
||||
children.push(document.createTextNode("foo"));
|
||||
children.push(document.createTextNode("bar"));
|
||||
children.push(document.createElement("span"));
|
||||
children.push(document.createElement("b"));
|
||||
children[2].appendChild(document.createElement("i"));
|
||||
children.forEach(function(child) { frag.appendChild(child); });
|
||||
ok(root.firstChild, "need to have children in order to test inserting before end");
|
||||
root.replaceChild(frag, root.firstChild);
|
||||
check();
|
||||
is(children.length, 0, "should have received DOMNodeRemoved for all frag children when inserting");
|
||||
is(frag.childNodes.length, 0, "fragment should be empty when inserting");
|
||||
|
||||
testName = "doc-fragment append at the end";
|
||||
children.push(document.createTextNode("foo"));
|
||||
children.push(document.createTextNode("bar"));
|
||||
children.push(document.createElement("span"));
|
||||
children.push(document.createElement("b"));
|
||||
children[2].appendChild(document.createElement("i"));
|
||||
children.forEach(function(child) { frag.appendChild(child); });
|
||||
root.appendChild(frag);
|
||||
check();
|
||||
is(children.length, 0, "should have received DOMNodeRemoved for all frag children when appending");
|
||||
is(frag.childNodes.length, 0, "fragment should be empty when appending");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
@ -50,11 +50,11 @@ function test() {
|
||||
testElementType("option");
|
||||
testElementType("optgroup");
|
||||
testElementType("button");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(test);
|
||||
addLoadEvent(SimpleTest.finish);
|
||||
addLoadEvent(() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test));
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -35,11 +35,11 @@ function testSelectedIndex()
|
||||
var selectElement = document.getElementsByTagName("select")[0];
|
||||
is(selectElement.selectedIndex, -1, "Wrong selected index!");
|
||||
is(selectElement.length, 0, "Select shouldn't have any options!");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(testSelectedIndex);
|
||||
addLoadEvent(SimpleTest.finish);
|
||||
addLoadEvent(() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, testSelectedIndex));
|
||||
|
||||
|
||||
</script>
|
||||
|
@ -2,21 +2,23 @@
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
const set = document.createElementNS("http://www.w3.org/2000/svg", "set");
|
||||
svg.appendChild(set);
|
||||
document.documentElement.appendChild(svg);
|
||||
const animation = new Animation();
|
||||
animation.addEventListener("finish", () =>
|
||||
svg.setAttribute("pointer-events", "visible")
|
||||
);
|
||||
animation.startTime = 2713;
|
||||
document.addEventListener("DOMAttrModified", e => {
|
||||
e.originalTarget.setCurrentTime(1.050520798894502e38);
|
||||
document.documentElement.removeAttribute("class");
|
||||
});
|
||||
});
|
||||
document.addEventListener("DOMContentLoaded", () =>
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, () => {
|
||||
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
const set = document.createElementNS("http://www.w3.org/2000/svg", "set");
|
||||
svg.appendChild(set);
|
||||
document.documentElement.appendChild(svg);
|
||||
const animation = new Animation();
|
||||
animation.addEventListener("finish", () =>
|
||||
svg.setAttribute("pointer-events", "visible")
|
||||
);
|
||||
animation.startTime = 2713;
|
||||
document.addEventListener("DOMAttrModified", e => {
|
||||
e.originalTarget.setCurrentTime(1.050520798894502e38);
|
||||
document.documentElement.removeAttribute("class");
|
||||
});
|
||||
})
|
||||
);
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
||||
|
@ -149,7 +149,8 @@ function run_tests() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", run_tests);
|
||||
window.addEventListener("load",
|
||||
() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, run_tests));
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
@ -65,7 +65,8 @@ function run_tests() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", run_tests);
|
||||
window.addEventListener("load",
|
||||
() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, run_tests));
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
@ -120,7 +120,8 @@ function run_tests() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", run_tests);
|
||||
window.addEventListener("load",
|
||||
() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, run_tests));
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
@ -452,7 +452,8 @@ function testMutationEvents(g) {
|
||||
eventChecker.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", main);
|
||||
window.addEventListener("load",
|
||||
() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, main));
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
@ -1363,7 +1363,8 @@ function run_tests() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", run_tests);
|
||||
window.addEventListener("load",
|
||||
() => SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, run_tests));
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
@ -250,7 +250,8 @@ function runTests() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", runTests);
|
||||
window.addEventListener("load", () =>
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, runTests));
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -13,13 +13,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1870055
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const node = document.createElement('div');
|
||||
document.documentElement.appendChild(node);
|
||||
document.addEventListener('DOMSubtreeModified', (e) => {
|
||||
node.setHTMLUnsafe('b');
|
||||
is(node.textContent, 'b', 'Re-entry into setHTMLUnsafe is valid');
|
||||
SimpleTest.finish();
|
||||
}, { once: true });
|
||||
node.setHTMLUnsafe('a');
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, () => {
|
||||
const node = document.createElement('div');
|
||||
document.documentElement.appendChild(node);
|
||||
document.addEventListener('DOMSubtreeModified', (e) => {
|
||||
node.setHTMLUnsafe('b');
|
||||
is(node.textContent, 'b', 'Re-entry into setHTMLUnsafe is valid');
|
||||
SimpleTest.finish();
|
||||
}, { once: true });
|
||||
node.setHTMLUnsafe('a');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -20,7 +20,7 @@ function onLoad() {
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="onLoad()">
|
||||
<body onload="SpecialPowers.pushPrefEnv({'set': [['dom.mutation_events.enabled', true]]}, onLoad)">
|
||||
<table></table>
|
||||
<style></style>
|
||||
<spacer contenteditable>
|
||||
|
@ -24,6 +24,6 @@ function init()
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="init()"><div id="ww"><input type="text" value="inputtext" id="inp">moretext</div></body>
|
||||
<body onload="SpecialPowers.pushPrefEnv({'set': [['dom.mutation_events.enabled', true]]}, init)"><div id="ww"><input type="text" value="inputtext" id="inp">moretext</div></body>
|
||||
|
||||
</html>
|
||||
|
@ -3246,6 +3246,12 @@
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Whether to dispatch mutation events.
|
||||
- name: dom.mutation_events.enabled
|
||||
type: bool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Limit of location change caused by content scripts in a time span per
|
||||
# BrowsingContext. This includes calls to History and Location APIs.
|
||||
- name: dom.navigation.locationChangeRateLimit.count
|
||||
|
@ -794,6 +794,10 @@ pref("dom.disable_window_move_resize", false);
|
||||
|
||||
pref("dom.allow_scripts_to_close_windows", false);
|
||||
|
||||
// List of urls for which mutation events are enabled even if mutation events
|
||||
// in general are disabled. See nsContentUtils::IsURIInPrefList.
|
||||
pref("dom.mutation_events.forceEnable", "");
|
||||
|
||||
pref("dom.popup_allowed_events", "change click dblclick auxclick mousedown mouseup pointerdown pointerup notificationclick reset submit touchend contextmenu");
|
||||
|
||||
pref("dom.serviceWorkers.disable_open_click_delay", 1000);
|
||||
|
@ -15,122 +15,125 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=613662
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
/** Test for Bug 613662 **/
|
||||
function test() {
|
||||
function testPositions(node) {
|
||||
node.insertAdjacentHTML("beforeBegin", "\u003Cscript>ok(false, 'script should not have run');\u003C/script><i></i>");
|
||||
is(node.previousSibling.localName, "i", "Should have had <i> as previous sibling");
|
||||
node.insertAdjacentHTML("Afterbegin", "<b></b>\u003Cscript>ok(false, 'script should not have run');\u003C/script>");
|
||||
is(node.firstChild.localName, "b", "Should have had <b> as first child");
|
||||
node.insertAdjacentHTML("BeforeEnd", "\u003Cscript>ok(false, 'script should not have run');\u003C/script><u></u>");
|
||||
is(node.lastChild.localName, "u", "Should have had <u> as last child");
|
||||
node.insertAdjacentHTML("afterend", "<a></a>\u003Cscript>ok(false, 'script should not have run');\u003C/script>");
|
||||
is(node.nextSibling.localName, "a", "Should have had <a> as next sibling");
|
||||
}
|
||||
|
||||
function testPositions(node) {
|
||||
node.insertAdjacentHTML("beforeBegin", "\u003Cscript>ok(false, 'script should not have run');\u003C/script><i></i>");
|
||||
is(node.previousSibling.localName, "i", "Should have had <i> as previous sibling");
|
||||
node.insertAdjacentHTML("Afterbegin", "<b></b>\u003Cscript>ok(false, 'script should not have run');\u003C/script>");
|
||||
is(node.firstChild.localName, "b", "Should have had <b> as first child");
|
||||
node.insertAdjacentHTML("BeforeEnd", "\u003Cscript>ok(false, 'script should not have run');\u003C/script><u></u>");
|
||||
is(node.lastChild.localName, "u", "Should have had <u> as last child");
|
||||
node.insertAdjacentHTML("afterend", "<a></a>\u003Cscript>ok(false, 'script should not have run');\u003C/script>");
|
||||
is(node.nextSibling.localName, "a", "Should have had <a> as next sibling");
|
||||
var content = document.getElementById("content");
|
||||
testPositions(content); // without next sibling
|
||||
testPositions(content); // test again when there's next sibling
|
||||
|
||||
try {
|
||||
content.insertAdjacentHTML("bar", "foo");
|
||||
ok(false, "insertAdjacentHTML should have thrown");
|
||||
} catch (e) {
|
||||
is(e.name, "SyntaxError", "insertAdjacentHTML should throw SyntaxError");
|
||||
is(e.code, 12, "insertAdjacentHTML should throw SYNTAX_ERR");
|
||||
}
|
||||
|
||||
var parent = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
|
||||
var child = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
|
||||
|
||||
try {
|
||||
child.insertAdjacentHTML("Beforebegin", "foo");
|
||||
ok(false, "insertAdjacentHTML should have thrown");
|
||||
} catch (e) {
|
||||
is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
|
||||
is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
|
||||
}
|
||||
|
||||
try {
|
||||
child.insertAdjacentHTML("AfterEnd", "foo");
|
||||
ok(false, "insertAdjacentHTML should have thrown");
|
||||
} catch (e) {
|
||||
is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
|
||||
is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
|
||||
}
|
||||
|
||||
child.insertAdjacentHTML("afterBegin", "foo"); // mustn't throw
|
||||
child.insertAdjacentHTML("beforeend", "foo"); // mustn't throw
|
||||
|
||||
parent.appendChild(child);
|
||||
testPositions(child); // node not in tree but has parent
|
||||
|
||||
content.appendChild(parent); // must not run scripts
|
||||
|
||||
try {
|
||||
document.documentElement.insertAdjacentHTML("afterend", "<div></div>");
|
||||
ok(false, "insertAdjacentHTML should have thrown");
|
||||
} catch (e) {
|
||||
is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
|
||||
is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
|
||||
}
|
||||
|
||||
var content2 = document.getElementById("content2");
|
||||
|
||||
var events = [
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
];
|
||||
|
||||
function mutationEventListener(evt) {
|
||||
var expected = events.shift();
|
||||
is(evt.type, expected[0], "Unexpected mutation type");
|
||||
is(evt.relatedNode, expected[1], "Unexpected related node");
|
||||
}
|
||||
|
||||
document.addEventListener("DOMSubtreeModified", mutationEventListener);
|
||||
document.addEventListener("DOMNodeInserted", mutationEventListener);
|
||||
document.addEventListener("DOMNodeRemoved", mutationEventListener);
|
||||
document.addEventListener("DOMNodeRemovedFromDocument", mutationEventListener);
|
||||
document.addEventListener("DOMNodeInsertedIntoDocument", mutationEventListener);
|
||||
document.addEventListener("DOMAttrModified", mutationEventListener);
|
||||
document.addEventListener("DOMCharacterDataModified", mutationEventListener);
|
||||
|
||||
testPositions(content2); // without next sibling
|
||||
testPositions(content2); // test again when there's next sibling
|
||||
|
||||
is(events.length, 0, "Not all expected events fired.");
|
||||
|
||||
// XML-only:
|
||||
try {
|
||||
content.insertAdjacentHTML("beforeend", "<p>");
|
||||
ok(false, "insertAdjacentHTML should have thrown");
|
||||
} catch (e) {
|
||||
is(e.name, "SyntaxError", "insertAdjacentHTML should throw SyntaxError");
|
||||
is(e.code, 12, "insertAdjacentHTML should throw SYNTAX_ERR");
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
var content = document.getElementById("content");
|
||||
testPositions(content); // without next sibling
|
||||
testPositions(content); // test again when there's next sibling
|
||||
|
||||
try {
|
||||
content.insertAdjacentHTML("bar", "foo");
|
||||
ok(false, "insertAdjacentHTML should have thrown");
|
||||
} catch (e) {
|
||||
is(e.name, "SyntaxError", "insertAdjacentHTML should throw SyntaxError");
|
||||
is(e.code, 12, "insertAdjacentHTML should throw SYNTAX_ERR");
|
||||
}
|
||||
|
||||
var parent = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
|
||||
var child = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
|
||||
|
||||
try {
|
||||
child.insertAdjacentHTML("Beforebegin", "foo");
|
||||
ok(false, "insertAdjacentHTML should have thrown");
|
||||
} catch (e) {
|
||||
is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
|
||||
is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
|
||||
}
|
||||
|
||||
try {
|
||||
child.insertAdjacentHTML("AfterEnd", "foo");
|
||||
ok(false, "insertAdjacentHTML should have thrown");
|
||||
} catch (e) {
|
||||
is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
|
||||
is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
|
||||
}
|
||||
|
||||
child.insertAdjacentHTML("afterBegin", "foo"); // mustn't throw
|
||||
child.insertAdjacentHTML("beforeend", "foo"); // mustn't throw
|
||||
|
||||
parent.appendChild(child);
|
||||
testPositions(child); // node not in tree but has parent
|
||||
|
||||
content.appendChild(parent); // must not run scripts
|
||||
|
||||
try {
|
||||
document.documentElement.insertAdjacentHTML("afterend", "<div></div>");
|
||||
ok(false, "insertAdjacentHTML should have thrown");
|
||||
} catch (e) {
|
||||
is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
|
||||
is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
|
||||
}
|
||||
|
||||
var content2 = document.getElementById("content2");
|
||||
|
||||
var events = [
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMNodeInserted", content2 ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMNodeInserted", document.body ],
|
||||
[ "DOMSubtreeModified", null ],
|
||||
];
|
||||
|
||||
function mutationEventListener(evt) {
|
||||
var expected = events.shift();
|
||||
is(evt.type, expected[0], "Unexpected mutation type");
|
||||
is(evt.relatedNode, expected[1], "Unexpected related node");
|
||||
}
|
||||
|
||||
document.addEventListener("DOMSubtreeModified", mutationEventListener);
|
||||
document.addEventListener("DOMNodeInserted", mutationEventListener);
|
||||
document.addEventListener("DOMNodeRemoved", mutationEventListener);
|
||||
document.addEventListener("DOMNodeRemovedFromDocument", mutationEventListener);
|
||||
document.addEventListener("DOMNodeInsertedIntoDocument", mutationEventListener);
|
||||
document.addEventListener("DOMAttrModified", mutationEventListener);
|
||||
document.addEventListener("DOMCharacterDataModified", mutationEventListener);
|
||||
|
||||
testPositions(content2); // without next sibling
|
||||
testPositions(content2); // test again when there's next sibling
|
||||
|
||||
is(events.length, 0, "Not all expected events fired.");
|
||||
|
||||
// XML-only:
|
||||
try {
|
||||
content.insertAdjacentHTML("beforeend", "<p>");
|
||||
ok(false, "insertAdjacentHTML should have thrown");
|
||||
} catch (e) {
|
||||
is(e.name, "SyntaxError", "insertAdjacentHTML should throw SyntaxError");
|
||||
is(e.code, 12, "insertAdjacentHTML should throw SYNTAX_ERR");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mutation_events.enabled", true]]}, test);
|
||||
]]></script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -1,3 +1,5 @@
|
||||
prefs: [dom.mutation_events.enabled: true]
|
||||
|
||||
[move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [TIMEOUT, OK]
|
||||
|
@ -1,3 +1,5 @@
|
||||
prefs: [dom.mutation_events.enabled: true]
|
||||
|
||||
[042.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
|
@ -1,3 +1,5 @@
|
||||
prefs: [dom.mutation_events.enabled: true]
|
||||
|
||||
[043.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
|
@ -1,3 +1,5 @@
|
||||
prefs: [dom.mutation_events.enabled: true]
|
||||
|
||||
[054.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
|
@ -1,3 +1,5 @@
|
||||
prefs: [dom.mutation_events.enabled: true]
|
||||
|
||||
[055.html]
|
||||
expected:
|
||||
if fission and (os == "android"): [OK, TIMEOUT]
|
||||
|
@ -0,0 +1 @@
|
||||
prefs: [dom.mutation_events.enabled: true]
|
@ -0,0 +1 @@
|
||||
prefs: [dom.mutation_events.enabled: true]
|
1
testing/web-platform/mozilla/meta/dom/classList.html.ini
Normal file
1
testing/web-platform/mozilla/meta/dom/classList.html.ini
Normal file
@ -0,0 +1 @@
|
||||
prefs: [dom.mutation_events.enabled: true]
|
@ -736,7 +736,8 @@ function init() {
|
||||
["mousewheel.with_meta.action", 0],
|
||||
["mousewheel.with_meta.action.override_x", -1],
|
||||
["dom.events.textevent.enabled", true],
|
||||
["layout.overflow-underflow.content.enabled", true]]}, runNextTest);
|
||||
["layout.overflow-underflow.content.enabled", true],
|
||||
["dom.mutation_events.enabled", true]]}, runNextTest);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
|
@ -10975,6 +10975,7 @@ async function runTest()
|
||||
set: [
|
||||
["dom.events.textevent.enabled", true],
|
||||
["test.ime_content_observer.assert_invalid_cache", true],
|
||||
["dom.mutation_events.enabled", true],
|
||||
],
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user