blob: 05c5758109537ec1a15dd6f42b69dbdac96b5955 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "core/inspector/EventListenerInfo.h"
#include "bindings/core/v8/ScriptEventListener.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/Document.h"
#include "core/dom/Node.h"
#include "core/events/EventTarget.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InjectedScriptManager.h"
namespace blink {
void EventListenerInfo::getEventListeners(EventTarget* target, Vector<EventListenerInfo>& eventInformation, bool includeAncestors)
{
// The Node's Ancestors including self.
Vector<EventTarget*> ancestors;
ancestors.append(target);
if (includeAncestors) {
Node* node = target->toNode();
for (ContainerNode* ancestor = node ? node->parentOrShadowHostNode() : nullptr; ancestor; ancestor = ancestor->parentOrShadowHostNode())
ancestors.append(ancestor);
}
// Nodes and their Listeners for the concerned event types (order is top to bottom)
for (size_t i = ancestors.size(); i; --i) {
EventTarget* ancestor = ancestors[i - 1];
Vector<AtomicString> eventTypes = ancestor->eventTypes();
for (size_t j = 0; j < eventTypes.size(); ++j) {
AtomicString& type = eventTypes[j];
const EventListenerVector& listeners = ancestor->getEventListeners(type);
EventListenerVector filteredListeners;
filteredListeners.reserveCapacity(listeners.size());
for (size_t k = 0; k < listeners.size(); ++k) {
if (listeners[k].listener->type() == EventListener::JSEventListenerType)
filteredListeners.append(listeners[k]);
}
if (!filteredListeners.isEmpty())
eventInformation.append(EventListenerInfo(ancestor, type, filteredListeners));
}
}
}
const RegisteredEventListener* RegisteredEventListenerIterator::nextRegisteredEventListener()
{
while (true) {
const EventListenerInfo& info = m_listenersArray[m_infoIndex];
const EventListenerVector& vector = info.eventListenerVector;
for (; m_listenerIndex < vector.size(); ++m_listenerIndex) {
if (m_isUseCapturePass == vector[m_listenerIndex].useCapture)
return &vector[m_listenerIndex++];
}
m_listenerIndex = 0;
if (m_isUseCapturePass) {
if (++m_infoIndex >= m_listenersArray.size())
m_isUseCapturePass = false;
}
if (!m_isUseCapturePass) {
if (m_infoIndex == 0)
return nullptr;
--m_infoIndex;
}
}
}
const EventListenerInfo& RegisteredEventListenerIterator::currentEventListenerInfo()
{
return m_listenersArray[m_infoIndex];
}
PassRefPtr<TypeBuilder::Runtime::RemoteObject> eventHandlerObject(ExecutionContext* context, EventListener* eventListener, InjectedScriptManager* manager, const String* objectGroupId)
{
ScriptValue functionValue = eventListenerHandler(context, eventListener);
if (functionValue.isEmpty() || !context->isDocument())
return nullptr;
LocalFrame* frame = toDocument(context)->frame();
if (!frame)
return nullptr;
ScriptState* scriptState = eventListenerHandlerScriptState(frame, eventListener);
if (scriptState) {
InjectedScript injectedScript = manager->injectedScriptFor(scriptState);
if (!injectedScript.isEmpty())
return injectedScript.wrapObject(functionValue, *objectGroupId);
}
return nullptr;
}
} // namespace blink