Changeset 69014 in webkit
- Timestamp:
- Oct 4, 2010 7:52:38 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r69010 r69014 1 2010-10-04 podivilov@chromium.org <podivilov@chromium.org> 2 3 Reviewed by Yury Semikhatsky. 4 5 Web Inspector: implement pausing on event listeners (back-end part) 6 https://bugs.webkit.org/show_bug.cgi?id=46624 7 8 * bindings/js/ScriptDebugServer.cpp: 9 (WebCore::ScriptDebugServer::setPauseOnNextStatement): 10 * bindings/js/ScriptDebugServer.h: 11 * bindings/v8/ScriptDebugServer.cpp: 12 (WebCore::ScriptDebugServer::setPauseOnNextStatement): 13 * bindings/v8/ScriptDebugServer.h: 14 * dom/Node.cpp: 15 (WebCore::Node::dispatchGenericEvent): 16 * inspector/InspectorController.cpp: 17 (WebCore::InspectorController::didCommitLoad): 18 (WebCore::InspectorController::setNativeBreakpoint): 19 (WebCore::InspectorController::removeNativeBreakpoint): 20 (WebCore::InspectorController::shouldBreakOnEvent): 21 (WebCore::InspectorController::shouldBreakOnXMLHttpRequest): 22 * inspector/InspectorController.h: 23 * inspector/InspectorDebuggerAgent.cpp: 24 (WebCore::InspectorDebuggerAgent::~InspectorDebuggerAgent): 25 (WebCore::InspectorDebuggerAgent::schedulePauseOnNextStatement): 26 (WebCore::InspectorDebuggerAgent::cancelPauseOnNextStatement): 27 (WebCore::InspectorDebuggerAgent::pause): 28 (WebCore::InspectorDebuggerAgent::didContinue): 29 (WebCore::InspectorDebuggerAgent::breakProgram): 30 * inspector/InspectorDebuggerAgent.h: 31 * inspector/InspectorInstrumentation.cpp: 32 (WebCore::eventHasListeners): 33 (WebCore::InspectorInstrumentation::instrumentWillDispatchEventImpl): 34 (WebCore::InspectorInstrumentation::instrumentDidDispatchEventImpl): 35 (WebCore::InspectorInstrumentation::instrumentWillSendXMLHttpRequestImpl): 36 * inspector/InspectorInstrumentation.h: 37 (WebCore::InspectorInstrumentation::instrumentWillDispatchEvent): 38 (WebCore::InspectorInstrumentation::instrumentDidDispatchEvent): 39 (WebCore::InspectorInstrumentation::instrumentWillSendXMLHttpRequest): 40 * inspector/InspectorTimelineAgent.cpp: 41 (WebCore::InspectorTimelineAgent::InspectorTimelineAgent): 42 * inspector/InspectorTimelineAgent.h: 43 (WebCore::InspectorTimelineAgent::id): 44 * inspector/front-end/CallStackSidebarPane.js: 45 1 46 2010-10-04 Pavel Feldman <pfeldman@chromium.org> 2 47 -
trunk/WebCore/bindings/js/ScriptDebugServer.cpp
r67432 r69014 201 201 } 202 202 203 void ScriptDebugServer:: pause()204 { 205 m_pauseOnNextStatement = true;203 void ScriptDebugServer::setPauseOnNextStatement(bool pause) 204 { 205 m_pauseOnNextStatement = pause; 206 206 } 207 207 -
trunk/WebCore/bindings/js/ScriptDebugServer.h
r65731 r69014 79 79 void setPauseOnExceptionsState(PauseOnExceptionsState); 80 80 81 void pause();81 void setPauseOnNextStatement(bool pause); 82 82 void breakProgram(); 83 83 void continueProgram(); -
trunk/WebCore/bindings/v8/ScriptDebugServer.cpp
r66013 r69014 226 226 } 227 227 228 void ScriptDebugServer::pause() 229 { 230 if (!m_pausedPage) 228 void ScriptDebugServer::setPauseOnNextStatement(bool pause) 229 { 230 if (m_pausedPage) 231 return; 232 if (pause) 231 233 v8::Debug::DebugBreak(); 234 else 235 v8::Debug::CancelDebugBreak(); 232 236 } 233 237 -
trunk/WebCore/bindings/v8/ScriptDebugServer.h
r66013 r69014 71 71 void setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExceptionsState); 72 72 73 void pause();73 void setPauseOnNextStatement(bool pause); 74 74 void breakProgram(); 75 75 void continueProgram(); -
trunk/WebCore/dom/Node.cpp
r68541 r69014 54 54 #include "FrameView.h" 55 55 #include "HTMLNames.h" 56 #include "Inspector TimelineAgent.h"56 #include "InspectorInstrumentation.h" 57 57 #include "KeyboardEvent.h" 58 58 #include "LabelsNodeList.h" … … 2578 2578 } 2579 2579 2580 static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, Vector<RefPtr<ContainerNode> >& ancestors)2581 {2582 if (window && window->hasEventListeners(eventType))2583 return true;2584 2585 if (node->hasEventListeners(eventType))2586 return true;2587 2588 for (size_t i = 0; i < ancestors.size(); i++) {2589 ContainerNode* ancestor = ancestors[i].get();2590 if (ancestor->hasEventListeners(eventType))2591 return true;2592 }2593 2594 return false;2595 }2596 2597 2580 bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent) 2598 2581 { … … 2620 2603 } 2621 2604 2622 #if ENABLE(INSPECTOR) 2623 Page* inspectedPage = InspectorTimelineAgent::instanceCount() ? document()->page() : 0; 2624 if (inspectedPage) { 2625 if (InspectorTimelineAgent* timelineAgent = eventHasListeners(event->type(), targetForWindowEvents, this, ancestors) ? inspectedPage->inspectorTimelineAgent() : 0) 2626 timelineAgent->willDispatchEvent(*event); 2627 else 2628 inspectedPage = 0; 2629 } 2630 #endif 2605 int instrumentationCookie = InspectorInstrumentation::instrumentWillDispatchEvent(document(), *event, targetForWindowEvents, this, ancestors); 2631 2606 2632 2607 // Give the target node a chance to do some work before DOM event handlers get a crack. … … 2710 2685 2711 2686 doneWithDefault: 2712 #if ENABLE(INSPECTOR) 2713 if (inspectedPage) 2714 if (InspectorTimelineAgent* timelineAgent = inspectedPage->inspectorTimelineAgent()) 2715 timelineAgent->didDispatchEvent(); 2716 #endif 2687 2688 InspectorInstrumentation::instrumentDidDispatchEvent(document(), instrumentationCookie); 2717 2689 2718 2690 return !event->defaultPrevented(); -
trunk/WebCore/inspector/InspectorController.cpp
r68781 r69014 133 133 static const char* const inspectorAttachedHeightName = "inspectorAttachedHeight"; 134 134 135 static const char* const xhrNativeBreakpointType = "XHR"; 136 static const char* const eventListenerNativeBreakpointType = "EventListener"; 137 135 138 const char* const InspectorController::ElementsPanel = "elements"; 136 139 const char* const InspectorController::ConsolePanel = "console"; … … 779 782 m_times.clear(); 780 783 m_counts.clear(); 784 781 785 #if ENABLE(JAVASCRIPT_DEBUGGER) 782 786 if (m_debuggerAgent) 783 787 m_debuggerAgent->clearForPageNavigation(); 784 788 789 m_nativeBreakpoints.clear(); 790 m_eventListenerBreakpoints.clear(); 791 m_eventNameToBreakpointCount.clear(); 785 792 m_XHRBreakpoints.clear(); 786 #endif 793 m_lastBreakpointId = 0; 794 #endif 795 787 796 #if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC) 788 797 m_profilerAgent->resetState(); 789 798 #endif 799 790 800 // unbindAllResources should be called before database and DOM storage 791 801 // resources are cleared so that it has a chance to unbind them. … … 1676 1686 if (!breakpoint->getString("type", &type)) 1677 1687 return; 1678 if (type == "XHR") {1679 RefPtr<InspectorObject> condition = breakpoint->getObject("condition");1680 if (!condition)1681 return;1688 RefPtr<InspectorObject> condition = breakpoint->getObject("condition"); 1689 if (!condition) 1690 return; 1691 if (type == xhrNativeBreakpointType) { 1682 1692 String url; 1683 1693 if (!condition->getString("url", &url)) 1684 1694 return; 1685 1695 *breakpointId = ++m_lastBreakpointId; 1696 m_nativeBreakpoints.set(*breakpointId, "XHR"); 1686 1697 m_XHRBreakpoints.set(*breakpointId, url); 1698 } else if (type == eventListenerNativeBreakpointType) { 1699 String eventName; 1700 if (!condition->getString("eventName", &eventName)) 1701 return; 1702 *breakpointId = ++m_lastBreakpointId; 1703 m_nativeBreakpoints.set(*breakpointId, "EventListener"); 1704 m_eventListenerBreakpoints.set(*breakpointId, eventName); 1705 HashMap<String, unsigned int>::iterator it = m_eventNameToBreakpointCount.find(eventName); 1706 if (it == m_eventNameToBreakpointCount.end()) 1707 m_eventNameToBreakpointCount.set(eventName, 1); 1708 else 1709 it->second += 1; 1687 1710 } 1688 1711 } … … 1690 1713 void InspectorController::removeNativeBreakpoint(unsigned int breakpointId) 1691 1714 { 1692 m_XHRBreakpoints.remove(breakpointId); 1715 String type = m_nativeBreakpoints.take(breakpointId); 1716 if (type == xhrNativeBreakpointType) 1717 m_XHRBreakpoints.remove(breakpointId); 1718 else if (type == eventListenerNativeBreakpointType) { 1719 String eventName = m_eventListenerBreakpoints.take(breakpointId); 1720 HashMap<String, unsigned int>::iterator it = m_eventNameToBreakpointCount.find(eventName); 1721 it->second -= 1; 1722 if (!it->second) 1723 m_eventNameToBreakpointCount.remove(it); 1724 } 1725 } 1726 1727 bool InspectorController::shouldBreakOnEvent(const String& eventName) 1728 { 1729 return m_eventNameToBreakpointCount.contains(eventName); 1730 } 1731 1732 bool InspectorController::shouldBreakOnXMLHttpRequest(const String& url) 1733 { 1734 for (HashMap<unsigned int, String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) { 1735 if (url.contains(it->second)) 1736 return true; 1737 } 1738 return false; 1693 1739 } 1694 1740 … … 2101 2147 } 2102 2148 2103 void InspectorController::instrumentWillSendXMLHttpRequest(const KURL& url)2104 {2105 #if ENABLE(JAVASCRIPT_DEBUGGER)2106 if (m_debuggerAgent) {2107 if (!m_XHRBreakpoints.size())2108 return;2109 for (HashMap<unsigned int, String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) {2110 if (!url.string().contains(it->second))2111 continue;2112 RefPtr<InspectorObject> eventData = InspectorObject::create();2113 eventData->setString("type", "XHR");2114 eventData->setString("url", url);2115 m_debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);2116 break;2117 }2118 }2119 #endif2120 }2121 2122 2123 2149 } // namespace WebCore 2124 2150 -
trunk/WebCore/inspector/InspectorController.h
r68767 r69014 262 262 void setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, unsigned int* breakpointId); 263 263 void removeNativeBreakpoint(unsigned int breakpointId); 264 265 264 #endif 266 265 … … 299 298 300 299 #if ENABLE(JAVASCRIPT_DEBUGGER) 301 302 300 void toggleRecordButton(bool); 303 301 void enableDebuggerFromFrontend(bool always); 302 303 bool shouldBreakOnEvent(const String& eventName); 304 bool shouldBreakOnXMLHttpRequest(const String&); 304 305 #endif 305 306 #if ENABLE(DATABASE) … … 329 330 330 331 void didEvaluateForTestInFrontend(long callId, const String& jsonResult); 331 332 void instrumentWillSendXMLHttpRequest(const KURL&);333 332 334 333 #if ENABLE(JAVASCRIPT_DEBUGGER) … … 393 392 OwnPtr<InspectorDebuggerAgent> m_debuggerAgent; 394 393 394 HashMap<unsigned int, String> m_nativeBreakpoints; 395 HashMap<unsigned int, String> m_eventListenerBreakpoints; 396 HashMap<String, unsigned int> m_eventNameToBreakpointCount; 395 397 HashMap<unsigned int, String> m_XHRBreakpoints; 396 398 unsigned int m_lastBreakpointId; -
trunk/WebCore/inspector/InspectorDebuggerAgent.cpp
r68635 r69014 58 58 } 59 59 60 InspectorDebuggerAgent* InspectorDebuggerAgent::s_debuggerAgentOnBreakpoint = 0;61 62 60 InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorController, InspectorFrontend* frontend) 63 61 : m_inspectorController(inspectorController) … … 72 70 ScriptDebugServer::shared().removeListener(this, m_inspectorController->inspectedPage()); 73 71 m_pausedScriptState = 0; 74 75 if (this == s_debuggerAgentOnBreakpoint)76 s_debuggerAgentOnBreakpoint = 0;77 72 } 78 73 … … 148 143 } 149 144 145 void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr<InspectorValue> data) 146 { 147 m_breakProgramDetails = InspectorObject::create(); 148 m_breakProgramDetails->setNumber("eventType", type); 149 m_breakProgramDetails->setValue("eventData", data); 150 ScriptDebugServer::shared().setPauseOnNextStatement(true); 151 } 152 153 void InspectorDebuggerAgent::cancelPauseOnNextStatement() 154 { 155 m_breakProgramDetails = 0; 156 ScriptDebugServer::shared().setPauseOnNextStatement(false); 157 } 158 150 159 void InspectorDebuggerAgent::pause() 151 160 { 152 ScriptDebugServer::shared().pause();161 schedulePauseOnNextStatement(JavaScriptPauseEventType, InspectorObject::create()); 153 162 } 154 163 … … 306 315 { 307 316 m_pausedScriptState = 0; 317 m_breakProgramDetails = 0; 308 318 m_frontend->resumedScript(); 309 319 } … … 314 324 m_breakProgramDetails->setNumber("eventType", type); 315 325 m_breakProgramDetails->setValue("eventData", data); 316 s_debuggerAgentOnBreakpoint = this;317 318 326 ScriptDebugServer::shared().breakProgram(); 319 if (!s_debuggerAgentOnBreakpoint)320 return;321 322 s_debuggerAgentOnBreakpoint = 0;323 m_breakProgramDetails = 0;324 327 } 325 328 -
trunk/WebCore/inspector/InspectorDebuggerAgent.h
r68635 r69014 48 48 49 49 enum DebuggerEventType { 50 JavaScriptPauseEventType, 50 51 DOMBreakpointDebuggerEventType, 51 52 NativeBreakpointDebuggerEventType … … 67 68 void getScriptSource(const String& sourceID, String* scriptSource); 68 69 70 void schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr<InspectorValue> data); 71 void cancelPauseOnNextStatement(); 72 void breakProgram(DebuggerEventType type, PassRefPtr<InspectorValue> data); 69 73 void pause(); 70 void breakProgram(DebuggerEventType type, PassRefPtr<InspectorValue> data);71 74 void resume(); 72 75 void stepOverStatement(); -
trunk/WebCore/inspector/InspectorInstrumentation.cpp
r68767 r69014 34 34 #if ENABLE(INSPECTOR) 35 35 36 #include "DOMWindow.h" 37 #include "Event.h" 36 38 #include "InspectorController.h" 37 39 #include "InspectorDOMAgent.h" 38 40 #include "InspectorDebuggerAgent.h" 41 #include "InspectorTimelineAgent.h" 39 42 40 43 namespace WebCore { 41 44 42 45 int InspectorInstrumentation::s_frontendCounter = 0; 46 47 static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors) 48 { 49 if (window && window->hasEventListeners(eventType)) 50 return true; 51 52 if (node->hasEventListeners(eventType)) 53 return true; 54 55 for (size_t i = 0; i < ancestors.size(); i++) { 56 ContainerNode* ancestor = ancestors[i].get(); 57 if (ancestor->hasEventListeners(eventType)) 58 return true; 59 } 60 61 return false; 62 } 43 63 44 64 void InspectorInstrumentation::willInsertDOMNodeImpl(InspectorController* inspectorController, Node* node, Node* parent) … … 125 145 } 126 146 127 void InspectorInstrumentation::instrumentWillSendXMLHttpRequestImpl(InspectorController* inspectorController, const KURL& url) 128 { 129 if (!inspectorController->hasFrontend()) 130 return; 131 inspectorController->instrumentWillSendXMLHttpRequest(url); 147 int InspectorInstrumentation::instrumentWillDispatchEventImpl(InspectorController* inspectorController, const Event& event, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors) 148 { 149 int instrumentationCookie = 0; 150 151 if (!inspectorController->hasFrontend()) 152 return instrumentationCookie; 153 154 #if ENABLE(JAVASCRIPT_DEBUGGER) 155 if (InspectorDebuggerAgent* debuggerAgent = inspectorController->m_debuggerAgent.get()) { 156 if (inspectorController->shouldBreakOnEvent(event.type())) { 157 RefPtr<InspectorObject> eventData = InspectorObject::create(); 158 eventData->setString("type", "EventListener"); 159 eventData->setString("eventName", event.type()); 160 debuggerAgent->schedulePauseOnNextStatement(NativeBreakpointDebuggerEventType, eventData); 161 } 162 } 163 #endif 164 165 InspectorTimelineAgent* timelineAgent = inspectorController->m_timelineAgent.get(); 166 if (timelineAgent && eventHasListeners(event.type(), window, node, ancestors)) { 167 timelineAgent->willDispatchEvent(event); 168 instrumentationCookie = timelineAgent->id(); 169 } 170 return instrumentationCookie; 171 } 172 173 void InspectorInstrumentation::instrumentDidDispatchEventImpl(InspectorController* inspectorController, int instrumentationCookie) 174 { 175 if (!inspectorController->hasFrontend()) 176 return; 177 178 #if ENABLE(JAVASCRIPT_DEBUGGER) 179 if (InspectorDebuggerAgent* debuggerAgent = inspectorController->m_debuggerAgent.get()) 180 debuggerAgent->cancelPauseOnNextStatement(); 181 #endif 182 183 InspectorTimelineAgent* timelineAgent = inspectorController->m_timelineAgent.get(); 184 if (timelineAgent && timelineAgent->id() == instrumentationCookie) 185 timelineAgent->didDispatchEvent(); 186 } 187 188 void InspectorInstrumentation::instrumentWillSendXMLHttpRequestImpl(InspectorController* inspectorController, const String& url) 189 { 190 #if ENABLE(JAVASCRIPT_DEBUGGER) 191 if (!inspectorController->hasFrontend()) 192 return; 193 194 InspectorDebuggerAgent* debuggerAgent = inspectorController->m_debuggerAgent.get(); 195 if (!debuggerAgent) 196 return; 197 198 if (!inspectorController->shouldBreakOnXMLHttpRequest(url)) 199 return; 200 201 RefPtr<InspectorObject> eventData = InspectorObject::create(); 202 eventData->setString("type", "XHR"); 203 eventData->setString("url", url); 204 debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData); 205 #endif 132 206 } 133 207 -
trunk/WebCore/inspector/InspectorInstrumentation.h
r68767 r69014 41 41 class Element; 42 42 class InspectorController; 43 class KURL;44 43 class Node; 45 44 … … 53 52 static void characterDataModified(Document*, CharacterData*); 54 53 55 static void instrumentWillSendXMLHttpRequest(ScriptExecutionContext*, const KURL&); 54 static int instrumentWillDispatchEvent(Document*, const Event&, DOMWindow*, Node*, const Vector<RefPtr<ContainerNode> >& ancestors); 55 static void instrumentDidDispatchEvent(Document*, int instrumentationCookie); 56 57 static void instrumentWillSendXMLHttpRequest(ScriptExecutionContext*, const String&); 56 58 57 59 #if ENABLE(INSPECTOR) … … 71 73 static void characterDataModifiedImpl(InspectorController*, CharacterData*); 72 74 73 static void instrumentWillSendXMLHttpRequestImpl(InspectorController*, const KURL&); 75 static int instrumentWillDispatchEventImpl(InspectorController*, const Event&, DOMWindow*, Node*, const Vector<RefPtr<ContainerNode> >& ancestors); 76 static void instrumentDidDispatchEventImpl(InspectorController*, int instrumentationCookie); 77 78 static void instrumentWillSendXMLHttpRequestImpl(InspectorController*, const String&); 74 79 75 80 static InspectorController* inspectorControllerForScriptExecutionContext(ScriptExecutionContext*); … … 131 136 } 132 137 133 inline void InspectorInstrumentation::instrumentWillSendXMLHttpRequest(ScriptExecutionContext* context, const KURL& url) 138 inline int InspectorInstrumentation::instrumentWillDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors) 139 { 140 #if ENABLE(INSPECTOR) 141 if (InspectorController* inspectorController = inspectorControllerForDocument(document)) 142 return instrumentWillDispatchEventImpl(inspectorController, event, window, node, ancestors); 143 #endif 144 return 0; 145 } 146 147 inline void InspectorInstrumentation::instrumentDidDispatchEvent(Document* document, int instrumentationCookie) 148 { 149 #if ENABLE(INSPECTOR) 150 if (InspectorController* inspectorController = inspectorControllerForDocument(document)) 151 instrumentDidDispatchEventImpl(inspectorController, instrumentationCookie); 152 #endif 153 } 154 155 inline void InspectorInstrumentation::instrumentWillSendXMLHttpRequest(ScriptExecutionContext* context, const String& url) 134 156 { 135 157 #if ENABLE(INSPECTOR) -
trunk/WebCore/inspector/InspectorTimelineAgent.cpp
r68779 r69014 46 46 47 47 int InspectorTimelineAgent::s_instanceCount = 0; 48 int InspectorTimelineAgent::s_id = 0; 48 49 49 50 InspectorTimelineAgent::InspectorTimelineAgent(InspectorFrontend* frontend) 50 51 : m_frontend(frontend) 52 , m_id(++s_id) 51 53 { 52 54 ++s_instanceCount; -
trunk/WebCore/inspector/InspectorTimelineAgent.h
r68779 r69014 77 77 InspectorTimelineAgent(InspectorFrontend* frontend); 78 78 ~InspectorTimelineAgent(); 79 80 int id() const { return m_id; } 79 81 80 82 void reset(); … … 157 159 Vector<TimelineRecordEntry> m_recordStack; 158 160 static int s_instanceCount; 161 static int s_id; 162 const int m_id; 159 163 struct GCEvent { 160 164 GCEvent(double startTime, double endTime, size_t collectedBytes) -
trunk/WebCore/inspector/front-end/CallStackSidebarPane.js
r68395 r69014 30 30 31 31 WebInspector.CallStackSidebarPane.DebuggerEventType = { 32 DOMBreakpoint: 0, 33 NativeBreakpoint: 1 32 JavaScriptPause: 0, 33 DOMBreakpoint: 1, 34 NativeBreakpoint: 2 34 35 }; 35 36
Note: See TracChangeset
for help on using the changeset viewer.