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 THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_EVENT_HANDLER_REGISTRY_H_
6 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_EVENT_HANDLER_REGISTRY_H_
7 
8 #include "third_party/blink/renderer/core/core_export.h"  // TODO(sashab): Remove this.
9 #include "third_party/blink/renderer/core/page/page.h"
10 #include "third_party/blink/renderer/platform/wtf/hash_counted_set.h"
11 
12 namespace blink {
13 
14 class AddEventListenerOptions;
15 class Document;
16 class EventTarget;
17 class LocalFrame;
18 
19 typedef HashCountedSet<UntracedMember<EventTarget>> EventTargetSet;
20 
21 // Registry for keeping track of event handlers. Note that only handlers on
22 // documents that can be rendered or can receive input (i.e., are attached to a
23 // Page) are registered here. Each local root has an EventHandlerRegistry;
24 // event targets for a frame may only be registered with the
25 // EventHandlerRegistry of its corresponding local root.
26 class CORE_EXPORT EventHandlerRegistry final
27     : public GarbageCollected<EventHandlerRegistry> {
28  public:
29   explicit EventHandlerRegistry(LocalFrame&);
30   virtual ~EventHandlerRegistry();
31 
32   // Supported event handler classes. Note that each one may correspond to
33   // multiple event types.
34   enum EventHandlerClass {
35     kScrollEvent,
36     kWheelEventBlocking,
37     kWheelEventPassive,
38     kTouchAction,
39     kTouchStartOrMoveEventBlocking,
40     kTouchStartOrMoveEventBlockingLowLatency,
41     kTouchStartOrMoveEventPassive,
42     kTouchEndOrCancelEventBlocking,
43     kTouchEndOrCancelEventPassive,
44     kPointerEvent,  // This includes all pointerevents excluding
45                     // pointerrawupdate.
46     kPointerRawUpdateEvent,
47 #if DCHECK_IS_ON()
48     // Additional event categories for verifying handler tracking logic.
49     kEventsForTesting,
50 #endif
51     kEventHandlerClassCount,  // Must be the last entry.
52   };
53 
54   // Returns true if the Page has event handlers of the specified class.
55   bool HasEventHandlers(EventHandlerClass) const;
56 
57   // Returns a set of EventTargets which have registered handlers of the given
58   // class.
59   const EventTargetSet* EventHandlerTargets(EventHandlerClass) const;
60 
61   // Registration and management of event handlers attached to EventTargets.
62   void DidAddEventHandler(EventTarget&,
63                           const AtomicString& event_type,
64                           const AddEventListenerOptions*);
65   void DidAddEventHandler(EventTarget&, EventHandlerClass);
66   void DidRemoveEventHandler(EventTarget&,
67                              const AtomicString& event_type,
68                              const AddEventListenerOptions*);
69   void DidRemoveEventHandler(EventTarget&, EventHandlerClass);
70   void DidRemoveAllEventHandlers(EventTarget&);
71 
72   void DidMoveIntoPage(EventTarget&);
73   void DidMoveOutOfPage(EventTarget&);
74 
75   // Either |documentDetached| or |didMove{Into,OutOf,Between}Pages| must
76   // be called whenever the Page that is associated with a registered event
77   // target changes. This ensures the registry does not end up with stale
78   // references to handlers that are no longer related to it.
79   void DocumentDetached(Document&);
80 
81   void Trace(Visitor*);
82 
83  private:
84   enum ChangeOperation {
85     kAdd,       // Add a new event handler.
86     kRemove,    // Remove an existing event handler.
87     kRemoveAll  // Remove any and all existing event handlers for a given
88                 // target.
89   };
90 
91   // Returns true if |eventType| belongs to a class this registry tracks.
92   static bool EventTypeToClass(const AtomicString& event_type,
93                                const AddEventListenerOptions*,
94                                EventHandlerClass* result);
95 
96   // Returns true if the operation actually added a new target or completely
97   // removed an existing one.
98   bool UpdateEventHandlerTargets(ChangeOperation,
99                                  EventHandlerClass,
100                                  EventTarget*);
101 
102   // Called on the EventHandlerRegistry of the root Document to notify
103   // clients when we have added or remove a handler for a given event class.
104   // |hasActiveHandlers| can be used to distinguish between having and not
105   // having an active handler.
106   void NotifyHandlersChanged(EventTarget*,
107                              EventHandlerClass,
108                              bool has_active_handlers);
109 
110   // Called to notify clients whenever a single event handler target is
111   // registered or unregistered. If several handlers are registered for the
112   // same target, only the first registration will trigger this notification.
113   void NotifyDidAddOrRemoveEventHandlerTarget(LocalFrame*, EventHandlerClass);
114 
115   // Record a change operation to a given event handler class and notify any
116   // parent registry and other clients accordingly.
117   void UpdateEventHandlerOfType(ChangeOperation,
118                                 const AtomicString& event_type,
119                                 const AddEventListenerOptions*,
120                                 EventTarget*);
121 
122   bool UpdateEventHandlerInternal(ChangeOperation,
123                                   EventHandlerClass,
124                                   EventTarget*);
125 
126   void UpdateAllEventHandlers(ChangeOperation, EventTarget&);
127 
128   void CheckConsistency(EventHandlerClass) const;
129 
130   Page* GetPage() const;
131 
132   void ProcessCustomWeakness(const WeakCallbackInfo&);
133 
134   Member<LocalFrame> frame_;
135   EventTargetSet targets_[kEventHandlerClassCount];
136 };
137 
138 }  // namespace blink
139 
140 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_EVENT_HANDLER_REGISTRY_H_
141