2010-10-04 podivilov@chromium.org <podivilov@chromium.org>
authorpodivilov@chromium.org <podivilov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Oct 2010 14:52:38 +0000 (14:52 +0000)
committerpodivilov@chromium.org <podivilov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Oct 2010 14:52:38 +0000 (14:52 +0000)
        Reviewed by Yury Semikhatsky.

        Web Inspector: implement pausing on event listeners (back-end part)
        https://bugs.webkit.org/show_bug.cgi?id=46624

        * bindings/js/ScriptDebugServer.cpp:
        (WebCore::ScriptDebugServer::setPauseOnNextStatement):
        * bindings/js/ScriptDebugServer.h:
        * bindings/v8/ScriptDebugServer.cpp:
        (WebCore::ScriptDebugServer::setPauseOnNextStatement):
        * bindings/v8/ScriptDebugServer.h:
        * dom/Node.cpp:
        (WebCore::Node::dispatchGenericEvent):
        * inspector/InspectorController.cpp:
        (WebCore::InspectorController::didCommitLoad):
        (WebCore::InspectorController::setNativeBreakpoint):
        (WebCore::InspectorController::removeNativeBreakpoint):
        (WebCore::InspectorController::shouldBreakOnEvent):
        (WebCore::InspectorController::shouldBreakOnXMLHttpRequest):
        * inspector/InspectorController.h:
        * inspector/InspectorDebuggerAgent.cpp:
        (WebCore::InspectorDebuggerAgent::~InspectorDebuggerAgent):
        (WebCore::InspectorDebuggerAgent::schedulePauseOnNextStatement):
        (WebCore::InspectorDebuggerAgent::cancelPauseOnNextStatement):
        (WebCore::InspectorDebuggerAgent::pause):
        (WebCore::InspectorDebuggerAgent::didContinue):
        (WebCore::InspectorDebuggerAgent::breakProgram):
        * inspector/InspectorDebuggerAgent.h:
        * inspector/InspectorInstrumentation.cpp:
        (WebCore::eventHasListeners):
        (WebCore::InspectorInstrumentation::instrumentWillDispatchEventImpl):
        (WebCore::InspectorInstrumentation::instrumentDidDispatchEventImpl):
        (WebCore::InspectorInstrumentation::instrumentWillSendXMLHttpRequestImpl):
        * inspector/InspectorInstrumentation.h:
        (WebCore::InspectorInstrumentation::instrumentWillDispatchEvent):
        (WebCore::InspectorInstrumentation::instrumentDidDispatchEvent):
        (WebCore::InspectorInstrumentation::instrumentWillSendXMLHttpRequest):
        * inspector/InspectorTimelineAgent.cpp:
        (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
        * inspector/InspectorTimelineAgent.h:
        (WebCore::InspectorTimelineAgent::id):
        * inspector/front-end/CallStackSidebarPane.js:

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

15 files changed:
WebCore/ChangeLog
WebCore/bindings/js/ScriptDebugServer.cpp
WebCore/bindings/js/ScriptDebugServer.h
WebCore/bindings/v8/ScriptDebugServer.cpp
WebCore/bindings/v8/ScriptDebugServer.h
WebCore/dom/Node.cpp
WebCore/inspector/InspectorController.cpp
WebCore/inspector/InspectorController.h
WebCore/inspector/InspectorDebuggerAgent.cpp
WebCore/inspector/InspectorDebuggerAgent.h
WebCore/inspector/InspectorInstrumentation.cpp
WebCore/inspector/InspectorInstrumentation.h
WebCore/inspector/InspectorTimelineAgent.cpp
WebCore/inspector/InspectorTimelineAgent.h
WebCore/inspector/front-end/CallStackSidebarPane.js

index be456a6..ca18194 100644 (file)
@@ -1,3 +1,48 @@
+2010-10-04  podivilov@chromium.org  <podivilov@chromium.org>
+
+        Reviewed by Yury Semikhatsky.
+
+        Web Inspector: implement pausing on event listeners (back-end part)
+        https://bugs.webkit.org/show_bug.cgi?id=46624
+
+        * bindings/js/ScriptDebugServer.cpp:
+        (WebCore::ScriptDebugServer::setPauseOnNextStatement):
+        * bindings/js/ScriptDebugServer.h:
+        * bindings/v8/ScriptDebugServer.cpp:
+        (WebCore::ScriptDebugServer::setPauseOnNextStatement):
+        * bindings/v8/ScriptDebugServer.h:
+        * dom/Node.cpp:
+        (WebCore::Node::dispatchGenericEvent):
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::didCommitLoad):
+        (WebCore::InspectorController::setNativeBreakpoint):
+        (WebCore::InspectorController::removeNativeBreakpoint):
+        (WebCore::InspectorController::shouldBreakOnEvent):
+        (WebCore::InspectorController::shouldBreakOnXMLHttpRequest):
+        * inspector/InspectorController.h:
+        * inspector/InspectorDebuggerAgent.cpp:
+        (WebCore::InspectorDebuggerAgent::~InspectorDebuggerAgent):
+        (WebCore::InspectorDebuggerAgent::schedulePauseOnNextStatement):
+        (WebCore::InspectorDebuggerAgent::cancelPauseOnNextStatement):
+        (WebCore::InspectorDebuggerAgent::pause):
+        (WebCore::InspectorDebuggerAgent::didContinue):
+        (WebCore::InspectorDebuggerAgent::breakProgram):
+        * inspector/InspectorDebuggerAgent.h:
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::eventHasListeners):
+        (WebCore::InspectorInstrumentation::instrumentWillDispatchEventImpl):
+        (WebCore::InspectorInstrumentation::instrumentDidDispatchEventImpl):
+        (WebCore::InspectorInstrumentation::instrumentWillSendXMLHttpRequestImpl):
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::instrumentWillDispatchEvent):
+        (WebCore::InspectorInstrumentation::instrumentDidDispatchEvent):
+        (WebCore::InspectorInstrumentation::instrumentWillSendXMLHttpRequest):
+        * inspector/InspectorTimelineAgent.cpp:
+        (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
+        * inspector/InspectorTimelineAgent.h:
+        (WebCore::InspectorTimelineAgent::id):
+        * inspector/front-end/CallStackSidebarPane.js:
+
 2010-10-04  Pavel Feldman  <pfeldman@chromium.org>
 
         Reviewed by Yury Semikhatsky.
index 1decefa..a440b81 100644 (file)
@@ -200,9 +200,9 @@ void ScriptDebugServer::setPauseOnExceptionsState(PauseOnExceptionsState pause)
     m_pauseOnExceptionsState = pause;
 }
 
-void ScriptDebugServer::pause()
+void ScriptDebugServer::setPauseOnNextStatement(bool pause)
 {
-    m_pauseOnNextStatement = true;
+    m_pauseOnNextStatement = pause;
 }
 
 void ScriptDebugServer::breakProgram()
index 432fe9a..3172c65 100644 (file)
@@ -78,7 +78,7 @@ public:
     PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; }
     void setPauseOnExceptionsState(PauseOnExceptionsState);
 
-    void pause();
+    void setPauseOnNextStatement(bool pause);
     void breakProgram();
     void continueProgram();
     void stepIntoStatement();
index 3f1a0c5..7a8dbf7 100644 (file)
@@ -225,10 +225,14 @@ void ScriptDebugServer::setPauseOnExceptionsState(PauseOnExceptionsState pauseOn
     setPauseOnExceptionsFunction->Call(m_debuggerScript.get(), 1, argv);
 }
 
-void ScriptDebugServer::pause()
+void ScriptDebugServer::setPauseOnNextStatement(bool pause)
 {
-    if (!m_pausedPage)
+    if (m_pausedPage)
+        return;
+    if (pause)
         v8::Debug::DebugBreak();
+    else
+        v8::Debug::CancelDebugBreak();
 }
 
 void ScriptDebugServer::breakProgram()
index d1fd71f..5c5d6c6 100644 (file)
@@ -70,7 +70,7 @@ public:
     PauseOnExceptionsState pauseOnExceptionsState();
     void setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExceptionsState);
 
-    void pause();
+    void setPauseOnNextStatement(bool pause);
     void breakProgram();
     void continueProgram();
     void stepIntoStatement();
index 53395a8..68666a0 100644 (file)
@@ -53,7 +53,7 @@
 #include "Frame.h"
 #include "FrameView.h"
 #include "HTMLNames.h"
-#include "InspectorTimelineAgent.h"
+#include "InspectorInstrumentation.h"
 #include "KeyboardEvent.h"
 #include "LabelsNodeList.h"
 #include "Logging.h"
@@ -2577,23 +2577,6 @@ bool Node::dispatchEvent(PassRefPtr<Event> prpEvent)
     return dispatchGenericEvent(event.release());
 }
 
-static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, Vector<RefPtr<ContainerNode> >& ancestors)
-{
-    if (window && window->hasEventListeners(eventType))
-        return true;
-
-    if (node->hasEventListeners(eventType))
-        return true;
-
-    for (size_t i = 0; i < ancestors.size(); i++) {
-        ContainerNode* ancestor = ancestors[i].get();
-        if (ancestor->hasEventListeners(eventType))
-            return true;
-    }
-
-   return false;    
-}
-
 bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
 {
     RefPtr<Event> event(prpEvent);
@@ -2619,15 +2602,7 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
             targetForWindowEvents = static_cast<Document*>(topLevelContainer)->domWindow();
     }
 
-#if ENABLE(INSPECTOR)
-    Page* inspectedPage = InspectorTimelineAgent::instanceCount() ? document()->page() : 0;
-    if (inspectedPage) {
-        if (InspectorTimelineAgent* timelineAgent = eventHasListeners(event->type(), targetForWindowEvents, this, ancestors) ? inspectedPage->inspectorTimelineAgent() : 0)
-            timelineAgent->willDispatchEvent(*event);
-        else
-            inspectedPage = 0;
-    }
-#endif
+    int instrumentationCookie = InspectorInstrumentation::instrumentWillDispatchEvent(document(), *event, targetForWindowEvents, this, ancestors);
 
     // Give the target node a chance to do some work before DOM event handlers get a crack.
     void* data = preDispatchEventHandler(event.get());
@@ -2709,11 +2684,8 @@ doneDispatching:
     }
 
 doneWithDefault:
-#if ENABLE(INSPECTOR)
-    if (inspectedPage)
-        if (InspectorTimelineAgent* timelineAgent = inspectedPage->inspectorTimelineAgent())
-            timelineAgent->didDispatchEvent();
-#endif
+
+    InspectorInstrumentation::instrumentDidDispatchEvent(document(), instrumentationCookie);
 
     return !event->defaultPrevented();
 }
index b5cff8d..f29c0de 100644 (file)
@@ -132,6 +132,9 @@ static const char* const pauseOnExceptionsStateStateName = "pauseOnExceptionsSta
 
 static const char* const inspectorAttachedHeightName = "inspectorAttachedHeight";
 
+static const char* const xhrNativeBreakpointType = "XHR";
+static const char* const eventListenerNativeBreakpointType = "EventListener";
+
 const char* const InspectorController::ElementsPanel = "elements";
 const char* const InspectorController::ConsolePanel = "console";
 const char* const InspectorController::ScriptsPanel = "scripts";
@@ -778,15 +781,22 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
 
         m_times.clear();
         m_counts.clear();
+
 #if ENABLE(JAVASCRIPT_DEBUGGER)
         if (m_debuggerAgent)
             m_debuggerAgent->clearForPageNavigation();
 
+        m_nativeBreakpoints.clear();
+        m_eventListenerBreakpoints.clear();
+        m_eventNameToBreakpointCount.clear();
         m_XHRBreakpoints.clear();
+        m_lastBreakpointId = 0;
 #endif
+
 #if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
         m_profilerAgent->resetState();
 #endif
+
         // unbindAllResources should be called before database and DOM storage
         // resources are cleared so that it has a chance to unbind them.
         unbindAllResources();
@@ -1675,21 +1685,57 @@ void InspectorController::setNativeBreakpoint(PassRefPtr<InspectorObject> breakp
     String type;
     if (!breakpoint->getString("type", &type))
         return;
-    if (type == "XHR") {
-        RefPtr<InspectorObject> condition = breakpoint->getObject("condition");
-        if (!condition)
-            return;
+    RefPtr<InspectorObject> condition = breakpoint->getObject("condition");
+    if (!condition)
+        return;
+    if (type == xhrNativeBreakpointType) {
         String url;
         if (!condition->getString("url", &url))
             return;
         *breakpointId = ++m_lastBreakpointId;
+        m_nativeBreakpoints.set(*breakpointId, "XHR");
         m_XHRBreakpoints.set(*breakpointId, url);
+    } else if (type == eventListenerNativeBreakpointType) {
+        String eventName;
+        if (!condition->getString("eventName", &eventName))
+            return;
+        *breakpointId = ++m_lastBreakpointId;
+        m_nativeBreakpoints.set(*breakpointId, "EventListener");
+        m_eventListenerBreakpoints.set(*breakpointId, eventName);
+        HashMap<String, unsigned int>::iterator it = m_eventNameToBreakpointCount.find(eventName);
+        if (it == m_eventNameToBreakpointCount.end())
+            m_eventNameToBreakpointCount.set(eventName, 1);
+        else
+            it->second += 1;
     }
 }
 
 void InspectorController::removeNativeBreakpoint(unsigned int breakpointId)
 {
-    m_XHRBreakpoints.remove(breakpointId);
+    String type = m_nativeBreakpoints.take(breakpointId);
+    if (type == xhrNativeBreakpointType)
+        m_XHRBreakpoints.remove(breakpointId);
+    else if (type == eventListenerNativeBreakpointType) {
+        String eventName = m_eventListenerBreakpoints.take(breakpointId);
+        HashMap<String, unsigned int>::iterator it = m_eventNameToBreakpointCount.find(eventName);
+        it->second -= 1;
+        if (!it->second)
+            m_eventNameToBreakpointCount.remove(it);
+    }
+}
+
+bool InspectorController::shouldBreakOnEvent(const String& eventName)
+{
+    return m_eventNameToBreakpointCount.contains(eventName);
+}
+
+bool InspectorController::shouldBreakOnXMLHttpRequest(const String& url)
+{
+    for (HashMap<unsigned int, String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) {
+        if (url.contains(it->second))
+            return true;
+    }
+    return false;
 }
 
 #endif
@@ -2100,26 +2146,6 @@ void InspectorController::reloadPage()
     m_inspectedPage->mainFrame()->redirectScheduler()->scheduleRefresh(true);
 }
 
-void InspectorController::instrumentWillSendXMLHttpRequest(const KURL& url)
-{
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-    if (m_debuggerAgent) {
-        if (!m_XHRBreakpoints.size())
-            return;
-        for (HashMap<unsigned int, String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) {
-            if (!url.string().contains(it->second))
-                continue;
-            RefPtr<InspectorObject> eventData = InspectorObject::create();
-            eventData->setString("type", "XHR");
-            eventData->setString("url", url);
-            m_debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
-            break;
-        }
-    }
-#endif
-}
-
-
 } // namespace WebCore
 
 #endif // ENABLE(INSPECTOR)
index 5616e02..41a030b 100644 (file)
@@ -261,7 +261,6 @@ public:
 
     void setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, unsigned int* breakpointId);
     void removeNativeBreakpoint(unsigned int breakpointId);
-
 #endif
 
     void evaluateForTestInFrontend(long testCallId, const String& script);
@@ -298,9 +297,11 @@ private:
     void releaseFrontendLifetimeAgents();
 
 #if ENABLE(JAVASCRIPT_DEBUGGER)
-
     void toggleRecordButton(bool);
     void enableDebuggerFromFrontend(bool always);
+
+    bool shouldBreakOnEvent(const String& eventName);
+    bool shouldBreakOnXMLHttpRequest(const String&);
 #endif
 #if ENABLE(DATABASE)
     void selectDatabase(Database* database);
@@ -329,8 +330,6 @@ private:
 
     void didEvaluateForTestInFrontend(long callId, const String& jsonResult);
 
-    void instrumentWillSendXMLHttpRequest(const KURL&);
-
 #if ENABLE(JAVASCRIPT_DEBUGGER)
     friend class InspectorDebuggerAgent;
     String breakpointsSettingKey();
@@ -392,6 +391,9 @@ 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_eventNameToBreakpointCount;
     HashMap<unsigned int, String> m_XHRBreakpoints;
     unsigned int m_lastBreakpointId;
 
index 4964c09..986e9c0 100644 (file)
@@ -57,8 +57,6 @@ PassOwnPtr<InspectorDebuggerAgent> InspectorDebuggerAgent::create(InspectorContr
     return agent.release();
 }
 
-InspectorDebuggerAgent* InspectorDebuggerAgent::s_debuggerAgentOnBreakpoint = 0;
-
 InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorController, InspectorFrontend* frontend)
     : m_inspectorController(inspectorController)
     , m_frontend(frontend)
@@ -71,9 +69,6 @@ InspectorDebuggerAgent::~InspectorDebuggerAgent()
 {
     ScriptDebugServer::shared().removeListener(this, m_inspectorController->inspectedPage());
     m_pausedScriptState = 0;
-
-    if (this == s_debuggerAgentOnBreakpoint)
-        s_debuggerAgentOnBreakpoint = 0;
 }
 
 bool InspectorDebuggerAgent::isDebuggerAlwaysEnabled()
@@ -147,9 +142,23 @@ void InspectorDebuggerAgent::getScriptSource(const String& sourceID, String* scr
     *scriptSource = m_scriptIDToContent.get(sourceID);
 }
 
+void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr<InspectorValue> data)
+{
+    m_breakProgramDetails = InspectorObject::create();
+    m_breakProgramDetails->setNumber("eventType", type);
+    m_breakProgramDetails->setValue("eventData", data);
+    ScriptDebugServer::shared().setPauseOnNextStatement(true);
+}
+
+void InspectorDebuggerAgent::cancelPauseOnNextStatement()
+{
+    m_breakProgramDetails = 0;
+    ScriptDebugServer::shared().setPauseOnNextStatement(false);
+}
+
 void InspectorDebuggerAgent::pause()
 {
-    ScriptDebugServer::shared().pause();
+    schedulePauseOnNextStatement(JavaScriptPauseEventType, InspectorObject::create());
 }
 
 void InspectorDebuggerAgent::resume()
@@ -305,6 +314,7 @@ void InspectorDebuggerAgent::didPause(ScriptState* scriptState)
 void InspectorDebuggerAgent::didContinue()
 {
     m_pausedScriptState = 0;
+    m_breakProgramDetails = 0;
     m_frontend->resumedScript();
 }
 
@@ -313,14 +323,7 @@ void InspectorDebuggerAgent::breakProgram(DebuggerEventType type, PassRefPtr<Ins
     m_breakProgramDetails = InspectorObject::create();
     m_breakProgramDetails->setNumber("eventType", type);
     m_breakProgramDetails->setValue("eventData", data);
-    s_debuggerAgentOnBreakpoint = this;
-
     ScriptDebugServer::shared().breakProgram();
-    if (!s_debuggerAgentOnBreakpoint)
-        return;
-
-    s_debuggerAgentOnBreakpoint = 0;
-    m_breakProgramDetails = 0;
 }
 
 } // namespace WebCore
index 8a5379d..5230b88 100644 (file)
@@ -47,6 +47,7 @@ class InspectorObject;
 class InspectorValue;
 
 enum DebuggerEventType {
+    JavaScriptPauseEventType,
     DOMBreakpointDebuggerEventType,
     NativeBreakpointDebuggerEventType
 };
@@ -66,8 +67,10 @@ public:
     void editScriptSource(const String& sourceID, const String& newContent, bool* success, String* result, RefPtr<InspectorValue>* newCallFrames);
     void getScriptSource(const String& sourceID, String* scriptSource);
 
-    void pause();
+    void schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr<InspectorValue> data);
+    void cancelPauseOnNextStatement();
     void breakProgram(DebuggerEventType type, PassRefPtr<InspectorValue> data);
+    void pause();
     void resume();
     void stepOverStatement();
     void stepIntoStatement();
index fbbcce4..fb5768a 100644 (file)
 
 #if ENABLE(INSPECTOR)
 
+#include "DOMWindow.h"
+#include "Event.h"
 #include "InspectorController.h"
 #include "InspectorDOMAgent.h"
 #include "InspectorDebuggerAgent.h"
+#include "InspectorTimelineAgent.h"
 
 namespace WebCore {
 
 int InspectorInstrumentation::s_frontendCounter = 0;
 
+static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors)
+{
+    if (window && window->hasEventListeners(eventType))
+        return true;
+
+    if (node->hasEventListeners(eventType))
+        return true;
+
+    for (size_t i = 0; i < ancestors.size(); i++) {
+        ContainerNode* ancestor = ancestors[i].get();
+        if (ancestor->hasEventListeners(eventType))
+            return true;
+    }
+
+    return false;
+}
+
 void InspectorInstrumentation::willInsertDOMNodeImpl(InspectorController* inspectorController, Node* node, Node* parent)
 {
 #if ENABLE(JAVASCRIPT_DEBUGGER)
@@ -124,11 +144,65 @@ void InspectorInstrumentation::characterDataModifiedImpl(InspectorController* in
         domAgent->characterDataModified(characterData);
 }
 
-void InspectorInstrumentation::instrumentWillSendXMLHttpRequestImpl(InspectorController* inspectorController, const KURL& url)
+int InspectorInstrumentation::instrumentWillDispatchEventImpl(InspectorController* inspectorController, const Event& event, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors)
+{
+    int instrumentationCookie = 0;
+
+    if (!inspectorController->hasFrontend())
+        return instrumentationCookie;
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+    if (InspectorDebuggerAgent* debuggerAgent = inspectorController->m_debuggerAgent.get()) {
+        if (inspectorController->shouldBreakOnEvent(event.type())) {
+            RefPtr<InspectorObject> eventData = InspectorObject::create();
+            eventData->setString("type", "EventListener");
+            eventData->setString("eventName", event.type());
+            debuggerAgent->schedulePauseOnNextStatement(NativeBreakpointDebuggerEventType, eventData);
+        }
+    }
+#endif
+
+    InspectorTimelineAgent* timelineAgent = inspectorController->m_timelineAgent.get();
+    if (timelineAgent && eventHasListeners(event.type(), window, node, ancestors)) {
+        timelineAgent->willDispatchEvent(event);
+        instrumentationCookie = timelineAgent->id();
+    }
+    return instrumentationCookie;
+}
+
+void InspectorInstrumentation::instrumentDidDispatchEventImpl(InspectorController* inspectorController, int instrumentationCookie)
 {
     if (!inspectorController->hasFrontend())
         return;
-    inspectorController->instrumentWillSendXMLHttpRequest(url);
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+    if (InspectorDebuggerAgent* debuggerAgent = inspectorController->m_debuggerAgent.get())
+        debuggerAgent->cancelPauseOnNextStatement();
+#endif
+
+    InspectorTimelineAgent* timelineAgent = inspectorController->m_timelineAgent.get();
+    if (timelineAgent && timelineAgent->id() == instrumentationCookie)
+        timelineAgent->didDispatchEvent();
+}
+
+void InspectorInstrumentation::instrumentWillSendXMLHttpRequestImpl(InspectorController* inspectorController, const String& url)
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+    if (!inspectorController->hasFrontend())
+        return;
+
+    InspectorDebuggerAgent* debuggerAgent = inspectorController->m_debuggerAgent.get();
+    if (!debuggerAgent)
+        return;
+
+    if (!inspectorController->shouldBreakOnXMLHttpRequest(url))
+        return;
+
+    RefPtr<InspectorObject> eventData = InspectorObject::create();
+    eventData->setString("type", "XHR");
+    eventData->setString("url", url);
+    debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
+#endif
 }
 
 } // namespace WebCore
index 4d804cd..5b66a2e 100644 (file)
@@ -40,7 +40,6 @@ namespace WebCore {
 class CharacterData;
 class Element;
 class InspectorController;
-class KURL;
 class Node;
 
 class InspectorInstrumentation {
@@ -52,7 +51,10 @@ public:
     static void didModifyDOMAttr(Document*, Element*);
     static void characterDataModified(Document*, CharacterData*);
 
-    static void instrumentWillSendXMLHttpRequest(ScriptExecutionContext*, const KURL&);
+    static int instrumentWillDispatchEvent(Document*, const Event&, DOMWindow*, Node*, const Vector<RefPtr<ContainerNode> >& ancestors);
+    static void instrumentDidDispatchEvent(Document*, int instrumentationCookie);
+
+    static void instrumentWillSendXMLHttpRequest(ScriptExecutionContext*, const String&);
 
 #if ENABLE(INSPECTOR)
     static void frontendCreated() { s_frontendCounter += 1; }
@@ -70,7 +72,10 @@ private:
     static void didModifyDOMAttrImpl(InspectorController*, Element*);
     static void characterDataModifiedImpl(InspectorController*, CharacterData*);
 
-    static void instrumentWillSendXMLHttpRequestImpl(InspectorController*, const KURL&);
+    static int instrumentWillDispatchEventImpl(InspectorController*, const Event&, DOMWindow*, Node*, const Vector<RefPtr<ContainerNode> >& ancestors);
+    static void instrumentDidDispatchEventImpl(InspectorController*, int instrumentationCookie);
+
+    static void instrumentWillSendXMLHttpRequestImpl(InspectorController*, const String&);
 
     static InspectorController* inspectorControllerForScriptExecutionContext(ScriptExecutionContext*);
     static InspectorController* inspectorControllerForDocument(Document*);
@@ -130,7 +135,24 @@ inline void InspectorInstrumentation::characterDataModified(Document* document,
 #endif
 }
 
-inline void InspectorInstrumentation::instrumentWillSendXMLHttpRequest(ScriptExecutionContext* context, const KURL& url)
+inline int InspectorInstrumentation::instrumentWillDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors)
+{
+#if ENABLE(INSPECTOR)
+    if (InspectorController* inspectorController = inspectorControllerForDocument(document))
+        return instrumentWillDispatchEventImpl(inspectorController, event, window, node, ancestors);
+#endif
+    return 0;
+}
+
+inline void InspectorInstrumentation::instrumentDidDispatchEvent(Document* document, int instrumentationCookie)
+{
+#if ENABLE(INSPECTOR)
+    if (InspectorController* inspectorController = inspectorControllerForDocument(document))
+        instrumentDidDispatchEventImpl(inspectorController, instrumentationCookie);
+#endif
+}
+
+inline void InspectorInstrumentation::instrumentWillSendXMLHttpRequest(ScriptExecutionContext* context, const String& url)
 {
 #if ENABLE(INSPECTOR)
     if (InspectorController* inspectorController = inspectorControllerForScriptExecutionContext(context))
index 656f2f3..1dd86ad 100644 (file)
 namespace WebCore {
 
 int InspectorTimelineAgent::s_instanceCount = 0;
+int InspectorTimelineAgent::s_id = 0;
 
 InspectorTimelineAgent::InspectorTimelineAgent(InspectorFrontend* frontend)
     : m_frontend(frontend)
+    , m_id(++s_id)
 {
     ++s_instanceCount;
     ScriptGCEvent::addEventListener(this);
index 261ae3a..9969a14 100644 (file)
@@ -77,6 +77,8 @@ public:
     InspectorTimelineAgent(InspectorFrontend* frontend);
     ~InspectorTimelineAgent();
 
+    int id() const { return m_id; }
+
     void reset();
     void resetFrontendProxyObject(InspectorFrontend*);
 
@@ -156,6 +158,8 @@ private:
 
     Vector<TimelineRecordEntry> m_recordStack;
     static int s_instanceCount;
+    static int s_id;
+    const int m_id;
     struct GCEvent {
         GCEvent(double startTime, double endTime, size_t collectedBytes)
             : startTime(startTime), endTime(endTime), collectedBytes(collectedBytes)
index 6212ea1..a0e5e3b 100644 (file)
@@ -29,8 +29,9 @@ WebInspector.CallStackSidebarPane = function()
 }
 
 WebInspector.CallStackSidebarPane.DebuggerEventType = {
-    DOMBreakpoint: 0,
-    NativeBreakpoint: 1
+    JavaScriptPause: 0,
+    DOMBreakpoint: 1,
+    NativeBreakpoint: 2
 };
 
 WebInspector.CallStackSidebarPane.prototype = {