tor-browser

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

UserActivation.h (6585B)


      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_dom_UserActivation_h
      8 #define mozilla_dom_UserActivation_h
      9 
     10 #include "mozilla/Assertions.h"
     11 #include "mozilla/EventForwards.h"
     12 #include "mozilla/TimeStamp.h"
     13 #include "nsCycleCollectionParticipant.h"
     14 #include "nsPIDOMWindow.h"
     15 #include "nsWrapperCache.h"
     16 
     17 namespace IPC {
     18 template <class P>
     19 struct ParamTraits;
     20 }  // namespace IPC
     21 
     22 namespace mozilla::dom {
     23 
     24 /**
     25 * Most of this class is for the old user activation model. The new model
     26 * defined in the spec [1] is implemented by `dom::WindowContext` (see
     27 * `WindowContext::GetUserActivationState` etc.) since the state defined in the
     28 * spec is associated with the `window` object.
     29 *
     30 * [1]:
     31 * https://html.spec.whatwg.org/multipage/interaction.html#user-activation-data-model
     32 */
     33 class UserActivation final : public nsISupports, public nsWrapperCache {
     34 public:
     35  // WebIDL UserActivation
     36 
     37  NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINAL
     38  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(UserActivation)
     39 
     40  explicit UserActivation(nsPIDOMWindowInner* aWindow);
     41 
     42  nsPIDOMWindowInner* GetParentObject() const { return mWindow; }
     43  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
     44 
     45  bool HasBeenActive() const;
     46  bool IsActive() const;
     47 
     48  // End of WebIDL UserActivation
     49 
     50  enum class State : uint8_t {
     51    // Not activated.
     52    None,
     53    // It is considered as has-been-activated, but not transient-activated given
     54    // that it is being consumed.
     55    HasBeenActivated,
     56    // It is considered as has-been-activated, and also transient-activated if
     57    // haven't timed out.
     58    FullActivated,
     59    EndGuard_
     60  };
     61 
     62  class StateAndModifiers;
     63 
     64  // Modifier keys held while the user activation.
     65  class Modifiers {
     66   public:
     67    static constexpr uint8_t Shift = 0x10;
     68    static constexpr uint8_t Meta = 0x20;
     69    static constexpr uint8_t Control = 0x40;
     70    static constexpr uint8_t Alt = 0x80;
     71    static constexpr uint8_t MiddleMouse = 0x08;
     72 
     73    static constexpr uint8_t Mask = 0xF8;
     74 
     75    static_assert((uint8_t(State::EndGuard_) & ~Mask) ==
     76                  uint8_t(State::EndGuard_));
     77 
     78    constexpr Modifiers() = default;
     79    explicit constexpr Modifiers(uint8_t aModifiers) : mModifiers(aModifiers) {}
     80 
     81    static constexpr Modifiers None() { return Modifiers(0); }
     82 
     83    void SetShift() { mModifiers |= Shift; }
     84    void SetMeta() { mModifiers |= Meta; }
     85    void SetControl() { mModifiers |= Control; }
     86    void SetAlt() { mModifiers |= Alt; }
     87    void SetMiddleMouse() { mModifiers |= MiddleMouse; }
     88 
     89    bool IsShift() const { return mModifiers & Shift; }
     90    bool IsMeta() const { return mModifiers & Meta; }
     91    bool IsControl() const { return mModifiers & Control; }
     92    bool IsAlt() const { return mModifiers & Alt; }
     93    bool IsMiddleMouse() const { return mModifiers & MiddleMouse; }
     94 
     95   private:
     96    uint8_t mModifiers = 0;
     97 
     98    friend class StateAndModifiers;
     99    template <class P>
    100    friend struct IPC::ParamTraits;
    101  };
    102 
    103  // State and Modifiers encoded into single data, for WindowContext field.
    104  class StateAndModifiers {
    105   public:
    106    using DataT = uint8_t;
    107 
    108    constexpr StateAndModifiers() = default;
    109    explicit constexpr StateAndModifiers(DataT aStateAndModifiers)
    110        : mStateAndModifiers(aStateAndModifiers) {}
    111 
    112    DataT GetRawData() const { return mStateAndModifiers; }
    113 
    114    State GetState() const { return State(RawState()); }
    115    void SetState(State aState) {
    116      MOZ_ASSERT((uint8_t(aState) & Modifiers::Mask) == 0);
    117      mStateAndModifiers = uint8_t(aState) | RawModifiers();
    118    }
    119 
    120    Modifiers GetModifiers() const { return Modifiers(RawModifiers()); }
    121    void SetModifiers(Modifiers aModifiers) {
    122      mStateAndModifiers = RawState() | aModifiers.mModifiers;
    123    }
    124 
    125   private:
    126    uint8_t RawState() const { return mStateAndModifiers & ~Modifiers::Mask; }
    127 
    128    uint8_t RawModifiers() const {
    129      return mStateAndModifiers & Modifiers::Mask;
    130    }
    131 
    132    uint8_t mStateAndModifiers = 0;
    133  };
    134 
    135  /**
    136   * Returns true if the current code is being executed as a result of
    137   * user input or keyboard input.  The former includes anything that is
    138   * initiated by user, with the exception of page load events or mouse
    139   * over events.  And the latter returns true when one of the user inputs
    140   * is an input from keyboard.  If these methods are called from asynchronously
    141   * executed code, such as during layout reflows, it will return false.
    142   */
    143  static bool IsHandlingUserInput();
    144  static bool IsHandlingKeyboardInput();
    145 
    146  /**
    147   * Returns true if the event is considered as user interaction event. I.e.,
    148   * enough obvious input to allow to open popup, etc. Otherwise, returns false.
    149   */
    150  static bool IsUserInteractionEvent(const WidgetEvent* aEvent);
    151 
    152  /**
    153   * StartHandlingUserInput() is called when we start to handle a user input.
    154   * StopHandlingUserInput() is called when we finish handling a user input.
    155   * If the caller knows which input event caused that, it should set
    156   * aMessage to the event message.  Otherwise, set eVoidEvent.
    157   * Note that StopHandlingUserInput() caller should call it with exactly same
    158   * event message as its corresponding StartHandlingUserInput() call because
    159   * these methods may count the number of specific event message.
    160   */
    161  static void StartHandlingUserInput(EventMessage aMessage);
    162  static void StopHandlingUserInput(EventMessage aMessage);
    163 
    164  static TimeStamp GetHandlingInputStart();
    165 
    166  /**
    167   * Get the timestamp at which the latest user input was handled.
    168   *
    169   * Guaranteed to be monotonic. Until the first user input, return
    170   * the epoch.
    171   */
    172  static TimeStamp LatestUserInputStart();
    173 
    174 private:
    175  ~UserActivation() = default;
    176 
    177  nsCOMPtr<nsPIDOMWindowInner> mWindow;
    178 };
    179 
    180 /**
    181 * This class is used while processing real user input. During this time, popups
    182 * are allowed. For mousedown events, mouse capturing is also permitted.
    183 */
    184 class MOZ_RAII AutoHandlingUserInputStatePusher final {
    185 public:
    186  explicit AutoHandlingUserInputStatePusher(bool aIsHandlingUserInput,
    187                                            WidgetEvent* aEvent = nullptr);
    188  ~AutoHandlingUserInputStatePusher();
    189 
    190 protected:
    191  EventMessage mMessage;
    192  bool mIsHandlingUserInput;
    193 };
    194 
    195 }  // namespace mozilla::dom
    196 
    197 #endif  // mozilla_dom_UserActivation_h