Chromium Code Reviews| Index: Source/core/inspector/InspectorDOMDebuggerAgent.cpp |
| diff --git a/Source/core/inspector/InspectorDOMDebuggerAgent.cpp b/Source/core/inspector/InspectorDOMDebuggerAgent.cpp |
| index 203b68e26b787f15d82edc34e27a14b20eca2098..9db713d8e227a69fddebf3bb2c124986bca8a704 100644 |
| --- a/Source/core/inspector/InspectorDOMDebuggerAgent.cpp |
| +++ b/Source/core/inspector/InspectorDOMDebuggerAgent.cpp |
| @@ -345,7 +345,6 @@ void InspectorDOMDebuggerAgent::getEventListeners(ErrorString* errorString, cons |
| *errorString = "Inspected frame has gone"; |
| return; |
| } |
| - |
| ScriptState* state = injectedScript.scriptState(); |
| ScriptState::Scope scope(state); |
| v8::Local<v8::Value> value = injectedScript.findObject(*remoteId); |
| @@ -353,51 +352,139 @@ void InspectorDOMDebuggerAgent::getEventListeners(ErrorString* errorString, cons |
| *errorString = "No object with passed objectId"; |
| return; |
| } |
| - EventTarget* target = InjectedScriptHost::eventTargetFromV8Value(state->isolate(), value); |
| - if (!target) { |
| - *errorString = "No event target with passed objectId"; |
| - return; |
| - } |
| + String objectGroup = injectedScript.objectIdToObjectGroupName(objectId); |
| listenersArray = TypeBuilder::Array<TypeBuilder::DOMDebugger::EventListener>::create(); |
| + |
| + eventListeners(injectedScript, value, objectGroup, listenersArray); |
| + frameworkUserEventListeners(injectedScript, value, objectGroup, listenersArray); |
| +} |
| + |
| +void InspectorDOMDebuggerAgent::eventListeners(InjectedScript& injectedScript, v8::Local<v8::Value> object, const String& objectGroup, RefPtr<TypeBuilder::Array<TypeBuilder::DOMDebugger::EventListener>>& listenersArray) |
| +{ |
| + ScriptState* state = injectedScript.scriptState(); |
| + EventTarget* eventTarget = InjectedScriptHost::eventTargetFromV8Value(state->isolate(), object); |
| + if (!eventTarget) |
| + return; |
| + ExecutionContext* executionContext = eventTarget->executionContext(); |
| + if (!executionContext) |
| + return; |
| + |
| WillBeHeapVector<EventListenerInfo> eventInformation; |
| - EventListenerInfo::getEventListeners(target, eventInformation, false); |
| + EventListenerInfo::getEventListeners(eventTarget, eventInformation, false); |
| if (eventInformation.isEmpty()) |
| return; |
| - String objectGroup = injectedScript.objectIdToObjectGroupName(objectId); |
| + v8::Local<v8::Set> frameworkInternalEventHandlers = injectedScript.frameworkInternalEventHandlers(object); |
| + v8::Local<v8::Context> v8Context(frameworkInternalEventHandlers->CreationContext()); |
| + |
| + using ListenerType = TypeBuilder::DOMDebugger::EventListener::ListenerType; |
| RegisteredEventListenerIterator iterator(eventInformation); |
| while (const RegisteredEventListener* listener = iterator.nextRegisteredEventListener()) { |
| + ListenerType::Enum listenerType = ListenerType::Normal; |
| + v8::Local<v8::Object> handler = eventListenerHandler(executionContext, listener->listener.get()); |
| + |
| + if (!frameworkInternalEventHandlers.IsEmpty()) { |
| + v8::Maybe<bool> hasHandler = frameworkInternalEventHandlers->Has(v8Context, handler); |
| + if (hasHandler.IsJust() && hasHandler.FromJust()) |
| + listenerType = ListenerType::FrameworkInternal; |
| + } |
| + |
| const EventListenerInfo& info = iterator.currentEventListenerInfo(); |
| - RefPtr<TypeBuilder::DOMDebugger::EventListener> listenerObject = buildObjectForEventListener(*listener, info.eventType, info.eventTarget, objectGroup); |
| + RefPtr<TypeBuilder::DOMDebugger::EventListener> listenerObject = buildObjectForEventListener(injectedScript, handler, listenerType, listener->useCapture, info.eventType, objectGroup); |
| if (listenerObject) |
| listenersArray->addItem(listenerObject); |
| } |
| } |
| -PassRefPtr<TypeBuilder::DOMDebugger::EventListener> InspectorDOMDebuggerAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, EventTarget* target, const String& objectGroupId) |
| +void InspectorDOMDebuggerAgent::frameworkUserEventListeners(InjectedScript& injectedScript, v8::Local<v8::Value> object, const String& objectGroup, RefPtr<TypeBuilder::Array<TypeBuilder::DOMDebugger::EventListener>>& listenersArray) |
| { |
| - EventListener* eventListener = registeredEventListener.listener.get(); |
| - RefPtrWillBeRawPtr<EventListener> protect(eventListener); |
| + v8::Local<v8::Array> listeners = injectedScript.frameworkUserEventListeners(object); |
| + if (listeners.IsEmpty()) |
| + return; |
| + |
| + ScriptState* scriptState = injectedScript.scriptState(); |
| + v8::Isolate* isolate = scriptState->isolate(); |
| + v8::Local<v8::Context> v8Context(listeners->CreationContext()); |
| + for (unsigned i = 0; i < listeners->Length(); ++i) { |
| + v8::Local<v8::Value> value; |
| + |
| + v8::Local<v8::Object> listenerObject; |
| + if (listeners->Get(v8Context, i).ToLocal(&value)) { |
| + if (value->IsObject()) |
| + listenerObject = value.As<v8::Object>(); |
| + else |
| + continue; |
| + } |
| + |
| + v8::Local<v8::Function> handler; |
| + if (listenerObject->Get(v8Context, v8String(isolate, "handler")).ToLocal(&value)) { |
| + if (value->IsFunction()) |
| + handler = value.As<v8::Function>(); |
| + else |
| + continue; |
| + } |
| + |
| + v8::Local<v8::String> type; |
| + if (listenerObject->Get(v8Context, v8String(isolate, "type")).ToLocal(&value)) { |
| + if (value->IsString()) |
| + type = value.As<v8::String>(); |
| + else |
| + continue; |
| + } |
| + |
| + v8::Local<v8::Boolean> useCapture; |
| + if (listenerObject->Get(v8Context, v8String(isolate, "useCapture")).ToLocal(&value)) { |
| + if (value->IsBoolean()) |
| + useCapture = value.As<v8::Boolean>(); |
| + else |
| + continue; |
| + } |
| + |
| + RefPtr<TypeBuilder::DOMDebugger::EventListener> inspectorListenerObject = buildObjectForEventListener(injectedScript, handler, TypeBuilder::DOMDebugger::EventListener::ListenerType::FrameworkUser, useCapture->Value(), toCoreString(type), objectGroup); |
| + if (inspectorListenerObject) |
| + listenersArray->addItem(inspectorListenerObject); |
| + } |
| +} |
| + |
|
yurys
2015/08/14 17:24:20
Consider inlining this function.
kozy
2015/08/14 18:15:45
Done.
|
| +static PassRefPtr<TypeBuilder::Runtime::RemoteObject> eventHandlerObject(v8::Local<v8::Object> handler, InjectedScriptManager* manager, const String* objectGroupId) |
| +{ |
| + if (handler.IsEmpty()) |
| + return nullptr; |
| + ScriptState* scriptState = ScriptState::from(handler->CreationContext()); |
| + InjectedScript injectedScript = manager->injectedScriptFor(scriptState); |
| + if (!injectedScript.isEmpty()) |
| + return injectedScript.wrapObject(ScriptValue(scriptState, handler), *objectGroupId); |
| + return nullptr; |
| +} |
| + |
| +PassRefPtr<TypeBuilder::DOMDebugger::EventListener> InspectorDOMDebuggerAgent::buildObjectForEventListener(InjectedScript& injectedScript, v8::Local<v8::Object> handler, TypeBuilder::DOMDebugger::EventListener::ListenerType::Enum listenerType, bool useCapture, const String& type, const String& objectGroupId) |
| +{ |
| + if (handler.IsEmpty()) |
| + return nullptr; |
| + |
| + ScriptState* scriptState = injectedScript.scriptState(); |
| + v8::Isolate* isolate = scriptState->isolate(); |
| + v8::Local<v8::Function> function = eventListenerEffectiveFunction(isolate, handler); |
| + if (function.IsEmpty()) |
| + return nullptr; |
| + |
| String scriptId; |
| int lineNumber; |
| int columnNumber; |
| - ExecutionContext* context = target->executionContext(); |
| - if (!context) |
| - return nullptr; |
| - if (!eventListenerHandlerLocation(context, eventListener, scriptId, lineNumber, columnNumber)) |
| - return nullptr; |
| + getFunctionLocation(function, scriptId, lineNumber, columnNumber); |
| RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create() |
| .setScriptId(scriptId) |
| .setLineNumber(lineNumber); |
| location->setColumnNumber(columnNumber); |
| RefPtr<TypeBuilder::DOMDebugger::EventListener> value = TypeBuilder::DOMDebugger::EventListener::create() |
| - .setType(eventType) |
| - .setUseCapture(registeredEventListener.useCapture) |
| + .setType(type) |
| + .setUseCapture(useCapture) |
| .setLocation(location); |
| + value->setListenerType(listenerType); |
| if (!objectGroupId.isEmpty()) |
| - value->setHandler(eventHandlerObject(context, eventListener, m_injectedScriptManager, &objectGroupId)); |
| + value->setHandler(eventHandlerObject(function, m_injectedScriptManager, &objectGroupId)); |
| return value.release(); |
| } |