Chromium Code Reviews| 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; |