Line data Source code
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/EventForwards.h"
12 : #include "mozilla/TextEventDispatcher.h"
13 : #include "mozilla/TextEventDispatcherListener.h"
14 : #include "nsITextInputProcessor.h"
15 : #include "nsITextInputProcessorCallback.h"
16 : #include "nsTArray.h"
17 :
18 : namespace mozilla {
19 :
20 : class TextInputProcessor final : public nsITextInputProcessor
21 : , public widget::TextEventDispatcherListener
22 : {
23 : typedef mozilla::widget::IMENotification IMENotification;
24 : typedef mozilla::widget::IMENotificationRequests IMENotificationRequests;
25 : typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
26 :
27 : public:
28 : TextInputProcessor();
29 :
30 : NS_DECL_ISUPPORTS
31 : NS_DECL_NSITEXTINPUTPROCESSOR
32 :
33 : // TextEventDispatcherListener
34 : NS_IMETHOD NotifyIME(TextEventDispatcher* aTextEventDispatcher,
35 : const IMENotification& aNotification) override;
36 :
37 : NS_IMETHOD_(IMENotificationRequests) GetIMENotificationRequests() override;
38 :
39 : NS_IMETHOD_(void)
40 : OnRemovedFrom(TextEventDispatcher* aTextEventDispatcher) override;
41 :
42 : NS_IMETHOD_(void) WillDispatchKeyboardEvent(
43 : TextEventDispatcher* aTextEventDispatcher,
44 : WidgetKeyboardEvent& aKeyboardEvent,
45 : uint32_t aIndexOfKeypress,
46 : void* aData) override;
47 :
48 : protected:
49 : virtual ~TextInputProcessor();
50 :
51 : private:
52 : bool IsComposing() const;
53 : nsresult BeginInputTransactionInternal(
54 : mozIDOMWindow* aWindow,
55 : nsITextInputProcessorCallback* aCallback,
56 : bool aForTests,
57 : bool& aSucceeded);
58 : nsresult CommitCompositionInternal(
59 : const WidgetKeyboardEvent* aKeyboardEvent = nullptr,
60 : uint32_t aKeyFlags = 0,
61 : const nsAString* aCommitString = nullptr,
62 : bool* aSucceeded = nullptr);
63 : nsresult CancelCompositionInternal(
64 : const WidgetKeyboardEvent* aKeyboardEvent = nullptr,
65 : uint32_t aKeyFlags = 0);
66 : nsresult KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
67 : uint32_t aKeyFlags,
68 : bool aAllowToDispatchKeypress,
69 : uint32_t& aConsumedFlags);
70 : nsresult KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
71 : uint32_t aKeyFlags,
72 : bool& aDoDefault);
73 : nsresult IsValidStateForComposition();
74 : void UnlinkFromTextEventDispatcher();
75 : nsresult PrepareKeyboardEventToDispatch(WidgetKeyboardEvent& aKeyboardEvent,
76 : uint32_t aKeyFlags);
77 : bool IsValidEventTypeForComposition(
78 : const WidgetKeyboardEvent& aKeyboardEvent) const;
79 : nsresult PrepareKeyboardEventForComposition(
80 : nsIDOMKeyEvent* aDOMKeyEvent,
81 : uint32_t& aKeyFlags,
82 : uint8_t aOptionalArgc,
83 : WidgetKeyboardEvent*& aKeyboardEvent);
84 :
85 : struct EventDispatcherResult
86 : {
87 : nsresult mResult;
88 : bool mDoDefault;
89 : bool mCanContinue;
90 :
91 0 : EventDispatcherResult()
92 0 : : mResult(NS_OK)
93 : , mDoDefault(true)
94 0 : , mCanContinue(true)
95 : {
96 0 : }
97 : };
98 : EventDispatcherResult MaybeDispatchKeydownForComposition(
99 : const WidgetKeyboardEvent* aKeyboardEvent,
100 : uint32_t aKeyFlags);
101 : EventDispatcherResult MaybeDispatchKeyupForComposition(
102 : const WidgetKeyboardEvent* aKeyboardEvent,
103 : uint32_t aKeyFlags);
104 :
105 : /**
106 : * AutoPendingCompositionResetter guarantees to clear all pending composition
107 : * data in its destructor.
108 : */
109 : class MOZ_STACK_CLASS AutoPendingCompositionResetter
110 : {
111 : public:
112 : explicit AutoPendingCompositionResetter(TextInputProcessor* aTIP);
113 : ~AutoPendingCompositionResetter();
114 :
115 : private:
116 : RefPtr<TextInputProcessor> mTIP;
117 : };
118 :
119 : /**
120 : * TextInputProcessor manages modifier state both with .key and .code.
121 : * For example, left shift key up shouldn't cause inactivating shift state
122 : * while right shift key is being pressed.
123 : */
124 : struct ModifierKeyData
125 : {
126 : // One of modifier key name
127 : KeyNameIndex mKeyNameIndex;
128 : // Any code name is allowed.
129 : CodeNameIndex mCodeNameIndex;
130 : // A modifier key flag which is activated by the key.
131 : Modifiers mModifier;
132 :
133 : explicit ModifierKeyData(const WidgetKeyboardEvent& aKeyboardEvent);
134 :
135 0 : bool operator==(const ModifierKeyData& aOther) const
136 : {
137 0 : return mKeyNameIndex == aOther.mKeyNameIndex &&
138 0 : mCodeNameIndex == aOther.mCodeNameIndex;
139 : }
140 : };
141 :
142 0 : class ModifierKeyDataArray : public nsTArray<ModifierKeyData>
143 : {
144 0 : NS_INLINE_DECL_REFCOUNTING(ModifierKeyDataArray)
145 :
146 : public:
147 : Modifiers GetActiveModifiers() const;
148 : void ActivateModifierKey(const ModifierKeyData& aModifierKeyData);
149 : void InactivateModifierKey(const ModifierKeyData& aModifierKeyData);
150 : void ToggleModifierKey(const ModifierKeyData& aModifierKeyData);
151 :
152 : private:
153 0 : virtual ~ModifierKeyDataArray() { }
154 : };
155 :
156 0 : Modifiers GetActiveModifiers() const
157 : {
158 : return mModifierKeyDataArray ?
159 0 : mModifierKeyDataArray->GetActiveModifiers() : 0;
160 : }
161 0 : void EnsureModifierKeyDataArray()
162 : {
163 0 : if (mModifierKeyDataArray) {
164 0 : return;
165 : }
166 0 : mModifierKeyDataArray = new ModifierKeyDataArray();
167 : }
168 0 : void ActivateModifierKey(const ModifierKeyData& aModifierKeyData)
169 : {
170 0 : EnsureModifierKeyDataArray();
171 0 : mModifierKeyDataArray->ActivateModifierKey(aModifierKeyData);
172 0 : }
173 0 : void InactivateModifierKey(const ModifierKeyData& aModifierKeyData)
174 : {
175 0 : if (!mModifierKeyDataArray) {
176 0 : return;
177 : }
178 0 : mModifierKeyDataArray->InactivateModifierKey(aModifierKeyData);
179 : }
180 0 : void ToggleModifierKey(const ModifierKeyData& aModifierKeyData)
181 : {
182 0 : EnsureModifierKeyDataArray();
183 0 : mModifierKeyDataArray->ToggleModifierKey(aModifierKeyData);
184 0 : }
185 :
186 : TextEventDispatcher* mDispatcher; // [Weak]
187 : nsCOMPtr<nsITextInputProcessorCallback> mCallback;
188 : RefPtr<ModifierKeyDataArray> mModifierKeyDataArray;
189 :
190 : bool mForTests;
191 : };
192 :
193 : } // namespace mozilla
194 :
195 : #endif // #ifndef mozilla_dom_textinputprocessor_h_
|