Chromium Code Reviews| 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..0a93359d286151dd0fa4e4380e667c182e6f1ae3 |
| --- /dev/null |
| +++ b/Source/core/dom/EventHandlerRegistry.h |
| @@ -0,0 +1,126 @@ |
| +// 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/DocumentLifecycleObserver.h" |
| +#include "core/dom/DocumentSupplementable.h" |
| +#include "core/events/Event.h" |
| +#include "core/frame/DOMWindowLifecycleObserver.h" |
| +#include "wtf/HashCountedSet.h" |
| + |
| +namespace WebCore { |
| + |
| +class DOMWindow; |
| + |
| +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 DOMWindowLifecycleObserver, public DocumentLifecycleObserver { |
| +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 the number of registered event handlers for the given class on |
| + // the host Document as well as all child Documents. For efficiency each |
|
Rick Byers
2014/03/27 16:43:31
I find this wording a little contradictory. How a
Sami
2014/04/02 19:58:05
Thanks for putting it into simpler words :) Note t
|
| + // child Document only reports none (0) or any (1) handlers instead of the |
| + // actual count. |
| + unsigned eventHandlerCount(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; |
| + |
| + // Registration and management of event handlers attached to EventTargets. |
| + void didAddEventHandler(EventTarget&, const AtomicString&); |
|
Rick Byers
2014/03/27 16:43:31
document (perhaps just with a good variable name)
Sami
2014/04/02 19:58:05
Done.
|
| + void didRemoveEventHandler(EventTarget&, const AtomicString&); |
| + void didMoveToNewDocument(EventTarget&, Document& oldDocument); |
| + void didRemoveAllEventHandlers(EventTarget&); |
| + |
| + // Registration of event handlers attached to non-DOM objects. |
| + void didAddExternalEventHandler(Document&, const AtomicString&); |
|
Rick Byers
2014/03/27 16:43:31
each EventHandlerRegistry is coupled to a specific
Sami
2014/04/02 19:58:05
Excellent point. Even though the call sites might
|
| + void didRemoveExternalEventHandler(Document&, const AtomicString&); |
| + |
| + // Inherited from DOMWindowLifecycleObserver |
|
Rick Byers
2014/03/27 16:43:31
It may be confusing to clients of this class wheth
Sami
2014/04/02 19:58:05
Great suggestion, done.
|
| + virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE; |
| + virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE; |
| + virtual void didRemoveAllEventListeners(DOMWindow*) OVERRIDE; |
| + |
| + // Inherited from DocumentLifecycleObserver |
| + virtual void documentWasAttached() OVERRIDE; |
| + virtual void willDetachDocument() 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, Document&, 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, Document&); |
| + |
| + // 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 notifyDidAddFirstOrRemoveLastEventHandler(Document&, EventHandlerClass, bool hasActiveHandlers); |
|
Rick Byers
2014/03/27 16:43:31
this method name is a mouthfull. How about notify
Sami
2014/04/02 19:58:05
Couldn't have put it better myself :)
|
| + |
| + // Record a change operation to a given event handler class and notify any |
| + // parent registry and other clients accordingly. |
| + void updateEventHandlerOfClass(ChangeOperation, EventHandlerClass, EventTarget&); |
| + void updateEventHandlerOfType(ChangeOperation, const AtomicString&, EventTarget&); |
| + |
| + void updateExternalHandlerCount(ChangeOperation, EventHandlerClass); |
| + void updateEventHandlerInternal(ChangeOperation, Document&, EventHandlerClass, EventTarget*); |
| + void checkEventHandlerConsistency(EventHandlerClass) const; |
| + |
| + // Perform a bulk update of all registered event handlers on a given |
| + // EventTarget. The updates will be applied to |EventHandlerRegistry| |
| + // instead of |this|. |
| + void updateAllEventHandlersForTarget(ChangeOperation, EventTarget&, EventHandlerRegistry&) const; |
| + |
| + struct HandlerState { |
| + HandlerState(); |
| + ~HandlerState(); |
| + |
| + OwnPtr<EventTargetSet> targets; |
| + // Count of all handler targets in |targets|, including repeated ones. |
| + unsigned handlerCount; |
| + // External handlers are not included in |targets|. |
| + unsigned externalHandlerCount; |
| + }; |
| + |
| + HandlerState m_eventHandlers[EventHandlerClassCount]; |
| +}; |
| + |
| +} // namespace WebCore |
| + |
| +#endif // EventHandlerRegistry_h |