Bumping manifests a=b2g-bump
[gecko.git] / dom / events / KeyboardEvent.cpp
blob55da9e3b141c933bbc906767230442ff5c2e3818
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/dom/KeyboardEvent.h"
7 #include "mozilla/TextEvents.h"
8 #include "nsIDocument.h"
9 #include "prtime.h"
11 namespace mozilla {
12 namespace dom {
14 KeyboardEvent::KeyboardEvent(EventTarget* aOwner,
15 nsPresContext* aPresContext,
16 WidgetKeyboardEvent* aEvent)
17 : UIEvent(aOwner, aPresContext,
18 aEvent ? aEvent : new WidgetKeyboardEvent(false, 0, nullptr))
19 , mInitializedByCtor(false)
20 , mInitialzedWhichValue(0)
22 NS_ASSERTION(mEvent->mClass == eKeyboardEventClass, "event type mismatch");
24 if (aEvent) {
25 mEventIsInternal = false;
27 else {
28 mEventIsInternal = true;
29 mEvent->time = PR_Now();
30 mEvent->AsKeyboardEvent()->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
34 NS_IMPL_ADDREF_INHERITED(KeyboardEvent, UIEvent)
35 NS_IMPL_RELEASE_INHERITED(KeyboardEvent, UIEvent)
37 NS_INTERFACE_MAP_BEGIN(KeyboardEvent)
38 NS_INTERFACE_MAP_ENTRY(nsIDOMKeyEvent)
39 NS_INTERFACE_MAP_END_INHERITING(UIEvent)
41 bool
42 KeyboardEvent::AltKey()
44 return mEvent->AsKeyboardEvent()->IsAlt();
47 NS_IMETHODIMP
48 KeyboardEvent::GetAltKey(bool* aIsDown)
50 NS_ENSURE_ARG_POINTER(aIsDown);
51 *aIsDown = AltKey();
52 return NS_OK;
55 bool
56 KeyboardEvent::CtrlKey()
58 return mEvent->AsKeyboardEvent()->IsControl();
61 NS_IMETHODIMP
62 KeyboardEvent::GetCtrlKey(bool* aIsDown)
64 NS_ENSURE_ARG_POINTER(aIsDown);
65 *aIsDown = CtrlKey();
66 return NS_OK;
69 bool
70 KeyboardEvent::ShiftKey()
72 return mEvent->AsKeyboardEvent()->IsShift();
75 NS_IMETHODIMP
76 KeyboardEvent::GetShiftKey(bool* aIsDown)
78 NS_ENSURE_ARG_POINTER(aIsDown);
79 *aIsDown = ShiftKey();
80 return NS_OK;
83 bool
84 KeyboardEvent::MetaKey()
86 return mEvent->AsKeyboardEvent()->IsMeta();
89 NS_IMETHODIMP
90 KeyboardEvent::GetMetaKey(bool* aIsDown)
92 NS_ENSURE_ARG_POINTER(aIsDown);
93 *aIsDown = MetaKey();
94 return NS_OK;
97 bool
98 KeyboardEvent::Repeat()
100 return mEvent->AsKeyboardEvent()->mIsRepeat;
103 NS_IMETHODIMP
104 KeyboardEvent::GetRepeat(bool* aIsRepeat)
106 NS_ENSURE_ARG_POINTER(aIsRepeat);
107 *aIsRepeat = Repeat();
108 return NS_OK;
111 bool
112 KeyboardEvent::IsComposing()
114 return mEvent->AsKeyboardEvent()->mIsComposing;
117 NS_IMETHODIMP
118 KeyboardEvent::GetModifierState(const nsAString& aKey,
119 bool* aState)
121 NS_ENSURE_ARG_POINTER(aState);
123 *aState = GetModifierState(aKey);
124 return NS_OK;
127 NS_IMETHODIMP
128 KeyboardEvent::GetKey(nsAString& aKeyName)
130 WidgetKeyboardEvent* keyboardEvent = mEvent->AsKeyboardEvent();
131 keyboardEvent->GetDOMKeyName(aKeyName);
133 nsIDocument::DeprecatedOperations deprecatedOperation;
134 switch (keyboardEvent->mKeyNameIndex) {
135 case KEY_NAME_INDEX_Down:
136 deprecatedOperation = nsIDocument::eKeyNameDown;
137 break;
138 case KEY_NAME_INDEX_Left:
139 deprecatedOperation = nsIDocument::eKeyNameLeft;
140 break;
141 case KEY_NAME_INDEX_Right:
142 deprecatedOperation = nsIDocument::eKeyNameRight;
143 break;
144 case KEY_NAME_INDEX_Up:
145 deprecatedOperation = nsIDocument::eKeyNameUp;
146 break;
147 case KEY_NAME_INDEX_Crsel:
148 deprecatedOperation = nsIDocument::eKeyNameCrsel;
149 break;
150 case KEY_NAME_INDEX_Del:
151 deprecatedOperation = nsIDocument::eKeyNameDel;
152 break;
153 case KEY_NAME_INDEX_Exsel:
154 deprecatedOperation = nsIDocument::eKeyNameExsel;
155 break;
156 case KEY_NAME_INDEX_Menu:
157 deprecatedOperation = nsIDocument::eKeyNameMenu;
158 break;
159 case KEY_NAME_INDEX_Esc:
160 deprecatedOperation = nsIDocument::eKeyNameEsc;
161 break;
162 case KEY_NAME_INDEX_Nonconvert:
163 deprecatedOperation = nsIDocument::eKeyNameNonconvert;
164 break;
165 case KEY_NAME_INDEX_HalfWidth:
166 deprecatedOperation = nsIDocument::eKeyNameHalfWidth;
167 break;
168 case KEY_NAME_INDEX_RomanCharacters:
169 deprecatedOperation = nsIDocument::eKeyNameRomanCharacters;
170 break;
171 case KEY_NAME_INDEX_FullWidth:
172 deprecatedOperation = nsIDocument::eKeyNameFullWidth;
173 break;
174 case KEY_NAME_INDEX_SelectMedia:
175 deprecatedOperation = nsIDocument::eKeyNameSelectMedia;
176 break;
177 case KEY_NAME_INDEX_MediaNextTrack:
178 deprecatedOperation = nsIDocument::eKeyNameMediaNextTrack;
179 break;
180 case KEY_NAME_INDEX_MediaPreviousTrack:
181 deprecatedOperation = nsIDocument::eKeyNameMediaPreviousTrack;
182 break;
183 case KEY_NAME_INDEX_Red:
184 deprecatedOperation = nsIDocument::eKeyNameRed;
185 break;
186 case KEY_NAME_INDEX_Green:
187 deprecatedOperation = nsIDocument::eKeyNameGreen;
188 break;
189 case KEY_NAME_INDEX_Yellow:
190 deprecatedOperation = nsIDocument::eKeyNameYellow;
191 break;
192 case KEY_NAME_INDEX_Blue:
193 deprecatedOperation = nsIDocument::eKeyNameBlue;
194 break;
195 case KEY_NAME_INDEX_Live:
196 deprecatedOperation = nsIDocument::eKeyNameLive;
197 break;
198 case KEY_NAME_INDEX_Apps:
199 deprecatedOperation = nsIDocument::eKeyNameApps;
200 break;
201 case KEY_NAME_INDEX_FastFwd:
202 deprecatedOperation = nsIDocument::eKeyNameFastFwd;
203 break;
204 case KEY_NAME_INDEX_Zoom:
205 deprecatedOperation = nsIDocument::eKeyNameZoom;
206 break;
207 case KEY_NAME_INDEX_DeadGrave:
208 case KEY_NAME_INDEX_DeadAcute:
209 case KEY_NAME_INDEX_DeadCircumflex:
210 case KEY_NAME_INDEX_DeadTilde:
211 case KEY_NAME_INDEX_DeadMacron:
212 case KEY_NAME_INDEX_DeadBreve:
213 case KEY_NAME_INDEX_DeadAboveDot:
214 case KEY_NAME_INDEX_DeadUmlaut:
215 case KEY_NAME_INDEX_DeadAboveRing:
216 case KEY_NAME_INDEX_DeadDoubleacute:
217 case KEY_NAME_INDEX_DeadCaron:
218 case KEY_NAME_INDEX_DeadCedilla:
219 case KEY_NAME_INDEX_DeadOgonek:
220 case KEY_NAME_INDEX_DeadIota:
221 case KEY_NAME_INDEX_DeadVoicedSound:
222 case KEY_NAME_INDEX_DeadSemivoicedSound:
223 deprecatedOperation = nsIDocument::eKeyNameDeadKeys;
224 break;
225 default:
226 return NS_OK;
229 nsIDocument* doc = mOwner ? mOwner->GetExtantDoc() : nullptr;
230 if (NS_WARN_IF(!doc)) {
231 return NS_OK;
233 doc->WarnOnceAbout(deprecatedOperation);
234 return NS_OK;
237 void
238 KeyboardEvent::GetCode(nsAString& aCodeName)
240 mEvent->AsKeyboardEvent()->GetDOMCodeName(aCodeName);
243 NS_IMETHODIMP
244 KeyboardEvent::GetCharCode(uint32_t* aCharCode)
246 NS_ENSURE_ARG_POINTER(aCharCode);
247 *aCharCode = CharCode();
248 return NS_OK;
251 uint32_t
252 KeyboardEvent::CharCode()
254 // If this event is initialized with ctor, we shouldn't check event type.
255 if (mInitializedByCtor) {
256 return mEvent->AsKeyboardEvent()->charCode;
259 switch (mEvent->message) {
260 case NS_KEY_UP:
261 case NS_KEY_DOWN:
262 return 0;
263 case NS_KEY_PRESS:
264 return mEvent->AsKeyboardEvent()->charCode;
266 return 0;
269 NS_IMETHODIMP
270 KeyboardEvent::GetKeyCode(uint32_t* aKeyCode)
272 NS_ENSURE_ARG_POINTER(aKeyCode);
273 *aKeyCode = KeyCode();
274 return NS_OK;
277 uint32_t
278 KeyboardEvent::KeyCode()
280 // If this event is initialized with ctor, we shouldn't check event type.
281 if (mInitializedByCtor) {
282 return mEvent->AsKeyboardEvent()->keyCode;
285 switch (mEvent->message) {
286 case NS_KEY_UP:
287 case NS_KEY_PRESS:
288 case NS_KEY_DOWN:
289 return mEvent->AsKeyboardEvent()->keyCode;
291 return 0;
294 uint32_t
295 KeyboardEvent::Which()
297 // If this event is initialized with ctor, which can have independent value.
298 if (mInitializedByCtor) {
299 return mInitialzedWhichValue;
302 switch (mEvent->message) {
303 case NS_KEY_UP:
304 case NS_KEY_DOWN:
305 return KeyCode();
306 case NS_KEY_PRESS:
307 //Special case for 4xp bug 62878. Try to make value of which
308 //more closely mirror the values that 4.x gave for RETURN and BACKSPACE
310 uint32_t keyCode = mEvent->AsKeyboardEvent()->keyCode;
311 if (keyCode == NS_VK_RETURN || keyCode == NS_VK_BACK) {
312 return keyCode;
314 return CharCode();
318 return 0;
321 NS_IMETHODIMP
322 KeyboardEvent::GetLocation(uint32_t* aLocation)
324 NS_ENSURE_ARG_POINTER(aLocation);
326 *aLocation = Location();
327 return NS_OK;
330 uint32_t
331 KeyboardEvent::Location()
333 return mEvent->AsKeyboardEvent()->location;
336 // static
337 already_AddRefed<KeyboardEvent>
338 KeyboardEvent::Constructor(const GlobalObject& aGlobal,
339 const nsAString& aType,
340 const KeyboardEventInit& aParam,
341 ErrorResult& aRv)
343 nsCOMPtr<EventTarget> target = do_QueryInterface(aGlobal.GetAsSupports());
344 nsRefPtr<KeyboardEvent> newEvent =
345 new KeyboardEvent(target, nullptr, nullptr);
346 bool trusted = newEvent->Init(target);
347 aRv = newEvent->InitKeyEvent(aType, aParam.mBubbles, aParam.mCancelable,
348 aParam.mView, aParam.mCtrlKey, aParam.mAltKey,
349 aParam.mShiftKey, aParam.mMetaKey,
350 aParam.mKeyCode, aParam.mCharCode);
351 newEvent->SetTrusted(trusted);
352 newEvent->mDetail = aParam.mDetail;
353 newEvent->mInitializedByCtor = true;
354 newEvent->mInitialzedWhichValue = aParam.mWhich;
356 WidgetKeyboardEvent* internalEvent = newEvent->mEvent->AsKeyboardEvent();
357 internalEvent->location = aParam.mLocation;
358 internalEvent->mIsRepeat = aParam.mRepeat;
359 internalEvent->mIsComposing = aParam.mIsComposing;
360 internalEvent->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
361 internalEvent->mKeyValue = aParam.mKey;
362 internalEvent->mCodeNameIndex = CODE_NAME_INDEX_USE_STRING;
363 internalEvent->mCodeValue = aParam.mCode;
365 return newEvent.forget();
368 NS_IMETHODIMP
369 KeyboardEvent::InitKeyEvent(const nsAString& aType,
370 bool aCanBubble,
371 bool aCancelable,
372 nsIDOMWindow* aView,
373 bool aCtrlKey,
374 bool aAltKey,
375 bool aShiftKey,
376 bool aMetaKey,
377 uint32_t aKeyCode,
378 uint32_t aCharCode)
380 nsresult rv = UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, 0);
381 NS_ENSURE_SUCCESS(rv, rv);
383 WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent();
384 keyEvent->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
385 keyEvent->keyCode = aKeyCode;
386 keyEvent->charCode = aCharCode;
388 return NS_OK;
391 } // namespace dom
392 } // namespace mozilla
394 using namespace mozilla;
395 using namespace mozilla::dom;
397 nsresult
398 NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
399 EventTarget* aOwner,
400 nsPresContext* aPresContext,
401 WidgetKeyboardEvent* aEvent)
403 KeyboardEvent* it = new KeyboardEvent(aOwner, aPresContext, aEvent);
404 NS_ADDREF(it);
405 *aInstancePtrResult = static_cast<Event*>(it);
406 return NS_OK;