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 : #include "mozilla/dom/KeyboardEvent.h"
8 : #include "mozilla/TextEvents.h"
9 : #include "prtime.h"
10 :
11 : namespace mozilla {
12 : namespace dom {
13 :
14 0 : KeyboardEvent::KeyboardEvent(EventTarget* aOwner,
15 : nsPresContext* aPresContext,
16 0 : WidgetKeyboardEvent* aEvent)
17 : : UIEvent(aOwner, aPresContext,
18 : aEvent ? aEvent :
19 0 : new WidgetKeyboardEvent(false, eVoidEvent, nullptr))
20 : , mInitializedByCtor(false)
21 0 : , mInitializedWhichValue(0)
22 : {
23 0 : if (aEvent) {
24 0 : mEventIsInternal = false;
25 : }
26 : else {
27 0 : mEventIsInternal = true;
28 0 : mEvent->mTime = PR_Now();
29 0 : mEvent->AsKeyboardEvent()->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
30 : }
31 0 : }
32 :
33 0 : NS_IMPL_ADDREF_INHERITED(KeyboardEvent, UIEvent)
34 0 : NS_IMPL_RELEASE_INHERITED(KeyboardEvent, UIEvent)
35 :
36 0 : NS_INTERFACE_MAP_BEGIN(KeyboardEvent)
37 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMKeyEvent)
38 0 : NS_INTERFACE_MAP_END_INHERITING(UIEvent)
39 :
40 : bool
41 0 : KeyboardEvent::AltKey()
42 : {
43 0 : return mEvent->AsKeyboardEvent()->IsAlt();
44 : }
45 :
46 : NS_IMETHODIMP
47 0 : KeyboardEvent::GetAltKey(bool* aIsDown)
48 : {
49 0 : NS_ENSURE_ARG_POINTER(aIsDown);
50 0 : *aIsDown = AltKey();
51 0 : return NS_OK;
52 : }
53 :
54 : bool
55 0 : KeyboardEvent::CtrlKey()
56 : {
57 0 : return mEvent->AsKeyboardEvent()->IsControl();
58 : }
59 :
60 : NS_IMETHODIMP
61 0 : KeyboardEvent::GetCtrlKey(bool* aIsDown)
62 : {
63 0 : NS_ENSURE_ARG_POINTER(aIsDown);
64 0 : *aIsDown = CtrlKey();
65 0 : return NS_OK;
66 : }
67 :
68 : bool
69 0 : KeyboardEvent::ShiftKey()
70 : {
71 0 : return mEvent->AsKeyboardEvent()->IsShift();
72 : }
73 :
74 : NS_IMETHODIMP
75 0 : KeyboardEvent::GetShiftKey(bool* aIsDown)
76 : {
77 0 : NS_ENSURE_ARG_POINTER(aIsDown);
78 0 : *aIsDown = ShiftKey();
79 0 : return NS_OK;
80 : }
81 :
82 : bool
83 0 : KeyboardEvent::MetaKey()
84 : {
85 0 : return mEvent->AsKeyboardEvent()->IsMeta();
86 : }
87 :
88 : NS_IMETHODIMP
89 0 : KeyboardEvent::GetMetaKey(bool* aIsDown)
90 : {
91 0 : NS_ENSURE_ARG_POINTER(aIsDown);
92 0 : *aIsDown = MetaKey();
93 0 : return NS_OK;
94 : }
95 :
96 : bool
97 0 : KeyboardEvent::Repeat()
98 : {
99 0 : return mEvent->AsKeyboardEvent()->mIsRepeat;
100 : }
101 :
102 : NS_IMETHODIMP
103 0 : KeyboardEvent::GetRepeat(bool* aIsRepeat)
104 : {
105 0 : NS_ENSURE_ARG_POINTER(aIsRepeat);
106 0 : *aIsRepeat = Repeat();
107 0 : return NS_OK;
108 : }
109 :
110 : bool
111 0 : KeyboardEvent::IsComposing()
112 : {
113 0 : return mEvent->AsKeyboardEvent()->mIsComposing;
114 : }
115 :
116 : NS_IMETHODIMP
117 0 : KeyboardEvent::GetModifierState(const nsAString& aKey,
118 : bool* aState)
119 : {
120 0 : NS_ENSURE_ARG_POINTER(aState);
121 :
122 0 : *aState = GetModifierState(aKey);
123 0 : return NS_OK;
124 : }
125 :
126 : NS_IMETHODIMP
127 0 : KeyboardEvent::GetKey(nsAString& aKeyName)
128 : {
129 0 : mEvent->AsKeyboardEvent()->GetDOMKeyName(aKeyName);
130 0 : return NS_OK;
131 : }
132 :
133 : void
134 0 : KeyboardEvent::GetCode(nsAString& aCodeName)
135 : {
136 0 : mEvent->AsKeyboardEvent()->GetDOMCodeName(aCodeName);
137 0 : }
138 :
139 0 : void KeyboardEvent::GetInitDict(KeyboardEventInit& aParam)
140 : {
141 0 : GetKey(aParam.mKey);
142 0 : GetCode(aParam.mCode);
143 0 : aParam.mLocation = Location();
144 0 : aParam.mRepeat = Repeat();
145 0 : aParam.mIsComposing = IsComposing();
146 :
147 : // legacy attributes
148 0 : aParam.mKeyCode = KeyCode();
149 0 : aParam.mCharCode = CharCode();
150 0 : aParam.mWhich = Which();
151 :
152 : // modifiers from EventModifierInit
153 0 : aParam.mCtrlKey = CtrlKey();
154 0 : aParam.mShiftKey = ShiftKey();
155 0 : aParam.mAltKey = AltKey();
156 0 : aParam.mMetaKey = MetaKey();
157 :
158 0 : WidgetKeyboardEvent* internalEvent = mEvent->AsKeyboardEvent();
159 0 : aParam.mModifierAltGraph = internalEvent->IsAltGraph();
160 0 : aParam.mModifierCapsLock = internalEvent->IsCapsLocked();
161 0 : aParam.mModifierFn = internalEvent->IsFn();
162 0 : aParam.mModifierFnLock = internalEvent->IsFnLocked();
163 0 : aParam.mModifierNumLock = internalEvent->IsNumLocked();
164 0 : aParam.mModifierOS = internalEvent->IsOS();
165 0 : aParam.mModifierScrollLock = internalEvent->IsScrollLocked();
166 0 : aParam.mModifierSymbol = internalEvent->IsSymbol();
167 0 : aParam.mModifierSymbolLock = internalEvent->IsSymbolLocked();
168 :
169 : // EventInit
170 0 : aParam.mBubbles = internalEvent->mFlags.mBubbles;
171 0 : aParam.mCancelable = internalEvent->mFlags.mCancelable;
172 0 : }
173 :
174 : NS_IMETHODIMP
175 0 : KeyboardEvent::GetCharCode(uint32_t* aCharCode)
176 : {
177 0 : NS_ENSURE_ARG_POINTER(aCharCode);
178 0 : *aCharCode = CharCode();
179 0 : return NS_OK;
180 : }
181 :
182 : uint32_t
183 0 : KeyboardEvent::CharCode()
184 : {
185 : // If this event is initialized with ctor, we shouldn't check event type.
186 0 : if (mInitializedByCtor) {
187 0 : return mEvent->AsKeyboardEvent()->mCharCode;
188 : }
189 :
190 0 : switch (mEvent->mMessage) {
191 : case eKeyDown:
192 : case eKeyDownOnPlugin:
193 : case eKeyUp:
194 : case eKeyUpOnPlugin:
195 0 : return 0;
196 : case eKeyPress:
197 : case eAccessKeyNotFound:
198 0 : return mEvent->AsKeyboardEvent()->mCharCode;
199 : default:
200 0 : break;
201 : }
202 0 : return 0;
203 : }
204 :
205 : NS_IMETHODIMP
206 0 : KeyboardEvent::GetKeyCode(uint32_t* aKeyCode)
207 : {
208 0 : NS_ENSURE_ARG_POINTER(aKeyCode);
209 0 : *aKeyCode = KeyCode();
210 0 : return NS_OK;
211 : }
212 :
213 : uint32_t
214 0 : KeyboardEvent::KeyCode()
215 : {
216 : // If this event is initialized with ctor, we shouldn't check event type.
217 0 : if (mInitializedByCtor) {
218 0 : return mEvent->AsKeyboardEvent()->mKeyCode;
219 : }
220 :
221 0 : if (mEvent->HasKeyEventMessage()) {
222 0 : return mEvent->AsKeyboardEvent()->mKeyCode;
223 : }
224 0 : return 0;
225 : }
226 :
227 : uint32_t
228 0 : KeyboardEvent::Which()
229 : {
230 : // If this event is initialized with ctor, which can have independent value.
231 0 : if (mInitializedByCtor) {
232 0 : return mInitializedWhichValue;
233 : }
234 :
235 0 : switch (mEvent->mMessage) {
236 : case eKeyDown:
237 : case eKeyDownOnPlugin:
238 : case eKeyUp:
239 : case eKeyUpOnPlugin:
240 0 : return KeyCode();
241 : case eKeyPress:
242 : //Special case for 4xp bug 62878. Try to make value of which
243 : //more closely mirror the values that 4.x gave for RETURN and BACKSPACE
244 : {
245 0 : uint32_t keyCode = mEvent->AsKeyboardEvent()->mKeyCode;
246 0 : if (keyCode == NS_VK_RETURN || keyCode == NS_VK_BACK) {
247 0 : return keyCode;
248 : }
249 0 : return CharCode();
250 : }
251 : default:
252 0 : break;
253 : }
254 :
255 0 : return 0;
256 : }
257 :
258 : NS_IMETHODIMP
259 0 : KeyboardEvent::GetLocation(uint32_t* aLocation)
260 : {
261 0 : NS_ENSURE_ARG_POINTER(aLocation);
262 :
263 0 : *aLocation = Location();
264 0 : return NS_OK;
265 : }
266 :
267 : uint32_t
268 0 : KeyboardEvent::Location()
269 : {
270 0 : return mEvent->AsKeyboardEvent()->mLocation;
271 : }
272 :
273 : // static
274 : already_AddRefed<KeyboardEvent>
275 0 : KeyboardEvent::Constructor(const GlobalObject& aGlobal,
276 : const nsAString& aType,
277 : const KeyboardEventInit& aParam,
278 : ErrorResult& aRv)
279 : {
280 0 : nsCOMPtr<EventTarget> target = do_QueryInterface(aGlobal.GetAsSupports());
281 : RefPtr<KeyboardEvent> newEvent =
282 0 : new KeyboardEvent(target, nullptr, nullptr);
283 0 : newEvent->InitWithKeyboardEventInit(target, aType, aParam, aRv);
284 :
285 0 : return newEvent.forget();
286 : }
287 :
288 : void
289 0 : KeyboardEvent::InitWithKeyboardEventInit(EventTarget* aOwner,
290 : const nsAString& aType,
291 : const KeyboardEventInit& aParam,
292 : ErrorResult& aRv)
293 : {
294 0 : bool trusted = Init(aOwner);
295 0 : InitKeyEvent(aType, aParam.mBubbles, aParam.mCancelable,
296 : aParam.mView, false, false, false, false,
297 0 : aParam.mKeyCode, aParam.mCharCode);
298 0 : InitModifiers(aParam);
299 0 : SetTrusted(trusted);
300 0 : mDetail = aParam.mDetail;
301 0 : mInitializedByCtor = true;
302 0 : mInitializedWhichValue = aParam.mWhich;
303 :
304 0 : WidgetKeyboardEvent* internalEvent = mEvent->AsKeyboardEvent();
305 0 : internalEvent->mLocation = aParam.mLocation;
306 0 : internalEvent->mIsRepeat = aParam.mRepeat;
307 0 : internalEvent->mIsComposing = aParam.mIsComposing;
308 0 : internalEvent->mKeyNameIndex =
309 0 : WidgetKeyboardEvent::GetKeyNameIndex(aParam.mKey);
310 0 : if (internalEvent->mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
311 0 : internalEvent->mKeyValue = aParam.mKey;
312 : }
313 0 : internalEvent->mCodeNameIndex =
314 0 : WidgetKeyboardEvent::GetCodeNameIndex(aParam.mCode);
315 0 : if (internalEvent->mCodeNameIndex == CODE_NAME_INDEX_USE_STRING) {
316 0 : internalEvent->mCodeValue = aParam.mCode;
317 : }
318 0 : }
319 :
320 : NS_IMETHODIMP
321 0 : KeyboardEvent::InitKeyEvent(const nsAString& aType,
322 : bool aCanBubble,
323 : bool aCancelable,
324 : mozIDOMWindow* aView,
325 : bool aCtrlKey,
326 : bool aAltKey,
327 : bool aShiftKey,
328 : bool aMetaKey,
329 : uint32_t aKeyCode,
330 : uint32_t aCharCode)
331 : {
332 0 : NS_ENSURE_TRUE(!mEvent->mFlags.mIsBeingDispatched, NS_OK);
333 :
334 0 : UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, 0);
335 :
336 0 : WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent();
337 0 : keyEvent->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
338 0 : keyEvent->mKeyCode = aKeyCode;
339 0 : keyEvent->mCharCode = aCharCode;
340 :
341 0 : return NS_OK;
342 : }
343 :
344 : } // namespace dom
345 : } // namespace mozilla
346 :
347 : using namespace mozilla;
348 : using namespace mozilla::dom;
349 :
350 : already_AddRefed<KeyboardEvent>
351 0 : NS_NewDOMKeyboardEvent(EventTarget* aOwner,
352 : nsPresContext* aPresContext,
353 : WidgetKeyboardEvent* aEvent)
354 : {
355 0 : RefPtr<KeyboardEvent> it = new KeyboardEvent(aOwner, aPresContext, aEvent);
356 0 : return it.forget();
357 : }
|