Index: Source/core/dom/EventHandlerRegistry.h |
diff --git a/Source/core/dom/EventHandlerRegistry.h b/Source/core/dom/EventHandlerRegistry.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ccaf06d2ba695da8781103a269c25f2148f87f71 |
--- /dev/null |
+++ b/Source/core/dom/EventHandlerRegistry.h |
@@ -0,0 +1,143 @@ |
+// 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. |
+ |
+#ifndef EventHandlerRegistry_h |
+#define EventHandlerRegistry_h |
+ |
+#include "core/dom/ActiveDOMObject.h" |
+#include "core/dom/DocumentLifecycleObserver.h" |
+#include "core/dom/DocumentSupplementable.h" |
+#include "core/events/Event.h" |
+#include "core/frame/DOMWindowLifecycleObserver.h" |
+#include "wtf/HashCountedSet.h" |
+ |
+namespace WebCore { |
+ |
+typedef HashCountedSet<EventTarget*> EventTargetSet; |
+ |
+// Registry for keeping track of event handlers. Handlers can either be |
+// associated with an EventTarget or be "external" handlers which live outside |
+// the DOM (e.g., WebViewImpl). |
+class EventHandlerRegistry FINAL : public DocumentSupplement { |
+public: |
+ virtual ~EventHandlerRegistry(); |
+ |
+ // Supported event handler classes. Note that each one may correspond to |
+ // multiple event types. |
+ enum EventHandlerClass { |
+ WheelEvent, |
+ ScrollEvent, |
+ TouchEvent, |
+ EventHandlerClassCount, // Must be the last entry. |
+ }; |
+ |
+ static const char* supplementName(); |
+ static EventHandlerRegistry* from(Document&); |
+ |
+ // Returns true if the host Document or any child documents have any |
+ // registered event handlers of the class. |
+ bool hasEventHandlers(EventHandlerClass) const; |
+ |
+ // Returns a set of EventTargets which have registered handlers of the |
+ // given class. Only contains targets directly in this document; all |
+ // handlers in a child Document are collapsed to a single respective |
+ // Document instance in the set. |
+ const EventTargetSet* eventHandlerTargets(EventHandlerClass) const; |
+ |
+ // Returns the number of external event handlers for a given class. |
+ // External handlers are not included in |eventHandlerTargets|. |
+ unsigned externalEventHandlerCount(EventHandlerClass) const; |
+ |
+ // Registration and management of event handlers attached to EventTargets. |
+ void didAddEventHandler(EventTarget&, const AtomicString& eventType); |
+ void didAddEventHandler(EventTarget&, EventHandlerClass); |
+ void didRemoveEventHandler(EventTarget&, const AtomicString& eventType); |
+ void didRemoveEventHandler(EventTarget&, EventHandlerClass); |
+ void didMoveFromOtherDocument(EventTarget&, Document& oldDocument); |
+ void didRemoveAllEventHandlers(EventTarget&); |
+ |
+ // Registration of event handlers attached to non-DOM objects. |
+ void didAddExternalEventHandler(const AtomicString& eventType); |
+ void didRemoveExternalEventHandler(const AtomicString& eventType); |
+ |
+ virtual void trace(Visitor*) OVERRIDE { } |
+private: |
+ explicit EventHandlerRegistry(Document&); |
+ |
+ enum ChangeOperation { |
+ Add, // Add a new event handler. |
+ Remove, // Remove an existing event handler. |
+ RemoveAll // Remove any and all existing event handlers for a given target. |
+ }; |
+ |
+ // Returns true if |eventType| belongs to a class this registry tracks. |
+ static bool eventTypeToClass(const AtomicString& eventType, EventHandlerClass* result); |
+ |
+ // Returns true if the operation actually added a new target or completely |
+ // removed an existing one. |
+ bool updateEventHandlerTargets(ChangeOperation, EventHandlerClass, EventTarget*); |
+ |
+ // Called to notify clients whenever a single event handler target is |
+ // registered or unregistered. If several handlers are registered for the |
+ // same target, only the first registration will trigger this notification. |
+ void notifyDidAddOrRemoveEventHandlerTarget(EventHandlerClass); |
+ |
+ // Called on the EventHandlerRegistry of the root Document to notify |
+ // clients when we have added the first handler or removed the last one for |
+ // a given event class. |hasActiveHandlers| can be used to distinguish |
+ // between the two cases. |
+ void notifyHasHandlersChanged(EventHandlerClass, bool hasActiveHandlers); |
+ |
+ // Record a change operation to a given event handler class and notify any |
+ // parent registry and other clients accordingly. |
+ void updateEventHandlerOfType(ChangeOperation, const AtomicString& eventType, EventTarget*); |
+ |
+ void updateExternalHandlerCount(ChangeOperation, EventHandlerClass); |
+ void updateEventHandlerInternal(ChangeOperation, EventHandlerClass, EventTarget*); |
+ |
+ class DocumentObserver: public DocumentLifecycleObserver, public ActiveDOMObject { |
abarth-chromium
2014/04/11 19:08:01
You shouldn't need to be both a DocumentLifecycleO
Sami
2014/04/15 18:31:52
Right, I don't need anything from DocumentLifecycl
|
+ public: |
+ explicit DocumentObserver(Document&); |
+ ~DocumentObserver(); |
abarth-chromium
2014/04/11 19:08:01
Presumably this needs to be virtual.
Sami
2014/04/15 18:31:52
Done.
|
+ |
+ // Inherited from DocumentLifecycleObserver |
+ virtual void documentWasAttached() OVERRIDE; |
+ |
+ // Inherited from ActiveDOMObject |
+ virtual void stop() OVERRIDE; |
+ }; |
+ |
+ class WindowObserver: public DOMWindowLifecycleObserver { |
+ public: |
+ WindowObserver(EventHandlerRegistry&, DOMWindow&); |
+ ~WindowObserver(); |
+ |
+ // Inherited from DOMWindowLifecycleObserver |
+ virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE; |
+ virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE; |
+ virtual void didRemoveAllEventListeners(DOMWindow*) OVERRIDE; |
+ private: |
+ EventHandlerRegistry& m_registry; |
+ }; |
+ |
+ struct HandlerState { |
+ HandlerState(); |
+ ~HandlerState(); |
+ |
+ OwnPtr<EventTargetSet> targets; |
+ // External handlers are not included in |targets|. |
+ unsigned externalHandlerCount; |
+ }; |
+ |
+ Document& m_document; |
+ |
+ DocumentObserver m_documentObserver; |
+ OwnPtr<WindowObserver> m_windowObserver; |
+ |
+ HandlerState m_eventHandlers[EventHandlerClassCount]; |
+}; |
+ |
+} // namespace WebCore |
+ |
+#endif // EventHandlerRegistry_h |