Diff
Modified: branches/safari-536.28-branch/LayoutTests/ChangeLog (133661 => 133662)
--- branches/safari-536.28-branch/LayoutTests/ChangeLog 2012-11-06 21:13:27 UTC (rev 133661)
+++ branches/safari-536.28-branch/LayoutTests/ChangeLog 2012-11-06 21:19:52 UTC (rev 133662)
@@ -1,5 +1,19 @@
2012-11-06 Lucas Forschler <lforsch...@apple.com>
+ Merge r126131
+
+ 2012-08-20 MORITA Hajime <morr...@google.com>
+
+ load event shouldn't fired during node insertion traversals.
+ https://bugs.webkit.org/show_bug.cgi?id=94447
+
+ Reviewed by Ryosuke Niwa.
+
+ * fast/frames/iframe-onload-and-domnodeinserted-expected.txt: Added.
+ * fast/frames/iframe-onload-and-domnodeinserted.html: Added.
+
+2012-11-06 Lucas Forschler <lforsch...@apple.com>
+
Merge r125988
2012-08-19 MORITA Hajime <morr...@google.com>
Added: branches/safari-536.28-branch/LayoutTests/fast/frames/iframe-onload-and-domnodeinserted-expected.txt (0 => 133662)
--- branches/safari-536.28-branch/LayoutTests/fast/frames/iframe-onload-and-domnodeinserted-expected.txt (rev 0)
+++ branches/safari-536.28-branch/LayoutTests/fast/frames/iframe-onload-and-domnodeinserted-expected.txt 2012-11-06 21:19:52 UTC (rev 133662)
@@ -0,0 +1,11 @@
+This test ensures that any tree mutation in the load event handler cannot harm the tree consistency.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS loadEventFired is true
+PASS unless crash.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: branches/safari-536.28-branch/LayoutTests/fast/frames/iframe-onload-and-domnodeinserted.html (0 => 133662)
--- branches/safari-536.28-branch/LayoutTests/fast/frames/iframe-onload-and-domnodeinserted.html (rev 0)
+++ branches/safari-536.28-branch/LayoutTests/fast/frames/iframe-onload-and-domnodeinserted.html 2012-11-06 21:19:52 UTC (rev 133662)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<div id="g"></div>
+<script>
+description("This test ensures that any tree mutation in the load event handler cannot harm the tree consistency.")
+var docElement = document.documentElement;
+
+textareaElement = document.createElement("textarea");
+iframeElement = document.createElement("iframe");
+
+var loadEventFired = false;
+textareaElement.appendChild(iframeElement);
+iframeElement.addEventListener("load", function () { iframeElement.innerHTML = "X"; loadEventFired = true; }, false);
+textareaElement.addEventListener("DOMNodeInserted", function () { document.implementation.createDocument("", "", null).adoptNode(textareaElement) }, false);
+document.documentElement.appendChild(textareaElement); // The DOMNodeInserted event is triggered here through innerHTML = "X"
+document.getElementById("g").appendChild(textareaElement);
+shouldBeTrue("loadEventFired");
+debug("PASS unless crash.");
+</script>
+<script src=""
+</body>
+</html>
Modified: branches/safari-536.28-branch/Source/WebCore/ChangeLog (133661 => 133662)
--- branches/safari-536.28-branch/Source/WebCore/ChangeLog 2012-11-06 21:13:27 UTC (rev 133661)
+++ branches/safari-536.28-branch/Source/WebCore/ChangeLog 2012-11-06 21:19:52 UTC (rev 133662)
@@ -1,5 +1,41 @@
2012-11-06 Lucas Forschler <lforsch...@apple.com>
+ Merge r126131
+
+ 2012-08-20 MORITA Hajime <morr...@google.com>
+
+ load event shouldn't fired during node insertion traversals.
+ https://bugs.webkit.org/show_bug.cgi?id=94447
+
+ Reviewed by Ryosuke Niwa.
+
+ HTMLFrameElementBase::didNotifyDescendantInsertions() with empty @src
+ can trigger a load event during ChildNodeInsertionNotifier
+ traversal, whose handler can make DOM tree state inconsistent.
+
+ This change introduces a post traversal hook,
+ didNotifySubtreeInsertions(), for the insertion traversal and
+ replaces the problematic didNotifyDescendantInsertions() with it.
+
+ Since didNotifySubtreeInsertions() is invoked after the traversal,
+ it is safe for event handlers to mutate the tree.
+
+ Test: fast/frames/iframe-onload-and-domnodeinserted.html
+
+ * dom/ContainerNodeAlgorithms.h:
+ (ChildNodeInsertionNotifier): Added a post subtree notification.
+ (WebCore::ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument):
+ (WebCore::ChildNodeInsertionNotifier::notify):
+ * dom/Node.h:
+ (WebCore::Node::didNotifySubtreeInsertions): Newly added.
+ * html/HTMLFrameElementBase.cpp:
+ (WebCore::HTMLFrameElementBase::insertedInto): Now returns InsertionShouldCallDidNotifySubtreeInsertions
+ (WebCore::HTMLFrameElementBase::didNotifySubtreeInsertions): Replaced didNotifyDescendantInsertions()
+ * html/HTMLFrameElementBase.h:
+ (HTMLFrameElementBase):
+
+2012-11-06 Lucas Forschler <lforsch...@apple.com>
+
Merge r125988
2012-08-19 MORITA Hajime <morr...@google.com>
Modified: branches/safari-536.28-branch/Source/WebCore/dom/ContainerNodeAlgorithms.h (133661 => 133662)
--- branches/safari-536.28-branch/Source/WebCore/dom/ContainerNodeAlgorithms.h 2012-11-06 21:13:27 UTC (rev 133661)
+++ branches/safari-536.28-branch/Source/WebCore/dom/ContainerNodeAlgorithms.h 2012-11-06 21:19:52 UTC (rev 133662)
@@ -46,6 +46,7 @@
void notifyNodeInsertedIntoTree(ContainerNode*);
Node* m_insertionPoint;
+ Vector< RefPtr<Node> > m_postInsertionNotificationTargets;
};
class ChildNodeRemovalNotifier {
@@ -196,8 +197,16 @@
if (node->isContainerNode())
notifyDescendantInsertedIntoDocument(toContainerNode(node));
- if (request == Node::InsertionShouldCallDidNotifyDescendantInseretions)
+ switch (request) {
+ case Node::InsertionDone:
+ break;
+ case Node::InsertionShouldCallDidNotifyDescendantInseretions:
node->didNotifyDescendantInseretions(m_insertionPoint);
+ break;
+ case Node::InsertionShouldCallDidNotifySubtreeInsertions:
+ m_postInsertionNotificationTargets.append(node);
+ break;
+ }
}
inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoTree(ContainerNode* node)
@@ -234,6 +243,9 @@
notifyNodeInsertedIntoDocument(node);
else if (node->isContainerNode())
notifyNodeInsertedIntoTree(toContainerNode(node));
+
+ for (size_t i = 0; i < m_postInsertionNotificationTargets.size(); ++i)
+ m_postInsertionNotificationTargets[i]->didNotifySubtreeInsertions(m_insertionPoint);
}
Modified: branches/safari-536.28-branch/Source/WebCore/dom/Node.h (133661 => 133662)
--- branches/safari-536.28-branch/Source/WebCore/dom/Node.h 2012-11-06 21:13:27 UTC (rev 133661)
+++ branches/safari-536.28-branch/Source/WebCore/dom/Node.h 2012-11-06 21:19:52 UTC (rev 133662)
@@ -527,11 +527,13 @@
//
enum InsertionNotificationRequest {
InsertionDone,
- InsertionShouldCallDidNotifyDescendantInseretions
+ InsertionShouldCallDidNotifyDescendantInseretions,
+ InsertionShouldCallDidNotifySubtreeInsertions
};
virtual InsertionNotificationRequest insertedInto(Node* insertionPoint);
virtual void didNotifyDescendantInseretions(Node*) { }
+ virtual void didNotifySubtreeInsertions(Node*) { }
// Notifies the node that it is no longer part of the tree.
//
Modified: branches/safari-536.28-branch/Source/WebCore/html/HTMLFrameElementBase.cpp (133661 => 133662)
--- branches/safari-536.28-branch/Source/WebCore/html/HTMLFrameElementBase.cpp 2012-11-06 21:13:27 UTC (rev 133661)
+++ branches/safari-536.28-branch/Source/WebCore/html/HTMLFrameElementBase.cpp 2012-11-06 21:19:52 UTC (rev 133662)
@@ -157,11 +157,11 @@
{
HTMLFrameOwnerElement::insertedInto(insertionPoint);
if (insertionPoint->inDocument())
- return InsertionShouldCallDidNotifyDescendantInseretions;
+ return InsertionShouldCallDidNotifySubtreeInsertions;
return InsertionDone;
}
-void HTMLFrameElementBase::didNotifyDescendantInseretions(Node* insertionPoint)
+void HTMLFrameElementBase::didNotifySubtreeInsertions(Node* insertionPoint)
{
ASSERT_UNUSED(insertionPoint, insertionPoint->inDocument());
Modified: branches/safari-536.28-branch/Source/WebCore/html/HTMLFrameElementBase.h (133661 => 133662)
--- branches/safari-536.28-branch/Source/WebCore/html/HTMLFrameElementBase.h 2012-11-06 21:13:27 UTC (rev 133661)
+++ branches/safari-536.28-branch/Source/WebCore/html/HTMLFrameElementBase.h 2012-11-06 21:19:52 UTC (rev 133662)
@@ -55,7 +55,7 @@
virtual void parseAttribute(Attribute*) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
- virtual void didNotifyDescendantInseretions(Node*) OVERRIDE;
+ virtual void didNotifySubtreeInsertions(Node*) OVERRIDE;
virtual void attach();
private: