Title: [113230] trunk
Revision
113230
Author
ad...@chromium.org
Date
2012-04-04 13:10:34 -0700 (Wed, 04 Apr 2012)

Log Message

Web Inspector: break on DOM node insertion only once per operation, not once per inserted node
https://bugs.webkit.org/show_bug.cgi?id=82967

Reviewed by Ojan Vafai.

Source/WebCore:

This change affects the case where a DocumentFragment is inserted,
rather than a single node. This is most common when using innerHTML:
the effect of the change is that inserting, e.g., '<input><input>',
the SubtreeModified breakpoint will be hit once, rather than twice
(once for each input element). Given that the particular node being
inserted wasn't exposed as part of the breakpoint, this seems strictly
better.

Now that the call to willInsertDOMNode is outside the loop, there's
not an obvious node to pass in as the new child. Luckily, InspectorDOMDebuggerAgent
already ignored that argument, so it's simply been removed from the signature.

This changes paves the way to do only tree-modification work, and no
external notifications, inside the loops in appendChild/insertBefore/replaceChild.

* dom/ContainerNode.cpp:
(WebCore::ContainerNode::insertBefore): Hoisted call to willInsertDOMNode out of loop.
(WebCore::ContainerNode::replaceChild): ditto.
(WebCore::ContainerNode::appendChild): ditto.
* inspector/InspectorDOMDebuggerAgent.cpp:
(WebCore::InspectorDOMDebuggerAgent::willInsertDOMNode): Removed first argument (now takes only the parent).
* inspector/InspectorDOMDebuggerAgent.h:
(InspectorDOMDebuggerAgent):
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::willInsertDOMNodeImpl): Removed second argument.
* inspector/InspectorInstrumentation.h:
(InspectorInstrumentation):
(WebCore::InspectorInstrumentation::willInsertDOMNode): Removed second argument.

LayoutTests:

Added test for setting inner HTML and ensuring that only a single
breakpoint is hit.

* inspector/debugger/dom-breakpoints.html:
* platform/chromium/inspector/debugger/dom-breakpoints-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (113229 => 113230)


--- trunk/LayoutTests/ChangeLog	2012-04-04 20:06:35 UTC (rev 113229)
+++ trunk/LayoutTests/ChangeLog	2012-04-04 20:10:34 UTC (rev 113230)
@@ -1,3 +1,16 @@
+2012-04-04  Adam Klein  <ad...@chromium.org>
+
+        Web Inspector: break on DOM node insertion only once per operation, not once per inserted node
+        https://bugs.webkit.org/show_bug.cgi?id=82967
+
+        Reviewed by Ojan Vafai.
+
+        Added test for setting inner HTML and ensuring that only a single
+        breakpoint is hit.
+
+        * inspector/debugger/dom-breakpoints.html:
+        * platform/chromium/inspector/debugger/dom-breakpoints-expected.txt:
+
 2012-04-04  Jeffrey Pfau  <jp...@apple.com>
 
         Move pending sheet removal from ~HTMLLinkElement to removal from document. 

Modified: trunk/LayoutTests/inspector/debugger/dom-breakpoints.html (113229 => 113230)


--- trunk/LayoutTests/inspector/debugger/dom-breakpoints.html	2012-04-04 20:06:35 UTC (rev 113229)
+++ trunk/LayoutTests/inspector/debugger/dom-breakpoints.html	2012-04-04 20:10:34 UTC (rev 113230)
@@ -44,6 +44,17 @@
     element.parentNode.removeChild(element);
 }
 
+function setInnerHTML(elementId, html)
+{
+    var element = document.getElementById(elementId);
+    element.innerHTML = html;
+}
+
+function breakDebugger()
+{
+    debugger;
+}
+
 function test()
 {
     WebInspector.inspectorView.setCurrentPanel(WebInspector.panels.elements);
@@ -80,12 +91,28 @@
             InspectorTest.addResult("Test that 'Subtree Modified' breakpoint is hit when removing a child.");
             InspectorTest.evaluateInPageWithTimeout("removeElement('grandchildElement')");
             InspectorTest.addResult("Remove grandchildElement.");
+            waitUntilPausedAndDumpStack(next);
+        },
+
+        function testInnerHTML(next)
+        {
+            InspectorTest.addResult("Test that 'Subtree Modified' breakpoint is hit exactly once when setting innerHTML.");
+            InspectorTest.evaluateInPageWithTimeout("setInnerHTML('childElement', '<br><br>')");
+            InspectorTest.addResult("Set childElement.innerHTML.");
             waitUntilPausedAndDumpStack(step2);
 
             function step2()
             {
+                InspectorTest.waitUntilPaused(step3);
+                InspectorTest.evaluateInPageWithTimeout("breakDebugger()");
+                InspectorTest.addResult("Call breakDebugger, expect it to show up in next stack trace.");
+            }
+
+            function step3(frames)
+            {
+                InspectorTest.captureStackTrace(frames);
                 pane._removeBreakpoint(rootElement, pane._breakpointTypes.SubtreeModified);
-                next();
+                InspectorTest.resumeExecution(next);
             }
         },
 

Modified: trunk/LayoutTests/platform/chromium/inspector/debugger/dom-breakpoints-expected.txt (113229 => 113230)


--- trunk/LayoutTests/platform/chromium/inspector/debugger/dom-breakpoints-expected.txt	2012-04-04 20:06:35 UTC (rev 113229)
+++ trunk/LayoutTests/platform/chromium/inspector/debugger/dom-breakpoints-expected.txt	2012-04-04 20:10:34 UTC (rev 113230)
@@ -33,6 +33,22 @@
 Paused on a "Subtree Modified" breakpoint set on div#rootElement, because its descendant div#grandchildElement was removed.
 Script execution resumed.
 
+Running: testInnerHTML
+Test that 'Subtree Modified' breakpoint is hit exactly once when setting innerHTML.
+Set childElement.innerHTML.
+Script execution paused.
+Call stack:
+    0) setInnerHTML (dom-breakpoints.html:50)
+    1)  (:1)
+Paused on a "Subtree Modified" breakpoint set on div#rootElement, because a new child was added to its descendant div#childElement.
+Script execution resumed.
+Call breakDebugger, expect it to show up in next stack trace.
+Script execution paused.
+Call stack:
+    0) breakDebugger (dom-breakpoints.html:55)
+    1)  (:1)
+Script execution resumed.
+
 Running: testModifyAttribute
 Test that 'Attribute Modified' breakpoint is hit when modifying attribute.
 Set 'Attribute Modified' DOM breakpoint on rootElement.

Modified: trunk/Source/WebCore/ChangeLog (113229 => 113230)


--- trunk/Source/WebCore/ChangeLog	2012-04-04 20:06:35 UTC (rev 113229)
+++ trunk/Source/WebCore/ChangeLog	2012-04-04 20:10:34 UTC (rev 113230)
@@ -1,3 +1,39 @@
+2012-04-04  Adam Klein  <ad...@chromium.org>
+
+        Web Inspector: break on DOM node insertion only once per operation, not once per inserted node
+        https://bugs.webkit.org/show_bug.cgi?id=82967
+
+        Reviewed by Ojan Vafai.
+
+        This change affects the case where a DocumentFragment is inserted,
+        rather than a single node. This is most common when using innerHTML:
+        the effect of the change is that inserting, e.g., '<input><input>',
+        the SubtreeModified breakpoint will be hit once, rather than twice
+        (once for each input element). Given that the particular node being
+        inserted wasn't exposed as part of the breakpoint, this seems strictly
+        better.
+
+        Now that the call to willInsertDOMNode is outside the loop, there's
+        not an obvious node to pass in as the new child. Luckily, InspectorDOMDebuggerAgent
+        already ignored that argument, so it's simply been removed from the signature.
+
+        This changes paves the way to do only tree-modification work, and no
+        external notifications, inside the loops in appendChild/insertBefore/replaceChild.
+
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::insertBefore): Hoisted call to willInsertDOMNode out of loop.
+        (WebCore::ContainerNode::replaceChild): ditto.
+        (WebCore::ContainerNode::appendChild): ditto.
+        * inspector/InspectorDOMDebuggerAgent.cpp:
+        (WebCore::InspectorDOMDebuggerAgent::willInsertDOMNode): Removed first argument (now takes only the parent).
+        * inspector/InspectorDOMDebuggerAgent.h:
+        (InspectorDOMDebuggerAgent):
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::willInsertDOMNodeImpl): Removed second argument.
+        * inspector/InspectorInstrumentation.h:
+        (InspectorInstrumentation):
+        (WebCore::InspectorInstrumentation::willInsertDOMNode): Removed second argument.
+
 2012-04-04  Jeffrey Pfau  <jp...@apple.com>
 
         Move pending sheet removal from ~HTMLLinkElement to removal from document.

Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (113229 => 113230)


--- trunk/Source/WebCore/dom/ContainerNode.cpp	2012-04-04 20:06:35 UTC (rev 113229)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp	2012-04-04 20:10:34 UTC (rev 113230)
@@ -152,6 +152,10 @@
     if (targets.isEmpty())
         return true;
 
+#if ENABLE(INSPECTOR)
+    InspectorInstrumentation::willInsertDOMNode(document(), this);
+#endif
+
 #if ENABLE(MUTATION_OBSERVERS)
     ChildListMutationScope mutation(this);
 #endif
@@ -168,10 +172,6 @@
         if (child->parentNode())
             break;
 
-#if ENABLE(INSPECTOR)
-        InspectorInstrumentation::willInsertDOMNode(document(), child, this);
-#endif
-
         treeScope()->adoptIfNeeded(child);
 
         insertBeforeCommon(next.get(), child);
@@ -278,6 +278,10 @@
     if (ec)
         return false;
 
+#if ENABLE(INSPECTOR)
+    InspectorInstrumentation::willInsertDOMNode(document(), this);
+#endif
+
     // Add the new child(ren)
     for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
         Node* child = it->get();
@@ -291,10 +295,6 @@
         if (child->parentNode())
             break;
 
-#if ENABLE(INSPECTOR)
-        InspectorInstrumentation::willInsertDOMNode(document(), child, this);
-#endif
-
         treeScope()->adoptIfNeeded(child);
 
         // Add child before "next".
@@ -558,6 +558,10 @@
     if (targets.isEmpty())
         return true;
 
+#if ENABLE(INSPECTOR)
+    InspectorInstrumentation::willInsertDOMNode(document(), this);
+#endif
+
 #if ENABLE(MUTATION_OBSERVERS)
     ChildListMutationScope mutation(this);
 #endif
@@ -572,10 +576,6 @@
         if (child->parentNode())
             break;
 
-#if ENABLE(INSPECTOR)
-        InspectorInstrumentation::willInsertDOMNode(document(), child, this);
-#endif
-
         treeScope()->adoptIfNeeded(child);
 
         // Append child to the end of the list

Modified: trunk/Source/WebCore/inspector/InspectorDOMDebuggerAgent.cpp (113229 => 113230)


--- trunk/Source/WebCore/inspector/InspectorDOMDebuggerAgent.cpp	2012-04-04 20:06:35 UTC (rev 113229)
+++ trunk/Source/WebCore/inspector/InspectorDOMDebuggerAgent.cpp	2012-04-04 20:10:34 UTC (rev 113230)
@@ -267,7 +267,7 @@
     }
 }
 
-void InspectorDOMDebuggerAgent::willInsertDOMNode(Node*, Node* parent)
+void InspectorDOMDebuggerAgent::willInsertDOMNode(Node* parent)
 {
     if (hasBreakpoint(parent, SubtreeModified)) {
         RefPtr<InspectorObject> eventData = InspectorObject::create();

Modified: trunk/Source/WebCore/inspector/InspectorDOMDebuggerAgent.h (113229 => 113230)


--- trunk/Source/WebCore/inspector/InspectorDOMDebuggerAgent.h	2012-04-04 20:06:35 UTC (rev 113229)
+++ trunk/Source/WebCore/inspector/InspectorDOMDebuggerAgent.h	2012-04-04 20:10:34 UTC (rev 113230)
@@ -72,7 +72,7 @@
     virtual void removeDOMBreakpoint(ErrorString*, int nodeId, const String& type);
 
     // InspectorInstrumentation API
-    void willInsertDOMNode(Node*, Node* parent);
+    void willInsertDOMNode(Node* parent);
     void didInvalidateStyleAttr(Node*);
     void didInsertDOMNode(Node*);
     void willRemoveDOMNode(Node*);

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (113229 => 113230)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2012-04-04 20:06:35 UTC (rev 113229)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2012-04-04 20:10:34 UTC (rev 113230)
@@ -123,11 +123,11 @@
     return false;
 }
 
-void InspectorInstrumentation::willInsertDOMNodeImpl(InstrumentingAgents* instrumentingAgents, Node* node, Node* parent)
+void InspectorInstrumentation::willInsertDOMNodeImpl(InstrumentingAgents* instrumentingAgents, Node* parent)
 {
 #if ENABLE(_javascript__DEBUGGER)
     if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents->inspectorDOMDebuggerAgent())
-        domDebuggerAgent->willInsertDOMNode(node, parent);
+        domDebuggerAgent->willInsertDOMNode(parent);
 #endif
 }
 

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (113229 => 113230)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2012-04-04 20:06:35 UTC (rev 113229)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2012-04-04 20:10:34 UTC (rev 113230)
@@ -84,7 +84,7 @@
     static void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld*);
     static bool isDebuggerPaused(Frame*);
 
-    static void willInsertDOMNode(Document*, Node*, Node* parent);
+    static void willInsertDOMNode(Document*, Node* parent);
     static void didInsertDOMNode(Document*, Node*);
     static void willRemoveDOMNode(Document*, Node*);
     static void willModifyDOMAttr(Document*, Element*, const AtomicString& oldValue, const AtomicString& newValue);
@@ -237,7 +237,7 @@
     static void didClearWindowObjectInWorldImpl(InstrumentingAgents*, Frame*, DOMWrapperWorld*);
     static bool isDebuggerPausedImpl(InstrumentingAgents*);
 
-    static void willInsertDOMNodeImpl(InstrumentingAgents*, Node*, Node* parent);
+    static void willInsertDOMNodeImpl(InstrumentingAgents*, Node* parent);
     static void didInsertDOMNodeImpl(InstrumentingAgents*, Node*);
     static void willRemoveDOMNodeImpl(InstrumentingAgents*, Node*);
     static void didRemoveDOMNodeImpl(InstrumentingAgents*, Node*);
@@ -406,12 +406,12 @@
     return false;
 }
 
-inline void InspectorInstrumentation::willInsertDOMNode(Document* document, Node* node, Node* parent)
+inline void InspectorInstrumentation::willInsertDOMNode(Document* document, Node* parent)
 {
 #if ENABLE(INSPECTOR)
     FAST_RETURN_IF_NO_FRONTENDS(void());
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document))
-        willInsertDOMNodeImpl(instrumentingAgents, node, parent);
+        willInsertDOMNodeImpl(instrumentingAgents, parent);
 #endif
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to