Index: Source/core/frame/EventHandlerRegistry.cpp |
diff --git a/Source/core/frame/EventHandlerRegistry.cpp b/Source/core/frame/EventHandlerRegistry.cpp |
index 5161cf92e82630ebc6e88c224c7c0a09c99f858d..0875283575d4a5d3c23c799d0db6ed6abca017cb 100644 |
--- a/Source/core/frame/EventHandlerRegistry.cpp |
+++ b/Source/core/frame/EventHandlerRegistry.cpp |
@@ -14,6 +14,15 @@ |
namespace WebCore { |
+EventHandlerRegistry::HandlerState::HandlerState() |
+ : externalHandlerCount(0) |
+{ |
+} |
+ |
+EventHandlerRegistry::HandlerState::~HandlerState() |
+{ |
+} |
+ |
EventHandlerRegistry::EventHandlerRegistry(FrameHost& frameHost) |
: m_frameHost(frameHost) |
{ |
@@ -28,6 +37,8 @@ bool EventHandlerRegistry::eventTypeToClass(const AtomicString& eventType, Event |
{ |
if (eventType == EventTypeNames::scroll) { |
*result = ScrollEvent; |
+ } else if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel) { |
+ *result = WheelEvent; |
#if ASSERT_ENABLED |
} else if (eventType == EventTypeNames::load || eventType == EventTypeNames::mousemove || eventType == EventTypeNames::touchstart) { |
*result = EventsForTesting; |
@@ -41,17 +52,34 @@ bool EventHandlerRegistry::eventTypeToClass(const AtomicString& eventType, Event |
const EventTargetSet* EventHandlerRegistry::eventHandlerTargets(EventHandlerClass handlerClass) const |
{ |
checkConsistency(); |
- return &m_targets[handlerClass]; |
+ return &m_handlers[handlerClass].targets; |
+} |
+ |
+unsigned EventHandlerRegistry::externalEventHandlerCount(EventHandlerClass handlerClass) const |
+{ |
+ return m_handlers[handlerClass].externalHandlerCount; |
} |
bool EventHandlerRegistry::hasEventHandlers(EventHandlerClass handlerClass) const |
{ |
- return m_targets[handlerClass].size(); |
+ const HandlerState& state = m_handlers[handlerClass]; |
+ return state.targets.size() || state.externalHandlerCount; |
+} |
+ |
+void EventHandlerRegistry::updateExternalHandlerCount(ChangeOperation op, EventHandlerClass handlerClass) |
+{ |
+ if (op == Add) { |
+ m_handlers[handlerClass].externalHandlerCount++; |
+ } else { |
+ ASSERT(op == Remove); |
+ ASSERT(m_handlers[handlerClass].externalHandlerCount > 0); |
+ m_handlers[handlerClass].externalHandlerCount--; |
+ } |
} |
bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHandlerClass handlerClass, EventTarget* target) |
{ |
- EventTargetSet* targets = &m_targets[handlerClass]; |
+ EventTargetSet* targets = &m_handlers[handlerClass].targets; |
if (op == Add) { |
if (!targets->add(target).isNewEntry) { |
// Just incremented refcount, no real change. |
@@ -78,7 +106,11 @@ bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHa |
void EventHandlerRegistry::updateEventHandlerInternal(ChangeOperation op, EventHandlerClass handlerClass, EventTarget* target) |
{ |
bool hadHandlers = hasEventHandlers(handlerClass); |
- updateEventHandlerTargets(op, handlerClass, target); |
+ if (target) { |
+ updateEventHandlerTargets(op, handlerClass, target); |
+ } else { |
+ updateExternalHandlerCount(op, handlerClass); |
+ } |
bool hasHandlers = hasEventHandlers(handlerClass); |
if (hadHandlers != hasHandlers) { |
@@ -95,6 +127,16 @@ void EventHandlerRegistry::updateEventHandlerOfType(ChangeOperation op, const At |
updateEventHandlerInternal(op, handlerClass, target); |
} |
+void EventHandlerRegistry::didAddExternalEventHandler(const AtomicString& eventType) |
+{ |
+ updateEventHandlerOfType(Add, eventType, 0); |
+} |
+ |
+void EventHandlerRegistry::didRemoveExternalEventHandler(const AtomicString& eventType) |
+{ |
+ updateEventHandlerOfType(Remove, eventType, 0); |
+} |
+ |
void EventHandlerRegistry::didAddEventHandler(EventTarget& target, const AtomicString& eventType) |
{ |
updateEventHandlerOfType(Add, eventType, &target); |
@@ -155,12 +197,21 @@ void EventHandlerRegistry::updateAllEventHandlers(ChangeOperation op, EventTarge |
void EventHandlerRegistry::notifyHasHandlersChanged(EventHandlerClass handlerClass, bool hasActiveHandlers) |
{ |
ScrollingCoordinator* scrollingCoordinator = m_frameHost.page().scrollingCoordinator(); |
+ LocalFrame* mainFrame = m_frameHost.page().mainFrame(); |
switch (handlerClass) { |
case ScrollEvent: |
if (scrollingCoordinator) |
scrollingCoordinator->updateHaveScrollEventHandlers(); |
break; |
+ case WheelEvent: |
+ if (mainFrame) { |
+ // TODO(skyostil): This notification is wired up to a black hole, so remove it. |
+ mainFrame->notifyChromeClientWheelEventHandlerCountChanged(); |
+ } |
+ if (scrollingCoordinator) |
+ scrollingCoordinator->updateHaveWheelEventHandlers(); |
+ break; |
#if ASSERT_ENABLED |
case EventsForTesting: |
break; |
@@ -181,7 +232,7 @@ void EventHandlerRegistry::clearWeakMembers(Visitor* visitor) |
Vector<EventTarget*> deadTargets; |
for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
- const EventTargetSet* targets = &m_targets[handlerClass]; |
+ const EventTargetSet* targets = &m_handlers[handlerClass].targets; |
for (EventTargetSet::const_iterator it = targets->begin(); it != targets->end(); ++it) { |
Node* node = it->key->toNode(); |
DOMWindow* window = it->key->toDOMWindow(); |
@@ -202,7 +253,7 @@ void EventHandlerRegistry::documentDetached(Document& document) |
for (size_t handlerClassIndex = 0; handlerClassIndex < EventHandlerClassCount; ++handlerClassIndex) { |
EventHandlerClass handlerClass = static_cast<EventHandlerClass>(handlerClassIndex); |
Vector<EventTarget*> targetsToRemove; |
- const EventTargetSet* targets = &m_targets[handlerClass]; |
+ const EventTargetSet* targets = &m_handlers[handlerClass].targets; |
for (EventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter) { |
if (Node* node = iter->key->toNode()) { |
for (Document* doc = &node->document(); doc; doc = doc->ownerElement() ? &doc->ownerElement()->document() : 0) { |
@@ -228,7 +279,7 @@ void EventHandlerRegistry::checkConsistency() const |
#if ASSERT_ENABLED |
for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
- const EventTargetSet* targets = &m_targets[handlerClass]; |
+ const EventTargetSet* targets = &m_handlers[handlerClass].targets; |
for (EventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter) { |
if (Node* node = iter->key->toNode()) { |
// See the comment for |documentDetached| if either of these assertions fails. |