Bug 562652 - MutationEvents don't get fired when documentFragment is added to a data document, r=sicking

This commit is contained in:
Olli Pettay 2010-04-30 14:01:25 +03:00
Родитель d67fd40425
Коммит 0a28b327d2
4 изменённых файлов: 91 добавлений и 17 удалений

Просмотреть файл

@ -3743,6 +3743,28 @@ PRBool IsAllowedAsChild(nsIContent* aNewChild, PRUint16 aNewNodeType,
return PR_FALSE; return PR_FALSE;
} }
void
nsGenericElement::FireNodeInserted(nsIDocument* aDoc,
nsINode* aParent,
nsCOMArray<nsIContent>& aNodes)
{
PRInt32 count = aNodes.Count();
for (PRInt32 i = 0; i < count; ++i) {
nsIContent* childContent = aNodes[i];
if (nsContentUtils::HasMutationListeners(childContent,
NS_EVENT_BITS_MUTATION_NODEINSERTED, aParent)) {
mozAutoRemovableBlockerRemover blockerRemover(aDoc);
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_NODEINSERTED);
mutation.mRelatedNode = do_QueryInterface(aParent);
mozAutoSubtreeModified subtree(aDoc, aParent);
nsEventDispatcher::Dispatch(childContent, nsnull, &mutation);
}
}
}
nsresult nsresult
nsINode::ReplaceOrInsertBefore(PRBool aReplace, nsINode* aNewChild, nsINode::ReplaceOrInsertBefore(PRBool aReplace, nsINode* aNewChild,
nsINode* aRefChild) nsINode* aRefChild)
@ -3951,23 +3973,11 @@ nsINode::ReplaceOrInsertBefore(PRBool aReplace, nsINode* aNewChild,
// Fire mutation events. Optimize for the case when there are no listeners // Fire mutation events. Optimize for the case when there are no listeners
nsPIDOMWindow* window = nsnull; nsPIDOMWindow* window = nsnull;
if (doc && (window = doc->GetInnerWindow()) && if (doc &&
window->HasMutationListeners(NS_EVENT_BITS_MUTATION_NODEINSERTED)) { (((window = doc->GetInnerWindow()) &&
window->HasMutationListeners(NS_EVENT_BITS_MUTATION_NODEINSERTED)) ||
for (i = 0; i < count; ++i, ++insPos) { !window)) {
nsIContent* childContent = fragChildren[i]; nsGenericElement::FireNodeInserted(doc, this, fragChildren);
if (nsContentUtils::HasMutationListeners(childContent,
NS_EVENT_BITS_MUTATION_NODEINSERTED, this)) {
mozAutoRemovableBlockerRemover blockerRemover(doc);
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_NODEINSERTED);
mutation.mRelatedNode = do_QueryInterface(this);
mozAutoSubtreeModified subtree(doc, this);
nsEventDispatcher::Dispatch(childContent, nsnull, &mutation);
}
}
} }
} }
else { else {

Просмотреть файл

@ -637,6 +637,14 @@ public:
nsAttrAndChildArray& aChildArray, nsAttrAndChildArray& aChildArray,
PRBool aMutationEvent); PRBool aMutationEvent);
/**
* If there are listeners for DOMNodeInserted event, fires the event on all
* aNodes
*/
static void FireNodeInserted(nsIDocument* aDoc,
nsINode* aParent,
nsCOMArray<nsIContent>& aNodes);
/** /**
* Helper methods for implementing querySelector/querySelectorAll * Helper methods for implementing querySelector/querySelectorAll
*/ */

Просмотреть файл

@ -380,6 +380,7 @@ _TEST_FILES = test_bug5141.html \
file_csp_redirects_resource.sjs \ file_csp_redirects_resource.sjs \
test_bug346485.html \ test_bug346485.html \
test_bug560780.html \ test_bug560780.html \
test_bug562652.html \
$(NULL) $(NULL)
# This test fails on the Mac for some reason # This test fails on the Mac for some reason

Просмотреть файл

@ -0,0 +1,55 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=562652
-->
<head>
<title>Test for Bug 562652</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=562652">Mozilla Bug 562652</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<div id="testtarget">_</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 562652 **/
var testCount = 0;
function createHTMLDoc() {
var dtd = document.implementation.createDocumentType("HTML", "-//W3C//DTD HTML 4.01//EN", null);
var d = document.implementation.createDocument(null, null, dtd);
d.appendChild(d.createElement("html"));
d.documentElement.appendChild(d.createElement("body"));
d.body.setAttribute("id", "testtarget");
return d;
}
function test(d) {
var t = d.getElementById("testtarget");
d.addEventListener("DOMNodeInserted", function(e) { ++testCount; }, false);
t.innerHTML = "_";
}
function runTests() {
test(document);
test(createHTMLDoc());
is(testCount, 2, "DOMNodeInserted should have fired 2 times!");
SimpleTest.finish();
}
addLoadEvent(runTests);
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>