forked from mirrors/gecko-dev
		
	# ignore-this-changeset --HG-- extra : amend_source : 4d301d3b0b8711c4692392aa76088ba7fd7d1022
		
			
				
	
	
		
			240 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | 
						|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | 
						|
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
#ifndef mozilla_dom_textinputprocessor_h_
 | 
						|
#define mozilla_dom_textinputprocessor_h_
 | 
						|
 | 
						|
#include "mozilla/Attributes.h"
 | 
						|
#include "mozilla/EventForwards.h"
 | 
						|
#include "mozilla/Maybe.h"
 | 
						|
#include "mozilla/TextEventDispatcher.h"
 | 
						|
#include "mozilla/TextEventDispatcherListener.h"
 | 
						|
#include "nsITextInputProcessor.h"
 | 
						|
#include "nsITextInputProcessorCallback.h"
 | 
						|
#include "nsTArray.h"
 | 
						|
 | 
						|
class nsPIDOMWindowInner;
 | 
						|
 | 
						|
namespace mozilla {
 | 
						|
 | 
						|
namespace dom {
 | 
						|
class KeyboardEvent;
 | 
						|
}  // namespace dom
 | 
						|
 | 
						|
class TextInputProcessor final : public nsITextInputProcessor,
 | 
						|
                                 public widget::TextEventDispatcherListener {
 | 
						|
  typedef mozilla::widget::IMENotification IMENotification;
 | 
						|
  typedef mozilla::widget::IMENotificationRequests IMENotificationRequests;
 | 
						|
  typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
 | 
						|
 | 
						|
 public:
 | 
						|
  TextInputProcessor();
 | 
						|
 | 
						|
  NS_DECL_ISUPPORTS
 | 
						|
  NS_DECL_NSITEXTINPUTPROCESSOR
 | 
						|
 | 
						|
  // TextEventDispatcherListener
 | 
						|
  NS_IMETHOD NotifyIME(TextEventDispatcher* aTextEventDispatcher,
 | 
						|
                       const IMENotification& aNotification) override;
 | 
						|
 | 
						|
  NS_IMETHOD_(IMENotificationRequests) GetIMENotificationRequests() override;
 | 
						|
 | 
						|
  NS_IMETHOD_(void)
 | 
						|
  OnRemovedFrom(TextEventDispatcher* aTextEventDispatcher) override;
 | 
						|
 | 
						|
  NS_IMETHOD_(void)
 | 
						|
  WillDispatchKeyboardEvent(TextEventDispatcher* aTextEventDispatcher,
 | 
						|
                            WidgetKeyboardEvent& aKeyboardEvent,
 | 
						|
                            uint32_t aIndexOfKeypress, void* aData) override;
 | 
						|
 | 
						|
  /**
 | 
						|
   * TextInputProcessor manages modifier key state.  E.g., when it dispatches
 | 
						|
   * a modifier keydown event, activates proper modifier state and when it
 | 
						|
   * dispatches a modifier keyup event, inactivates proper modifier state.
 | 
						|
   * This returns all active modifiers in the instance.
 | 
						|
   */
 | 
						|
  Modifiers GetActiveModifiers() const {
 | 
						|
    return mModifierKeyDataArray ? mModifierKeyDataArray->GetActiveModifiers()
 | 
						|
                                 : MODIFIER_NONE;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This begins transaction for fuzzing.  This must be called only by
 | 
						|
   * FuzzingFunctions since this skips the permission check.
 | 
						|
   * See explanation of nsITextInputProcessor::BeginInputTransaction() for
 | 
						|
   * the detail.
 | 
						|
   */
 | 
						|
  nsresult BeginInputTransactionForFuzzing(
 | 
						|
      nsPIDOMWindowInner* aWindow, nsITextInputProcessorCallback* aCallback,
 | 
						|
      bool* aSucceeded);
 | 
						|
 | 
						|
  /**
 | 
						|
   * The following Keydown() and KeyUp() are same as nsITextInputProcessor's
 | 
						|
   * same name methods except the type of event class.  See explanation in
 | 
						|
   * nsITextInputProcessor for the detail.
 | 
						|
   */
 | 
						|
  nsresult Keydown(const WidgetKeyboardEvent& aKeyboardEvent,
 | 
						|
                   uint32_t aKeyFlags, uint32_t* aConsumedFlags = nullptr);
 | 
						|
  nsresult Keyup(const WidgetKeyboardEvent& aKeyboardEvent, uint32_t aKeyFlags,
 | 
						|
                 bool* aDoDefault = nullptr);
 | 
						|
 | 
						|
  /**
 | 
						|
   * GuessCodeNameIndexOfPrintableKeyInUSEnglishLayout() returns CodeNameIndex
 | 
						|
   * of a printable key which is in usual keyboard of the platform and when
 | 
						|
   * active keyboard layout is US-English.
 | 
						|
   * Note that this does not aware of option key mapping on macOS.
 | 
						|
   *
 | 
						|
   * @param aKeyValue          The key value. Must be a character which can
 | 
						|
   *                           be inputted with US-English keyboard layout.
 | 
						|
   * @param aLocation          The location of the key.  This is important
 | 
						|
   *                           to distinguish whether the key is in Standard
 | 
						|
   *                           or Numpad. If this is not some, treated as
 | 
						|
   *                           Standard.
 | 
						|
   * @return                   Returns CODE_NAME_INDEX_UNKNOWN if there is
 | 
						|
   *                           no proper key.
 | 
						|
   */
 | 
						|
  static CodeNameIndex GuessCodeNameIndexOfPrintableKeyInUSEnglishLayout(
 | 
						|
      const nsAString& aKeyValue, const Maybe<uint32_t>& aLocation);
 | 
						|
 | 
						|
  /**
 | 
						|
   * GuessKeyCodeOfPrintableKeyInUSEnglishLayout() returns a key code value
 | 
						|
   * of a printable key which is in usual keyboard of the platform and when
 | 
						|
   * active keyboard layout is US-English.
 | 
						|
   * Note that this does not aware of option key mapping on macOS.
 | 
						|
   *
 | 
						|
   * @param aKeyValue          The key value. Must be a character which can
 | 
						|
   *                           be inputted with US-English keyboard layout.
 | 
						|
   * @param aLocation          The location of the key.  This is important
 | 
						|
   *                           to distinguish whether the key is in Standard
 | 
						|
   *                           or Numpad. If this is not some, treated as
 | 
						|
   *                           Standard.
 | 
						|
   * @return                   Returns 0 if there is no proper key to input
 | 
						|
   *                           aKeyValue with US-English keyboard layout.
 | 
						|
   */
 | 
						|
  static uint32_t GuessKeyCodeOfPrintableKeyInUSEnglishLayout(
 | 
						|
      const nsAString& aKeyValue, const Maybe<uint32_t>& aLocation);
 | 
						|
 | 
						|
 protected:
 | 
						|
  virtual ~TextInputProcessor();
 | 
						|
 | 
						|
 private:
 | 
						|
  bool IsComposing() const;
 | 
						|
  nsresult BeginInputTransactionInternal(
 | 
						|
      mozIDOMWindow* aWindow, nsITextInputProcessorCallback* aCallback,
 | 
						|
      bool aForTests, bool& aSucceeded);
 | 
						|
  nsresult CommitCompositionInternal(
 | 
						|
      const WidgetKeyboardEvent* aKeyboardEvent = nullptr,
 | 
						|
      uint32_t aKeyFlags = 0, const nsAString* aCommitString = nullptr,
 | 
						|
      bool* aSucceeded = nullptr);
 | 
						|
  nsresult CancelCompositionInternal(
 | 
						|
      const WidgetKeyboardEvent* aKeyboardEvent = nullptr,
 | 
						|
      uint32_t aKeyFlags = 0);
 | 
						|
  nsresult KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
 | 
						|
                           uint32_t aKeyFlags, bool aAllowToDispatchKeypress,
 | 
						|
                           uint32_t& aConsumedFlags);
 | 
						|
  nsresult KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
 | 
						|
                         uint32_t aKeyFlags, bool& aDoDefault);
 | 
						|
  nsresult IsValidStateForComposition();
 | 
						|
  void UnlinkFromTextEventDispatcher();
 | 
						|
  nsresult PrepareKeyboardEventToDispatch(WidgetKeyboardEvent& aKeyboardEvent,
 | 
						|
                                          uint32_t aKeyFlags);
 | 
						|
  bool IsValidEventTypeForComposition(
 | 
						|
      const WidgetKeyboardEvent& aKeyboardEvent) const;
 | 
						|
  nsresult PrepareKeyboardEventForComposition(
 | 
						|
      dom::KeyboardEvent* aDOMKeyEvent, uint32_t& aKeyFlags,
 | 
						|
      uint8_t aOptionalArgc, WidgetKeyboardEvent*& aKeyboardEvent);
 | 
						|
 | 
						|
  struct EventDispatcherResult {
 | 
						|
    nsresult mResult;
 | 
						|
    bool mDoDefault;
 | 
						|
    bool mCanContinue;
 | 
						|
 | 
						|
    EventDispatcherResult()
 | 
						|
        : mResult(NS_OK), mDoDefault(true), mCanContinue(true) {}
 | 
						|
  };
 | 
						|
  EventDispatcherResult MaybeDispatchKeydownForComposition(
 | 
						|
      const WidgetKeyboardEvent* aKeyboardEvent, uint32_t aKeyFlags);
 | 
						|
  EventDispatcherResult MaybeDispatchKeyupForComposition(
 | 
						|
      const WidgetKeyboardEvent* aKeyboardEvent, uint32_t aKeyFlags);
 | 
						|
 | 
						|
  /**
 | 
						|
   * AutoPendingCompositionResetter guarantees to clear all pending composition
 | 
						|
   * data in its destructor.
 | 
						|
   */
 | 
						|
  class MOZ_STACK_CLASS AutoPendingCompositionResetter {
 | 
						|
   public:
 | 
						|
    explicit AutoPendingCompositionResetter(TextInputProcessor* aTIP);
 | 
						|
    ~AutoPendingCompositionResetter();
 | 
						|
 | 
						|
   private:
 | 
						|
    RefPtr<TextInputProcessor> mTIP;
 | 
						|
  };
 | 
						|
 | 
						|
  /**
 | 
						|
   * TextInputProcessor manages modifier state both with .key and .code.
 | 
						|
   * For example, left shift key up shouldn't cause inactivating shift state
 | 
						|
   * while right shift key is being pressed.
 | 
						|
   */
 | 
						|
  struct ModifierKeyData {
 | 
						|
    // One of modifier key name
 | 
						|
    KeyNameIndex mKeyNameIndex;
 | 
						|
    // Any code name is allowed.
 | 
						|
    CodeNameIndex mCodeNameIndex;
 | 
						|
    // A modifier key flag which is activated by the key.
 | 
						|
    Modifiers mModifier;
 | 
						|
 | 
						|
    explicit ModifierKeyData(const WidgetKeyboardEvent& aKeyboardEvent);
 | 
						|
 | 
						|
    bool operator==(const ModifierKeyData& aOther) const {
 | 
						|
      return mKeyNameIndex == aOther.mKeyNameIndex &&
 | 
						|
             mCodeNameIndex == aOther.mCodeNameIndex;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  class ModifierKeyDataArray : public nsTArray<ModifierKeyData> {
 | 
						|
    NS_INLINE_DECL_REFCOUNTING(ModifierKeyDataArray)
 | 
						|
 | 
						|
   public:
 | 
						|
    Modifiers GetActiveModifiers() const;
 | 
						|
    void ActivateModifierKey(const ModifierKeyData& aModifierKeyData);
 | 
						|
    void InactivateModifierKey(const ModifierKeyData& aModifierKeyData);
 | 
						|
    void ToggleModifierKey(const ModifierKeyData& aModifierKeyData);
 | 
						|
 | 
						|
   private:
 | 
						|
    virtual ~ModifierKeyDataArray() {}
 | 
						|
  };
 | 
						|
 | 
						|
  void EnsureModifierKeyDataArray() {
 | 
						|
    if (mModifierKeyDataArray) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    mModifierKeyDataArray = new ModifierKeyDataArray();
 | 
						|
  }
 | 
						|
  void ActivateModifierKey(const ModifierKeyData& aModifierKeyData) {
 | 
						|
    EnsureModifierKeyDataArray();
 | 
						|
    mModifierKeyDataArray->ActivateModifierKey(aModifierKeyData);
 | 
						|
  }
 | 
						|
  void InactivateModifierKey(const ModifierKeyData& aModifierKeyData) {
 | 
						|
    if (!mModifierKeyDataArray) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    mModifierKeyDataArray->InactivateModifierKey(aModifierKeyData);
 | 
						|
  }
 | 
						|
  void ToggleModifierKey(const ModifierKeyData& aModifierKeyData) {
 | 
						|
    EnsureModifierKeyDataArray();
 | 
						|
    mModifierKeyDataArray->ToggleModifierKey(aModifierKeyData);
 | 
						|
  }
 | 
						|
 | 
						|
  TextEventDispatcher* mDispatcher;  // [Weak]
 | 
						|
  nsCOMPtr<nsITextInputProcessorCallback> mCallback;
 | 
						|
  RefPtr<ModifierKeyDataArray> mModifierKeyDataArray;
 | 
						|
 | 
						|
  bool mForTests;
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace mozilla
 | 
						|
 | 
						|
#endif  // #ifndef mozilla_dom_textinputprocessor_h_
 |