19f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project// Copyright 2014 The Chromium Authors. All rights reserved.
29f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project// Use of this source code is governed by a BSD-style license that can be
39f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project// found in the LICENSE file.
49f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
59f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifndef EventHandlerRegistry_h
69f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define EventHandlerRegistry_h
79f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
89f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "core/frame/FrameHost.h"
99f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "wtf/HashCountedSet.h"
109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectnamespace blink {
129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectclass Document;
149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectclass EventTarget;
159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef HashCountedSet<EventTarget*> EventTargetSet;
179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project// Registry for keeping track of event handlers. Note that only handlers on
199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project// documents that can be rendered or can receive input (i.e., are attached to a
209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project// FrameHost) are registered here.
219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectclass EventHandlerRegistry FINAL : public NoBaseWillBeGarbageCollectedFinalized<EventHandlerRegistry> {
229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectpublic:
239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    explicit EventHandlerRegistry(FrameHost&);
249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    virtual ~EventHandlerRegistry();
259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // Supported event handler classes. Note that each one may correspond to
279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // multiple event types.
289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    enum EventHandlerClass {
299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project        ScrollEvent,
309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project        WheelEvent,
319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project        TouchEvent,
329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#if ENABLE(ASSERT)
339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project        // Additional event categories for verifying handler tracking logic.
349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project        EventsForTesting,
359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project        EventHandlerClassCount, // Must be the last entry.
379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    };
389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // Returns true if the FrameHost has event handlers of the specified class.
409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    bool hasEventHandlers(EventHandlerClass) const;
419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // Returns a set of EventTargets which have registered handlers of the given class.
439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    const EventTargetSet* eventHandlerTargets(EventHandlerClass) const;
449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // Registration and management of event handlers attached to EventTargets.
469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void didAddEventHandler(EventTarget&, const AtomicString& eventType);
479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void didAddEventHandler(EventTarget&, EventHandlerClass);
489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void didRemoveEventHandler(EventTarget&, const AtomicString& eventType);
499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void didRemoveEventHandler(EventTarget&, EventHandlerClass);
509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void didRemoveAllEventHandlers(EventTarget&);
519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void didMoveIntoFrameHost(EventTarget&);
539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void didMoveOutOfFrameHost(EventTarget&);
549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    static void didMoveBetweenFrameHosts(EventTarget&, FrameHost* oldFrameHost, FrameHost* newFrameHost);
559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // Either |documentDetached| or |didMove{Into,OutOf,Between}FrameHosts| must
579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // be called whenever the FrameHost that is associated with a registered event
589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // target changes. This ensures the registry does not end up with stale
599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // references to handlers that are no longer related to it.
609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void documentDetached(Document&);
619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void trace(Visitor*);
639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void clearWeakMembers(Visitor*);
649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectprivate:
669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    enum ChangeOperation {
679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project        Add, // Add a new event handler.
689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project        Remove, // Remove an existing event handler.
699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project        RemoveAll // Remove any and all existing event handlers for a given target.
709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    };
719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // Returns true if |eventType| belongs to a class this registry tracks.
739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    static bool eventTypeToClass(const AtomicString& eventType, EventHandlerClass* result);
749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // Returns true if the operation actually added a new target or completely
769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // removed an existing one.
779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    bool updateEventHandlerTargets(ChangeOperation, EventHandlerClass, EventTarget*);
789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // Called on the EventHandlerRegistry of the root Document to notify
809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // clients when we have added the first handler or removed the last one for
819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // a given event class. |hasActiveHandlers| can be used to distinguish
829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // between the two cases.
839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void notifyHasHandlersChanged(EventHandlerClass, bool hasActiveHandlers);
849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // Called to notify clients whenever a single event handler target is
869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // registered or unregistered. If several handlers are registered for the
879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // same target, only the first registration will trigger this notification.
889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void notifyDidAddOrRemoveEventHandlerTarget(EventHandlerClass);
899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // Record a change operation to a given event handler class and notify any
919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    // parent registry and other clients accordingly.
929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void updateEventHandlerOfType(ChangeOperation, const AtomicString& eventType, EventTarget*);
939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void updateEventHandlerInternal(ChangeOperation, EventHandlerClass, EventTarget*);
959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void updateAllEventHandlers(ChangeOperation, EventTarget&);
979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    void checkConsistency() const;
999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    FrameHost& m_frameHost;
1019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    EventTargetSet m_targets[EventHandlerClassCount];
1029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project};
1039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} // namespace blink
1059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif // EventHandlerRegistry_h
1079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project