tor-browser

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

TextInputProcessor.h (9879B)


      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_textinputprocessor_h_
      8 #define mozilla_dom_textinputprocessor_h_
      9 
     10 #include "mozilla/Attributes.h"
     11 #include "mozilla/BasicEvents.h"
     12 #include "mozilla/EventForwards.h"
     13 #include "mozilla/Maybe.h"
     14 #include "mozilla/TextEventDispatcher.h"
     15 #include "mozilla/TextEventDispatcherListener.h"
     16 #include "nsITextInputProcessor.h"
     17 #include "nsITextInputProcessorCallback.h"
     18 #include "nsTArray.h"
     19 
     20 class nsPIDOMWindowInner;
     21 
     22 namespace mozilla {
     23 
     24 namespace dom {
     25 class KeyboardEvent;
     26 }  // namespace dom
     27 
     28 class TextInputProcessor final : public nsITextInputProcessor,
     29                                 public widget::TextEventDispatcherListener {
     30  typedef mozilla::widget::IMENotification IMENotification;
     31  typedef mozilla::widget::IMENotificationRequests IMENotificationRequests;
     32  typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
     33 
     34 public:
     35  TextInputProcessor();
     36 
     37  NS_DECL_ISUPPORTS
     38  NS_DECL_NSITEXTINPUTPROCESSOR
     39 
     40  // TextEventDispatcherListener
     41  MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD
     42  NotifyIME(TextEventDispatcher* aTextEventDispatcher,
     43            const IMENotification& aNotification) override;
     44 
     45  NS_IMETHOD_(IMENotificationRequests) GetIMENotificationRequests() override;
     46 
     47  NS_IMETHOD_(void)
     48  OnRemovedFrom(TextEventDispatcher* aTextEventDispatcher) override;
     49 
     50  NS_IMETHOD_(void)
     51  WillDispatchKeyboardEvent(TextEventDispatcher* aTextEventDispatcher,
     52                            WidgetKeyboardEvent& aKeyboardEvent,
     53                            uint32_t aIndexOfKeypress, void* aData) override;
     54 
     55  /**
     56   * TextInputProcessor manages modifier key state.  E.g., when it dispatches
     57   * a modifier keydown event, activates proper modifier state and when it
     58   * dispatches a modifier keyup event, inactivates proper modifier state.
     59   * This returns all active modifiers in the instance.
     60   */
     61  Modifiers GetActiveModifiers() const {
     62    return mModifierKeyDataArray ? mModifierKeyDataArray->GetActiveModifiers()
     63                                 : MODIFIER_NONE;
     64  }
     65 
     66  /**
     67   * This begins transaction for fuzzing.  This must be called only by
     68   * FuzzingFunctions since this skips the permission check.
     69   * See explanation of nsITextInputProcessor::BeginInputTransaction() for
     70   * the detail.
     71   */
     72  nsresult BeginInputTransactionForFuzzing(
     73      nsPIDOMWindowInner* aWindow, nsITextInputProcessorCallback* aCallback,
     74      bool* aSucceeded);
     75 
     76  /**
     77   * The following Keydown() and KeyUp() are same as nsITextInputProcessor's
     78   * same name methods except the type of event class.  See explanation in
     79   * nsITextInputProcessor for the detail.
     80   */
     81  MOZ_CAN_RUN_SCRIPT nsresult Keydown(const WidgetKeyboardEvent& aKeyboardEvent,
     82                                      uint32_t aKeyFlags,
     83                                      uint32_t* aConsumedFlags = nullptr);
     84  nsresult Keyup(const WidgetKeyboardEvent& aKeyboardEvent, uint32_t aKeyFlags,
     85                 bool* aDoDefault = nullptr);
     86 
     87  /**
     88   * GuessCodeNameIndexOfPrintableKeyInUSEnglishLayout() returns CodeNameIndex
     89   * of a printable key which is in usual keyboard of the platform and when
     90   * active keyboard layout is US-English.
     91   * Note that this does not aware of option key mapping on macOS.
     92   *
     93   * @param aKeyValue          The key value. Must be a character which can
     94   *                           be inputted with US-English keyboard layout.
     95   * @param aLocation          The location of the key.  This is important
     96   *                           to distinguish whether the key is in Standard
     97   *                           or Numpad. If this is not some, treated as
     98   *                           Standard.
     99   * @return                   Returns CODE_NAME_INDEX_UNKNOWN if there is
    100   *                           no proper key.
    101   */
    102  static CodeNameIndex GuessCodeNameIndexOfPrintableKeyInUSEnglishLayout(
    103      const nsAString& aKeyValue, const Maybe<uint32_t>& aLocation);
    104 
    105  /**
    106   * GuessKeyCodeOfPrintableKeyInUSEnglishLayout() returns a key code value
    107   * of a printable key which is in usual keyboard of the platform and when
    108   * active keyboard layout is US-English.
    109   * Note that this does not aware of option key mapping on macOS.
    110   *
    111   * @param aKeyValue          The key value. Must be a character which can
    112   *                           be inputted with US-English keyboard layout.
    113   * @param aLocation          The location of the key.  This is important
    114   *                           to distinguish whether the key is in Standard
    115   *                           or Numpad. If this is not some, treated as
    116   *                           Standard.
    117   * @return                   Returns 0 if there is no proper key to input
    118   *                           aKeyValue with US-English keyboard layout.
    119   */
    120  static uint32_t GuessKeyCodeOfPrintableKeyInUSEnglishLayout(
    121      const nsAString& aKeyValue, const Maybe<uint32_t>& aLocation);
    122 
    123 protected:
    124  virtual ~TextInputProcessor();
    125 
    126 private:
    127  bool IsComposing() const;
    128  nsresult BeginInputTransactionInternal(
    129      mozIDOMWindow* aWindow, nsITextInputProcessorCallback* aCallback,
    130      bool aForTests, bool& aSucceeded);
    131  MOZ_CAN_RUN_SCRIPT nsresult CommitCompositionInternal(
    132      const WidgetKeyboardEvent* aKeyboardEvent = nullptr,
    133      uint32_t aKeyFlags = 0, const nsAString* aCommitString = nullptr,
    134      bool* aSucceeded = nullptr);
    135  MOZ_CAN_RUN_SCRIPT nsresult
    136  CancelCompositionInternal(const WidgetKeyboardEvent* aKeyboardEvent = nullptr,
    137                            uint32_t aKeyFlags = 0);
    138  MOZ_CAN_RUN_SCRIPT nsresult
    139  KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent, uint32_t aKeyFlags,
    140                  bool aAllowToDispatchKeypress, uint32_t& aConsumedFlags);
    141  nsresult KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
    142                         uint32_t aKeyFlags, bool& aDoDefault);
    143  nsresult IsValidStateForComposition();
    144  void UnlinkFromTextEventDispatcher();
    145  nsresult PrepareKeyboardEventToDispatch(WidgetKeyboardEvent& aKeyboardEvent,
    146                                          uint32_t aKeyFlags);
    147  /**
    148   * InitEditCommands() initializes edit commands of aKeyboardEvent.
    149   * This must be called only in a content process, and aKeyboardEvent must
    150   * be used only for `eKeyPress` event.
    151   */
    152  MOZ_CAN_RUN_SCRIPT nsresult
    153  InitEditCommands(WidgetKeyboardEvent& aKeyboardEvent) const;
    154 
    155  bool IsValidEventTypeForComposition(
    156      const WidgetKeyboardEvent& aKeyboardEvent) const;
    157  nsresult PrepareKeyboardEventForComposition(
    158      dom::KeyboardEvent* aDOMKeyEvent, uint32_t& aKeyFlags,
    159      uint8_t aOptionalArgc, WidgetKeyboardEvent*& aKeyboardEvent);
    160 
    161  struct EventDispatcherResult {
    162    nsresult mResult;
    163    bool mDoDefault;
    164    bool mCanContinue;
    165 
    166    EventDispatcherResult()
    167        : mResult(NS_OK), mDoDefault(true), mCanContinue(true) {}
    168  };
    169  MOZ_CAN_RUN_SCRIPT EventDispatcherResult MaybeDispatchKeydownForComposition(
    170      const WidgetKeyboardEvent* aKeyboardEvent, uint32_t aKeyFlags);
    171  EventDispatcherResult MaybeDispatchKeyupForComposition(
    172      const WidgetKeyboardEvent* aKeyboardEvent, uint32_t aKeyFlags);
    173 
    174  /**
    175   * AutoPendingCompositionResetter guarantees to clear all pending composition
    176   * data in its destructor.
    177   */
    178  class MOZ_STACK_CLASS AutoPendingCompositionResetter {
    179   public:
    180    explicit AutoPendingCompositionResetter(TextInputProcessor* aTIP);
    181    ~AutoPendingCompositionResetter();
    182 
    183   private:
    184    RefPtr<TextInputProcessor> mTIP;
    185  };
    186 
    187  /**
    188   * TextInputProcessor manages modifier state both with .key and .code.
    189   * For example, left shift key up shouldn't cause inactivating shift state
    190   * while right shift key is being pressed.
    191   */
    192  struct ModifierKeyData {
    193    // One of modifier key name
    194    KeyNameIndex mKeyNameIndex;
    195    // Any code name is allowed.
    196    CodeNameIndex mCodeNameIndex;
    197    // A modifier key flag which is activated by the key.
    198    Modifiers mModifier;
    199 
    200    explicit ModifierKeyData(const WidgetKeyboardEvent& aKeyboardEvent);
    201 
    202    bool operator==(const ModifierKeyData& aOther) const {
    203      return mKeyNameIndex == aOther.mKeyNameIndex &&
    204             mCodeNameIndex == aOther.mCodeNameIndex;
    205    }
    206  };
    207 
    208  class ModifierKeyDataArray : public nsTArray<ModifierKeyData> {
    209    NS_INLINE_DECL_REFCOUNTING(ModifierKeyDataArray)
    210 
    211   public:
    212    Modifiers GetActiveModifiers() const;
    213    void ActivateModifierKey(const ModifierKeyData& aModifierKeyData);
    214    void InactivateModifierKey(const ModifierKeyData& aModifierKeyData);
    215    void ToggleModifierKey(const ModifierKeyData& aModifierKeyData);
    216 
    217   private:
    218    virtual ~ModifierKeyDataArray() = default;
    219  };
    220 
    221  void EnsureModifierKeyDataArray() {
    222    if (mModifierKeyDataArray) {
    223      return;
    224    }
    225    mModifierKeyDataArray = new ModifierKeyDataArray();
    226  }
    227  void ActivateModifierKey(const ModifierKeyData& aModifierKeyData) {
    228    EnsureModifierKeyDataArray();
    229    mModifierKeyDataArray->ActivateModifierKey(aModifierKeyData);
    230  }
    231  void InactivateModifierKey(const ModifierKeyData& aModifierKeyData) {
    232    if (!mModifierKeyDataArray) {
    233      return;
    234    }
    235    mModifierKeyDataArray->InactivateModifierKey(aModifierKeyData);
    236  }
    237  void ToggleModifierKey(const ModifierKeyData& aModifierKeyData) {
    238    EnsureModifierKeyDataArray();
    239    mModifierKeyDataArray->ToggleModifierKey(aModifierKeyData);
    240  }
    241 
    242  TextEventDispatcher* mDispatcher;  // [Weak]
    243  nsCOMPtr<nsITextInputProcessorCallback> mCallback;
    244  RefPtr<ModifierKeyDataArray> mModifierKeyDataArray;
    245 
    246  bool mForTests;
    247 };
    248 
    249 }  // namespace mozilla
    250 
    251 #endif  // #ifndef mozilla_dom_textinputprocessor_h_