Title: [220036] trunk
Revision
220036
Author
[email protected]
Date
2017-07-28 17:33:12 -0700 (Fri, 28 Jul 2017)

Log Message

Web Inspector: capture an async stack trace when web content calls addEventListener
https://bugs.webkit.org/show_bug.cgi?id=174739
<rdar://problem/33468197>

Reviewed by Brian Burg.

Source/_javascript_Core:

Allow debugger agents to perform custom logic when asynchronous stack
trace data is cleared. For example, the PageDebuggerAgent would clear
its list of registered listeners for which call stacks have been recorded.

* inspector/agents/InspectorDebuggerAgent.cpp:
(Inspector::InspectorDebuggerAgent::clearAsyncStackTraceData):
* inspector/agents/InspectorDebuggerAgent.h:

Source/WebCore:

Test: inspector/debugger/async-stack-trace.html

Add instrumentation to EventTarget to support showing asynchronous
stack traces when the debugger breaks in a script event listener.

* dom/EventTarget.cpp:
(WebCore::EventTarget::addEventListener):
(WebCore::EventTarget::removeEventListener):
(WebCore::EventTarget::fireEventListeners):
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::didAddEventListenerImpl):
(WebCore::InspectorInstrumentation::willRemoveEventListenerImpl):
(WebCore::InspectorInstrumentation::willHandleEventImpl):
(WebCore::InspectorInstrumentation::didHandleEventImpl):
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::didAddEventListener):
(WebCore::InspectorInstrumentation::willRemoveEventListener):
(WebCore::InspectorInstrumentation::willHandleEvent):
(WebCore::InspectorInstrumentation::didHandleEvent):
* inspector/PageDebuggerAgent.cpp:
(WebCore::PageDebuggerAgent::didClearAsyncStackTraceData):
(WebCore::PageDebuggerAgent::didAddEventListener):
(WebCore::PageDebuggerAgent::willRemoveEventListener):
(WebCore::PageDebuggerAgent::willHandleEvent):
* inspector/PageDebuggerAgent.h:

LayoutTests:

Add test case checking that async stack traces are recorded for addEventListener.

* inspector/debugger/async-stack-trace-expected.txt:
* inspector/debugger/async-stack-trace.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (220035 => 220036)


--- trunk/LayoutTests/ChangeLog	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/LayoutTests/ChangeLog	2017-07-29 00:33:12 UTC (rev 220036)
@@ -1,3 +1,16 @@
+2017-07-28  Matt Baker  <[email protected]>
+
+        Web Inspector: capture an async stack trace when web content calls addEventListener
+        https://bugs.webkit.org/show_bug.cgi?id=174739
+        <rdar://problem/33468197>
+
+        Reviewed by Brian Burg.
+
+        Add test case checking that async stack traces are recorded for addEventListener.
+
+        * inspector/debugger/async-stack-trace-expected.txt:
+        * inspector/debugger/async-stack-trace.html:
+
 2017-07-28  Matt Rajca  <[email protected]>
 
         Don't add autoplay restrictions to media elements created in response to user gestures.

Modified: trunk/LayoutTests/inspector/debugger/async-stack-trace-expected.txt (220035 => 220036)


--- trunk/LayoutTests/inspector/debugger/async-stack-trace-expected.txt	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/LayoutTests/inspector/debugger/async-stack-trace-expected.txt	2017-07-29 00:33:12 UTC (rev 220036)
@@ -64,6 +64,18 @@
 3: --- setInterval ---
 4: [F] testReferenceCounting
 5: [P] Global Code
+
+-- Running test case: CheckAsyncStackTrace.AddEventListener
+PAUSE #1
+CALL STACK:
+0: [F] pauseThenFinishTest
+1: [F] clickFired
+2: [F] testAddEventListener
+3: [P] Global Code
+ASYNC CALL STACK:
+4: --- addEventListener ---
+5: [F] testAddEventListener
+6: [P] Global Code
 -- Running test setup.
 Save DebuggerManager.asyncStackTraceDepth
 

Modified: trunk/LayoutTests/inspector/debugger/async-stack-trace.html (220035 => 220036)


--- trunk/LayoutTests/inspector/debugger/async-stack-trace.html	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/LayoutTests/inspector/debugger/async-stack-trace.html	2017-07-29 00:33:12 UTC (rev 220036)
@@ -41,6 +41,15 @@
     }, timerDelay);
 }
 
+function testAddEventListener() {
+    document.body.addEventListener("click", function clickFired() {
+        document.body.removeEventListener("click", clickFired);
+        pauseThenFinishTest();
+    });
+
+    document.body.click();
+}
+
 function recursiveCallThenTest(testFunction, depth) {
     if (depth) {
         recursiveCallThenTest(testFunction, depth - 1);
@@ -93,6 +102,7 @@
     addSimpleTestCase("SetInterval", "testSetInterval(3)");
     addSimpleTestCase("ChainedRequestAnimationFrame", "testChainedRequestAnimationFrame()");
     addSimpleTestCase("ReferenceCounting", "testReferenceCounting()");
+    addSimpleTestCase("AddEventListener", "testAddEventListener()");
 
     function setup(resolve) {
         InspectorTest.log("Save DebuggerManager.asyncStackTraceDepth");

Modified: trunk/Source/_javascript_Core/ChangeLog (220035 => 220036)


--- trunk/Source/_javascript_Core/ChangeLog	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-07-29 00:33:12 UTC (rev 220036)
@@ -1,3 +1,19 @@
+2017-07-28  Matt Baker  <[email protected]>
+
+        Web Inspector: capture an async stack trace when web content calls addEventListener
+        https://bugs.webkit.org/show_bug.cgi?id=174739
+        <rdar://problem/33468197>
+
+        Reviewed by Brian Burg.
+
+        Allow debugger agents to perform custom logic when asynchronous stack
+        trace data is cleared. For example, the PageDebuggerAgent would clear
+        its list of registered listeners for which call stacks have been recorded.
+
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::clearAsyncStackTraceData):
+        * inspector/agents/InspectorDebuggerAgent.h:
+
 2017-07-28  Mark Lam  <[email protected]>
 
         ObjectToStringAdaptiveStructureWatchpoint should not fire if it's dying imminently.

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp (220035 => 220036)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp	2017-07-29 00:33:12 UTC (rev 220036)
@@ -1145,6 +1145,8 @@
 {
     m_pendingAsyncCalls.clear();
     m_currentAsyncCallIdentifier = std::nullopt;
+
+    didClearAsyncStackTraceData();
 }
 
 } // namespace Inspector

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h (220035 => 220036)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h	2017-07-29 00:33:12 UTC (rev 220036)
@@ -93,6 +93,7 @@
 
     enum class AsyncCallType {
         DOMTimer,
+        EventListener,
         RequestAnimationFrame,
     };
 
@@ -135,6 +136,7 @@
     virtual String sourceMapURLForScript(const Script&);
 
     void didClearGlobalObject();
+    virtual void didClearAsyncStackTraceData() { }
 
 private:
     Ref<Inspector::Protocol::Array<Inspector::Protocol::Debugger::CallFrame>> currentCallFrames(const InjectedScript&);

Modified: trunk/Source/WebCore/ChangeLog (220035 => 220036)


--- trunk/Source/WebCore/ChangeLog	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/Source/WebCore/ChangeLog	2017-07-29 00:33:12 UTC (rev 220036)
@@ -1,3 +1,37 @@
+2017-07-28  Matt Baker  <[email protected]>
+
+        Web Inspector: capture an async stack trace when web content calls addEventListener
+        https://bugs.webkit.org/show_bug.cgi?id=174739
+        <rdar://problem/33468197>
+
+        Reviewed by Brian Burg.
+
+        Test: inspector/debugger/async-stack-trace.html
+
+        Add instrumentation to EventTarget to support showing asynchronous
+        stack traces when the debugger breaks in a script event listener.
+
+        * dom/EventTarget.cpp:
+        (WebCore::EventTarget::addEventListener):
+        (WebCore::EventTarget::removeEventListener):
+        (WebCore::EventTarget::fireEventListeners):
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::didAddEventListenerImpl):
+        (WebCore::InspectorInstrumentation::willRemoveEventListenerImpl):
+        (WebCore::InspectorInstrumentation::willHandleEventImpl):
+        (WebCore::InspectorInstrumentation::didHandleEventImpl):
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::didAddEventListener):
+        (WebCore::InspectorInstrumentation::willRemoveEventListener):
+        (WebCore::InspectorInstrumentation::willHandleEvent):
+        (WebCore::InspectorInstrumentation::didHandleEvent):
+        * inspector/PageDebuggerAgent.cpp:
+        (WebCore::PageDebuggerAgent::didClearAsyncStackTraceData):
+        (WebCore::PageDebuggerAgent::didAddEventListener):
+        (WebCore::PageDebuggerAgent::willRemoveEventListener):
+        (WebCore::PageDebuggerAgent::willHandleEvent):
+        * inspector/PageDebuggerAgent.h:
+
 2017-07-28  Matt Rajca  <[email protected]>
 
         Don't add autoplay restrictions to media elements created in response to user gestures.

Modified: trunk/Source/WebCore/dom/EventTarget.cpp (220035 => 220036)


--- trunk/Source/WebCore/dom/EventTarget.cpp	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/Source/WebCore/dom/EventTarget.cpp	2017-07-29 00:33:12 UTC (rev 220036)
@@ -68,7 +68,15 @@
 
 bool EventTarget::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
 {
-    return ensureEventTargetData().eventListenerMap.add(eventType, WTFMove(listener), { options.capture, options.passive, options.once });
+    bool listenerCreatedFromScript = listener->type() == EventListener::JSEventListenerType && !listener->wasCreatedFromMarkup();
+
+    if (!ensureEventTargetData().eventListenerMap.add(eventType, WTFMove(listener), { options.capture, options.passive, options.once }))
+        return false;
+
+    if (listenerCreatedFromScript)
+        InspectorInstrumentation::didAddEventListener(*this, eventType);
+
+    return true;
 }
 
 void EventTarget::addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&& listener, AddEventListenerOptionsOrBoolean&& variant)
@@ -102,7 +110,12 @@
 bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options)
 {
     auto* data = ""
-    return data && data->eventListenerMap.remove(eventType, listener, options.capture);
+    if (!data)
+        return false;
+
+    InspectorInstrumentation::willRemoveEventListener(*this, eventType, listener, options.capture);
+
+    return data->eventListenerMap.remove(eventType, listener, options.capture);
 }
 
 bool EventTarget::setAttributeEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, DOMWrapperWorld& isolatedWorld)
@@ -260,8 +273,9 @@
         if (registeredListener->isPassive())
             event.setInPassiveListener(true);
 
-        InspectorInstrumentation::willHandleEvent(&context, event);
+        InspectorInstrumentation::willHandleEvent(context, event, *registeredListener);
         registeredListener->callback().handleEvent(context, event);
+        InspectorInstrumentation::didHandleEvent(context);
 
         if (registeredListener->isPassive())
             event.setInPassiveListener(false);

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (220035 => 220036)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2017-07-29 00:33:12 UTC (rev 220036)
@@ -61,6 +61,7 @@
 #include "RenderObject.h"
 #include "RenderView.h"
 #include "ScriptController.h"
+#include "ScriptExecutionContext.h"
 #include "WebConsoleAgent.h"
 #include "WebGLRenderingContextBase.h"
 #include "WebSocketFrame.h"
@@ -350,6 +351,18 @@
         timelineAgent->didRemoveTimer(timerId, frameForScriptExecutionContext(context));
 }
 
+void InspectorInstrumentation::didAddEventListenerImpl(InstrumentingAgents& instrumentingAgents, EventTarget& target, const AtomicString& eventType)
+{
+    if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent())
+        pageDebuggerAgent->didAddEventListener(target, eventType);
+}
+
+void InspectorInstrumentation::willRemoveEventListenerImpl(InstrumentingAgents& instrumentingAgents, EventTarget& target, const AtomicString& eventType, EventListener& listener, bool capture)
+{
+    if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent())
+        pageDebuggerAgent->willRemoveEventListener(target, eventType, listener, capture);
+}
+
 InspectorInstrumentationCookie InspectorInstrumentation::willCallFunctionImpl(InstrumentingAgents& instrumentingAgents, const String& scriptName, int scriptLine, ScriptExecutionContext* context)
 {
     int timelineAgentId = 0;
@@ -378,11 +391,20 @@
     return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId);
 }
 
-void InspectorInstrumentation::willHandleEventImpl(InstrumentingAgents& instrumentingAgents, const Event& event)
+void InspectorInstrumentation::willHandleEventImpl(InstrumentingAgents& instrumentingAgents, const Event& event, const RegisteredEventListener& listener)
 {
+    if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent())
+        pageDebuggerAgent->willHandleEvent(listener);
+
     pauseOnNativeEventIfNeeded(instrumentingAgents, true, event.type(), false);
 }
 
+void InspectorInstrumentation::didHandleEventImpl(InstrumentingAgents& instrumentingAgents)
+{
+    if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent())
+        debuggerAgent->didDispatchAsyncCall();
+}
+
 void InspectorInstrumentation::didDispatchEventImpl(const InspectorInstrumentationCookie& cookie)
 {
     if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (220035 => 220036)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2017-07-29 00:33:12 UTC (rev 220036)
@@ -36,6 +36,7 @@
 #include "CanvasRenderingContext.h"
 #include "DocumentThreadableLoader.h"
 #include "Element.h"
+#include "EventTarget.h"
 #include "FormData.h"
 #include "Frame.h"
 #include "HTMLCanvasElement.h"
@@ -43,7 +44,6 @@
 #include "InspectorController.h"
 #include "InspectorInstrumentationCookie.h"
 #include "Page.h"
-#include "ScriptExecutionContext.h"
 #include "StorageArea.h"
 #include "WorkerGlobalScope.h"
 #include "WorkerInspectorController.h"
@@ -65,6 +65,7 @@
 class Database;
 class Document;
 class DocumentLoader;
+class EventListener;
 class HTTPHeaderMap;
 class InspectorTimelineAgent;
 class InstrumentingAgents;
@@ -71,11 +72,13 @@
 class NetworkLoadMetrics;
 class Node;
 class PseudoElement;
+class RegisteredEventListener;
 class RenderLayer;
 class RenderObject;
 class ResourceLoader;
 class ResourceRequest;
 class ResourceResponse;
+class ScriptExecutionContext;
 class SecurityOrigin;
 class ShadowRoot;
 class URL;
@@ -129,9 +132,12 @@
 
     static InspectorInstrumentationCookie willCallFunction(ScriptExecutionContext*, const String& scriptName, int scriptLine);
     static void didCallFunction(const InspectorInstrumentationCookie&, ScriptExecutionContext*);
+    static void didAddEventListener(EventTarget&, const AtomicString& eventType);
+    static void willRemoveEventListener(EventTarget&, const AtomicString& eventType, EventListener&, bool capture);
     static InspectorInstrumentationCookie willDispatchEvent(Document&, const Event&, bool hasEventListeners);
     static void didDispatchEvent(const InspectorInstrumentationCookie&);
-    static void willHandleEvent(ScriptExecutionContext*, const Event&);
+    static void willHandleEvent(ScriptExecutionContext&, const Event&, const RegisteredEventListener&);
+    static void didHandleEvent(ScriptExecutionContext&);
     static InspectorInstrumentationCookie willDispatchEventOnWindow(Frame*, const Event&, DOMWindow&);
     static void didDispatchEventOnWindow(const InspectorInstrumentationCookie&);
     static InspectorInstrumentationCookie willEvaluateScript(Frame&, const String& url, int lineNumber);
@@ -289,8 +295,11 @@
 
     static InspectorInstrumentationCookie willCallFunctionImpl(InstrumentingAgents&, const String& scriptName, int scriptLine, ScriptExecutionContext*);
     static void didCallFunctionImpl(const InspectorInstrumentationCookie&, ScriptExecutionContext*);
+    static void didAddEventListenerImpl(InstrumentingAgents&, EventTarget&, const AtomicString& eventType);
+    static void willRemoveEventListenerImpl(InstrumentingAgents&, EventTarget&, const AtomicString& eventType, EventListener&, bool capture);
     static InspectorInstrumentationCookie willDispatchEventImpl(InstrumentingAgents&, Document&, const Event&, bool hasEventListeners);
-    static void willHandleEventImpl(InstrumentingAgents&, const Event&);
+    static void willHandleEventImpl(InstrumentingAgents&, const Event&, const RegisteredEventListener&);
+    static void didHandleEventImpl(InstrumentingAgents&);
     static void didDispatchEventImpl(const InspectorInstrumentationCookie&);
     static InspectorInstrumentationCookie willDispatchEventOnWindowImpl(InstrumentingAgents&, const Event&, DOMWindow&);
     static void didDispatchEventOnWindowImpl(const InspectorInstrumentationCookie&);
@@ -635,6 +644,20 @@
         didRemoveTimerImpl(*instrumentingAgents, timerId, context);
 }
 
+inline void InspectorInstrumentation::didAddEventListener(EventTarget& target, const AtomicString& eventType)
+{
+    FAST_RETURN_IF_NO_FRONTENDS(void());
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(target.scriptExecutionContext()))
+        didAddEventListenerImpl(*instrumentingAgents, target, eventType);
+}
+
+inline void InspectorInstrumentation::willRemoveEventListener(EventTarget& target, const AtomicString& eventType, EventListener& listener, bool capture)
+{
+    FAST_RETURN_IF_NO_FRONTENDS(void());
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(target.scriptExecutionContext()))
+        willRemoveEventListenerImpl(*instrumentingAgents, target, eventType, listener, capture);
+}
+
 inline InspectorInstrumentationCookie InspectorInstrumentation::willCallFunction(ScriptExecutionContext* context, const String& scriptName, int scriptLine)
 {
     FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie());
@@ -665,13 +688,20 @@
         didDispatchEventImpl(cookie);
 }
 
-inline void InspectorInstrumentation::willHandleEvent(ScriptExecutionContext* context, const Event& event)
+inline void InspectorInstrumentation::willHandleEvent(ScriptExecutionContext& context, const Event& event, const RegisteredEventListener& listener)
 {
     FAST_RETURN_IF_NO_FRONTENDS(void());
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context))
-        return willHandleEventImpl(*instrumentingAgents, event);
+        return willHandleEventImpl(*instrumentingAgents, event, listener);
 }
 
+inline void InspectorInstrumentation::didHandleEvent(ScriptExecutionContext& context)
+{
+    FAST_RETURN_IF_NO_FRONTENDS(void());
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context))
+        return didHandleEventImpl(*instrumentingAgents);
+}
+
 inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventOnWindow(Frame* frame, const Event& event, DOMWindow& window)
 {
     FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie());

Modified: trunk/Source/WebCore/inspector/PageDebuggerAgent.cpp (220035 => 220036)


--- trunk/Source/WebCore/inspector/PageDebuggerAgent.cpp	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/Source/WebCore/inspector/PageDebuggerAgent.cpp	2017-07-29 00:33:12 UTC (rev 220036)
@@ -34,6 +34,8 @@
 
 #include "CachedResource.h"
 #include "Document.h"
+#include "EventListener.h"
+#include "EventTarget.h"
 #include "InspectorOverlay.h"
 #include "InspectorPageAgent.h"
 #include "InstrumentingAgents.h"
@@ -41,6 +43,7 @@
 #include "Page.h"
 #include "PageConsoleClient.h"
 #include "PageScriptDebugServer.h"
+#include "ScriptExecutionContext.h"
 #include "ScriptState.h"
 #include <inspector/InjectedScript.h>
 #include <inspector/InjectedScriptManager.h>
@@ -93,6 +96,12 @@
     return InspectorDebuggerAgent::sourceMapURLForScript(script);
 }
 
+void PageDebuggerAgent::didClearAsyncStackTraceData()
+{
+    m_registeredEventListeners.clear();
+    m_nextEventListenerIdentifier = 1;
+}
+
 void PageDebuggerAgent::muteConsole()
 {
     PageConsoleClient::mute();
@@ -151,6 +160,51 @@
     setSuppressAllPauses(false);
 }
 
+void PageDebuggerAgent::didAddEventListener(EventTarget& target, const AtomicString& eventType)
+{
+    if (!breakpointsActive())
+        return;
+
+    auto& eventListeners = target.eventListeners(eventType);
+    const RefPtr<RegisteredEventListener>& listener = eventListeners.last();
+    if (m_registeredEventListeners.contains(listener.get())) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    JSC::ExecState* scriptState = target.scriptExecutionContext()->execState();
+    if (!scriptState)
+        return;
+
+    int identifier = m_nextEventListenerIdentifier++;
+    m_registeredEventListeners.set(listener.get(), identifier);
+
+    didScheduleAsyncCall(scriptState, InspectorDebuggerAgent::AsyncCallType::EventListener, identifier, listener->isOnce());
+}
+
+void PageDebuggerAgent::willRemoveEventListener(EventTarget& target, const AtomicString& eventType, EventListener& listener, bool capture)
+{
+    auto& eventListeners = target.eventListeners(eventType);
+    size_t listenerIndex = eventListeners.findMatching([&](auto& registeredListener) {
+        return &registeredListener->callback() == &listener && registeredListener->useCapture() == capture;
+    });
+
+    if (listenerIndex == notFound)
+        return;
+
+    int identifier = m_registeredEventListeners.take(eventListeners[listenerIndex].get());
+    didCancelAsyncCall(InspectorDebuggerAgent::AsyncCallType::EventListener, identifier);
+}
+
+void PageDebuggerAgent::willHandleEvent(const RegisteredEventListener& listener)
+{
+    auto it = m_registeredEventListeners.find(&listener);
+    if (it == m_registeredEventListeners.end())
+        return;
+
+    willDispatchAsyncCall(InspectorDebuggerAgent::AsyncCallType::EventListener, it->value);
+}
+
 void PageDebuggerAgent::didRequestAnimationFrame(int callbackId, Document& document)
 {
     if (!breakpointsActive())

Modified: trunk/Source/WebCore/inspector/PageDebuggerAgent.h (220035 => 220036)


--- trunk/Source/WebCore/inspector/PageDebuggerAgent.h	2017-07-29 00:25:49 UTC (rev 220035)
+++ trunk/Source/WebCore/inspector/PageDebuggerAgent.h	2017-07-29 00:33:12 UTC (rev 220036)
@@ -36,9 +36,12 @@
 namespace WebCore {
 
 class Document;
+class EventListener;
+class EventTarget;
 class InspectorOverlay;
 class InspectorPageAgent;
 class Page;
+class RegisteredEventListener;
 
 class PageDebuggerAgent final : public WebDebuggerAgent {
     WTF_MAKE_NONCOPYABLE(PageDebuggerAgent);
@@ -57,6 +60,10 @@
     void willFireAnimationFrame(int callbackId);
     void didCancelAnimationFrame(int callbackId);
 
+    void didAddEventListener(EventTarget&, const AtomicString& eventType);
+    void willRemoveEventListener(EventTarget&, const AtomicString& eventType, EventListener&, bool capture);
+    void willHandleEvent(const RegisteredEventListener&);
+
 protected:
     void enable() override;
     void disable(bool isBeingDestroyed) override;
@@ -63,6 +70,8 @@
 
     String sourceMapURLForScript(const Script&) override;
 
+    void didClearAsyncStackTraceData() override;
+
 private:
     void muteConsole() override;
     void unmuteConsole() override;
@@ -76,6 +85,9 @@
 
     InspectorPageAgent* m_pageAgent;
     InspectorOverlay* m_overlay { nullptr };
+
+    HashMap<const RegisteredEventListener*, int> m_registeredEventListeners;
+    int m_nextEventListenerIdentifier { 1 };
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to