Title: [128524] trunk
Revision
128524
Author
[email protected]
Date
2012-09-13 16:12:03 -0700 (Thu, 13 Sep 2012)

Log Message

Source/WebCore: ASSERT(!eventDispatchForbidden()) fires when removed plugin re-inserted as part of readyStateChange.
https://bugs.webkit.org/show_bug.cgi?id=93639

Reviewed by Ryosuke Niwa.

Removing a plugin causes a detach which can cancel the last remaining load on a page,
resulting in a readyStateChange event during a time when things are inconsisent. Defer
the detach which triggers this chain of events until after the node is fully removed
from the document's elementsById map.

Test: plugins/plugin-remove-readystatechange.html

* dom/ContainerNode.cpp:
(WebCore::ContainerNode::removeChild):
(WebCore::ContainerNode::removeChildren):

LayoutTests: ASSERT(!eventDispatchForbidden()) firest when removed plugin re-inserted as part of readyStateChange.
https://bugs.webkit.org/show_bug.cgi?id=93639

Reviewed by Ryosuke Niwa.

Add a new testcase to cover this issue.  Test passes if assert doesn't fire in debug builds.

* plugins/plugin-remove-readystatechange-expected.txt: Added.
* plugins/plugin-remove-readystatechange.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (128523 => 128524)


--- trunk/LayoutTests/ChangeLog	2012-09-13 23:09:30 UTC (rev 128523)
+++ trunk/LayoutTests/ChangeLog	2012-09-13 23:12:03 UTC (rev 128524)
@@ -1,3 +1,15 @@
+2012-09-13  Tom Sepez  <[email protected]>
+
+        ASSERT(!eventDispatchForbidden()) firest when removed plugin re-inserted as part of readyStateChange.
+        https://bugs.webkit.org/show_bug.cgi?id=93639
+
+        Reviewed by Ryosuke Niwa.
+
+        Add a new testcase to cover this issue.  Test passes if assert doesn't fire in debug builds.
+
+        * plugins/plugin-remove-readystatechange-expected.txt: Added.
+        * plugins/plugin-remove-readystatechange.html: Added.
+
 2012-09-13  Ojan Vafai  <[email protected]>
 
         percentage heights in quirks mode with auto-sized body are computed incorrectly

Added: trunk/LayoutTests/plugins/plugin-remove-readystatechange-expected.txt (0 => 128524)


--- trunk/LayoutTests/plugins/plugin-remove-readystatechange-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/plugins/plugin-remove-readystatechange-expected.txt	2012-09-13 23:12:03 UTC (rev 128524)
@@ -0,0 +1,3 @@
+ALERT: PASS: element could not be re-appended
+This test passes if it does not trip an assert in debug builds. It ensures a readystatechange event can't get dispatched until after a plugin is fully removed.
+

Added: trunk/LayoutTests/plugins/plugin-remove-readystatechange.html (0 => 128524)


--- trunk/LayoutTests/plugins/plugin-remove-readystatechange.html	                        (rev 0)
+++ trunk/LayoutTests/plugins/plugin-remove-readystatechange.html	2012-09-13 23:12:03 UTC (rev 128524)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div>
+This test passes if it does not trip an assert in debug builds.
+It ensures a readystatechange event can't get dispatched until after a plugin is fully removed.
+</div>
+<embed id="viewer" src=""
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+var i = 0;
+document.addEventListener('readystatechange', function() {
+    if (i == 1) {
+        try {
+            document.body.appendChild(document.getElementById('viewer'));
+        }
+        catch (e) {
+            alert('PASS: element could not be re-appended');
+       }
+    }
+    i++;
+});
+
+window.addEventListener('DOMContentLoaded', function() {
+    document.body.removeChild(document.getElementById('viewer'));
+});
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (128523 => 128524)


--- trunk/Source/WebCore/ChangeLog	2012-09-13 23:09:30 UTC (rev 128523)
+++ trunk/Source/WebCore/ChangeLog	2012-09-13 23:12:03 UTC (rev 128524)
@@ -1,3 +1,21 @@
+2012-09-13  Tom Sepez  <[email protected]>
+
+        ASSERT(!eventDispatchForbidden()) fires when removed plugin re-inserted as part of readyStateChange.
+        https://bugs.webkit.org/show_bug.cgi?id=93639
+
+        Reviewed by Ryosuke Niwa.
+
+        Removing a plugin causes a detach which can cancel the last remaining load on a page,
+        resulting in a readyStateChange event during a time when things are inconsisent. Defer
+        the detach which triggers this chain of events until after the node is fully removed
+        from the document's elementsById map.
+
+        Test: plugins/plugin-remove-readystatechange.html
+
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::removeChild):
+        (WebCore::ContainerNode::removeChildren):
+
 2012-09-13  Tim Horton  <[email protected]>
 
         Add optional debug logging when we fall into/out of threaded scrolling

Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (128523 => 128524)


--- trunk/Source/WebCore/dom/ContainerNode.cpp	2012-09-13 23:09:30 UTC (rev 128523)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp	2012-09-13 23:12:03 UTC (rev 128524)
@@ -39,6 +39,7 @@
 #include "Page.h"
 #include "RenderBox.h"
 #include "RenderTheme.h"
+#include "RenderWidget.h"
 #include "RootInlineBox.h"
 #include "UndoManager.h"
 #include <wtf/CurrentTime.h>
@@ -418,13 +419,15 @@
         return false;
     }
 
+    RenderWidget::suspendWidgetHierarchyUpdates();
+
     Node* prev = child->previousSibling();
     Node* next = child->nextSibling();
     removeBetween(prev, next, child.get());
-
     childrenChanged(false, prev, next, -1);
+    ChildNodeRemovalNotifier(this).notify(child.get());
 
-    ChildNodeRemovalNotifier(this).notify(child.get());
+    RenderWidget::resumeWidgetHierarchyUpdates();
     dispatchSubtreeModifiedEvent();
 
     return child;
@@ -494,6 +497,7 @@
     // and remove... e.g. stop loading frames, fire unload events.
     willRemoveChildren(protect.get());
 
+    RenderWidget::suspendWidgetHierarchyUpdates();
     forbidEventDispatch();
     Vector<RefPtr<Node>, 10> removedChildren;
     removedChildren.reserveInitialCapacity(childNodeCount());
@@ -535,6 +539,8 @@
         ChildNodeRemovalNotifier(this).notify(removedChildren[i].get());
 
     allowEventDispatch();
+    RenderWidget::resumeWidgetHierarchyUpdates();
+
     dispatchSubtreeModifiedEvent();
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to