Home | History | Annotate | Download | only in frame
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef EventHandlerRegistry_h
      6 #define EventHandlerRegistry_h
      7 
      8 #include "core/frame/FrameHost.h"
      9 #include "wtf/HashCountedSet.h"
     10 
     11 namespace blink {
     12 
     13 class Document;
     14 class EventTarget;
     15 
     16 typedef HashCountedSet<EventTarget*> EventTargetSet;
     17 
     18 // Registry for keeping track of event handlers. Note that only handlers on
     19 // documents that can be rendered or can receive input (i.e., are attached to a
     20 // FrameHost) are registered here.
     21 class EventHandlerRegistry FINAL : public NoBaseWillBeGarbageCollectedFinalized<EventHandlerRegistry> {
     22 public:
     23     explicit EventHandlerRegistry(FrameHost&);
     24     virtual ~EventHandlerRegistry();
     25 
     26     // Supported event handler classes. Note that each one may correspond to
     27     // multiple event types.
     28     enum EventHandlerClass {
     29         ScrollEvent,
     30         WheelEvent,
     31         TouchEvent,
     32 #if ENABLE(ASSERT)
     33         // Additional event categories for verifying handler tracking logic.
     34         EventsForTesting,
     35 #endif
     36         EventHandlerClassCount, // Must be the last entry.
     37     };
     38 
     39     // Returns true if the FrameHost has event handlers of the specified class.
     40     bool hasEventHandlers(EventHandlerClass) const;
     41 
     42     // Returns a set of EventTargets which have registered handlers of the given class.
     43     const EventTargetSet* eventHandlerTargets(EventHandlerClass) const;
     44 
     45     // Registration and management of event handlers attached to EventTargets.
     46     void didAddEventHandler(EventTarget&, const AtomicString& eventType);
     47     void didAddEventHandler(EventTarget&, EventHandlerClass);
     48     void didRemoveEventHandler(EventTarget&, const AtomicString& eventType);
     49     void didRemoveEventHandler(EventTarget&, EventHandlerClass);
     50     void didRemoveAllEventHandlers(EventTarget&);
     51 
     52     void didMoveIntoFrameHost(EventTarget&);
     53     void didMoveOutOfFrameHost(EventTarget&);
     54     static void didMoveBetweenFrameHosts(EventTarget&, FrameHost* oldFrameHost, FrameHost* newFrameHost);
     55 
     56     // Either |documentDetached| or |didMove{Into,OutOf,Between}FrameHosts| must
     57     // be called whenever the FrameHost that is associated with a registered event
     58     // target changes. This ensures the registry does not end up with stale
     59     // references to handlers that are no longer related to it.
     60     void documentDetached(Document&);
     61 
     62     void trace(Visitor*);
     63     void clearWeakMembers(Visitor*);
     64 
     65 private:
     66     enum ChangeOperation {
     67         Add, // Add a new event handler.
     68         Remove, // Remove an existing event handler.
     69         RemoveAll // Remove any and all existing event handlers for a given target.
     70     };
     71 
     72     // Returns true if |eventType| belongs to a class this registry tracks.
     73     static bool eventTypeToClass(const AtomicString& eventType, EventHandlerClass* result);
     74 
     75     // Returns true if the operation actually added a new target or completely
     76     // removed an existing one.
     77     bool updateEventHandlerTargets(ChangeOperation, EventHandlerClass, EventTarget*);
     78 
     79     // Called on the EventHandlerRegistry of the root Document to notify
     80     // clients when we have added the first handler or removed the last one for
     81     // a given event class. |hasActiveHandlers| can be used to distinguish
     82     // between the two cases.
     83     void notifyHasHandlersChanged(EventHandlerClass, bool hasActiveHandlers);
     84 
     85     // Called to notify clients whenever a single event handler target is
     86     // registered or unregistered. If several handlers are registered for the
     87     // same target, only the first registration will trigger this notification.
     88     void notifyDidAddOrRemoveEventHandlerTarget(EventHandlerClass);
     89 
     90     // Record a change operation to a given event handler class and notify any
     91     // parent registry and other clients accordingly.
     92     void updateEventHandlerOfType(ChangeOperation, const AtomicString& eventType, EventTarget*);
     93 
     94     void updateEventHandlerInternal(ChangeOperation, EventHandlerClass, EventTarget*);
     95 
     96     void updateAllEventHandlers(ChangeOperation, EventTarget&);
     97 
     98     void checkConsistency() const;
     99 
    100     FrameHost& m_frameHost;
    101     EventTargetSet m_targets[EventHandlerClassCount];
    102 };
    103 
    104 } // namespace blink
    105 
    106 #endif // EventHandlerRegistry_h
    107