[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

podivilov at chromium.org podivilov at chromium.org
Wed Dec 22 14:31:13 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 72ee245e09fa2edffc2f0de57ed18411a1aaff2a
Author: podivilov at chromium.org <podivilov at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Oct 12 09:35:27 2010 +0000

    2010-10-07  Pavel Podivilov  <podivilov at chromium.org>
    
            Reviewed by Pavel Feldman.
    
            Web Inspector: refactoring of native breakpoints.
            https://bugs.webkit.org/show_bug.cgi?id=47360
    
            Make DOM, EventListener and XHR breakpoints subclasses of NativeBreakpoint class.
            Move stuff that depends on breakpoint type to corresponding subclass.
    
            * inspector/Inspector.idl:
            * inspector/InspectorController.cpp:
            (WebCore::InspectorController::didCommitLoad):
            (WebCore::InspectorController::setNativeBreakpoint):
            (WebCore::InspectorController::removeNativeBreakpoint):
            (WebCore::InspectorController::findEventListenerBreakpoint):
            (WebCore::InspectorController::findXHRBreakpoint):
            * inspector/InspectorController.h:
            * inspector/InspectorDOMAgent.cpp:
            (WebCore::InspectorDOMAgent::setDOMBreakpoint):
            (WebCore::InspectorDOMAgent::removeDOMBreakpoint):
            (WebCore::InspectorDOMAgent::descriptionForDOMEvent):
            (WebCore::InspectorDOMAgent::didRemoveDOMNode):
            (WebCore::InspectorDOMAgent::removeBreakpointsForNode):
            (WebCore::InspectorDOMAgent::createBreakpointId):
            * inspector/InspectorDOMAgent.h:
            * inspector/InspectorDebuggerAgent.h:
            * inspector/InspectorInstrumentation.cpp:
            (WebCore::InspectorInstrumentation::willInsertDOMNodeImpl):
            (WebCore::InspectorInstrumentation::willRemoveDOMNodeImpl):
            (WebCore::InspectorInstrumentation::willModifyDOMAttrImpl):
            (WebCore::InspectorInstrumentation::willSendXMLHttpRequestImpl):
            (WebCore::InspectorInstrumentation::willDispatchEventImpl):
            * inspector/front-end/BreakpointManager.js:
            (WebInspector.BreakpointManager):
            (WebInspector.BreakpointManager.prototype.reset):
            (WebInspector.BreakpointManager.prototype.createDOMBreakpoint):
            (WebInspector.BreakpointManager.prototype.createEventListenerBreakpoint):
            (WebInspector.BreakpointManager.prototype.createXHRBreakpoint):
            (WebInspector.BreakpointManager.prototype._removeNativeBreakpoint):
            (WebInspector.BreakpointManager.prototype._setNativeBreakpointOnBackend.didSetNativeBreakpoint):
            (WebInspector.BreakpointManager.prototype._setNativeBreakpointOnBackend):
            (WebInspector.BreakpointManager.prototype.debuggerPaused):
            (WebInspector.BreakpointManager.prototype.debuggerResumed):
            (WebInspector.BreakpointManager.prototype.restoreDOMBreakpoints.restoreBreakpointsForNode):
            (WebInspector.BreakpointManager.prototype.restoreDOMBreakpoints):
            (WebInspector.NativeBreakpoint):
            (WebInspector.NativeBreakpoint.prototype.remove):
            (WebInspector.NativeBreakpoint.prototype.get _frontendId):
            (WebInspector.NativeBreakpoint.prototype.get _type):
            (WebInspector.NativeBreakpoint.prototype._compare):
            (WebInspector.NativeBreakpoint.prototype._onRemove):
            (WebInspector.DOMBreakpoint):
            (WebInspector.DOMBreakpoint.prototype.click):
            (WebInspector.DOMBreakpoint.prototype.compareTo):
            (WebInspector.DOMBreakpoint.prototype.populateLabelElement):
            (WebInspector.DOMBreakpoint.prototype.populateStatusMessageElement.formatters.s):
            (WebInspector.DOMBreakpoint.prototype.populateStatusMessageElement.append):
            (WebInspector.DOMBreakpoint.prototype.populateStatusMessageElement):
            (WebInspector.DOMBreakpoint.prototype._condition):
            (WebInspector.DOMBreakpoint.prototype._onRemove):
            (WebInspector.EventListenerBreakpoint):
            (WebInspector.EventListenerBreakpoint.prototype.compareTo):
            (WebInspector.EventListenerBreakpoint.prototype.label):
            (WebInspector.EventListenerBreakpoint.prototype.populateStatusMessageElement):
            (WebInspector.EventListenerBreakpoint.prototype._condition):
            (WebInspector.XHRBreakpoint):
            (WebInspector.XHRBreakpoint.prototype.compareTo):
            (WebInspector.XHRBreakpoint.prototype.populateLabelElement):
            (WebInspector.XHRBreakpoint.prototype.populateStatusMessageElement):
            (WebInspector.XHRBreakpoint.prototype._condition):
            (WebInspector.domBreakpointTypeLabel):
            (WebInspector.domBreakpointTypeContextMenuLabel):
            * inspector/front-end/BreakpointsSidebarPane.js:
            (WebInspector.BreakpointItem):
            (WebInspector.BreakpointItem.prototype._breakpointClicked):
            (WebInspector.EventListenerBreakpointsSidebarPane.prototype._populate):
            * inspector/front-end/CallStackSidebarPane.js:
            (WebInspector.CallStackSidebarPane):
            (WebInspector.CallStackSidebarPane.prototype.registerShortcuts):
            (WebInspector.CallStackSidebarPane.prototype._breakpointHit):
            * inspector/front-end/DOMAgent.js:
            (WebInspector.DOMNode):
            (WebInspector.DOMAgent.prototype._setDocument):
            (WebInspector.DOMAgent.prototype._removeBreakpoints):
            (WebInspector.childNodeRemoved):
            * inspector/front-end/ElementsTreeOutline.js:
            (WebInspector.ElementsTreeElement.prototype._populateTagContextMenu):
            * inspector/front-end/ScriptsPanel.js:
            (WebInspector.ScriptsPanel.prototype.debuggerPaused):
            * inspector/front-end/inspector.js:
            (WebInspector.createDOMBreakpointsSidebarPane.breakpointAdded):
            (WebInspector.createDOMBreakpointsSidebarPane):
            (WebInspector.reset):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@69567 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 4f33570..61d5d87 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,98 @@
+2010-10-07  Pavel Podivilov  <podivilov at chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        Web Inspector: refactoring of native breakpoints.
+        https://bugs.webkit.org/show_bug.cgi?id=47360
+
+        Make DOM, EventListener and XHR breakpoints subclasses of NativeBreakpoint class.
+        Move stuff that depends on breakpoint type to corresponding subclass.
+
+        * inspector/Inspector.idl:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::didCommitLoad):
+        (WebCore::InspectorController::setNativeBreakpoint):
+        (WebCore::InspectorController::removeNativeBreakpoint):
+        (WebCore::InspectorController::findEventListenerBreakpoint):
+        (WebCore::InspectorController::findXHRBreakpoint):
+        * inspector/InspectorController.h:
+        * inspector/InspectorDOMAgent.cpp:
+        (WebCore::InspectorDOMAgent::setDOMBreakpoint):
+        (WebCore::InspectorDOMAgent::removeDOMBreakpoint):
+        (WebCore::InspectorDOMAgent::descriptionForDOMEvent):
+        (WebCore::InspectorDOMAgent::didRemoveDOMNode):
+        (WebCore::InspectorDOMAgent::removeBreakpointsForNode):
+        (WebCore::InspectorDOMAgent::createBreakpointId):
+        * inspector/InspectorDOMAgent.h:
+        * inspector/InspectorDebuggerAgent.h:
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::willInsertDOMNodeImpl):
+        (WebCore::InspectorInstrumentation::willRemoveDOMNodeImpl):
+        (WebCore::InspectorInstrumentation::willModifyDOMAttrImpl):
+        (WebCore::InspectorInstrumentation::willSendXMLHttpRequestImpl):
+        (WebCore::InspectorInstrumentation::willDispatchEventImpl):
+        * inspector/front-end/BreakpointManager.js:
+        (WebInspector.BreakpointManager):
+        (WebInspector.BreakpointManager.prototype.reset):
+        (WebInspector.BreakpointManager.prototype.createDOMBreakpoint):
+        (WebInspector.BreakpointManager.prototype.createEventListenerBreakpoint):
+        (WebInspector.BreakpointManager.prototype.createXHRBreakpoint):
+        (WebInspector.BreakpointManager.prototype._removeNativeBreakpoint):
+        (WebInspector.BreakpointManager.prototype._setNativeBreakpointOnBackend.didSetNativeBreakpoint):
+        (WebInspector.BreakpointManager.prototype._setNativeBreakpointOnBackend):
+        (WebInspector.BreakpointManager.prototype.debuggerPaused):
+        (WebInspector.BreakpointManager.prototype.debuggerResumed):
+        (WebInspector.BreakpointManager.prototype.restoreDOMBreakpoints.restoreBreakpointsForNode):
+        (WebInspector.BreakpointManager.prototype.restoreDOMBreakpoints):
+        (WebInspector.NativeBreakpoint):
+        (WebInspector.NativeBreakpoint.prototype.remove):
+        (WebInspector.NativeBreakpoint.prototype.get _frontendId):
+        (WebInspector.NativeBreakpoint.prototype.get _type):
+        (WebInspector.NativeBreakpoint.prototype._compare):
+        (WebInspector.NativeBreakpoint.prototype._onRemove):
+        (WebInspector.DOMBreakpoint):
+        (WebInspector.DOMBreakpoint.prototype.click):
+        (WebInspector.DOMBreakpoint.prototype.compareTo):
+        (WebInspector.DOMBreakpoint.prototype.populateLabelElement):
+        (WebInspector.DOMBreakpoint.prototype.populateStatusMessageElement.formatters.s):
+        (WebInspector.DOMBreakpoint.prototype.populateStatusMessageElement.append):
+        (WebInspector.DOMBreakpoint.prototype.populateStatusMessageElement):
+        (WebInspector.DOMBreakpoint.prototype._condition):
+        (WebInspector.DOMBreakpoint.prototype._onRemove):
+        (WebInspector.EventListenerBreakpoint):
+        (WebInspector.EventListenerBreakpoint.prototype.compareTo):
+        (WebInspector.EventListenerBreakpoint.prototype.label):
+        (WebInspector.EventListenerBreakpoint.prototype.populateStatusMessageElement):
+        (WebInspector.EventListenerBreakpoint.prototype._condition):
+        (WebInspector.XHRBreakpoint):
+        (WebInspector.XHRBreakpoint.prototype.compareTo):
+        (WebInspector.XHRBreakpoint.prototype.populateLabelElement):
+        (WebInspector.XHRBreakpoint.prototype.populateStatusMessageElement):
+        (WebInspector.XHRBreakpoint.prototype._condition):
+        (WebInspector.domBreakpointTypeLabel):
+        (WebInspector.domBreakpointTypeContextMenuLabel):
+        * inspector/front-end/BreakpointsSidebarPane.js:
+        (WebInspector.BreakpointItem):
+        (WebInspector.BreakpointItem.prototype._breakpointClicked):
+        (WebInspector.EventListenerBreakpointsSidebarPane.prototype._populate):
+        * inspector/front-end/CallStackSidebarPane.js:
+        (WebInspector.CallStackSidebarPane):
+        (WebInspector.CallStackSidebarPane.prototype.registerShortcuts):
+        (WebInspector.CallStackSidebarPane.prototype._breakpointHit):
+        * inspector/front-end/DOMAgent.js:
+        (WebInspector.DOMNode):
+        (WebInspector.DOMAgent.prototype._setDocument):
+        (WebInspector.DOMAgent.prototype._removeBreakpoints):
+        (WebInspector.childNodeRemoved):
+        * inspector/front-end/ElementsTreeOutline.js:
+        (WebInspector.ElementsTreeElement.prototype._populateTagContextMenu):
+        * inspector/front-end/ScriptsPanel.js:
+        (WebInspector.ScriptsPanel.prototype.debuggerPaused):
+        * inspector/front-end/inspector.js:
+        (WebInspector.createDOMBreakpointsSidebarPane.breakpointAdded):
+        (WebInspector.createDOMBreakpointsSidebarPane):
+        (WebInspector.reset):
+
 2010-10-11  Eric Uhrhane  <ericu at chromium.org>
 
         Reviewed by Dumitru Daniliuc.
diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl
index 8a160b8..e400604 100644
--- a/WebCore/inspector/Inspector.idl
+++ b/WebCore/inspector/Inspector.idl
@@ -135,8 +135,8 @@ module core {
         [handler=Debug] void editScriptSource(in String sourceID, in String newContent, out boolean success, out String result, out Value newCallFrames);
         [handler=Debug] void getScriptSource(in String sourceID, out String scriptSource);
 
-        [handler=Controller] void setNativeBreakpoint(in Object breakpoint, out unsigned int breakpointId);
-        [handler=Controller] void removeNativeBreakpoint(in unsigned int breakpointId);
+        [handler=Controller] void setNativeBreakpoint(in Object breakpoint, out String breakpointId);
+        [handler=Controller] void removeNativeBreakpoint(in String breakpointId);
 
         [handler=Controller] void enableProfiler(in boolean always);
         [handler=Controller] void disableProfiler(in boolean always);
@@ -171,8 +171,6 @@ module core {
         [handler=DOM] void performSearch(in String query, in boolean runSynchronously);
         [handler=DOM] void searchCanceled();
         [handler=DOM] void pushNodeByPathToFrontend(in String path, out long nodeId);
-        [handler=DOM] void setDOMBreakpoint(in long nodeId, in long type);
-        [handler=DOM] void removeDOMBreakpoint(in long nodeId, in long type);
 
         [handler=Controller] void clearConsoleMessages();
         [handler=Controller] void highlightDOMNode(in long nodeId);
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index 1b66851..c11390b 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -132,8 +132,9 @@ static const char* const pauseOnExceptionsStateStateName = "pauseOnExceptionsSta
 
 static const char* const inspectorAttachedHeightName = "inspectorAttachedHeight";
 
-static const char* const xhrNativeBreakpointType = "XHR";
+static const char* const domNativeBreakpointType = "DOM";
 static const char* const eventListenerNativeBreakpointType = "EventListener";
+static const char* const xhrNativeBreakpointType = "XHR";
 
 const char* const InspectorController::ElementsPanel = "elements";
 const char* const InspectorController::ConsolePanel = "console";
@@ -788,7 +789,6 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
 
         m_nativeBreakpoints.clear();
         m_eventListenerBreakpoints.clear();
-        m_eventNameToBreakpointId.clear();
         m_XHRBreakpoints.clear();
         m_lastBreakpointId = 0;
 #endif
@@ -1679,9 +1679,9 @@ void InspectorController::resume()
         m_debuggerAgent->resume();
 }
 
-void InspectorController::setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, unsigned int* breakpointId)
+void InspectorController::setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, String* breakpointId)
 {
-    *breakpointId = 0;
+    *breakpointId = "";
     String type;
     if (!breakpoint->getString("type", &type))
         return;
@@ -1692,47 +1692,61 @@ void InspectorController::setNativeBreakpoint(PassRefPtr<InspectorObject> breakp
         String url;
         if (!condition->getString("url", &url))
             return;
-        *breakpointId = ++m_lastBreakpointId;
-        m_nativeBreakpoints.set(*breakpointId, "XHR");
+        *breakpointId = String::number(++m_lastBreakpointId);
         m_XHRBreakpoints.set(*breakpointId, url);
+        m_nativeBreakpoints.set(*breakpointId, type);
     } else if (type == eventListenerNativeBreakpointType) {
         String eventName;
         if (!condition->getString("eventName", &eventName))
             return;
-        if (m_eventNameToBreakpointId.contains(eventName))
+        if (m_eventListenerBreakpoints.contains(eventName))
+            return;
+        *breakpointId = eventName;
+        m_eventListenerBreakpoints.add(eventName);
+        m_nativeBreakpoints.set(*breakpointId, type);
+    } else if (type == domNativeBreakpointType) {
+        if (!m_domAgent)
+            return;
+        double nodeIdNumber;
+        if (!condition->getNumber("nodeId", &nodeIdNumber))
             return;
-        *breakpointId = ++m_lastBreakpointId;
-        m_nativeBreakpoints.set(*breakpointId, "EventListener");
-        m_eventListenerBreakpoints.set(*breakpointId, eventName);
-        m_eventNameToBreakpointId.set(eventName, *breakpointId);
+        double domBreakpointTypeNumber;
+        if (!condition->getNumber("type", &domBreakpointTypeNumber))
+            return;
+        long nodeId = (long) nodeIdNumber;
+        long domBreakpointType = (long) domBreakpointTypeNumber;
+        *breakpointId = m_domAgent->setDOMBreakpoint(nodeId, domBreakpointType);
+        if (!breakpointId->isEmpty())
+            m_nativeBreakpoints.set(*breakpointId, type);
     }
 }
 
-void InspectorController::removeNativeBreakpoint(unsigned int breakpointId)
+void InspectorController::removeNativeBreakpoint(const String& breakpointId)
 {
     String type = m_nativeBreakpoints.take(breakpointId);
     if (type == xhrNativeBreakpointType)
         m_XHRBreakpoints.remove(breakpointId);
-    else if (type == eventListenerNativeBreakpointType) {
-        String eventName = m_eventListenerBreakpoints.take(breakpointId);
-        m_eventNameToBreakpointId.remove(eventName);
+    else if (type == eventListenerNativeBreakpointType)
+        m_eventListenerBreakpoints.remove(breakpointId);
+    else if (type == domNativeBreakpointType) {
+        if (m_domAgent)
+            m_domAgent->removeDOMBreakpoint(breakpointId);
     }
 }
 
-unsigned int InspectorController::findEventListenerBreakpoint(const String& eventName)
+String InspectorController::findEventListenerBreakpoint(const String& eventName)
 {
-    return m_eventNameToBreakpointId.get(eventName);
+    return m_eventListenerBreakpoints.contains(eventName) ? eventName : "";
 }
 
-unsigned int InspectorController::findXHRBreakpoint(const String& url)
+String InspectorController::findXHRBreakpoint(const String& url)
 {
-    for (HashMap<unsigned int, String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) {
+    for (HashMap<String, String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) {
         if (url.contains(it->second))
             return it->first;
     }
-    return 0;
+    return "";
 }
-
 #endif
 
 void InspectorController::evaluateForTestInFrontend(long callId, const String& script)
diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h
index 0c2885e..ab38a8b 100644
--- a/WebCore/inspector/InspectorController.h
+++ b/WebCore/inspector/InspectorController.h
@@ -259,8 +259,8 @@ public:
     InspectorDebuggerAgent* debuggerAgent() const { return m_debuggerAgent.get(); }
     void resume();
 
-    void setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, unsigned int* breakpointId);
-    void removeNativeBreakpoint(unsigned int breakpointId);
+    void setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, String* breakpointId);
+    void removeNativeBreakpoint(const String& breakpointId);
 #endif
 
     void evaluateForTestInFrontend(long testCallId, const String& script);
@@ -300,8 +300,8 @@ private:
     void toggleRecordButton(bool);
     void enableDebuggerFromFrontend(bool always);
 
-    unsigned int findEventListenerBreakpoint(const String& eventName);
-    unsigned int findXHRBreakpoint(const String&);
+    String findEventListenerBreakpoint(const String& eventName);
+    String findXHRBreakpoint(const String& url);
 #endif
 #if ENABLE(DATABASE)
     void selectDatabase(Database* database);
@@ -391,10 +391,10 @@ private:
     bool m_attachDebuggerWhenShown;
     OwnPtr<InspectorDebuggerAgent> m_debuggerAgent;
 
-    HashMap<unsigned int, String> m_nativeBreakpoints;
-    HashMap<unsigned int, String> m_eventListenerBreakpoints;
-    HashMap<String, unsigned int> m_eventNameToBreakpointId;
-    HashMap<unsigned int, String> m_XHRBreakpoints;
+    HashMap<String, String> m_nativeBreakpoints;
+    HashSet<String> m_eventListenerBreakpoints;
+    HashMap<String, String> m_XHRBreakpoints;
+
     unsigned int m_lastBreakpointId;
 
     OwnPtr<InspectorProfilerAgent> m_profilerAgent;
diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp
index a2a02d0..adaf52e 100644
--- a/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/WebCore/inspector/InspectorDOMAgent.cpp
@@ -205,7 +205,8 @@ public:
 enum DOMBreakpointType {
     SubtreeModified = 0,
     AttributeModified,
-    NodeRemoved
+    NodeRemoved,
+    DOMBreakpointTypesCount
 };
 
 const uint32_t inheritableDOMBreakpointTypesMask = (1 << SubtreeModified);
@@ -753,11 +754,17 @@ void InspectorDOMAgent::searchCanceled()
     m_searchResults.clear();
 }
 
-void InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type)
+String InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type)
 {
     Node* node = nodeForId(nodeId);
     if (!node)
-        return;
+        return "";
+
+    String breakpointId = createBreakpointId(nodeId, type);
+    if (m_idToBreakpoint.contains(breakpointId))
+        return "";
+
+    m_idToBreakpoint.set(breakpointId, std::make_pair(nodeId, type));
 
     uint32_t rootBit = 1 << type;
     m_breakpoints.set(node, m_breakpoints.get(node) | rootBit);
@@ -765,15 +772,19 @@ void InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type)
         for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child))
             updateSubtreeBreakpoints(child, rootBit, true);
     }
+
+    return breakpointId;
 }
 
-void InspectorDOMAgent::removeDOMBreakpoint(long nodeId, long type)
+void InspectorDOMAgent::removeDOMBreakpoint(const String& breakpointId)
 {
-    Node* node = nodeForId(nodeId);
+    Breakpoint breakpoint = m_idToBreakpoint.take(breakpointId);
+
+    Node* node = nodeForId(breakpoint.first);
     if (!node)
         return;
 
-    uint32_t rootBit = 1 << type;
+    uint32_t rootBit = 1 << breakpoint.second;
     uint32_t mask = m_breakpoints.get(node) & ~rootBit;
     if (mask)
         m_breakpoints.set(node, mask);
@@ -845,11 +856,7 @@ PassRefPtr<InspectorValue> InspectorDOMAgent::descriptionForDOMEvent(Node* targe
 
     long breakpointOwnerNodeId = m_documentNodeToIdMap.get(breakpointOwner);
     ASSERT(breakpointOwnerNodeId);
-
-    RefPtr<InspectorObject> breakpoint = InspectorObject::create();
-    breakpoint->setNumber("nodeId", breakpointOwnerNodeId);
-    breakpoint->setNumber("type", breakpointType);
-    description->setObject("breakpoint", breakpoint);
+    description->setString("breakpointId", createBreakpointId(breakpointOwnerNodeId, breakpointType));
 
     return description;
 }
@@ -1093,14 +1100,14 @@ void InspectorDOMAgent::didRemoveDOMNode(Node* node)
 
     if (m_breakpoints.size()) {
         // Remove subtree breakpoints.
-        m_breakpoints.remove(node);
+        removeBreakpointsForNode(node);
         Vector<Node*> stack(1, innerFirstChild(node));
         do {
             Node* node = stack.last();
             stack.removeLast();
             if (!node)
                 continue;
-            m_breakpoints.remove(node);
+            removeBreakpointsForNode(node);
             stack.append(innerFirstChild(node));
             stack.append(innerNextSibling(node));
         } while (!stack.isEmpty());
@@ -1167,6 +1174,25 @@ void InspectorDOMAgent::updateSubtreeBreakpoints(Node* node, uint32_t rootMask,
         updateSubtreeBreakpoints(child, newRootMask, set);
 }
 
+void InspectorDOMAgent::removeBreakpointsForNode(Node* node)
+{
+    uint32_t mask = m_breakpoints.take(node);
+    if (!mask)
+        return;
+    long nodeId = m_documentNodeToIdMap.get(node);
+    if (!nodeId)
+        return;
+    for (int type = 0; type < DOMBreakpointTypesCount; ++type) {
+        if (mask && (1 << type))
+            m_idToBreakpoint.remove(createBreakpointId(nodeId, type));
+    }
+}
+
+String InspectorDOMAgent::createBreakpointId(long nodeId, long type)
+{
+    return String::format("dom:%ld:%ld", nodeId, type);
+}
+
 void InspectorDOMAgent::getStyles(long nodeId, bool authorOnly, RefPtr<InspectorValue>* styles)
 {
     Node* node = nodeForId(nodeId);
diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h
index 2727ac2..eeb21a6 100644
--- a/WebCore/inspector/InspectorDOMAgent.h
+++ b/WebCore/inspector/InspectorDOMAgent.h
@@ -120,8 +120,6 @@ namespace WebCore {
         void addInspectedNode(long nodeId);
         void performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously);
         void searchCanceled();
-        void setDOMBreakpoint(long nodeId, long type);
-        void removeDOMBreakpoint(long nodeId, long type);
         bool shouldBreakOnNodeInsertion(Node* node, Node* parent, PassRefPtr<InspectorValue>* details);
         bool shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorValue>* details);
         bool shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorValue>* details);
@@ -161,6 +159,9 @@ namespace WebCore {
 
         String documentURLString(Document* document) const;
 
+        String setDOMBreakpoint(long nodeId, long type);
+        void removeDOMBreakpoint(const String& breakpointId);
+
     private:
         void startListening(Document* document);
         void stopListening(Document* document);
@@ -176,7 +177,9 @@ namespace WebCore {
 
         bool hasBreakpoint(Node* node, long type);
         void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
+        void removeBreakpointsForNode(Node* node);
         PassRefPtr<InspectorValue> descriptionForDOMEvent(Node* target, long breakpointType, bool insertion);
+        String createBreakpointId(long nodeId, long type);
 
         PassRefPtr<InspectorObject> buildObjectForAttributeStyles(Element* element);
         PassRefPtr<InspectorArray> buildArrayForCSSRules(Document* ownerDocument, CSSRuleList*);
@@ -232,6 +235,8 @@ namespace WebCore {
         HashSet<RefPtr<Node> > m_searchResults;
         Vector<long> m_inspectedNodes;
         HashMap<Node*, uint32_t> m_breakpoints;
+        typedef pair<long, long> Breakpoint;
+        HashMap<String, Breakpoint> m_idToBreakpoint;
     };
 
 #endif
diff --git a/WebCore/inspector/InspectorDebuggerAgent.h b/WebCore/inspector/InspectorDebuggerAgent.h
index 5230b88..3825042 100644
--- a/WebCore/inspector/InspectorDebuggerAgent.h
+++ b/WebCore/inspector/InspectorDebuggerAgent.h
@@ -48,7 +48,7 @@ class InspectorValue;
 
 enum DebuggerEventType {
     JavaScriptPauseEventType,
-    DOMBreakpointDebuggerEventType,
+    JavaScriptBreakpointEventType,
     NativeBreakpointDebuggerEventType
 };
 
diff --git a/WebCore/inspector/InspectorInstrumentation.cpp b/WebCore/inspector/InspectorInstrumentation.cpp
index 4efceee..6e5bed7 100644
--- a/WebCore/inspector/InspectorInstrumentation.cpp
+++ b/WebCore/inspector/InspectorInstrumentation.cpp
@@ -73,7 +73,7 @@ void InspectorInstrumentation::willInsertDOMNodeImpl(InspectorController* inspec
         return;
     PassRefPtr<InspectorValue> eventData;
     if (domAgent->shouldBreakOnNodeInsertion(node, parent, &eventData))
-        debuggerAgent->breakProgram(DOMBreakpointDebuggerEventType, eventData);
+        debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
 #endif
 }
 
@@ -94,7 +94,7 @@ void InspectorInstrumentation::willRemoveDOMNodeImpl(InspectorController* inspec
         return;
     PassRefPtr<InspectorValue> eventData;
     if (domAgent->shouldBreakOnNodeRemoval(node, &eventData))
-        debuggerAgent->breakProgram(DOMBreakpointDebuggerEventType, eventData);
+        debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
 #endif
 }
 
@@ -115,7 +115,7 @@ void InspectorInstrumentation::willModifyDOMAttrImpl(InspectorController* inspec
         return;
     PassRefPtr<InspectorValue> eventData;
     if (domAgent->shouldBreakOnAttributeModification(element, &eventData))
-        debuggerAgent->breakProgram(DOMBreakpointDebuggerEventType, eventData);
+        debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
 #endif
 }
 
@@ -139,13 +139,12 @@ void InspectorInstrumentation::willSendXMLHttpRequestImpl(InspectorController* i
     if (!debuggerAgent)
         return;
 
-    unsigned int breakpointId = inspectorController->findXHRBreakpoint(url);
-    if (!breakpointId)
+    String breakpointId = inspectorController->findXHRBreakpoint(url);
+    if (breakpointId.isEmpty())
         return;
 
     RefPtr<InspectorObject> eventData = InspectorObject::create();
-    eventData->setNumber("breakpointId", breakpointId);
-    eventData->setString("type", "XHR");
+    eventData->setString("breakpointId", breakpointId);
     eventData->setString("url", url);
     debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
 #endif
@@ -208,11 +207,10 @@ InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(I
 {
 #if ENABLE(JAVASCRIPT_DEBUGGER)
     if (InspectorDebuggerAgent* debuggerAgent = inspectorController->m_debuggerAgent.get()) {
-        unsigned int breakpointId = inspectorController->findEventListenerBreakpoint(event.type());
-        if (breakpointId) {
+        String breakpointId = inspectorController->findEventListenerBreakpoint(event.type());
+        if (!breakpointId.isEmpty()) {
             RefPtr<InspectorObject> eventData = InspectorObject::create();
-            eventData->setNumber("breakpointId", breakpointId);
-            eventData->setString("type", "EventListener");
+            eventData->setString("breakpointId", breakpointId);
             eventData->setString("eventName", event.type());
             debuggerAgent->schedulePauseOnNextStatement(NativeBreakpointDebuggerEventType, eventData);
         }
diff --git a/WebCore/inspector/front-end/BreakpointManager.js b/WebCore/inspector/front-end/BreakpointManager.js
index e12c8a7..0e72051 100644
--- a/WebCore/inspector/front-end/BreakpointManager.js
+++ b/WebCore/inspector/front-end/BreakpointManager.js
@@ -27,15 +27,10 @@
 WebInspector.BreakpointManager = function()
 {
     this._breakpoints = {};
-    this._xhrBreakpoints = {};
+    this._nativeBreakpoints = {};
+    this._domBreakpoints = {};
 }
 
-WebInspector.BreakpointManager.DebuggerEventType = {
-    JavaScriptPause: 0,
-    DOMBreakpoint: 1,
-    NativeBreakpoint: 2
-};
-
 WebInspector.BreakpointManager.prototype = {
     setOneTimeBreakpoint: function(sourceID, line)
     {
@@ -93,7 +88,7 @@ WebInspector.BreakpointManager.prototype = {
     {
         this._breakpoints = {};
         delete this._oneTimeBreakpoint;
-        this._xhrBreakpoints = {};
+        this._nativeBreakpoints = {};
     },
 
     _setBreakpoint: function(sourceID, url, line, enabled, condition)
@@ -134,43 +129,43 @@ WebInspector.BreakpointManager.prototype = {
         InspectorBackend.setBreakpoint(breakpoint.sourceID, breakpoint.line, breakpoint.enabled, breakpoint.condition, didSetBreakpoint.bind(this));
     },
 
-    createEventListenerBreakpoint: function(eventName)
+    createDOMBreakpoint: function(nodeId, domEventType, disabled)
     {
-        var data = { type: "EventListener", condition: { eventName: eventName } };
-        var breakpoint = new WebInspector.NativeBreakpoint(data, this);
-        breakpoint.label = eventName;
+        var frontendId = "dom:" + nodeId + ":" + domEventType;
+        if (frontendId in this._nativeBreakpoints)
+            return;
+
+        var breakpoint = new WebInspector.DOMBreakpoint(this, frontendId, nodeId, domEventType);
+        this._nativeBreakpoints[frontendId] = breakpoint;
+        this._domBreakpoints[frontendId] = breakpoint;
+        this.dispatchEventToListeners("dom-breakpoint-added", breakpoint);
+        breakpoint.enabled = !disabled;
         return breakpoint;
     },
 
-    createXHRBreakpoint: function(url)
+    createEventListenerBreakpoint: function(eventName, disabled)
     {
-        if (url in this._xhrBreakpoints)
+        var frontendId = eventName;
+        if (frontendId in this._nativeBreakpoints)
             return;
-        this._xhrBreakpoints[url] = true;
-
-        var data = { type: "XHR", condition: { url: url } };
-        var breakpoint = new WebInspector.NativeBreakpoint(data, this);
-        if (!url.length)
-            breakpoint.label = WebInspector.UIString("Any XHR");
-        else
-            breakpoint.label = WebInspector.UIString("URL contains \"%s\"", url);
-        breakpoint.compareTo = function(other)
-        {
-            var urlOther = other._data.condition.url;
-            if (url !== urlOther)
-                return url < urlOther ? -1 : 1;
-            return 0;
-        };
-
-        breakpoint.addEventListener("removed", this._xhrBreakpointRemoved.bind(this, url));
-        this.dispatchEventToListeners("xhr-breakpoint-added", breakpoint);
 
-        breakpoint.enabled = true;
+        var breakpoint = new WebInspector.EventListenerBreakpoint(this, frontendId, eventName);
+        this._nativeBreakpoints[frontendId] = breakpoint;
+        breakpoint.enabled = !disabled;
+        return breakpoint;
     },
 
-    _xhrBreakpointRemoved: function(url)
+    createXHRBreakpoint: function(url, disabled)
     {
-        delete this._xhrBreakpoints[url];
+        var frontendId = url;
+        if (frontendId in this._nativeBreakpoints)
+            return;
+
+        var breakpoint = new WebInspector.XHRBreakpoint(this, frontendId, url);
+        this._nativeBreakpoints[frontendId] = breakpoint;
+        this.dispatchEventToListeners("xhr-breakpoint-added", breakpoint);
+        breakpoint.enabled = !disabled
+        return breakpoint;
     },
 
     _removeNativeBreakpoint: function(breakpoint)
@@ -179,6 +174,9 @@ WebInspector.BreakpointManager.prototype = {
             return;
         if (breakpoint.enabled)
             this._removeNativeBreakpointFromBackend(breakpoint);
+        delete this._nativeBreakpoints[breakpoint._frontendId];
+        if (breakpoint._type === "DOM")
+            delete this._domBreakpoints[breakpoint._frontendId];
         breakpoint.dispatchEventToListeners("removed");
     },
 
@@ -197,12 +195,13 @@ WebInspector.BreakpointManager.prototype = {
     _setNativeBreakpointOnBackend: function(breakpoint)
     {
         breakpoint._beingSetOnBackend = true;
-        InspectorBackend.setNativeBreakpoint(breakpoint._data, didSetNativeBreakpoint.bind(this));
+        var data = { type: breakpoint._type, condition: breakpoint._condition() };
+        InspectorBackend.setNativeBreakpoint(data, didSetNativeBreakpoint.bind(this));
 
         function didSetNativeBreakpoint(backendBreakpointId)
         {
             breakpoint._beingSetOnBackend = false;
-            if (backendBreakpointId !== 0) {
+            if (backendBreakpointId !== "") {
                 breakpoint._backendId = backendBreakpointId;
                 this._breakpoints[backendBreakpointId] = breakpoint;
             }
@@ -220,14 +219,18 @@ WebInspector.BreakpointManager.prototype = {
 
     debuggerPaused: function(details)
     {
-        if (details.eventType !== WebInspector.BreakpointManager.DebuggerEventType.NativeBreakpoint)
+        if (details.eventType !== WebInspector.DebuggerEventTypes.NativeBreakpoint)
             return;
+
         var breakpoint = this._breakpoints[details.eventData.breakpointId];
-        if (breakpoint) {
-            breakpoint.hit = true;
-            breakpoint.dispatchEventToListeners("hit-state-changed");
-            this._lastHitBreakpoint = breakpoint;
-        }
+        if (!breakpoint)
+            return;
+
+        breakpoint.hit = true;
+        breakpoint.dispatchEventToListeners("hit-state-changed");
+        this._lastHitBreakpoint = breakpoint;
+
+        this.dispatchEventToListeners("breakpoint-hit", { breakpoint: breakpoint, eventData: details.eventData });
     },
 
     debuggerResumed: function()
@@ -237,6 +240,33 @@ WebInspector.BreakpointManager.prototype = {
         this._lastHitBreakpoint.hit = false;
         this._lastHitBreakpoint.dispatchEventToListeners("hit-state-changed");
         delete this._lastHitBreakpoint;
+    },
+
+    restoreDOMBreakpoints: function()
+    {
+        var domBreakpoints = this._domBreakpoints;
+        this._domBreakpoints = {};
+
+        var breakpointsToRestore = {};
+        for (var frontendId in domBreakpoints) {
+            var breakpoint = domBreakpoints[frontendId];
+            var path = breakpoint._path;
+            if (!path)
+                continue;
+            if (!breakpointsToRestore[path]) {
+                breakpointsToRestore[path] = [];
+                InspectorBackend.pushNodeByPathToFrontend(path, restoreBreakpointsForNode.bind(this, breakpointsToRestore[path]));
+            }
+            breakpointsToRestore[path].push(breakpoint);
+        }
+
+        function restoreBreakpointsForNode(breakpoints, nodeId)
+        {
+            if (!nodeId)
+                return;
+            for (var i = 0; i < breakpoints.length; ++i)
+                this.createDOMBreakpoint(nodeId, breakpoints[i]._domEventType, !breakpoints[i].enabled);
+        }
     }
 }
 
@@ -322,10 +352,11 @@ WebInspector.Breakpoint.prototype = {
 
 WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype;
 
-WebInspector.NativeBreakpoint = function(data, manager)
+WebInspector.NativeBreakpoint = function(manager, frontendId, type)
 {
-    this._data = data;
     this._manager = manager;
+    this.__frontendId = frontendId;
+    this.__type = type;
 }
 
 WebInspector.NativeBreakpoint.prototype = {
@@ -342,7 +373,204 @@ WebInspector.NativeBreakpoint.prototype = {
     remove: function()
     {
         this._manager._removeNativeBreakpoint(this);
+        this._onRemove();
+    },
+
+    get _frontendId()
+    {
+        return this.__frontendId;
+    },
+
+    get _type()
+    {
+        return this.__type;
+    },
+
+    _compare: function(x, y)
+    {
+        if (x !== y)
+            return x < y ? -1 : 1;
+        return 0;
+    },
+
+    _onRemove: function()
+    {
     }
 }
 
 WebInspector.NativeBreakpoint.prototype.__proto__ = WebInspector.Object.prototype;
+
+WebInspector.DOMBreakpoint = function(manager, frontendId, nodeId, domEventType)
+{
+    WebInspector.NativeBreakpoint.call(this, manager, frontendId, "DOM");
+    this._nodeId = nodeId;
+    this._domEventType = domEventType;
+
+    var node = WebInspector.domAgent.nodeForId(this._nodeId);
+    if (node) {
+        node.breakpoints[this._domEventType] = this;
+        this._path = node.path();
+    }
+}
+
+WebInspector.DOMBreakpoint.prototype = {
+    click: function()
+    {
+        WebInspector.updateFocusedNode(this._nodeId);
+    },
+
+    compareTo: function(other)
+    {
+        return this._compare(this._domEventType, other._domEventType);
+    },
+
+    populateLabelElement: function(element)
+    {
+        element.appendChild(WebInspector.panels.elements.linkifyNodeById(this._nodeId));
+        element.appendChild(document.createTextNode(" - "));
+        element.appendChild(document.createTextNode(WebInspector.domBreakpointTypeLabel(this._domEventType)));
+    },
+
+    populateStatusMessageElement: function(element, eventData)
+    {
+        var substitutions = [WebInspector.domBreakpointTypeLabel(this._domEventType), WebInspector.panels.elements.linkifyNodeById(this._nodeId)];
+        var formatters = {
+            s: function(substitution)
+            {
+                return substitution;
+            }
+        };
+        function append(a, b)
+        {
+            if (typeof b === "string")
+                b = document.createTextNode(b);
+            element.appendChild(b);
+        }
+        if (this._domEventType === WebInspector.DOMBreakpointTypes.SubtreeModified) {
+            var targetNode = WebInspector.panels.elements.linkifyNodeById(eventData.targetNodeId);
+            if (eventData.insertion) {
+                if (eventData.targetNodeId !== this._nodeId)
+                    WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.", substitutions.concat(targetNode), formatters, "", append);
+                else
+                    WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.", substitutions, formatters, "", append);
+            } else
+                WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.", substitutions.concat(targetNode), formatters, "", append);
+        } else
+            WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s.", substitutions, formatters, "", append);
+    },
+
+    _condition: function()
+    {
+        return { nodeId: this._nodeId, type: this._domEventType };
+    },
+
+    _onRemove: function()
+    {
+        var node = WebInspector.domAgent.nodeForId(this._nodeId);
+        if (node)
+            delete node.breakpoints[this._domEventType];
+    }
+}
+
+WebInspector.DOMBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype;
+
+WebInspector.EventListenerBreakpoint = function(manager, frontendId, eventName)
+{
+    WebInspector.NativeBreakpoint.call(this, manager, frontendId, "EventListener");
+    this._eventName = eventName;
+}
+
+WebInspector.EventListenerBreakpoint.prototype = {
+    compareTo: function(other)
+    {
+        return this._compare(this._eventName, other._eventName);
+    },
+
+    label: function()
+    {
+        return this._eventName;
+    },
+
+    populateStatusMessageElement: function(element, eventData)
+    {
+        var status = WebInspector.UIString("Paused on a \"%s\" Event Listener.", this._eventName);
+        element.appendChild(document.createTextNode(status));
+    },
+
+    _condition: function()
+    {
+        return { eventName: this._eventName };
+    }
+}
+
+WebInspector.EventListenerBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype;
+
+WebInspector.XHRBreakpoint = function(manager, frontendId, url)
+{
+    WebInspector.NativeBreakpoint.call(this, manager, frontendId, "XHR");
+    this._url = url;
+}
+
+WebInspector.XHRBreakpoint.prototype = {
+    compareTo: function(other)
+    {
+        return this._compare(this._url, other._url);
+    },
+
+    populateLabelElement: function(element)
+    {
+        var label;
+        if (!this._url.length)
+            label = WebInspector.UIString("Any XHR");
+        else
+            label = WebInspector.UIString("URL contains \"%s\"", this._url);
+        element.appendChild(document.createTextNode(label));
+    },
+
+    populateStatusMessageElement: function(element)
+    {
+        var status = WebInspector.UIString("Paused on a XMLHttpRequest.");
+        element.appendChild(document.createTextNode(status));
+    },
+
+    _condition: function()
+    {
+        return { url: this._url };
+    }
+}
+
+WebInspector.XHRBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype;
+
+WebInspector.DebuggerEventTypes = {
+    JavaScriptPause: 0,
+    JavaScriptBreakpoint: 1,
+    NativeBreakpoint: 2
+};
+
+WebInspector.DOMBreakpointTypes = {
+    SubtreeModified: 0,
+    AttributeModified: 1,
+    NodeRemoved: 2
+};
+
+WebInspector.domBreakpointTypeLabel = function(type)
+{
+    if (!WebInspector._DOMBreakpointTypeLabels) {
+        WebInspector._DOMBreakpointTypeLabels = {};
+        WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified");
+        WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified");
+        WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed");
+    }
+    return WebInspector._DOMBreakpointTypeLabels[type];
+}
+
+WebInspector.domBreakpointTypeContextMenuLabel = function(type)
+{
+    if (!WebInspector._DOMBreakpointTypeContextMenuLabels) {
+        WebInspector._DOMBreakpointTypeContextMenuLabels = {};
+        WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.SubtreeModified] = WebInspector.UIString("Break on Subtree Modifications");
+        WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.AttributeModified] = WebInspector.UIString("Break on Attributes Modifications");
+        WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.NodeRemoved] = WebInspector.UIString("Break on Node Removal");
+    }
+    return WebInspector._DOMBreakpointTypeContextMenuLabels[type];
+}
diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
index fbf773d..9ea67a1 100644
--- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js
+++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
@@ -145,8 +145,8 @@ WebInspector.BreakpointItem = function(breakpoint)
     checkboxElement.addEventListener("click", this._checkboxClicked.bind(this), false);
     this._element.appendChild(checkboxElement);
 
-    if ("label" in this._breakpoint)
-        this._element.appendChild(document.createTextNode(this._breakpoint.label));
+    if ("populateLabelElement" in this._breakpoint)
+        this._breakpoint.populateLabelElement(this._element);
 
     this._breakpoint.addEventListener("enable-changed", this._enableChanged, this);
     this._breakpoint.addEventListener("hit-state-changed", this._hitStateChanged, this);
@@ -171,6 +171,8 @@ WebInspector.BreakpointItem.prototype = {
 
     _breakpointClicked: function(event)
     {
+        if ("click" in this._breakpoint)
+            this._breakpoint.click();
     },
 
     _checkboxClicked: function(event)
@@ -229,27 +231,6 @@ WebInspector.JSBreakpointItem.prototype = {
 
 WebInspector.JSBreakpointItem.prototype.__proto__ = WebInspector.BreakpointItem.prototype;
 
-WebInspector.DOMBreakpointItem = function(breakpoint)
-{
-    WebInspector.BreakpointItem.call(this, breakpoint);
-
-    var link = WebInspector.panels.elements.linkifyNodeById(this._breakpoint.nodeId);
-    this._element.appendChild(link);
-
-    var type = WebInspector.DOMBreakpoint.labelForType(this._breakpoint.type);
-    var typeElement = document.createTextNode(" - " + type);
-    this._element.appendChild(typeElement);
-}
-
-WebInspector.DOMBreakpointItem.prototype = {
-    _breakpointClicked: function()
-    {
-        WebInspector.updateFocusedNode(this._breakpoint.nodeId);
-    }
-}
-
-WebInspector.DOMBreakpointItem.prototype.__proto__ = WebInspector.BreakpointItem.prototype;
-
 WebInspector.EventListenerBreakpointsSidebarPane = function()
 {
     WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listener Breakpoints"));
@@ -283,9 +264,11 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = {
             for (var i = 0; i < eventNames.length; ++i) {
                 var eventName = eventNames[i];
 
-                var breakpoint = WebInspector.breakpointManager.createEventListenerBreakpoint(eventName);
+                var breakpoint = WebInspector.breakpointManager.createEventListenerBreakpoint(eventName, true);
+                if (!breakpoint)
+                    continue;
 
-                var eventNameTreeElement = new TreeElement(breakpoint.label);
+                var eventNameTreeElement = new TreeElement(breakpoint.label());
                 categoryTreeElement.appendChild(eventNameTreeElement);
                 eventNameTreeElement.listItemElement.addStyleClass("source-code");
                 eventNameTreeElement.selectable = true;
diff --git a/WebCore/inspector/front-end/CallStackSidebarPane.js b/WebCore/inspector/front-end/CallStackSidebarPane.js
index e1d342b..08c1942 100644
--- a/WebCore/inspector/front-end/CallStackSidebarPane.js
+++ b/WebCore/inspector/front-end/CallStackSidebarPane.js
@@ -26,6 +26,7 @@
 WebInspector.CallStackSidebarPane = function()
 {
     WebInspector.SidebarPane.call(this, WebInspector.UIString("Call Stack"));
+    WebInspector.breakpointManager.addEventListener("breakpoint-hit", this._breakpointHit, this);
 }
 
 WebInspector.CallStackSidebarPane.prototype = {
@@ -82,47 +83,6 @@ WebInspector.CallStackSidebarPane.prototype = {
         }
     },
 
-    updateStatus:  function(eventType, eventData)
-    {
-        var statusElement = document.createElement("div");
-        if (eventType === WebInspector.BreakpointManager.DebuggerEventType.DOMBreakpoint) {
-            var breakpoint = eventData.breakpoint;
-            var substitutions = [WebInspector.DOMBreakpoint.labelForType(breakpoint.type), WebInspector.panels.elements.linkifyNodeById(breakpoint.nodeId)];
-            var formatters = {
-                s: function(substitution)
-                {
-                    return substitution;
-                }
-            };
-            function append(a, b)
-            {
-                if (typeof b === "string")
-                    b = document.createTextNode(b);
-                statusElement.appendChild(b);
-            }
-            if (breakpoint.type === WebInspector.DOMBreakpoint.Types.SubtreeModified) {
-                var targetNode = WebInspector.panels.elements.linkifyNodeById(eventData.targetNodeId);
-                if (eventData.insertion) {
-                    if (eventData.targetNodeId !== breakpoint.nodeId)
-                        WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.", substitutions.concat(targetNode), formatters, "", append);
-                    else
-                        WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.", substitutions, formatters, "", append);
-                } else
-                    WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.", substitutions.concat(targetNode), formatters, "", append);
-            } else
-                WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s.", substitutions, formatters, "", append);
-        } else if (eventType === WebInspector.BreakpointManager.DebuggerEventType.NativeBreakpoint) {
-            if (eventData.type === "XHR")
-                statusElement.appendChild(document.createTextNode(WebInspector.UIString("Paused on a XMLHttpRequest.")));
-            else if (eventData.type === "EventListener")
-                statusElement.appendChild(document.createTextNode(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventData.eventName)));
-        } else
-            return;
-
-        statusElement.className = "info";
-        this.bodyElement.appendChild(statusElement);
-    },
-
     get selectedCallFrame()
     {
         return this._selectedCallFrame;
@@ -208,6 +168,16 @@ WebInspector.CallStackSidebarPane.prototype = {
         this._shortcuts[prevCallFrame.key] = this._selectPreviousCallFrameOnStack.bind(this);
 
         section.addRelatedKeys([ nextCallFrame.name, prevCallFrame.name ], WebInspector.UIString("Next/previous call frame"));
+    },
+
+    _breakpointHit:  function(event)
+    {
+        var breakpoint = event.data.breakpoint;
+
+        var statusMessageElement = document.createElement("div");
+        statusMessageElement.className = "info";
+        breakpoint.populateStatusMessageElement(statusMessageElement, event.data.eventData);
+        this.bodyElement.appendChild(statusMessageElement);
     }
 }
 
diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js
index 279852e..e99624d 100644
--- a/WebCore/inspector/front-end/DOMAgent.js
+++ b/WebCore/inspector/front-end/DOMAgent.js
@@ -60,6 +60,8 @@ WebInspector.DOMNode = function(doc, payload) {
     this.style = null;
     this._matchedCSSRules = [];
 
+    this.breakpoints = {};
+
     if (this.nodeType === Node.ELEMENT_NODE) {
         // HTML and BODY from internal iframes should not overwrite top-level ones.
         if (!this.ownerDocument.documentElement && this.nodeName === "HTML")
@@ -149,28 +151,6 @@ WebInspector.DOMNode.prototype = {
         return path.join(",");
     },
 
-    setBreakpoint: function(type)
-    {
-        return WebInspector.domBreakpointManager.setBreakpoint(this.id, type, true, this.path());
-    },
-
-    hasBreakpoint: function(type)
-    {
-        return !!WebInspector.domBreakpointManager.findBreakpoint(this.id, type);
-    },
-
-    removeBreakpoint: function(type)
-    {
-        var breakpoint = WebInspector.domBreakpointManager.findBreakpoint(this.id, type);
-        if (breakpoint)
-            breakpoint.remove();
-    },
-
-    removeBreakpoints: function()
-    {
-        WebInspector.domBreakpointManager.removeBreakpointsForNode(this.id);
-    },
-
     _setAttributesPayload: function(attrs)
     {
         this.attributes = [];
@@ -399,7 +379,7 @@ WebInspector.DOMAgent.prototype = {
             this.document = new WebInspector.DOMDocument(this, this._window, payload);
             this._idToDOMNode[payload.id] = this.document;
             this._bindNodes(this.document.children);
-            WebInspector.domBreakpointManager.restoreBreakpoints();
+            WebInspector.breakpointManager.restoreDOMBreakpoints();
         } else
             this.document = null;
         WebInspector.panels.elements.setDocument(this.document);
@@ -461,12 +441,13 @@ WebInspector.DOMAgent.prototype = {
 
     _removeBreakpoints: function(node)
     {
-        node.removeBreakpoints();
+        for (var type in node.breakpoints)
+            node.breakpoints[type].remove();
         if (!node.children)
             return;
         for (var i = 0; i < node.children.length; ++i)
             this._removeBreakpoints(node.children[i]);
-     }
+    }
 }
 
 WebInspector.ApplicationCache = {}
@@ -728,166 +709,3 @@ WebInspector.childNodeRemoved = function()
 {
     this.domAgent._childNodeRemoved.apply(this.domAgent, arguments);
 }
-
-WebInspector.DOMBreakpointManager = function()
-{
-    this._breakpoints = {};
-    this._pathCache = {};
-}
-
-WebInspector.DOMBreakpointManager.prototype = {
-    setBreakpoint: function(nodeId, type, enabled, path)
-    {
-        if (!(nodeId in this._breakpoints))
-            this._breakpoints[nodeId] = {};
-        else if (type in this._breakpoints[nodeId])
-            return;
-
-        var breakpoint = new WebInspector.DOMBreakpoint(nodeId, type, enabled);
-        this._breakpoints[nodeId][type] = breakpoint;
-        breakpoint.addEventListener("removed", this._breakpointRemoved, this);
-
-        if (!(nodeId in this._pathCache))
-            this._pathCache[nodeId] = path;
-
-        this.dispatchEventToListeners("dom-breakpoint-added", breakpoint);
-    },
-
-    findBreakpoint: function(nodeId, type)
-    {
-        var nodeBreakpoints = this._breakpoints[nodeId];
-        if (nodeBreakpoints && type in nodeBreakpoints)
-            return nodeBreakpoints[type];
-    },
-
-    removeBreakpointsForNode: function(nodeId)
-    {
-        var nodeBreakpoints = this._breakpoints[nodeId];
-        for (var type in nodeBreakpoints)
-            nodeBreakpoints[type].remove();
-    },
-
-    _breakpointRemoved: function(event)
-    {
-        var breakpoint = event.target;
-
-        var nodeBreakpoints = this._breakpoints[breakpoint.nodeId];
-        delete nodeBreakpoints[breakpoint.type];
-        for (var type in nodeBreakpoints)
-            return;
-
-        delete this._breakpoints[breakpoint.nodeId];
-        delete this._pathCache[breakpoint.nodeId];
-    },
-
-    restoreBreakpoints: function()
-    {
-        var breakpoints = this._breakpoints;
-        this._breakpoints = {};
-        var pathCache = this._pathCache;
-        this._pathCache = {};
-
-        for (var oldNodeId in breakpoints) {
-            var path = pathCache[oldNodeId];
-            InspectorBackend.pushNodeByPathToFrontend(path, restoreBreakpointsForNode.bind(this, breakpoints[oldNodeId], path));
-        }
-
-        function restoreBreakpointsForNode(nodeBreakpoints, path, nodeId)
-        {
-            if (!nodeId)
-                return;
-            for (var type in nodeBreakpoints) {
-                var breakpoint = nodeBreakpoints[type];
-                this.setBreakpoint(nodeId, breakpoint.type, breakpoint.enabled, path);
-            }
-        }
-    }
-}
-
-WebInspector.DOMBreakpointManager.prototype.__proto__ = WebInspector.Object.prototype;
-
-WebInspector.DOMBreakpoint = function(nodeId, type, enabled)
-{
-    this._nodeId = nodeId;
-    this._type = type;
-    this._enabled = enabled;
-
-    if (this.enabled)
-        InspectorBackend.setDOMBreakpoint(this.nodeId, this.type);
-}
-
-WebInspector.DOMBreakpoint.Types = {
-    SubtreeModified: 0,
-    AttributeModified: 1,
-    NodeRemoved: 2
-};
-
-WebInspector.DOMBreakpoint.labelForType = function(type)
-{
-    if (!WebInspector.DOMBreakpoint._labels) {
-        WebInspector.DOMBreakpoint._labels = {};
-        WebInspector.DOMBreakpoint._labels[WebInspector.DOMBreakpoint.Types.SubtreeModified] = WebInspector.UIString("Subtree Modified");
-        WebInspector.DOMBreakpoint._labels[WebInspector.DOMBreakpoint.Types.AttributeModified] = WebInspector.UIString("Attribute Modified");
-        WebInspector.DOMBreakpoint._labels[WebInspector.DOMBreakpoint.Types.NodeRemoved] = WebInspector.UIString("Node Removed");
-    }
-    return WebInspector.DOMBreakpoint._labels[type];
-}
-
-WebInspector.DOMBreakpoint.contextMenuLabelForType = function(type)
-{
-    if (!WebInspector.DOMBreakpoint._contextMenuLabels) {
-        WebInspector.DOMBreakpoint._contextMenuLabels = {};
-        WebInspector.DOMBreakpoint._contextMenuLabels[WebInspector.DOMBreakpoint.Types.SubtreeModified] = WebInspector.UIString("Break on Subtree Modifications");
-        WebInspector.DOMBreakpoint._contextMenuLabels[WebInspector.DOMBreakpoint.Types.AttributeModified] = WebInspector.UIString("Break on Attributes Modifications");
-        WebInspector.DOMBreakpoint._contextMenuLabels[WebInspector.DOMBreakpoint.Types.NodeRemoved] = WebInspector.UIString("Break on Node Removal");
-    }
-    return WebInspector.DOMBreakpoint._contextMenuLabels[type];
-}
-
-WebInspector.DOMBreakpoint.prototype = {
-    get nodeId()
-    {
-        return this._nodeId;
-    },
-
-    get type()
-    {
-        return this._type;
-    },
-
-    get enabled()
-    {
-        return this._enabled;
-    },
-
-    set enabled(enabled)
-    {
-        if (this._enabled === enabled)
-            return;
-
-        this._enabled = enabled;
-        if (this.enabled)
-            InspectorBackend.setDOMBreakpoint(this.nodeId, this.type);
-        else
-            InspectorBackend.removeDOMBreakpoint(this.nodeId, this.type);
-
-        this.dispatchEventToListeners("enable-changed");
-    },
-
-    compareTo: function(other)
-    {
-        if (this.type != other.type)
-            return this.type < other.type ? -1 : 1;
-        return 0;
-    },
-
-    remove: function()
-    {
-        if (this.enabled)
-            InspectorBackend.removeDOMBreakpoint(this.nodeId, this.type);
-        this.dispatchEventToListeners("removed");
-    }
-}
-
-WebInspector.DOMBreakpoint.prototype.__proto__ = WebInspector.Object.prototype;
-
diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js
index 1479c9a..1d546c2 100644
--- a/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -759,15 +759,15 @@ WebInspector.ElementsTreeElement.prototype = {
             contextMenu.appendSeparator();
 
             var node = this.representedObject;
-            for (var key in WebInspector.DOMBreakpoint.Types) {
-                var type = WebInspector.DOMBreakpoint.Types[key];
-                var label = WebInspector.DOMBreakpoint.contextMenuLabelForType(type);
-                var hasBreakpoint = node.hasBreakpoint(type);
-                if (!hasBreakpoint)
-                    var handler = node.setBreakpoint.bind(node, type);
+            for (var key in WebInspector.DOMBreakpointTypes) {
+                var type = WebInspector.DOMBreakpointTypes[key];
+                var label = WebInspector.domBreakpointTypeContextMenuLabel(type);
+                var breakpoint = node.breakpoints[type];
+                if (!breakpoint)
+                    var handler = WebInspector.breakpointManager.createDOMBreakpoint.bind(WebInspector.breakpointManager, node.id, type);
                 else
-                    var handler = node.removeBreakpoint.bind(node, type);
-                contextMenu.appendCheckboxItem(label, handler, hasBreakpoint);
+                    var handler = breakpoint.remove.bind(breakpoint);
+                contextMenu.appendCheckboxItem(label, handler, !!breakpoint);
             }
         }
     },
diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js
index a7aac78..e6a78b4 100644
--- a/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/WebCore/inspector/front-end/ScriptsPanel.js
@@ -388,9 +388,6 @@ WebInspector.ScriptsPanel.prototype = {
         this.sidebarPanes.callstack.update(details.callFrames, this._sourceIDMap);
         this.sidebarPanes.callstack.selectedCallFrame = details.callFrames[0];
 
-        if ("eventType" in details)
-            this.sidebarPanes.callstack.updateStatus(details.eventType, details.eventData);
-
         WebInspector.currentPanel = this;
         window.focus();
     },
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 5ab4b32..80e28a5 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -213,9 +213,9 @@ var WebInspector = {
         var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints"));
         function breakpointAdded(event)
         {
-            pane.addBreakpoint(new WebInspector.DOMBreakpointItem(event.data));
+            pane.addBreakpoint(new WebInspector.BreakpointItem(event.data));
         }
-        WebInspector.domBreakpointManager.addEventListener("dom-breakpoint-added", breakpointAdded);
+        WebInspector.breakpointManager.addEventListener("dom-breakpoint-added", breakpointAdded);
         return pane;
     },
 
@@ -530,7 +530,6 @@ WebInspector.doLoadedDone = function()
     };
 
     this.breakpointManager = new WebInspector.BreakpointManager();
-    this.domBreakpointManager = new WebInspector.DOMBreakpointManager();
     this.cssModel = new WebInspector.CSSStyleModel();
 
     this.panels = {};
@@ -1459,6 +1458,8 @@ WebInspector.resumedScript = function()
 
 WebInspector.reset = function()
 {
+    this.breakpointManager.reset();
+
     for (var panelName in this.panels) {
         var panel = this.panels[panelName];
         if ("reset" in panel)
@@ -1466,7 +1467,6 @@ WebInspector.reset = function()
     }
 
     this.sessionSettings.reset();
-    this.breakpointManager.reset();
 
     for (var category in this.resourceCategories)
         this.resourceCategories[category].removeAllResources();

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list