2010-12-10 Pavel Podivilov <podivilov@chromium.org>
authorpodivilov@chromium.org <podivilov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Dec 2010 15:33:21 +0000 (15:33 +0000)
committerpodivilov@chromium.org <podivilov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Dec 2010 15:33:21 +0000 (15:33 +0000)
        Reviewed by Yury Semikhatsky.

        Web Inspector: introduce a pair of set/remove methods for each breakpoint type.
        https://bugs.webkit.org/show_bug.cgi?id=50809

        * inspector/Inspector.idl:
        * inspector/InspectorController.cpp:
        (WebCore::InspectorController::InspectorController):
        (WebCore::InspectorController::setEventListenerBreakpoint):
        (WebCore::InspectorController::removeEventListenerBreakpoint):
        (WebCore::InspectorController::hasEventListenerBreakpoint):
        (WebCore::InspectorController::setXHRBreakpoint):
        (WebCore::InspectorController::removeXHRBreakpoint):
        (WebCore::InspectorController::hasXHRBreakpoint):
        (WebCore::InspectorController::clearNativeBreakpoints):
        * inspector/InspectorController.h:
        * inspector/InspectorDOMAgent.cpp:
        (WebCore::InspectorDOMAgent::setDOMBreakpoint):
        (WebCore::InspectorDOMAgent::removeDOMBreakpoint):
        (WebCore::InspectorDOMAgent::shouldBreakOnNodeInsertion):
        (WebCore::InspectorDOMAgent::shouldBreakOnNodeRemoval):
        (WebCore::InspectorDOMAgent::shouldBreakOnAttributeModification):
        (WebCore::InspectorDOMAgent::descriptionForDOMEvent):
        (WebCore::InspectorDOMAgent::didRemoveDOMNode):
        * inspector/InspectorDOMAgent.h:
        * inspector/InspectorInstrumentation.cpp:
        (WebCore::InspectorInstrumentation::willInsertDOMNodeImpl):
        (WebCore::InspectorInstrumentation::willRemoveDOMNodeImpl):
        (WebCore::InspectorInstrumentation::willModifyDOMAttrImpl):
        (WebCore::InspectorInstrumentation::willSendXMLHttpRequestImpl):
        (WebCore::InspectorInstrumentation::pauseOnNativeEventIfNeeded):
        * inspector/front-end/BreakpointManager.js:
        (WebInspector.BreakpointManager):
        (WebInspector.NativeBreakpoint):
        (WebInspector.DOMBreakpoint):
        (WebInspector.EventListenerBreakpoint):
        (WebInspector.XHRBreakpoint):
        * inspector/front-end/CallStackSidebarPane.js:
        (WebInspector.CallStackSidebarPane):
        (WebInspector.CallStackSidebarPane.prototype._nativeBreakpointHit):
        * inspector/front-end/DebuggerModel.js:
        (WebInspector.DebuggerModel.prototype.debuggerPaused):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@73726 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/inspector/Inspector.idl
WebCore/inspector/InspectorController.cpp
WebCore/inspector/InspectorController.h
WebCore/inspector/InspectorDOMAgent.cpp
WebCore/inspector/InspectorDOMAgent.h
WebCore/inspector/InspectorInstrumentation.cpp
WebCore/inspector/front-end/BreakpointManager.js
WebCore/inspector/front-end/CallStackSidebarPane.js
WebCore/inspector/front-end/DebuggerModel.js

index 25ba435..f2b688b 100644 (file)
@@ -1,3 +1,48 @@
+2010-12-10  Pavel Podivilov  <podivilov@chromium.org>
+
+        Reviewed by Yury Semikhatsky.
+
+        Web Inspector: introduce a pair of set/remove methods for each breakpoint type.
+        https://bugs.webkit.org/show_bug.cgi?id=50809
+
+        * inspector/Inspector.idl:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::InspectorController):
+        (WebCore::InspectorController::setEventListenerBreakpoint):
+        (WebCore::InspectorController::removeEventListenerBreakpoint):
+        (WebCore::InspectorController::hasEventListenerBreakpoint):
+        (WebCore::InspectorController::setXHRBreakpoint):
+        (WebCore::InspectorController::removeXHRBreakpoint):
+        (WebCore::InspectorController::hasXHRBreakpoint):
+        (WebCore::InspectorController::clearNativeBreakpoints):
+        * inspector/InspectorController.h:
+        * inspector/InspectorDOMAgent.cpp:
+        (WebCore::InspectorDOMAgent::setDOMBreakpoint):
+        (WebCore::InspectorDOMAgent::removeDOMBreakpoint):
+        (WebCore::InspectorDOMAgent::shouldBreakOnNodeInsertion):
+        (WebCore::InspectorDOMAgent::shouldBreakOnNodeRemoval):
+        (WebCore::InspectorDOMAgent::shouldBreakOnAttributeModification):
+        (WebCore::InspectorDOMAgent::descriptionForDOMEvent):
+        (WebCore::InspectorDOMAgent::didRemoveDOMNode):
+        * inspector/InspectorDOMAgent.h:
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::willInsertDOMNodeImpl):
+        (WebCore::InspectorInstrumentation::willRemoveDOMNodeImpl):
+        (WebCore::InspectorInstrumentation::willModifyDOMAttrImpl):
+        (WebCore::InspectorInstrumentation::willSendXMLHttpRequestImpl):
+        (WebCore::InspectorInstrumentation::pauseOnNativeEventIfNeeded):
+        * inspector/front-end/BreakpointManager.js:
+        (WebInspector.BreakpointManager):
+        (WebInspector.NativeBreakpoint):
+        (WebInspector.DOMBreakpoint):
+        (WebInspector.EventListenerBreakpoint):
+        (WebInspector.XHRBreakpoint):
+        * inspector/front-end/CallStackSidebarPane.js:
+        (WebInspector.CallStackSidebarPane):
+        (WebInspector.CallStackSidebarPane.prototype._nativeBreakpointHit):
+        * inspector/front-end/DebuggerModel.js:
+        (WebInspector.DebuggerModel.prototype.debuggerPaused):
+
 2010-12-10  Adam Roben  <aroben@apple.com>
 
         Windows production build fix after r72555
index 6d8f22b..c214f74 100644 (file)
@@ -145,8 +145,12 @@ module core {
         [domain=Debugger] void editScriptSource(in String sourceID, in String newContent, out boolean success, out String result, out Value newCallFrames);
         [domain=Debugger] void getScriptSource(in String sourceID, out String scriptSource);
 
-        [domain=Inspector] void setNativeBreakpoint(in Object breakpoint, out String breakpointId);
-        [domain=Inspector] void removeNativeBreakpoint(in String breakpointId);
+        [domain=DOM] void setDOMBreakpoint(in long nodeId, in long type);
+        [domain=DOM] void removeDOMBreakpoint(in long nodeId, in long type);
+        [domain=Inspector] void setEventListenerBreakpoint(in String eventName);
+        [domain=Inspector] void removeEventListenerBreakpoint(in String eventName);
+        [domain=Inspector] void setXHRBreakpoint(in String url);
+        [domain=Inspector] void removeXHRBreakpoint(in String url);
 
         [domain=Inspector] void enableProfiler(in boolean always);
         [domain=Inspector] void disableProfiler(in boolean always);
index f0cd8cf..e045382 100644 (file)
@@ -124,10 +124,6 @@ using namespace std;
 
 namespace WebCore {
 
-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";
 const char* const InspectorController::ScriptsPanel = "scripts";
@@ -152,7 +148,7 @@ InspectorController::InspectorController(Page* page, InspectorClient* client)
     , m_injectedScriptHost(InjectedScriptHost::create(this))
 #if ENABLE(JAVASCRIPT_DEBUGGER)
     , m_attachDebuggerWhenShown(false)
-    , m_lastBreakpointId(0)
+    , m_hasXHRBreakpointWithEmptyURL(false)
     , m_profilerAgent(InspectorProfilerAgent::create(this))
 #endif
 {
@@ -1386,81 +1382,57 @@ void InspectorController::resume()
         m_debuggerAgent->resume();
 }
 
-void InspectorController::setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, String* breakpointId)
+void InspectorController::setEventListenerBreakpoint(const String& eventName)
 {
-    *breakpointId = "";
-    String type;
-    if (!breakpoint->getString("type", &type))
-        return;
-    RefPtr<InspectorObject> condition = breakpoint->getObject("condition");
-    if (!condition)
-        return;
-    if (type == xhrNativeBreakpointType) {
-        String url;
-        if (!condition->getString("url", &url))
-            return;
-        *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_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;
-        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);
-    }
+    m_eventListenerBreakpoints.add(eventName);
 }
 
-void InspectorController::removeNativeBreakpoint(const String& breakpointId)
+void InspectorController::removeEventListenerBreakpoint(const String& eventName)
 {
-    String type = m_nativeBreakpoints.take(breakpointId);
-    if (type == xhrNativeBreakpointType)
-        m_XHRBreakpoints.remove(breakpointId);
-    else if (type == eventListenerNativeBreakpointType)
-        m_eventListenerBreakpoints.remove(breakpointId);
-    else if (type == domNativeBreakpointType) {
-        if (m_domAgent)
-            m_domAgent->removeDOMBreakpoint(breakpointId);
-    }
+    m_eventListenerBreakpoints.remove(eventName);
 }
 
-String InspectorController::findEventListenerBreakpoint(const String& eventName)
+bool InspectorController::hasEventListenerBreakpoint(const String& eventName)
 {
-    return m_eventListenerBreakpoints.contains(eventName) ? eventName : "";
+    return m_eventListenerBreakpoints.contains(eventName);
 }
 
-String InspectorController::findXHRBreakpoint(const String& url)
+void InspectorController::setXHRBreakpoint(const String& url)
 {
-    for (HashMap<String, String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) {
-        if (url.contains(it->second))
-            return it->first;
+    if (url.isEmpty())
+        m_hasXHRBreakpointWithEmptyURL = true;
+    else
+        m_XHRBreakpoints.add(url);
+}
+
+void InspectorController::removeXHRBreakpoint(const String& url)
+{
+    if (url.isEmpty())
+        m_hasXHRBreakpointWithEmptyURL = false;
+    else
+        m_XHRBreakpoints.remove(url);
+}
+
+bool InspectorController::hasXHRBreakpoint(const String& url, String* breakpointURL)
+{
+    if (m_hasXHRBreakpointWithEmptyURL) {
+        *breakpointURL = "";
+        return true;
+    }
+    for (HashSet<String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) {
+        if (url.contains(*it)) {
+            *breakpointURL = *it;
+            return true;
+        }
     }
-    return "";
+    return false;
 }
 
 void InspectorController::clearNativeBreakpoints()
 {
-    m_nativeBreakpoints.clear();
     m_eventListenerBreakpoints.clear();
     m_XHRBreakpoints.clear();
-    m_lastBreakpointId = 0;
+    m_hasXHRBreakpointWithEmptyURL = false;
 }
 #endif
 
index 0865a3a..14d5632 100644 (file)
@@ -255,8 +255,12 @@ public:
     InspectorDebuggerAgent* debuggerAgent() const { return m_debuggerAgent.get(); }
     void resume();
 
-    void setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, String* breakpointId);
-    void removeNativeBreakpoint(const String& breakpointId);
+    void setEventListenerBreakpoint(const String& eventName);
+    void removeEventListenerBreakpoint(const String& eventName);
+    bool hasEventListenerBreakpoint(const String& eventName);
+    void setXHRBreakpoint(const String& url);
+    void removeXHRBreakpoint(const String& url);
+    bool hasXHRBreakpoint(const String& url, String* breakpointURL);
 #endif
 
     void evaluateForTestInFrontend(long testCallId, const String& script);
@@ -306,8 +310,6 @@ private:
     void toggleRecordButton(bool);
     void enableDebuggerFromFrontend(bool always);
 
-    String findEventListenerBreakpoint(const String& eventName);
-    String findXHRBreakpoint(const String& url);
     void clearNativeBreakpoints();
 #endif
 #if ENABLE(DATABASE)
@@ -386,11 +388,9 @@ private:
     bool m_attachDebuggerWhenShown;
     OwnPtr<InspectorDebuggerAgent> m_debuggerAgent;
 
-    HashMap<String, String> m_nativeBreakpoints;
     HashSet<String> m_eventListenerBreakpoints;
-    HashMap<String, String> m_XHRBreakpoints;
-
-    unsigned int m_lastBreakpointId;
+    HashSet<String> m_XHRBreakpoints;
+    bool m_hasXHRBreakpointWithEmptyURL;
 
     OwnPtr<InspectorProfilerAgent> m_profilerAgent;
 #endif
index 29715b4..cbba75f 100644 (file)
@@ -760,17 +760,11 @@ void InspectorDOMAgent::searchCanceled()
     m_searchResults.clear();
 }
 
-String InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type)
+void InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type)
 {
     Node* node = nodeForId(nodeId);
     if (!node)
-        return "";
-
-    String breakpointId = createBreakpointId(nodeId, type);
-    if (m_idToBreakpoint.contains(breakpointId))
-        return "";
-
-    m_idToBreakpoint.set(breakpointId, std::make_pair(nodeId, type));
+        return;
 
     uint32_t rootBit = 1 << type;
     m_breakpoints.set(node, m_breakpoints.get(node) | rootBit);
@@ -778,19 +772,15 @@ String InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type)
         for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child))
             updateSubtreeBreakpoints(child, rootBit, true);
     }
-
-    return breakpointId;
 }
 
-void InspectorDOMAgent::removeDOMBreakpoint(const String& breakpointId)
+void InspectorDOMAgent::removeDOMBreakpoint(long nodeId, long type)
 {
-    Breakpoint breakpoint = m_idToBreakpoint.take(breakpointId);
-
-    Node* node = nodeForId(breakpoint.first);
+    Node* node = nodeForId(nodeId);
     if (!node)
         return;
 
-    uint32_t rootBit = 1 << breakpoint.second;
+    uint32_t rootBit = 1 << type;
     uint32_t mask = m_breakpoints.get(node) & ~rootBit;
     if (mask)
         m_breakpoints.set(node, mask);
@@ -803,42 +793,41 @@ void InspectorDOMAgent::removeDOMBreakpoint(const String& breakpointId)
     }
 }
 
-bool InspectorDOMAgent::shouldBreakOnNodeInsertion(Node*, Node* parent, PassRefPtr<InspectorValue>* details)
+bool InspectorDOMAgent::shouldBreakOnNodeInsertion(Node*, Node* parent, PassRefPtr<InspectorObject> details)
 {
     if (hasBreakpoint(parent, SubtreeModified)) {
-        *details = descriptionForDOMEvent(parent, SubtreeModified, true);
+        descriptionForDOMEvent(parent, SubtreeModified, true, details);
         return true;
     }
     return false;
 }
 
-bool InspectorDOMAgent::shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorValue>* details)
+bool InspectorDOMAgent::shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorObject> details)
 {
     if (hasBreakpoint(node, NodeRemoved)) {
-        *details = descriptionForDOMEvent(node, NodeRemoved, false);
+        descriptionForDOMEvent(node, NodeRemoved, false, details);
         return true;
     }
     if (hasBreakpoint(innerParentNode(node), SubtreeModified)) {
-        *details = descriptionForDOMEvent(node, SubtreeModified, false);
+        descriptionForDOMEvent(node, SubtreeModified, false, details);
         return true;
     }
     return false;
 }
 
-bool InspectorDOMAgent::shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorValue>* details)
+bool InspectorDOMAgent::shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorObject> details)
 {
     if (hasBreakpoint(element, AttributeModified)) {
-        *details = descriptionForDOMEvent(element, AttributeModified, false);
+        descriptionForDOMEvent(element, AttributeModified, false, details);
         return true;
     }
     return false;
 }
 
-PassRefPtr<InspectorValue> InspectorDOMAgent::descriptionForDOMEvent(Node* target, long breakpointType, bool insertion)
+void InspectorDOMAgent::descriptionForDOMEvent(Node* target, long breakpointType, bool insertion, PassRefPtr<InspectorObject> description)
 {
     ASSERT(hasBreakpoint(target, breakpointType));
 
-    RefPtr<InspectorObject> description = InspectorObject::create();
     Node* breakpointOwner = target;
     if ((1 << breakpointType) & inheritableDOMBreakpointTypesMask) {
         // For inheritable breakpoint types, target node isn't always the same as the node that owns a breakpoint.
@@ -862,9 +851,8 @@ PassRefPtr<InspectorValue> InspectorDOMAgent::descriptionForDOMEvent(Node* targe
 
     long breakpointOwnerNodeId = m_documentNodeToIdMap.get(breakpointOwner);
     ASSERT(breakpointOwnerNodeId);
-    description->setString("breakpointId", createBreakpointId(breakpointOwnerNodeId, breakpointType));
-
-    return description;
+    description->setNumber("nodeId", breakpointOwnerNodeId);
+    description->setNumber("type", breakpointType);
 }
 
 String InspectorDOMAgent::documentURLString(Document* document) const
@@ -1106,14 +1094,14 @@ void InspectorDOMAgent::didRemoveDOMNode(Node* node)
 
     if (m_breakpoints.size()) {
         // Remove subtree breakpoints.
-        removeBreakpointsForNode(node);
+        m_breakpoints.remove(node);
         Vector<Node*> stack(1, innerFirstChild(node));
         do {
             Node* node = stack.last();
             stack.removeLast();
             if (!node)
                 continue;
-            removeBreakpointsForNode(node);
+            m_breakpoints.remove(node);
             stack.append(innerFirstChild(node));
             stack.append(innerNextSibling(node));
         } while (!stack.isEmpty());
@@ -1180,25 +1168,6 @@ 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 makeString("dom:", String::number(nodeId), ':', String::number(type));
-}
-
 Node* InspectorDOMAgent::nodeForPath(const String& path)
 {
     // The path is of form "1,HTML,2,BODY,1,DIV"
index edd405b..5347090 100644 (file)
@@ -119,9 +119,9 @@ namespace WebCore {
         void addInspectedNode(long nodeId);
         void performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously);
         void searchCanceled();
-        bool shouldBreakOnNodeInsertion(Node* node, Node* parent, PassRefPtr<InspectorValue>* details);
-        bool shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorValue>* details);
-        bool shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorValue>* details);
+        bool shouldBreakOnNodeInsertion(Node* node, Node* parent, PassRefPtr<InspectorObject> details);
+        bool shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorObject> details);
+        bool shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorObject> details);
 
         // Methods called from the InspectorController.
         void setDocument(Document* document);
@@ -143,8 +143,8 @@ namespace WebCore {
 
         String documentURLString(Document* document) const;
 
-        String setDOMBreakpoint(long nodeId, long type);
-        void removeDOMBreakpoint(const String& breakpointId);
+        void setDOMBreakpoint(long nodeId, long type);
+        void removeDOMBreakpoint(long nodeId, long type);
 
     private:
         void startListening(Document* document);
@@ -161,9 +161,7 @@ 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);
+        void descriptionForDOMEvent(Node* target, long breakpointType, bool insertion, PassRefPtr<InspectorObject> description);
 
         PassRefPtr<InspectorObject> buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap);
         PassRefPtr<InspectorArray> buildArrayForElementAttributes(Element* element);
@@ -204,8 +202,6 @@ 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
index cf41527..f3a73ba 100644 (file)
 
 namespace WebCore {
 
+static const char* const domNativeBreakpointType = "DOM";
+static const char* const eventListenerNativeBreakpointType = "EventListener";
+static const char* const xhrNativeBreakpointType = "XHR";
+
 static const char* const listenerEventCategoryType = "listener";
 static const char* const instrumentationEventCategoryType = "instrumentation";
 
@@ -80,9 +84,11 @@ void InspectorInstrumentation::willInsertDOMNodeImpl(InspectorController* inspec
     InspectorDOMAgent* domAgent = inspectorController->m_domAgent.get();
     if (!domAgent)
         return;
-    PassRefPtr<InspectorValue> eventData;
-    if (domAgent->shouldBreakOnNodeInsertion(node, parent, &eventData))
+    RefPtr<InspectorObject> eventData = InspectorObject::create();
+    if (domAgent->shouldBreakOnNodeInsertion(node, parent, eventData)) {
+        eventData->setString("breakpointType", domNativeBreakpointType);
         debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
+    }
 #endif
 }
 
@@ -101,9 +107,11 @@ void InspectorInstrumentation::willRemoveDOMNodeImpl(InspectorController* inspec
     InspectorDOMAgent* domAgent = inspectorController->m_domAgent.get();
     if (!domAgent)
         return;
-    PassRefPtr<InspectorValue> eventData;
-    if (domAgent->shouldBreakOnNodeRemoval(node, &eventData))
+    RefPtr<InspectorObject> eventData = InspectorObject::create();
+    if (domAgent->shouldBreakOnNodeRemoval(node, eventData)) {
+        eventData->setString("breakpointType", domNativeBreakpointType);
         debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
+    }
 #endif
 }
 
@@ -122,9 +130,11 @@ void InspectorInstrumentation::willModifyDOMAttrImpl(InspectorController* inspec
     InspectorDOMAgent* domAgent = inspectorController->m_domAgent.get();
     if (!domAgent)
         return;
-    PassRefPtr<InspectorValue> eventData;
-    if (domAgent->shouldBreakOnAttributeModification(element, &eventData))
+    RefPtr<InspectorObject> eventData = InspectorObject::create();
+    if (domAgent->shouldBreakOnAttributeModification(element, eventData)) {
+        eventData->setString("breakpointType", domNativeBreakpointType);
         debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
+    }
 #endif
 }
 
@@ -147,12 +157,13 @@ void InspectorInstrumentation::willSendXMLHttpRequestImpl(InspectorController* i
     if (!debuggerAgent)
         return;
 
-    String breakpointId = inspectorController->findXHRBreakpoint(url);
-    if (breakpointId.isEmpty())
+    String breakpointURL;
+    if (!inspectorController->hasXHRBreakpoint(url, &breakpointURL))
         return;
 
     RefPtr<InspectorObject> eventData = InspectorObject::create();
-    eventData->setString("breakpointId", breakpointId);
+    eventData->setString("breakpointType", xhrNativeBreakpointType);
+    eventData->setString("breakpointURL", breakpointURL);
     eventData->setString("url", url);
     debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
 #endif
@@ -446,11 +457,11 @@ void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InspectorController* i
     if (!debuggerAgent)
         return;
     String fullEventName = String::format("%s:%s", categoryType.utf8().data(), eventName.utf8().data());
-    String breakpointId = inspectorController->findEventListenerBreakpoint(fullEventName);
-    if (breakpointId.isEmpty())
+    if (!inspectorController->hasEventListenerBreakpoint(fullEventName))
         return;
     RefPtr<InspectorObject> eventData = InspectorObject::create();
-    eventData->setString("breakpointId", breakpointId);
+    eventData->setString("breakpointType", eventListenerNativeBreakpointType);
+    eventData->setString("eventName", fullEventName);
     if (synchronous)
         debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
     else
index 61b2bc8..04ffcd3 100644 (file)
 WebInspector.BreakpointManager = function()
 {
     this._nativeBreakpoints = {};
-    this._backendIdToBreakpoint = {};
 
     WebInspector.debuggerModel.addEventListener("native-breakpoint-hit", this._nativeBreakpointHit, this);
     WebInspector.debuggerModel.addEventListener("debugger-resumed", this._debuggerResumed, this);
 }
 
+WebInspector.BreakpointManager.NativeBreakpointTypes = {
+    DOM: "DOM",
+    EventListener: "EventListener",
+    XHR: "XHR"
+}
+
 WebInspector.BreakpointManager.prototype = {
-    createDOMBreakpoint: function(nodeId, domEventType, disabled)
+    createDOMBreakpoint: function(nodeId, type, disabled)
     {
-        var frontendId = "dom:" + nodeId + ":" + domEventType;
-        if (frontendId in this._nativeBreakpoints)
+        var node = WebInspector.domAgent.nodeForId(nodeId);
+        if (!node)
             return;
 
-        var breakpoint = new WebInspector.DOMBreakpoint(this, frontendId, nodeId, domEventType);
-        this._nativeBreakpoints[frontendId] = breakpoint;
+        var breakpointId = this._createDOMBreakpointId(nodeId, type);
+        if (breakpointId in this._nativeBreakpoints)
+            return;
+
+        var breakpoint = new WebInspector.DOMBreakpoint(this, breakpointId, !disabled, node, type);
+        this._nativeBreakpoints[breakpointId] = breakpoint;
+        this._updateNativeBreakpointsInSettings();
         this.dispatchEventToListeners("dom-breakpoint-added", breakpoint);
-        breakpoint.enabled = !disabled;
         return breakpoint;
     },
 
     createEventListenerBreakpoint: function(eventName)
     {
-        var frontendId = eventName;
-        if (frontendId in this._nativeBreakpoints)
+        var breakpointId = this._createEventListenerBreakpointId(eventName);
+        if (breakpointId in this._nativeBreakpoints)
             return;
 
-        var breakpoint = new WebInspector.EventListenerBreakpoint(this, frontendId, eventName);
-        this._nativeBreakpoints[frontendId] = breakpoint;
+        var breakpoint = new WebInspector.EventListenerBreakpoint(this, breakpointId, true, eventName);
+        this._nativeBreakpoints[breakpointId] = breakpoint;
+        this._updateNativeBreakpointsInSettings();
         this.dispatchEventToListeners("event-listener-breakpoint-added", { breakpoint: breakpoint, eventName: eventName });
-        breakpoint.enabled = true;
         return breakpoint;
     },
 
     createXHRBreakpoint: function(url, disabled)
     {
-        var frontendId = url;
-        if (frontendId in this._nativeBreakpoints)
+        var breakpointId = this._createXHRBreakpointId(url);
+        if (breakpointId in this._nativeBreakpoints)
             return;
 
-        var breakpoint = new WebInspector.XHRBreakpoint(this, frontendId, url);
-        this._nativeBreakpoints[frontendId] = breakpoint;
+        var breakpoint = new WebInspector.XHRBreakpoint(this, breakpointId, !disabled, url);
+        this._nativeBreakpoints[breakpointId] = breakpoint;
+        this._updateNativeBreakpointsInSettings();
         this.dispatchEventToListeners("xhr-breakpoint-added", breakpoint);
-        breakpoint.enabled = !disabled
         return breakpoint;
     },
 
-    findBreakpoint: function(backendBreakpointId)
-    {
-        return this._backendIdToBreakpoint[backendBreakpointId];
-    },
-
-    _removeNativeBreakpoint: function(breakpoint)
+    _setNativeBreakpointEnabled: function(breakpointId, enabled)
     {
-        if (breakpoint._beingSetOnBackend)
-            return;
-        if (breakpoint.enabled)
-            this._removeNativeBreakpointFromBackend(breakpoint);
-        delete this._nativeBreakpoints[breakpoint._frontendId];
-        this._updateNativeBreakpointsInSettings();
-        breakpoint.dispatchEventToListeners("removed");
-    },
+        var breakpoint = this._nativeBreakpoints[breakpointId];
 
-    _setNativeBreakpointEnabled: function(breakpoint, enabled)
-    {
-        if (breakpoint._beingSetOnBackend)
-            return;
-        if (breakpoint.enabled === enabled)
-            return;
         if (enabled)
-            this._setNativeBreakpointOnBackend(breakpoint);
+            breakpoint._enable();
         else
-            this._removeNativeBreakpointFromBackend(breakpoint);
+            breakpoint._disable();
+
+        breakpoint._enabled = enabled;
+        this._updateNativeBreakpointsInSettings();
+        breakpoint.dispatchEventToListeners("enable-changed");
     },
 
-    _setNativeBreakpointOnBackend: function(breakpoint)
+    _removeNativeBreakpoint: function(breakpointId)
     {
-        breakpoint._beingSetOnBackend = true;
-        var data = { type: breakpoint._type, condition: breakpoint._condition };
-        InspectorBackend.setNativeBreakpoint(data, didSetNativeBreakpoint.bind(this));
+        var breakpoint = this._nativeBreakpoints[breakpointId];
 
-        function didSetNativeBreakpoint(backendBreakpointId)
-        {
-            breakpoint._beingSetOnBackend = false;
-            if (backendBreakpointId !== "") {
-                breakpoint._backendId = backendBreakpointId;
-                this._backendIdToBreakpoint[backendBreakpointId] = breakpoint;
-            }
-            breakpoint.dispatchEventToListeners("enable-changed");
-            this._updateNativeBreakpointsInSettings();
-        }
-    },
+        if (breakpoint.enabled)
+            breakpoint._disable();
 
-    _removeNativeBreakpointFromBackend: function(breakpoint)
-    {
-        InspectorBackend.removeNativeBreakpoint(breakpoint._backendId);
-        delete this._backendIdToBreakpoint[breakpoint._backendId]
-        delete breakpoint._backendId;
-        breakpoint.dispatchEventToListeners("enable-changed");
+        delete this._nativeBreakpoints[breakpointId];
         this._updateNativeBreakpointsInSettings();
+        breakpoint.dispatchEventToListeners("removed");
     },
 
     _updateNativeBreakpointsInSettings: function()
     {
-        var persistentBreakpoints = [];
+        var breakpoints = [];
         for (var id in this._nativeBreakpoints) {
             var breakpoint = this._nativeBreakpoints[id];
-            if (breakpoint._persistentCondition)
-                persistentBreakpoints.push({ type: breakpoint._type, enabled: breakpoint.enabled, condition: breakpoint._persistentCondition });
+            breakpoints.push(breakpoint._serializeToJSON());
         }
-        WebInspector.settings.nativeBreakpoints = persistentBreakpoints;
+        WebInspector.settings.nativeBreakpoints = breakpoints;
     },
 
     _nativeBreakpointHit: function(event)
     {
-        var breakpointId = event.data.breakpointId;
+        var eventData = event.data;
+
+        var breakpointId;
+        if (eventData.breakpointType === WebInspector.BreakpointManager.NativeBreakpointTypes.DOM)
+            breakpointId = this._createDOMBreakpointId(eventData.nodeId, eventData.type);
+        else if (eventData.breakpointType === WebInspector.BreakpointManager.NativeBreakpointTypes.EventListener)
+            breakpointId = this._createEventListenerBreakpointId(eventData.eventName);
+        else if (eventData.breakpointType === WebInspector.BreakpointManager.NativeBreakpointTypes.XHR)
+            breakpointId = this._createXHRBreakpointId(eventData.breakpointURL);
 
-        var breakpoint = this._backendIdToBreakpoint[breakpointId];
+        var breakpoint = this._nativeBreakpoints[breakpointId];
         if (!breakpoint)
             return;
 
         breakpoint.hit = true;
-        breakpoint.dispatchEventToListeners("hit-state-changed");
         this._lastHitBreakpoint = breakpoint;
+        this.dispatchEventToListeners("native-breakpoint-hit", { breakpoint: breakpoint, eventData: eventData });
     },
 
     _debuggerResumed: function(event)
@@ -161,17 +148,19 @@ WebInspector.BreakpointManager.prototype = {
         if (!this._lastHitBreakpoint)
             return;
         this._lastHitBreakpoint.hit = false;
-        this._lastHitBreakpoint.dispatchEventToListeners("hit-state-changed");
         delete this._lastHitBreakpoint;
     },
 
     restoreBreakpoints: function()
     {
         var breakpoints = this._persistentBreakpoints();
+        this._domBreakpoints = [];
         for (var i = 0; i < breakpoints.length; ++i) {
-            if (breakpoints[i].type === "EventListener")
+            if (breakpoints[i].type === WebInspector.BreakpointManager.NativeBreakpointTypes.DOM)
+                this._domBreakpoints.push(breakpoints[i]);
+            else if (breakpoints[i].type === WebInspector.BreakpointManager.NativeBreakpointTypes.EventListener)
                 this.createEventListenerBreakpoint(breakpoints[i].condition.eventName);
-            else if (breakpoints[i].type === "XHR")
+            else if (breakpoints[i].type === WebInspector.BreakpointManager.NativeBreakpointTypes.XHR)
                 this.createXHRBreakpoint(breakpoints[i].condition.url, !breakpoints[i].enabled);
         }
     },
@@ -185,6 +174,8 @@ WebInspector.BreakpointManager.prototype = {
             if (pendingCalls)
                 return;
             for (var i = 0; i < breakpoints.length; ++i) {
+                if (breakpoints[i].type !== WebInspector.BreakpointManager.NativeBreakpointTypes.DOM)
+                    continue;
                 var breakpoint = breakpoints[i];
                 var nodeId = pathToNodeId[breakpoint.condition.path];
                 if (nodeId)
@@ -192,11 +183,11 @@ WebInspector.BreakpointManager.prototype = {
             }
         }
 
-        var breakpoints = this._persistentBreakpoints();
+        var breakpoints = this._domBreakpoints;
         var pathToNodeId = {};
         var pendingCalls = 0;
         for (var i = 0; i < breakpoints.length; ++i) {
-            if (breakpoints[i].type !== "DOM")
+            if (breakpoints[i].type !== WebInspector.BreakpointManager.NativeBreakpointTypes.DOM)
                 continue;
             var path = breakpoints[i].condition.path;
             if (path in pathToNodeId)
@@ -221,47 +212,63 @@ WebInspector.BreakpointManager.prototype = {
         return result;
     },
 
+    _createDOMBreakpointId: function(nodeId, type)
+    {
+        return "dom:" + nodeId + ":" + type;
+    },
+
+    _createEventListenerBreakpointId: function(eventName)
+    {
+        return "eventListner:" + eventName;
+    },
+
+    _createXHRBreakpointId: function(url)
+    {
+        return "xhr:" + url;
+    },
+
     reset: function()
     {
         this._nativeBreakpoints = {};
-        this._backendIdToBreakpoint = {};
     }
 }
 
 WebInspector.BreakpointManager.prototype.__proto__ = WebInspector.Object.prototype;
 
-WebInspector.NativeBreakpoint = function(manager, frontendId, type)
+WebInspector.NativeBreakpoint = function(manager, id, enabled)
 {
     this._manager = manager;
-    this.__frontendId = frontendId;
-    this.__type = type;
+    this._id = id;
+    this._enabled = enabled;
+    this._hit = false;
 }
 
 WebInspector.NativeBreakpoint.prototype = {
     get enabled()
     {
-        return "_backendId" in this;
+        return this._enabled;
     },
 
     set enabled(enabled)
     {
-        this._manager._setNativeBreakpointEnabled(this, enabled);
+        this._manager._setNativeBreakpointEnabled(this._id, enabled);
     },
 
-    remove: function()
+    get hit()
     {
-        this._manager._removeNativeBreakpoint(this);
-        this._onRemove();
+        return this._hit;
     },
 
-    get _frontendId()
+    set hit(hit)
     {
-        return this.__frontendId;
+        this._hit = hit;
+        this.dispatchEventToListeners("hit-state-changed");
     },
 
-    get _type()
+    remove: function()
     {
-        return this.__type;
+        this._manager._removeNativeBreakpoint(this._id);
+        this._onRemove();
     },
 
     _compare: function(x, y)
@@ -278,24 +285,23 @@ WebInspector.NativeBreakpoint.prototype = {
 
 WebInspector.NativeBreakpoint.prototype.__proto__ = WebInspector.Object.prototype;
 
-WebInspector.DOMBreakpoint = function(manager, frontendId, nodeId, domEventType)
+WebInspector.DOMBreakpoint = function(manager, id, enabled, node, type)
 {
-    WebInspector.NativeBreakpoint.call(this, manager, frontendId, "DOM");
-    this._nodeId = nodeId;
-    this._domEventType = domEventType;
-    this._condition = { nodeId: this._nodeId, type: this._domEventType };
-
-    var node = WebInspector.domAgent.nodeForId(this._nodeId);
-    if (node) {
-        node.breakpoints[this._domEventType] = this;
-        this._persistentCondition = { path: node.path(), type: this._domEventType };
-    }
+    WebInspector.NativeBreakpoint.call(this, manager, id, enabled);
+    this._node = node;
+    this._nodeId = node.id;
+    this._path = node.path();
+    this._type = type;
+    if (enabled)
+        this._enable();
+
+    node.breakpoints[this._type] = this;
 }
 
 WebInspector.DOMBreakpoint.prototype = {
     compareTo: function(other)
     {
-        return this._compare(this._domEventType, other._domEventType);
+        return this._compare(this._type, other._type);
     },
 
     populateLabelElement: function(element)
@@ -306,13 +312,13 @@ WebInspector.DOMBreakpoint.prototype = {
         element.appendChild(linkifiedNode);
         var description = document.createElement("div");
         description.className = "source-text";
-        description.textContent = WebInspector.domBreakpointTypeLabel(this._domEventType);
+        description.textContent = WebInspector.domBreakpointTypeLabel(this._type);
         element.appendChild(description);
     },
 
     populateStatusMessageElement: function(element, eventData)
     {
-        var substitutions = [WebInspector.domBreakpointTypeLabel(this._domEventType), WebInspector.panels.elements.linkifyNodeById(this._nodeId)];
+        var substitutions = [WebInspector.domBreakpointTypeLabel(this._type), WebInspector.panels.elements.linkifyNodeById(this._nodeId)];
         var formatters = {
             s: function(substitution)
             {
@@ -325,7 +331,7 @@ WebInspector.DOMBreakpoint.prototype = {
                 b = document.createTextNode(b);
             element.appendChild(b);
         }
-        if (this._domEventType === WebInspector.DOMBreakpointTypes.SubtreeModified) {
+        if (this._type === WebInspector.DOMBreakpointTypes.SubtreeModified) {
             var targetNode = WebInspector.panels.elements.linkifyNodeById(eventData.targetNodeId);
             if (eventData.insertion) {
                 if (eventData.targetNodeId !== this._nodeId)
@@ -338,22 +344,36 @@ WebInspector.DOMBreakpoint.prototype = {
             WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s.", substitutions, formatters, "", append);
     },
 
+    _enable: function()
+    {
+        InspectorBackend.setDOMBreakpoint(this._nodeId, this._type);
+    },
+
+    _disable: function()
+    {
+        InspectorBackend.removeDOMBreakpoint(this._nodeId, this._type);
+    },
+
+    _serializeToJSON: function()
+    {
+        var type = WebInspector.BreakpointManager.NativeBreakpointTypes.DOM;
+        return { type: type, enabled: this._enabled, condition: { path: this._path, type: this._type } };
+    },
+
     _onRemove: function()
     {
-        var node = WebInspector.domAgent.nodeForId(this._nodeId);
-        if (node)
-            delete node.breakpoints[this._domEventType];
+        delete this._node.breakpoints[this._type];
     }
 }
 
 WebInspector.DOMBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype;
 
-WebInspector.EventListenerBreakpoint = function(manager, frontendId, eventName)
+WebInspector.EventListenerBreakpoint = function(manager, id, enabled, eventName)
 {
-    WebInspector.NativeBreakpoint.call(this, manager, frontendId, "EventListener");
+    WebInspector.NativeBreakpoint.call(this, manager, id, enabled);
     this._eventName = eventName;
-    this._condition = { eventName: this._eventName };
-    this._persistentCondition = this._condition;
+    if (enabled)
+        this._enable();
 }
 
 WebInspector.EventListenerBreakpoint.eventNameForUI = function(eventName)
@@ -388,17 +408,33 @@ WebInspector.EventListenerBreakpoint.prototype = {
     _uiEventName: function()
     {
         return WebInspector.EventListenerBreakpoint.eventNameForUI(this._eventName);
+    },
+
+    _enable: function()
+    {
+        InspectorBackend.setEventListenerBreakpoint(this._eventName);
+    },
+
+    _disable: function()
+    {
+        InspectorBackend.removeEventListenerBreakpoint(this._eventName);
+    },
+
+    _serializeToJSON: function()
+    {
+        var type = WebInspector.BreakpointManager.NativeBreakpointTypes.EventListener;
+        return { type: type, enabled: this._enabled, condition: { eventName: this._eventName } };
     }
 }
 
 WebInspector.EventListenerBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype;
 
-WebInspector.XHRBreakpoint = function(manager, frontendId, url)
+WebInspector.XHRBreakpoint = function(manager, id, enabled, url)
 {
-    WebInspector.NativeBreakpoint.call(this, manager, frontendId, "XHR");
+    WebInspector.NativeBreakpoint.call(this, manager, id, enabled);
     this._url = url;
-    this._condition = { url: this._url };
-    this._persistentCondition = this._condition;
+    if (enabled)
+        this._enable();
 }
 
 WebInspector.XHRBreakpoint.prototype = {
@@ -427,6 +463,22 @@ WebInspector.XHRBreakpoint.prototype = {
     {
         var status = WebInspector.UIString("Paused on a XMLHttpRequest.");
         element.appendChild(document.createTextNode(status));
+    },
+
+    _enable: function()
+    {
+        InspectorBackend.setXHRBreakpoint(this._url);
+    },
+
+    _disable: function()
+    {
+        InspectorBackend.removeXHRBreakpoint(this._url);
+    },
+
+    _serializeToJSON: function()
+    {
+        var type = WebInspector.BreakpointManager.NativeBreakpointTypes.XHR;
+        return { type: type, enabled: this._enabled, condition: { url: this._url } };
     }
 }
 
index 16c5fe4..8b74126 100644 (file)
@@ -26,7 +26,7 @@
 WebInspector.CallStackSidebarPane = function()
 {
     WebInspector.SidebarPane.call(this, WebInspector.UIString("Call Stack"));
-    WebInspector.debuggerModel.addEventListener("native-breakpoint-hit", this._nativeBreakpointHit, this);
+    WebInspector.breakpointManager.addEventListener("native-breakpoint-hit", this._nativeBreakpointHit, this);
     WebInspector.debuggerModel.addEventListener("script-breakpoint-hit", this._scriptBreakpointHit, this);
 }
 
@@ -173,9 +173,7 @@ WebInspector.CallStackSidebarPane.prototype = {
 
     _nativeBreakpointHit:  function(event)
     {
-        var breakpoint = WebInspector.breakpointManager.findBreakpoint(event.data.breakpointId);
-        if (!breakpoint)
-            return;
+        var breakpoint = event.data.breakpoint;
         var statusMessageElement = document.createElement("div");
         statusMessageElement.className = "info";
         breakpoint.populateStatusMessageElement(statusMessageElement, event.data.eventData);
index 37f4dd0..a170018 100644 (file)
@@ -134,8 +134,7 @@ WebInspector.DebuggerModel.prototype = {
         if (details.eventType === WebInspector.DebuggerEventTypes.JavaScriptPause)
             return;
         if (details.eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint) {
-            var breakpointId = details.eventData.breakpointId;
-            this.dispatchEventToListeners("native-breakpoint-hit", { breakpointId: breakpointId, eventData: details.eventData });
+            this.dispatchEventToListeners("native-breakpoint-hit", details.eventData);
             return;
         }