forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			199 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
	
		
			6.4 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/TextEventDispatcher.h"
 | |
| #include "mozilla/TextEventDispatcherListener.h"
 | |
| #include "nsITextInputProcessor.h"
 | |
| #include "nsITextInputProcessorCallback.h"
 | |
| #include "nsTArray.h"
 | |
| 
 | |
| 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;
 | |
| 
 | |
| 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() { }
 | |
|   };
 | |
| 
 | |
|   Modifiers GetActiveModifiers() const
 | |
|   {
 | |
|     return mModifierKeyDataArray ?
 | |
|       mModifierKeyDataArray->GetActiveModifiers() : 0;
 | |
|   }
 | |
|   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_
 | 
