Title: [128791] branches/chromium/1229

Diff

Copied: branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame-expected.txt (from rev 127534, trunk/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame-expected.txt) (0 => 128791)


--- branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame-expected.txt	                        (rev 0)
+++ branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame-expected.txt	2012-09-17 19:08:30 UTC (rev 128791)
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 19: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7: An attempt was made to modify an object where modifications are not allowed.
+This tests that several ways of making an iframe that isn't inserted into a document tree but has a child frame will fail.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS targetFrame1.contentWindow == undefined is true
+PASS targetFrame2.contentWindow == undefined is true
+PASS targetFrame3.contentWindow == undefined is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Copied: branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html (from rev 127534, trunk/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html) (0 => 128791)


--- branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html	                        (rev 0)
+++ branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html	2012-09-17 19:08:30 UTC (rev 128791)
@@ -0,0 +1,52 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<div id="main"/>
+<script>
+description("This tests that several ways of making an iframe that isn't inserted into a document tree"
+    + " but has a child frame will fail.");
+
+main = document.getElementById("main");
+
+try {
+    container = main.appendChild(document.createElement("div"));
+    helperFrame = container.appendChild(document.createElement("iframe"));
+    targetFrame1 = document.createElement("iframe");
+
+    helperFrame.contentWindow._onunload_ = function() {
+        container.insertBefore(targetFrame1, helperFrame);
+    }
+
+    main.removeChild(container);
+} catch (e) { }
+shouldBeTrue("targetFrame1.contentWindow == undefined");
+
+try {
+    container = main.appendChild(document.createElement("div"));
+    helperElement = container.appendChild(document.createElement("input"));
+    helperElement.focus();
+    targetFrame2 = document.createElement("iframe");
+
+    helperElement._onblur_ = function() {
+        container.appendChild(targetFrame2);
+    }
+
+    main.removeChild(container);
+} catch (e) { }
+shouldBeTrue("targetFrame2.contentWindow == undefined");
+
+try {
+    container = document.createElement("div");
+    targetFrame3 = container.appendChild(document.createElement("iframe"));
+    helperFrame = targetFrame3.appendChild(document.createElement("iframe"));
+    helperFrame.src = ""
+    document.body.appendChild(container);
+} catch (e) { }
+shouldBeTrue("targetFrame3.contentWindow == undefined");
+
+isSuccessfullyParsed();
+</script>
+</body>
+</html>

Modified: branches/chromium/1229/LayoutTests/fast/innerHTML/innerHTML-iframe-expected.txt (128790 => 128791)


--- branches/chromium/1229/LayoutTests/fast/innerHTML/innerHTML-iframe-expected.txt	2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/LayoutTests/fast/innerHTML/innerHTML-iframe-expected.txt	2012-09-17 19:08:30 UTC (rev 128791)
@@ -1 +1,2 @@
+CONSOLE MESSAGE: line 12: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7: An attempt was made to modify an object where modifications are not allowed.
 PASS: body and iframe cleared without crashing.

Copied: branches/chromium/1229/LayoutTests/platform/chromium/fast/frames/out-of-document-iframe-has-child-frame-expected.txt (from rev 127534, trunk/LayoutTests/platform/chromium/fast/frames/out-of-document-iframe-has-child-frame-expected.txt) (0 => 128791)


--- branches/chromium/1229/LayoutTests/platform/chromium/fast/frames/out-of-document-iframe-has-child-frame-expected.txt	                        (rev 0)
+++ branches/chromium/1229/LayoutTests/platform/chromium/fast/frames/out-of-document-iframe-has-child-frame-expected.txt	2012-09-17 19:08:30 UTC (rev 128791)
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 19: Uncaught Error: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7
+This tests that several ways of making an iframe that isn't inserted into a document tree but has a child frame will fail.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS targetFrame1.contentWindow == undefined is true
+PASS targetFrame2.contentWindow == undefined is true
+PASS targetFrame3.contentWindow == undefined is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Modified: branches/chromium/1229/Source/WebCore/dom/ContainerNode.cpp (128790 => 128791)


--- branches/chromium/1229/Source/WebCore/dom/ContainerNode.cpp	2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/Source/WebCore/dom/ContainerNode.cpp	2012-09-17 19:08:30 UTC (rev 128791)
@@ -352,8 +352,9 @@
 
         // fire removed from document mutation events.
         dispatchChildRemovalEvents(child);
-        ChildFrameDisconnector(child).disconnect();
     }
+
+    ChildFrameDisconnector(container, ChildFrameDisconnector::DoNotIncludeRoot).disconnect();
 }
 
 void ContainerNode::disconnectDescendantFrames()
@@ -384,14 +385,7 @@
     }
 
     RefPtr<Node> child = oldChild;
-    willRemoveChild(child.get());
 
-    // Mutation events might have moved this child into a different parent.
-    if (child->parentNode() != this) {
-        ec = NOT_FOUND_ERR;
-        return false;
-    }
-
     document()->removeFocusedNodeOfSubtree(child.get());
 
 #if ENABLE(FULLSCREEN_API)
@@ -405,6 +399,14 @@
         return false;
     }
 
+    willRemoveChild(child.get());
+
+    // Mutation events might have moved this child into a different parent.
+    if (child->parentNode() != this) {
+        ec = NOT_FOUND_ERR;
+        return false;
+    }
+
     Node* prev = child->previousSibling();
     Node* next = child->nextSibling();
     removeBetween(prev, next, child.get());
@@ -470,10 +472,6 @@
     // The container node can be removed from event handlers.
     RefPtr<ContainerNode> protect(this);
 
-    // Do any prep work needed before actually starting to detach
-    // and remove... e.g. stop loading frames, fire unload events.
-    willRemoveChildren(protect.get());
-
     // exclude this node when looking for removed focusedNode since only children will be removed
     document()->removeFocusedNodeOfSubtree(this, true);
 
@@ -481,6 +479,10 @@
     document()->removeFullScreenElementOfSubtree(this, true);
 #endif
 
+    // Do any prep work needed before actually starting to detach
+    // and remove... e.g. stop loading frames, fire unload events.
+    willRemoveChildren(protect.get());
+
     forbidEventDispatch();
     Vector<RefPtr<Node>, 10> removedChildren;
     removedChildren.reserveInitialCapacity(childNodeCount());

Modified: branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.cpp (128790 => 128791)


--- branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.cpp	2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.cpp	2012-09-17 19:08:30 UTC (rev 128791)
@@ -110,7 +110,7 @@
 void ChildFrameDisconnector::collectDescendant(ElementShadow* shadow)
 {
     for (ShadowRoot* root = shadow->youngestShadowRoot(); root; root = root->olderShadowRoot())
-        collectDescendant(root);
+        collectDescendant(root, IncludeRoot);
 }
 
 void ChildFrameDisconnector::Target::disconnect()

Modified: branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.h (128790 => 128791)


--- branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.h	2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.h	2012-09-17 19:08:30 UTC (rev 128791)
@@ -281,13 +281,37 @@
 
 class ChildFrameDisconnector {
 public:
-    explicit ChildFrameDisconnector(Node* root);
+    enum ShouldIncludeRoot {
+        DoNotIncludeRoot,
+        IncludeRoot
+    };
+
+    explicit ChildFrameDisconnector(Node* root, ShouldIncludeRoot shouldIncludeRoot = IncludeRoot)
+        : m_root(root)
+    {
+        collectDescendant(m_root, shouldIncludeRoot);
+        rootNodes().add(m_root);
+    }
+
+    ~ChildFrameDisconnector()
+    {
+        rootNodes().remove(m_root);
+    }
+
     void disconnect();
 
+    static bool nodeHasDisconnector(Node*);
+
 private:
-    void collectDescendant(Node* root);
+    void collectDescendant(Node* root, ShouldIncludeRoot);
     void collectDescendant(ElementShadow*);
 
+    static HashSet<Node*>& rootNodes()
+    {
+        DEFINE_STATIC_LOCAL(HashSet<Node*>, nodes, ());
+        return nodes;
+    }
+
     class Target {
     public:
         Target(HTMLFrameOwnerElement* element)
@@ -305,16 +329,13 @@
     };
 
     Vector<Target, 10> m_list;
+    Node* m_root;
 };
 
-inline ChildFrameDisconnector::ChildFrameDisconnector(Node* root)
+inline void ChildFrameDisconnector::collectDescendant(Node* root, ShouldIncludeRoot shouldIncludeRoot)
 {
-    collectDescendant(root);
-}
-
-inline void ChildFrameDisconnector::collectDescendant(Node* root)
-{
-    for (Node* node = root; node; node = node->traverseNextNode(root)) {
+    for (Node* node = shouldIncludeRoot == IncludeRoot ? root : root->firstChild(); node;
+            node = node->traverseNextNode(root)) {
         if (!node->isElementNode())
             continue;
         Element* element = toElement(node);
@@ -335,6 +356,20 @@
     }
 }
 
+inline bool ChildFrameDisconnector::nodeHasDisconnector(Node* node)
+{
+    HashSet<Node*>& nodes = rootNodes();
+
+    if (nodes.isEmpty())
+        return false;
+
+    for (; node; node = node->parentNode())
+        if (nodes.contains(node))
+            return true;
+
+    return false;
+}
+
 } // namespace WebCore
 
 #endif // ContainerNodeAlgorithms_h

Modified: branches/chromium/1229/Source/WebCore/dom/Node.cpp (128790 => 128791)


--- branches/chromium/1229/Source/WebCore/dom/Node.cpp	2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/Source/WebCore/dom/Node.cpp	2012-09-17 19:08:30 UTC (rev 128791)
@@ -40,6 +40,7 @@
 #include "CSSStyleSheet.h"
 #include "ChildNodeList.h"
 #include "ClassNodeList.h"
+#include "ContainerNodeAlgorithms.h"
 #include "ContextMenuController.h"
 #include "DOMImplementation.h"
 #include "DOMSettableTokenList.h"
@@ -1199,6 +1200,11 @@
         ec = HIERARCHY_REQUEST_ERR;
         return;
     }
+
+    if (newParent->inDocument() && ChildFrameDisconnector::nodeHasDisconnector(newParent)) {
+        ec = NO_MODIFICATION_ALLOWED_ERR;
+        return;
+    }
 }
 
 void Node::checkReplaceChild(Node* newChild, Node* oldChild, ExceptionCode& ec)

Modified: branches/chromium/1229/Source/WebCore/html/HTMLFrameElementBase.cpp (128790 => 128791)


--- branches/chromium/1229/Source/WebCore/html/HTMLFrameElementBase.cpp	2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/Source/WebCore/html/HTMLFrameElementBase.cpp	2012-09-17 19:08:30 UTC (rev 128791)
@@ -161,9 +161,10 @@
     return InsertionDone;
 }
 
-void HTMLFrameElementBase::didNotifySubtreeInsertions(ContainerNode* insertionPoint)
+void HTMLFrameElementBase::didNotifySubtreeInsertions(ContainerNode*)
 {
-    ASSERT_UNUSED(insertionPoint, insertionPoint->inDocument());
+    if (!inDocument())
+        return;
 
     // DocumentFragments don't kick of any loads.
     if (!document()->frame())
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to