forked from mirrors/gecko-dev
		
	 265e672179
			
		
	
	
		265e672179
		
	
	
	
	
		
			
			# 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_
 |