tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ElementStateManager.h (4568B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_layers_ElementStateManager_h
      8 #define mozilla_layers_ElementStateManager_h
      9 
     10 #include "nsCOMPtr.h"
     11 #include "nsISupportsImpl.h"
     12 #include "mozilla/EnumSet.h"
     13 
     14 namespace mozilla {
     15 
     16 class CancelableRunnable;
     17 
     18 namespace dom {
     19 class Element;
     20 class EventTarget;
     21 }  // namespace dom
     22 
     23 namespace layers {
     24 
     25 class DelayedClearElementActivation;
     26 
     27 namespace apz {
     28 enum class SingleTapState : uint8_t;
     29 }  // namespace apz
     30 
     31 /**
     32 * Manages setting and clearing the ':active' or `:hover` CSS pseudostate in the
     33 * presence of touch input.
     34 */
     35 class ElementStateManager final {
     36  ~ElementStateManager();
     37 
     38 public:
     39  NS_INLINE_DECL_REFCOUNTING(ElementStateManager)
     40 
     41  ElementStateManager();
     42 
     43  enum class PreventDefault : bool { No, Yes };
     44  /**
     45   * Specify the target of a touch. Typically this should be called right
     46   * after HandleTouchStart(), but in cases where the APZ needs to wait for
     47   * a content response the HandleTouchStart() may be delayed, in which case
     48   * this function can be called first.
     49   * |aTarget| may be nullptr.
     50   */
     51  void SetTargetElement(dom::EventTarget* aTarget,
     52                        PreventDefault aTouchStartPreventDefault);
     53  /**
     54   * Handle a touch-start state notification from APZ. This notification
     55   * may be delayed until after touch listeners have responded to the APZ.
     56   * @param aCanBePanOrZoom whether the touch can be a pan or double-tap-to-zoom
     57   */
     58  void HandleTouchStart(bool aCanBePanOrZoom);
     59 
     60  /**
     61   * Handle an eStartPanning state notification from APZ.
     62   */
     63  void HandleStartPanning();
     64 
     65  /**
     66   * Clear the active element.
     67   */
     68  void ClearActivation();
     69  /**
     70   * Handle a touch-end or touch-cancel event.
     71   * @param aWasClick whether the touch was a click
     72   */
     73  bool HandleTouchEndEvent(apz::SingleTapState aState);
     74  /**
     75   * Handle a touch-end state notification from APZ. This notification may be
     76   * delayed until after touch listeners have responded to the APZ.
     77   */
     78  bool HandleTouchEnd(apz::SingleTapState aState);
     79  /**
     80   * Possibly clear active element sate in response to a single tap.
     81   */
     82  void ProcessSingleTap();
     83  /**
     84   * Cleanup on window destroy.
     85   */
     86  void Destroy();
     87 
     88 private:
     89  /**
     90   * The target of the first touch point in the current touch block.
     91   */
     92  RefPtr<dom::Element> mTarget;
     93  /**
     94   * Whether the current touch block can be a pan or double-tap-to-zoom. Set in
     95   * HandleTouchStart().
     96   */
     97  bool mCanBePanOrZoom;
     98  /**
     99   * Whether mCanBePanOrZoom has been set for the current touch block.
    100   * We need to keep track of this to allow HandleTouchStart() and
    101   * SetTargetElement() to be called in either order.
    102   */
    103  bool mCanBePanOrZoomSet;
    104 
    105  bool mSingleTapBeforeActivation;
    106 
    107  enum class TouchEndState : uint8_t {
    108    GotTouchEndNotification,
    109    GotTouchEndEvent,
    110  };
    111  using TouchEndStates = EnumSet<TouchEndState>;
    112 
    113  /**
    114   * A flag tracks whether `APZStateChange::eEndTouch` notification has arrived
    115   * and whether `eTouchEnd` event has arrived.
    116   */
    117  TouchEndStates mTouchEndState;
    118 
    119  /**
    120   * A tri-state variable to represent the single tap state when both of
    121   * `APZStateChange::eEndTouch` notification and `eTouchEnd` event arrived.
    122   */
    123  apz::SingleTapState mSingleTapState;
    124 
    125  /**
    126   * A task for calling SetActive() after a timeout.
    127   */
    128  RefPtr<CancelableRunnable> mSetActiveTask;
    129 
    130  /**
    131   * A task for calling SetHover() after a timeout.
    132   */
    133  RefPtr<CancelableRunnable> mSetHoverTask;
    134 
    135  // Store the pending single tap event element activation clearing
    136  // task.
    137  RefPtr<DelayedClearElementActivation> mDelayedClearElementActivation;
    138 
    139  // Helpers
    140  void TriggerElementActivation();
    141  void SetActive(dom::Element* aTarget);
    142  void SetHover(dom::Element* aTarget);
    143  void ResetActive();
    144  void ResetTouchBlockState();
    145  void ScheduleSetActiveTask();
    146  void SetActiveTask(const nsCOMPtr<dom::Element>& aTarget);
    147  void CancelActiveTask();
    148  void ScheduleSetHoverTask();
    149  void SetHoverTask(const nsCOMPtr<dom::Element>& aTarget);
    150  void CancelHoverTask();
    151  // Returns true if the function changed the active element state.
    152  bool MaybeChangeActiveState(apz::SingleTapState aState);
    153 };
    154 
    155 }  // namespace layers
    156 }  // namespace mozilla
    157 
    158 #endif /* mozilla_layers_ElementStateManager_h */