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

Unified Diff: Source/core/dom/EventHandlerRegistry.cpp

Issue 206603002: Add EventHandlerRegistry (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: One more unneeded include. Created 6 years, 8 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
« no previous file with comments | « Source/core/dom/EventHandlerRegistry.h ('k') | Source/core/dom/Node.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/dom/EventHandlerRegistry.cpp
diff --git a/Source/core/dom/EventHandlerRegistry.cpp b/Source/core/dom/EventHandlerRegistry.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b72b465ffaadc0a31187c14559227570e38b81e7
--- /dev/null
+++ b/Source/core/dom/EventHandlerRegistry.cpp
@@ -0,0 +1,202 @@
+// Copyright 2014 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/dom/EventHandlerRegistry.h"
+
+#include "core/dom/Document.h"
+#include "core/events/ThreadLocalEventNames.h"
+#include "core/events/WheelEvent.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/Page.h"
+#include "core/page/scrolling/ScrollingCoordinator.h"
+
+namespace WebCore {
+
+EventHandlerRegistry::HandlerState::HandlerState()
+{
+}
+
+EventHandlerRegistry::HandlerState::~HandlerState()
+{
+}
+
+EventHandlerRegistry::EventHandlerRegistry(Document& document)
+ : m_document(document)
+{
+}
+
+EventHandlerRegistry::~EventHandlerRegistry()
+{
+}
+
+const char* EventHandlerRegistry::supplementName()
+{
+ return "EventHandlerRegistry";
+}
+
+EventHandlerRegistry* EventHandlerRegistry::from(Document& document)
+{
+ EventHandlerRegistry* registry = static_cast<EventHandlerRegistry*>(DocumentSupplement::from(document, supplementName()));
+ if (!registry) {
+ registry = new EventHandlerRegistry(document);
+ DocumentSupplement::provideTo(document, supplementName(), adoptPtr(registry));
+ }
+ return registry;
+}
+
+bool EventHandlerRegistry::eventTypeToClass(const AtomicString& eventType, EventHandlerClass* result)
+{
+ if (eventType == EventTypeNames::scroll) {
+ *result = ScrollEvent;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+const EventTargetSet* EventHandlerRegistry::eventHandlerTargets(EventHandlerClass handlerClass) const
+{
+ return m_eventHandlers[handlerClass].targets.get();
+}
+
+bool EventHandlerRegistry::hasEventHandlers(EventHandlerClass handlerClass) const
+{
+ EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get();
+ return targets && targets->size();
+}
+
+bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHandlerClass handlerClass, EventTarget* target)
+{
+ EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get();
+ if (op == Add) {
+#if ASSERT_ENABLED
+ if (Node* node = target->toNode())
+ ASSERT(&node->document() == &m_document);
+#endif // ASSERT_ENABLED
+
+ if (!targets) {
+ m_eventHandlers[handlerClass].targets = adoptPtr(new EventTargetSet);
+ targets = m_eventHandlers[handlerClass].targets.get();
+ }
+
+ if (!targets->add(target).isNewEntry) {
+ // Just incremented refcount, no real change.
+ return false;
+ }
+ } else {
+ // Note that we can't assert that |target| is in this document because
+ // it might be in the process of moving out of it.
+ ASSERT(op == Remove || op == RemoveAll);
+ ASSERT(op == RemoveAll || targets->contains(target));
+ if (!targets)
+ return false;
+
+ if (op == RemoveAll) {
+ if (!targets->contains(target))
+ return false;
+ targets->removeAll(target);
+ } else {
+ if (!targets->remove(target)) {
+ // Just decremented refcount, no real update.
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void EventHandlerRegistry::updateEventHandlerInternal(ChangeOperation op, EventHandlerClass handlerClass, EventTarget* target)
+{
+ // After the document has stopped, all updates become no-ops.
+ if (!m_document.isActive()) {
+ return;
+ }
+
+ bool hadHandlers = hasEventHandlers(handlerClass);
+ updateEventHandlerTargets(op, handlerClass, target);
+ bool hasHandlers = hasEventHandlers(handlerClass);
+
+ // Notify the parent document's registry if we added the first or removed
+ // the last handler.
+ if (hadHandlers != hasHandlers && !m_document.parentDocument()) {
+ // This is the root registry; notify clients accordingly.
+ notifyHasHandlersChanged(handlerClass, hasHandlers);
+ }
+}
+
+void EventHandlerRegistry::updateEventHandlerOfType(ChangeOperation op, const AtomicString& eventType, EventTarget* target)
+{
+ EventHandlerClass handlerClass;
+ if (!eventTypeToClass(eventType, &handlerClass))
+ return;
+ updateEventHandlerInternal(op, handlerClass, target);
+}
+
+void EventHandlerRegistry::didAddEventHandler(EventTarget& target, const AtomicString& eventType)
+{
+ updateEventHandlerOfType(Add, eventType, &target);
+}
+
+void EventHandlerRegistry::didRemoveEventHandler(EventTarget& target, const AtomicString& eventType)
+{
+ updateEventHandlerOfType(Remove, eventType, &target);
+}
+
+void EventHandlerRegistry::didAddEventHandler(EventTarget& target, EventHandlerClass handlerClass)
+{
+ updateEventHandlerInternal(Add, handlerClass, &target);
+}
+
+void EventHandlerRegistry::didRemoveEventHandler(EventTarget& target, EventHandlerClass handlerClass)
+{
+ updateEventHandlerInternal(Remove, handlerClass, &target);
+}
+
+void EventHandlerRegistry::didMoveFromOtherDocument(EventTarget& target, Document& oldDocument)
+{
+ EventHandlerRegistry* oldRegistry = EventHandlerRegistry::from(oldDocument);
+ for (size_t i = 0; i < EventHandlerClassCount; ++i) {
+ EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i);
+ const EventTargetSet* targets = oldRegistry->eventHandlerTargets(handlerClass);
+ if (!targets)
+ continue;
+ for (unsigned count = targets->count(&target); count > 0; --count) {
+ oldRegistry->updateEventHandlerInternal(Remove, handlerClass, &target);
+ updateEventHandlerInternal(Add, handlerClass, &target);
+ }
+ }
+}
+
+void EventHandlerRegistry::didRemoveAllEventHandlers(EventTarget& target)
+{
+ for (size_t i = 0; i < EventHandlerClassCount; ++i) {
+ EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i);
+ const EventTargetSet* targets = eventHandlerTargets(handlerClass);
+ if (!targets)
+ continue;
+ updateEventHandlerInternal(RemoveAll, handlerClass, &target);
+ }
+}
+
+void EventHandlerRegistry::notifyHasHandlersChanged(EventHandlerClass handlerClass, bool hasActiveHandlers)
+{
+ Page* page = m_document.page();
+ ScrollingCoordinator* scrollingCoordinator = page ? page->scrollingCoordinator() : 0;
+
+ switch (handlerClass) {
+ case ScrollEvent:
+ if (scrollingCoordinator)
+ scrollingCoordinator->updateHaveScrollEventHandlers();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+} // namespace WebCore
« no previous file with comments | « Source/core/dom/EventHandlerRegistry.h ('k') | Source/core/dom/Node.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698