Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Unified Diff: third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp

Issue 1950403002: Add the ability to return descedant event listeners. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address pfeldman's comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
index 7d0d87ec8b7830811eefec9d7ec6cbed5589c8c0..e8a3f969eac72bc675ceb8d921a27b11a730f1a4 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
@@ -33,14 +33,18 @@
#include "bindings/core/v8/ScriptEventListener.h"
#include "bindings/core/v8/V8EventTarget.h"
#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/Node.h"
#include "core/events/Event.h"
#include "core/events/EventTarget.h"
#include "core/frame/LocalDOMWindow.h"
+#include "core/html/HTMLFrameOwnerElement.h"
#include "core/inspector/InspectorDOMAgent.h"
#include "platform/inspector_protocol/Values.h"
#include "platform/v8_inspector/public/V8InspectorSession.h"
+namespace blink {
+
namespace {
enum DOMBreakpointType {
@@ -56,33 +60,9 @@ static const char instrumentationEventCategoryType[] = "instrumentation:";
const uint32_t inheritableDOMBreakpointTypesMask = (1 << SubtreeModified);
const int domBreakpointDerivedTypeShift = 16;
-} // namespace
-
-namespace blink {
-
-static const char webglErrorFiredEventName[] = "webglErrorFired";
-static const char webglWarningFiredEventName[] = "webglWarningFired";
-static const char webglErrorNameProperty[] = "webglErrorName";
-
-namespace DOMDebuggerAgentState {
-static const char eventListenerBreakpoints[] = "eventListenerBreakpoints";
-static const char eventTargetAny[] = "*";
-static const char pauseOnAllXHRs[] = "pauseOnAllXHRs";
-static const char xhrBreakpoints[] = "xhrBreakpoints";
-static const char enabled[] = "enabled";
-}
-
-void InspectorDOMDebuggerAgent::eventListenersInfoForTarget(v8::Isolate* isolate, v8::Local<v8::Value> value, V8EventListenerInfoList& eventInformation)
+void addEventListenersForEventTarget(EventTarget* target, EventListenerFilter filterMask, V8EventListenerInfoList& eventInformation)
{
- EventTarget* target = V8EventTarget::toImplWithTypeCheck(isolate, value);
- // We need to handle LocalDOMWindow specially, because LocalDOMWindow wrapper exists on prototype chain.
- if (!target)
- target = toDOMWindow(isolate, value);
- if (!target || !target->getExecutionContext())
- return;
-
ExecutionContext* executionContext = target->getExecutionContext();
-
// Nodes and their Listeners for the concerned event types (order is top to bottom)
Vector<AtomicString> eventTypes = target->eventTypes();
for (size_t j = 0; j < eventTypes.size(); ++j) {
@@ -91,25 +71,83 @@ void InspectorDOMDebuggerAgent::eventListenersInfoForTarget(v8::Isolate* isolate
if (!listeners)
continue;
for (size_t k = 0; k < listeners->size(); ++k) {
- EventListener* eventListener = listeners->at(k).listener();
+ auto& registeredEventListener = listeners->at(k);
+ EventListener* eventListener = registeredEventListener.listener();
if (eventListener->type() != EventListener::JSEventListenerType)
continue;
- V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(eventListener);
- v8::Local<v8::Context> context = toV8Context(executionContext, v8Listener->world());
- // Hide listeners from other contexts.
- if (context != isolate->GetCurrentContext())
+ if (!(filterMask & EventListenerFilter::ShowPassive) && registeredEventListener.passive())
continue;
+ if (!(filterMask & EventListenerFilter::ShowBlocking) && !registeredEventListener.passive())
+ continue;
+ V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(eventListener);
// getListenerObject() may cause JS in the event attribute to get
// compiled, potentially unsuccessfully. In that case, the function
// returns the empty handle without an exception.
v8::Local<v8::Object> handler = v8Listener->getListenerObject(executionContext);
if (handler.IsEmpty())
continue;
- eventInformation.append(V8EventListenerInfo(type, listeners->at(k).capture(), listeners->at(k).passive(), handler));
+ eventInformation.append(V8EventListenerInfo(type, registeredEventListener.capture(), registeredEventListener.passive(), handler));
}
}
}
+void addEventListenersForEventTargetAndDescendants(EventTarget* target, EventListenerFilter filterMask, V8EventListenerInfoList& eventInformation)
+{
+ addEventListenersForEventTarget(target, filterMask, eventInformation);
pfeldman 2016/06/01 22:40:30 I don't think this code works for the case of targ
+ Node* rootNode = nullptr;
+ if (LocalDOMWindow* window = target->toLocalDOMWindow()) {
+ if (Document* document = window->document()) {
+ addEventListenersForEventTarget(document, filterMask, eventInformation);
+ rootNode = document;
+ }
+ } else if (Node* node = target->toNode()) {
+ rootNode = node;
+ }
+
+ if (rootNode) {
+ for (Element& element : ElementTraversal::descendantsOf(*rootNode)) {
+ addEventListenersForEventTarget(&element, filterMask, eventInformation);
+ if (element.isFrameOwnerElement()) {
+ if (HTMLFrameOwnerElement* frameElement = toHTMLFrameOwnerElement(&element)) {
+ if (DOMWindow* subFrameWindow = frameElement->contentWindow())
+ addEventListenersForEventTargetAndDescendants(subFrameWindow, filterMask, eventInformation);
+ }
+ }
+ }
+ }
+}
+
+static const char webglErrorFiredEventName[] = "webglErrorFired";
pfeldman 2016/06/01 22:40:30 Lets keep constants all together (above methods)
+static const char webglWarningFiredEventName[] = "webglWarningFired";
+static const char webglErrorNameProperty[] = "webglErrorName";
+
+} // namespace
+
+namespace DOMDebuggerAgentState {
pfeldman 2016/06/01 22:40:30 This could also be a part of anonymous namespace.
+
+static const char eventListenerBreakpoints[] = "eventListenerBreakpoints";
+static const char eventTargetAny[] = "*";
+static const char pauseOnAllXHRs[] = "pauseOnAllXHRs";
+static const char xhrBreakpoints[] = "xhrBreakpoints";
+static const char enabled[] = "enabled";
+
+} // namespace DOMDebuggerAgentState
+
+void InspectorDOMDebuggerAgent::eventListenersInfoForTarget(v8::Isolate* isolate, v8::Local<v8::Value> value, EventListenerFilter filterMask, V8EventListenerInfoList& eventInformation)
+{
+ EventTarget* target = V8EventTarget::toImplWithTypeCheck(isolate, value);
+ // We need to handle LocalDOMWindow specially, because LocalDOMWindow wrapper exists on prototype chain.
+ if (!target)
+ target = toDOMWindow(isolate, value);
+ if (!target || !target->getExecutionContext())
+ return;
+
+ if (filterMask & EventListenerFilter::ShowDescendants)
+ addEventListenersForEventTargetAndDescendants(target, filterMask, eventInformation);
pfeldman 2016/06/01 22:40:30 We already pass filterMask in, why would we branch
+ else
+ addEventListenersForEventTarget(target, filterMask, eventInformation);
+}
+
InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(v8::Isolate* isolate, InspectorDOMAgent* domAgent, V8InspectorSession* v8Session)
: m_isolate(isolate)
, m_domAgent(domAgent)
@@ -329,7 +367,7 @@ void InspectorDOMDebuggerAgent::removeDOMBreakpoint(ErrorString* errorString, in
didRemoveBreakpoint();
}
-void InspectorDOMDebuggerAgent::getEventListeners(ErrorString* errorString, const String16& objectId, std::unique_ptr<protocol::Array<protocol::DOMDebugger::EventListener>>* listenersArray)
+void InspectorDOMDebuggerAgent::getEventListeners(ErrorString* errorString, const String16& objectId, const Maybe<bool>& inDescendants, std::unique_ptr<protocol::Array<protocol::DOMDebugger::EventListener>>* listenersArray)
{
v8::HandleScope handles(m_isolate);
@@ -338,15 +376,19 @@ void InspectorDOMDebuggerAgent::getEventListeners(ErrorString* errorString, cons
v8::Local<v8::Value> value = m_v8Session->findObject(errorString, objectId, &context, &objectGroup);
if (value.IsEmpty())
return;
+
v8::Context::Scope scope(context);
*listenersArray = protocol::Array<protocol::DOMDebugger::EventListener>::create();
- eventListeners(context, value, objectGroup, listenersArray->get());
+ EventListenerFilter filterMask = static_cast<EventListenerFilter>(EventListenerFilter::ShowPassive | EventListenerFilter::ShowBlocking);
+ if (inDescendants.fromMaybe(false))
+ filterMask = static_cast<EventListenerFilter>(filterMask | EventListenerFilter::ShowDescendants);
+ eventListeners(context, value, objectGroup, filterMask, listenersArray->get());
}
-void InspectorDOMDebuggerAgent::eventListeners(v8::Local<v8::Context> context, v8::Local<v8::Value> object, const String16& objectGroup, protocol::Array<protocol::DOMDebugger::EventListener>* listenersArray)
+void InspectorDOMDebuggerAgent::eventListeners(v8::Local<v8::Context> context, v8::Local<v8::Value> object, const String16& objectGroup, EventListenerFilter filterMask, protocol::Array<protocol::DOMDebugger::EventListener>* listenersArray)
{
V8EventListenerInfoList eventInformation;
- InspectorDOMDebuggerAgent::eventListenersInfoForTarget(context->GetIsolate(), object, eventInformation);
+ InspectorDOMDebuggerAgent::eventListenersInfoForTarget(context->GetIsolate(), object, filterMask, eventInformation);
for (const auto& info : eventInformation) {
if (!info.useCapture)
continue;

Powered by Google App Engine
This is Rietveld 408576698