View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.javascript.host.event;
16  
17  import static org.htmlunit.BrowserVersionFeatures.JS_EVENT_KEYBOARD_CTOR_WHICH;
18  import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
19  import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR;
20  
21  import java.util.HashMap;
22  import java.util.Map;
23  
24  import org.htmlunit.corejs.javascript.ScriptableObject;
25  import org.htmlunit.html.DomNode;
26  import org.htmlunit.javascript.JavaScriptEngine;
27  import org.htmlunit.javascript.configuration.JsxClass;
28  import org.htmlunit.javascript.configuration.JsxConstant;
29  import org.htmlunit.javascript.configuration.JsxConstructor;
30  import org.htmlunit.javascript.configuration.JsxFunction;
31  import org.htmlunit.javascript.configuration.JsxGetter;
32  
33  /**
34   * JavaScript object representing a Keyboard Event.
35   * For general information on which properties and functions should be supported, see
36   * <a href="http://www.w3c.org/TR/DOM-Level-3-Events/#Events-KeyboardEvents-Interfaces">
37   * DOM Level 3 Events</a>.
38   *
39   * @author Ahmed Ashour
40   * @author Frank Danek
41   * @author Ronald Brill
42   * @author Joerg Werner
43   */
44  @JsxClass
45  public class KeyboardEvent extends UIEvent {
46  
47      /** Constant for {@code DOM_KEY_LOCATION_STANDARD}. */
48      @JsxConstant
49      public static final int DOM_KEY_LOCATION_STANDARD = 0;
50  
51      /** Constant for {@code DOM_KEY_LOCATION_LEFT}. */
52      @JsxConstant
53      public static final int DOM_KEY_LOCATION_LEFT = 1;
54  
55      /** Constant for {@code DOM_KEY_LOCATION_RIGHT}. */
56      @JsxConstant
57      public static final int DOM_KEY_LOCATION_RIGHT = 2;
58  
59      /** Constant for {@code DOM_KEY_LOCATION_NUMPAD}. */
60      @JsxConstant
61      public static final int DOM_KEY_LOCATION_NUMPAD = 3;
62  
63      /** Constant for {@code DOM_VK_CANCEL}. */
64      @JsxConstant({FF, FF_ESR})
65      public static final int DOM_VK_CANCEL = 3;
66  
67      /** Constant for {@code DOM_VK_HELP}. */
68      @JsxConstant({FF, FF_ESR})
69      public static final int DOM_VK_HELP = 6;
70  
71      /** Constant for {@code DOM_VK_TAB}. */
72      @JsxConstant({FF, FF_ESR})
73      public static final int DOM_VK_TAB = 9;
74  
75      /** Constant for {@code DOM_VK_CLEAR}. */
76      @JsxConstant({FF, FF_ESR})
77      public static final int DOM_VK_CLEAR = 12;
78  
79      /** Constant for {@code DOM_VK_RETURN}. */
80      @JsxConstant({FF, FF_ESR})
81      public static final int DOM_VK_RETURN = 13;
82  
83      /** Constant for {@code DOM_VK_SHIFT}. */
84      @JsxConstant({FF, FF_ESR})
85      public static final int DOM_VK_SHIFT = 16;
86  
87      /** Constant for {@code DOM_VK_CONTROL}. */
88      @JsxConstant({FF, FF_ESR})
89      public static final int DOM_VK_CONTROL = 17;
90  
91      /** Constant for {@code DOM_VK_ALT}. */
92      @JsxConstant({FF, FF_ESR})
93      public static final int DOM_VK_ALT = 18;
94  
95      /** Constant for {@code DOM_VK_PAUSE}. */
96      @JsxConstant({FF, FF_ESR})
97      public static final int DOM_VK_PAUSE = 19;
98  
99      /** Constant for {@code DOM_VK_CAPS_LOCK}. */
100     @JsxConstant({FF, FF_ESR})
101     public static final int DOM_VK_CAPS_LOCK = 20;
102 
103     /** Constant for {@code DOM_VK_HANGUL}. */
104     @JsxConstant({FF, FF_ESR})
105     public static final int DOM_VK_HANGUL = 21;
106 
107     /** Constant for {@code DOM_VK_KANA}. */
108     @JsxConstant({FF, FF_ESR})
109     public static final int DOM_VK_KANA = 21;
110 
111     /** Constant for {@code DOM_VK_EISU}. */
112     @JsxConstant({FF, FF_ESR})
113     public static final int DOM_VK_EISU = 22;
114 
115     /** Constant for {@code DOM_VK_FINAL}. */
116     @JsxConstant({FF, FF_ESR})
117     public static final int DOM_VK_FINAL = 24;
118 
119     /** Constant for {@code DOM_VK_JUNJA}. */
120     @JsxConstant({FF, FF_ESR})
121     public static final int DOM_VK_JUNJA = 23;
122 
123     /** Constant for {@code DOM_VK_HANJA}. */
124     @JsxConstant({FF, FF_ESR})
125     public static final int DOM_VK_HANJA = 25;
126 
127     /** Constant for {@code DOM_VK_KANJI}. */
128     @JsxConstant({FF, FF_ESR})
129     public static final int DOM_VK_KANJI = 25;
130 
131     /** Constant for {@code DOM_VK_ESCAPE}. */
132     @JsxConstant({FF, FF_ESR})
133     public static final int DOM_VK_ESCAPE = 27;
134 
135     /** Constant for {@code DOM_VK_CONVERT}. */
136     @JsxConstant({FF, FF_ESR})
137     public static final int DOM_VK_CONVERT = 28;
138 
139     /** Constant for {@code DOM_VK_NONCONVERT}. */
140     @JsxConstant({FF, FF_ESR})
141     public static final int DOM_VK_NONCONVERT = 29;
142 
143     /** Constant for {@code DOM_VK_ACCEPT}. */
144     @JsxConstant({FF, FF_ESR})
145     public static final int DOM_VK_ACCEPT = 30;
146 
147     /** Constant for {@code DOM_VK_MODECHANGE}. */
148     @JsxConstant({FF, FF_ESR})
149     public static final int DOM_VK_MODECHANGE = 31;
150 
151     /** Constant for {@code DOM_VK_SPACE}. */
152     @JsxConstant({FF, FF_ESR})
153     public static final int DOM_VK_SPACE = 32;
154 
155     /** Constant for {@code DOM_VK_PAGE_UP}. */
156     @JsxConstant({FF, FF_ESR})
157     public static final int DOM_VK_PAGE_UP = 33;
158 
159     /** Constant for {@code DOM_VK_PAGE_DOWN}. */
160     @JsxConstant({FF, FF_ESR})
161     public static final int DOM_VK_PAGE_DOWN = 34;
162 
163     /** Constant for {@code DOM_VK_END}. */
164     @JsxConstant({FF, FF_ESR})
165     public static final int DOM_VK_END = 35;
166 
167     /** Constant for {@code DOM_VK_HOME}. */
168     @JsxConstant({FF, FF_ESR})
169     public static final int DOM_VK_HOME = 36;
170 
171     /** Constant for {@code DOM_VK_LEFT}. */
172     @JsxConstant({FF, FF_ESR})
173     public static final int DOM_VK_LEFT = 37;
174 
175     /** Constant for {@code DOM_VK_UP}. */
176     @JsxConstant({FF, FF_ESR})
177     public static final int DOM_VK_UP = 38;
178 
179     /** Constant for {@code DOM_VK_RIGHT}. */
180     @JsxConstant({FF, FF_ESR})
181     public static final int DOM_VK_RIGHT = 39;
182 
183     /** Constant for {@code DOM_VK_SELECT}. */
184     @JsxConstant({FF, FF_ESR})
185     public static final int DOM_VK_SELECT = 41;
186 
187     /** Constant for {@code DOM_VK_DOWN}. */
188     @JsxConstant({FF, FF_ESR})
189     public static final int DOM_VK_DOWN = 40;
190 
191     /** Constant for {@code DOM_VK_PRINT}. */
192     @JsxConstant({FF, FF_ESR})
193     public static final int DOM_VK_PRINT = 42;
194 
195     /** Constant for {@code DOM_VK_EXECUTE}. */
196     @JsxConstant({FF, FF_ESR})
197     public static final int DOM_VK_EXECUTE = 43;
198 
199     /** Constant for {@code DOM_VK_PRINTSCREEN}. */
200     @JsxConstant({FF, FF_ESR})
201     public static final int DOM_VK_PRINTSCREEN = 44;
202 
203     /** Constant for {@code DOM_VK_INSERT}. */
204     @JsxConstant({FF, FF_ESR})
205     public static final int DOM_VK_INSERT = 45;
206 
207     /** Constant for {@code DOM_VK_DELETE}. */
208     @JsxConstant({FF, FF_ESR})
209     public static final int DOM_VK_DELETE = 46;
210 
211     /** Constant for {@code DOM_VK_0}. */
212     @JsxConstant({FF, FF_ESR})
213     public static final int DOM_VK_0 = 48;
214 
215     /** Constant for {@code DOM_VK_1}. */
216     @JsxConstant({FF, FF_ESR})
217     public static final int DOM_VK_1 = 49;
218 
219     /** Constant for {@code DOM_VK_2}. */
220     @JsxConstant({FF, FF_ESR})
221     public static final int DOM_VK_2 = 50;
222 
223     /** Constant for {@code DOM_VK_3}. */
224     @JsxConstant({FF, FF_ESR})
225     public static final int DOM_VK_3 = 51;
226 
227     /** Constant for {@code DOM_VK_4}. */
228     @JsxConstant({FF, FF_ESR})
229     public static final int DOM_VK_4 = 52;
230 
231     /** Constant for {@code DOM_VK_5}. */
232     @JsxConstant({FF, FF_ESR})
233     public static final int DOM_VK_5 = 53;
234 
235     /** Constant for {@code DOM_VK_6}. */
236     @JsxConstant({FF, FF_ESR})
237     public static final int DOM_VK_6 = 54;
238 
239     /** Constant for {@code DOM_VK_7}. */
240     @JsxConstant({FF, FF_ESR})
241     public static final int DOM_VK_7 = 55;
242 
243     /** Constant for {@code DOM_VK_8}. */
244     @JsxConstant({FF, FF_ESR})
245     public static final int DOM_VK_8 = 56;
246 
247     /** Constant for {@code DOM_VK_9}. */
248     @JsxConstant({FF, FF_ESR})
249     public static final int DOM_VK_9 = 57;
250 
251     /** Constant for {@code DOM_VK_COLON}. */
252     @JsxConstant({FF, FF_ESR})
253     public static final int DOM_VK_COLON = 58;
254 
255     /** Constant for {@code DOM_VK_SEMICOLON}. */
256     @JsxConstant({FF, FF_ESR})
257     public static final int DOM_VK_SEMICOLON = 59;
258 
259     /** Constant for {@code DOM_VK_LESS_THAN}. */
260     @JsxConstant({FF, FF_ESR})
261     public static final int DOM_VK_LESS_THAN = 60;
262 
263     /** Constant for {@code DOM_VK_EQUALS}. */
264     @JsxConstant({FF, FF_ESR})
265     public static final int DOM_VK_EQUALS = 61;
266 
267     /** Constant for {@code DOM_VK_GREATER_THAN}. */
268     @JsxConstant({FF, FF_ESR})
269     public static final int DOM_VK_GREATER_THAN = 62;
270 
271     /** Constant for {@code DOM_VK_QUESTION_MARK}. */
272     @JsxConstant({FF, FF_ESR})
273     public static final int DOM_VK_QUESTION_MARK = 63;
274 
275     /** Constant for {@code DOM_VK_AT}. */
276     @JsxConstant({FF, FF_ESR})
277     public static final int DOM_VK_AT = 64;
278 
279     /** Constant for {@code DOM_VK_A}. */
280     @JsxConstant({FF, FF_ESR})
281     public static final int DOM_VK_A = 65;
282 
283     /** Constant for {@code DOM_VK_B}. */
284     @JsxConstant({FF, FF_ESR})
285     public static final int DOM_VK_B = 66;
286 
287     /** Constant for {@code DOM_VK_C}. */
288     @JsxConstant({FF, FF_ESR})
289     public static final int DOM_VK_C = 67;
290 
291     /** Constant for {@code DOM_VK_D}. */
292     @JsxConstant({FF, FF_ESR})
293     public static final int DOM_VK_D = 68;
294 
295     /** Constant for {@code DOM_VK_E}. */
296     @JsxConstant({FF, FF_ESR})
297     public static final int DOM_VK_E = 69;
298 
299     /** Constant for {@code DOM_VK_F}. */
300     @JsxConstant({FF, FF_ESR})
301     public static final int DOM_VK_F = 70;
302 
303     /** Constant for {@code DOM_VK_G}. */
304     @JsxConstant({FF, FF_ESR})
305     public static final int DOM_VK_G = 71;
306 
307     /** Constant for {@code DOM_VK_H}. */
308     @JsxConstant({FF, FF_ESR})
309     public static final int DOM_VK_H = 72;
310 
311     /** Constant for {@code DOM_VK_I}. */
312     @JsxConstant({FF, FF_ESR})
313     public static final int DOM_VK_I = 73;
314 
315     /** Constant for {@code DOM_VK_J}. */
316     @JsxConstant({FF, FF_ESR})
317     public static final int DOM_VK_J = 74;
318 
319     /** Constant for {@code DOM_VK_K}. */
320     @JsxConstant({FF, FF_ESR})
321     public static final int DOM_VK_K = 75;
322 
323     /** Constant for {@code DOM_VK_L}. */
324     @JsxConstant({FF, FF_ESR})
325     public static final int DOM_VK_L = 76;
326 
327     /** Constant for {@code DOM_VK_M}. */
328     @JsxConstant({FF, FF_ESR})
329     public static final int DOM_VK_M = 77;
330 
331     /** Constant for {@code DOM_VK_N}. */
332     @JsxConstant({FF, FF_ESR})
333     public static final int DOM_VK_N = 78;
334 
335     /** Constant for {@code DOM_VK_O}. */
336     @JsxConstant({FF, FF_ESR})
337     public static final int DOM_VK_O = 79;
338 
339     /** Constant for {@code DOM_VK_BACK_SPACE}. */
340     @JsxConstant({FF, FF_ESR})
341     public static final int DOM_VK_BACK_SPACE = 8;
342 
343     /** Constant for {@code DOM_VK_P}. */
344     @JsxConstant({FF, FF_ESR})
345     public static final int DOM_VK_P = 80;
346 
347     /** Constant for {@code DOM_VK_Q}. */
348     @JsxConstant({FF, FF_ESR})
349     public static final int DOM_VK_Q = 81;
350 
351     /** Constant for {@code DOM_VK_R}. */
352     @JsxConstant({FF, FF_ESR})
353     public static final int DOM_VK_R = 82;
354 
355     /** Constant for {@code DOM_VK_S}. */
356     @JsxConstant({FF, FF_ESR})
357     public static final int DOM_VK_S = 83;
358 
359     /** Constant for {@code DOM_VK_T}. */
360     @JsxConstant({FF, FF_ESR})
361     public static final int DOM_VK_T = 84;
362 
363     /** Constant for {@code DOM_VK_U}. */
364     @JsxConstant({FF, FF_ESR})
365     public static final int DOM_VK_U = 85;
366 
367     /** Constant for {@code DOM_VK_V}. */
368     @JsxConstant({FF, FF_ESR})
369     public static final int DOM_VK_V = 86;
370 
371     /** Constant for {@code DOM_VK_W}. */
372     @JsxConstant({FF, FF_ESR})
373     public static final int DOM_VK_W = 87;
374 
375     /** Constant for {@code DOM_VK_X}. */
376     @JsxConstant({FF, FF_ESR})
377     public static final int DOM_VK_X = 88;
378 
379     /** Constant for {@code DOM_VK_Y}. */
380     @JsxConstant({FF, FF_ESR})
381     public static final int DOM_VK_Y = 89;
382 
383     /** Constant for {@code DOM_VK_Z}. */
384     @JsxConstant({FF, FF_ESR})
385     public static final int DOM_VK_Z = 90;
386 
387     /** Constant for {@code DOM_VK_WIN}. */
388     @JsxConstant({FF, FF_ESR})
389     public static final int DOM_VK_WIN = 91;
390 
391     /** Constant for {@code DOM_VK_CONTEXT_MENU}. */
392     @JsxConstant({FF, FF_ESR})
393     public static final int DOM_VK_CONTEXT_MENU = 93;
394 
395     /** Constant for {@code DOM_VK_SLEEP}. */
396     @JsxConstant({FF, FF_ESR})
397     public static final int DOM_VK_SLEEP = 95;
398 
399     /** Constant for {@code DOM_VK_NUMPAD0}. */
400     @JsxConstant({FF, FF_ESR})
401     public static final int DOM_VK_NUMPAD0 = 96;
402 
403     /** Constant for {@code DOM_VK_NUMPAD1}. */
404     @JsxConstant({FF, FF_ESR})
405     public static final int DOM_VK_NUMPAD1 = 97;
406 
407     /** Constant for {@code DOM_VK_NUMPAD2}. */
408     @JsxConstant({FF, FF_ESR})
409     public static final int DOM_VK_NUMPAD2 = 98;
410 
411     /** Constant for {@code DOM_VK_NUMPAD3}. */
412     @JsxConstant({FF, FF_ESR})
413     public static final int DOM_VK_NUMPAD3 = 99;
414 
415     /** Constant for {@code DOM_VK_NUMPAD4}. */
416     @JsxConstant({FF, FF_ESR})
417     public static final int DOM_VK_NUMPAD4 = 100;
418 
419     /** Constant for {@code DOM_VK_NUMPAD5}. */
420     @JsxConstant({FF, FF_ESR})
421     public static final int DOM_VK_NUMPAD5 = 101;
422 
423     /** Constant for {@code DOM_VK_NUMPAD6}. */
424     @JsxConstant({FF, FF_ESR})
425     public static final int DOM_VK_NUMPAD6 = 102;
426 
427     /** Constant for {@code DOM_VK_NUMPAD7}. */
428     @JsxConstant({FF, FF_ESR})
429     public static final int DOM_VK_NUMPAD7 = 103;
430 
431     /** Constant for {@code DOM_VK_NUMPAD8}. */
432     @JsxConstant({FF, FF_ESR})
433     public static final int DOM_VK_NUMPAD8 = 104;
434 
435     /** Constant for {@code DOM_VK_NUMPAD9}. */
436     @JsxConstant({FF, FF_ESR})
437     public static final int DOM_VK_NUMPAD9 = 105;
438 
439     /** Constant for {@code DOM_VK_MULTIPLY}. */
440     @JsxConstant({FF, FF_ESR})
441     public static final int DOM_VK_MULTIPLY = 106;
442 
443     /** Constant for {@code DOM_VK_ADD}. */
444     @JsxConstant({FF, FF_ESR})
445     public static final int DOM_VK_ADD = 107;
446 
447     /** Constant for {@code DOM_VK_SEPARATOR}. */
448     @JsxConstant({FF, FF_ESR})
449     public static final int DOM_VK_SEPARATOR = 108;
450 
451     /** Constant for {@code DOM_VK_SUBTRACT}. */
452     @JsxConstant({FF, FF_ESR})
453     public static final int DOM_VK_SUBTRACT = 109;
454 
455     /** Constant for {@code DOM_VK_DECIMAL}. */
456     @JsxConstant({FF, FF_ESR})
457     public static final int DOM_VK_DECIMAL = 110;
458 
459     /** Constant for {@code DOM_VK_DIVIDE}. */
460     @JsxConstant({FF, FF_ESR})
461     public static final int DOM_VK_DIVIDE = 111;
462 
463     /** Constant for {@code DOM_VK_F1}. */
464     @JsxConstant({FF, FF_ESR})
465     public static final int DOM_VK_F1 = 112;
466 
467     /** Constant for {@code DOM_VK_F2}. */
468     @JsxConstant({FF, FF_ESR})
469     public static final int DOM_VK_F2 = 113;
470 
471     /** Constant for {@code DOM_VK_F3}. */
472     @JsxConstant({FF, FF_ESR})
473     public static final int DOM_VK_F3 = 114;
474 
475     /** Constant for {@code DOM_VK_F4}. */
476     @JsxConstant({FF, FF_ESR})
477     public static final int DOM_VK_F4 = 115;
478 
479     /** Constant for {@code DOM_VK_F5}. */
480     @JsxConstant({FF, FF_ESR})
481     public static final int DOM_VK_F5 = 116;
482 
483     /** Constant for {@code DOM_VK_F6}. */
484     @JsxConstant({FF, FF_ESR})
485     public static final int DOM_VK_F6 = 117;
486 
487     /** Constant for {@code DOM_VK_F7}. */
488     @JsxConstant({FF, FF_ESR})
489     public static final int DOM_VK_F7 = 118;
490 
491     /** Constant for {@code DOM_VK_F8}. */
492     @JsxConstant({FF, FF_ESR})
493     public static final int DOM_VK_F8 = 119;
494 
495     /** Constant for {@code DOM_VK_F9}. */
496     @JsxConstant({FF, FF_ESR})
497     public static final int DOM_VK_F9 = 120;
498 
499     /** Constant for {@code DOM_VK_F10}. */
500     @JsxConstant({FF, FF_ESR})
501     public static final int DOM_VK_F10 = 121;
502 
503     /** Constant for {@code DOM_VK_F11}. */
504     @JsxConstant({FF, FF_ESR})
505     public static final int DOM_VK_F11 = 122;
506 
507     /** Constant for {@code DOM_VK_F12}. */
508     @JsxConstant({FF, FF_ESR})
509     public static final int DOM_VK_F12 = 123;
510 
511     /** Constant for {@code DOM_VK_F13}. */
512     @JsxConstant({FF, FF_ESR})
513     public static final int DOM_VK_F13 = 124;
514 
515     /** Constant for {@code DOM_VK_F14}. */
516     @JsxConstant({FF, FF_ESR})
517     public static final int DOM_VK_F14 = 125;
518 
519     /** Constant for {@code DOM_VK_F15}. */
520     @JsxConstant({FF, FF_ESR})
521     public static final int DOM_VK_F15 = 126;
522 
523     /** Constant for {@code DOM_VK_F16}. */
524     @JsxConstant({FF, FF_ESR})
525     public static final int DOM_VK_F16 = 127;
526 
527     /** Constant for {@code DOM_VK_F17}. */
528     @JsxConstant({FF, FF_ESR})
529     public static final int DOM_VK_F17 = 128;
530 
531     /** Constant for {@code DOM_VK_F18}. */
532     @JsxConstant({FF, FF_ESR})
533     public static final int DOM_VK_F18 = 129;
534 
535     /** Constant for {@code DOM_VK_F19}. */
536     @JsxConstant({FF, FF_ESR})
537     public static final int DOM_VK_F19 = 130;
538 
539     /** Constant for {@code DOM_VK_F20}. */
540     @JsxConstant({FF, FF_ESR})
541     public static final int DOM_VK_F20 = 131;
542 
543     /** Constant for {@code DOM_VK_F21}. */
544     @JsxConstant({FF, FF_ESR})
545     public static final int DOM_VK_F21 = 132;
546 
547     /** Constant for {@code DOM_VK_F22}. */
548     @JsxConstant({FF, FF_ESR})
549     public static final int DOM_VK_F22 = 133;
550 
551     /** Constant for {@code DOM_VK_F23}. */
552     @JsxConstant({FF, FF_ESR})
553     public static final int DOM_VK_F23 = 134;
554 
555     /** Constant for {@code DOM_VK_F24}. */
556     @JsxConstant({FF, FF_ESR})
557     public static final int DOM_VK_F24 = 135;
558 
559     /** Constant for {@code DOM_VK_NUM_LOCK}. */
560     @JsxConstant({FF, FF_ESR})
561     public static final int DOM_VK_NUM_LOCK = 144;
562 
563     /** Constant for {@code DOM_VK_SCROLL_LOCK}. */
564     @JsxConstant({FF, FF_ESR})
565     public static final int DOM_VK_SCROLL_LOCK = 145;
566 
567     /** Constant for {@code DOM_VK_WIN_OEM_FJ_JISHO}. */
568     @JsxConstant({FF, FF_ESR})
569     public static final int DOM_VK_WIN_OEM_FJ_JISHO = 146;
570 
571     /** Constant for {@code DOM_VK_WIN_OEM_FJ_MASSHOU}. */
572     @JsxConstant({FF, FF_ESR})
573     public static final int DOM_VK_WIN_OEM_FJ_MASSHOU = 147;
574 
575     /** Constant for {@code DOM_VK_WIN_OEM_FJ_TOUROKU}. */
576     @JsxConstant({FF, FF_ESR})
577     public static final int DOM_VK_WIN_OEM_FJ_TOUROKU = 148;
578 
579     /** Constant for {@code DOM_VK_WIN_OEM_FJ_LOYA}. */
580     @JsxConstant({FF, FF_ESR})
581     public static final int DOM_VK_WIN_OEM_FJ_LOYA = 149;
582 
583     /** Constant for {@code DOM_VK_WIN_OEM_FJ_ROYA}. */
584     @JsxConstant({FF, FF_ESR})
585     public static final int DOM_VK_WIN_OEM_FJ_ROYA = 150;
586 
587     /** Constant for {@code DOM_VK_CIRCUMFLEX}. */
588     @JsxConstant({FF, FF_ESR})
589     public static final int DOM_VK_CIRCUMFLEX = 160;
590 
591     /** Constant for {@code DOM_VK_EXCLAMATION}. */
592     @JsxConstant({FF, FF_ESR})
593     public static final int DOM_VK_EXCLAMATION = 161;
594 
595     /** Constant for {@code DOM_VK_DOUBLE_QUOTE}. */
596     @JsxConstant({FF, FF_ESR})
597     public static final int DOM_VK_DOUBLE_QUOTE = 162;
598 
599     /** Constant for {@code DOM_VK_HASH}. */
600     @JsxConstant({FF, FF_ESR})
601     public static final int DOM_VK_HASH = 163;
602 
603     /** Constant for {@code DOM_VK_DOLLAR}. */
604     @JsxConstant({FF, FF_ESR})
605     public static final int DOM_VK_DOLLAR = 164;
606 
607     /** Constant for {@code DOM_VK_PERCENT}. */
608     @JsxConstant({FF, FF_ESR})
609     public static final int DOM_VK_PERCENT = 165;
610 
611     /** Constant for {@code DOM_VK_AMPERSAND}. */
612     @JsxConstant({FF, FF_ESR})
613     public static final int DOM_VK_AMPERSAND = 166;
614 
615     /** Constant for {@code DOM_VK_UNDERSCORE}. */
616     @JsxConstant({FF, FF_ESR})
617     public static final int DOM_VK_UNDERSCORE = 167;
618 
619     /** Constant for {@code DOM_VK_OPEN_PAREN}. */
620     @JsxConstant({FF, FF_ESR})
621     public static final int DOM_VK_OPEN_PAREN = 168;
622 
623     /** Constant for {@code DOM_VK_CLOSE_PAREN}. */
624     @JsxConstant({FF, FF_ESR})
625     public static final int DOM_VK_CLOSE_PAREN = 169;
626 
627     /** Constant for {@code DOM_VK_ASTERISK}. */
628     @JsxConstant({FF, FF_ESR})
629     public static final int DOM_VK_ASTERISK = 170;
630 
631     /** Constant for {@code DOM_VK_PLUS}. */
632     @JsxConstant({FF, FF_ESR})
633     public static final int DOM_VK_PLUS = 171;
634 
635     /** Constant for {@code DOM_VK_PIPE}. */
636     @JsxConstant({FF, FF_ESR})
637     public static final int DOM_VK_PIPE = 172;
638 
639     /** Constant for {@code DOM_VK_HYPHEN_MINUS}. */
640     @JsxConstant({FF, FF_ESR})
641     public static final int DOM_VK_HYPHEN_MINUS = 173;
642 
643     /** Constant for {@code DOM_VK_OPEN_CURLY_BRACKET}. */
644     @JsxConstant({FF, FF_ESR})
645     public static final int DOM_VK_OPEN_CURLY_BRACKET = 174;
646 
647     /** Constant for {@code DOM_VK_CLOSE_CURLY_BRACKET}. */
648     @JsxConstant({FF, FF_ESR})
649     public static final int DOM_VK_CLOSE_CURLY_BRACKET = 175;
650 
651     /** Constant for {@code DOM_VK_TILDE}. */
652     @JsxConstant({FF, FF_ESR})
653     public static final int DOM_VK_TILDE = 176;
654 
655     /** Constant for {@code DOM_VK_VOLUME_MUTE}. */
656     @JsxConstant({FF, FF_ESR})
657     public static final int DOM_VK_VOLUME_MUTE = 181;
658 
659     /** Constant for {@code DOM_VK_VOLUME_DOWN}. */
660     @JsxConstant({FF, FF_ESR})
661     public static final int DOM_VK_VOLUME_DOWN = 182;
662 
663     /** Constant for {@code DOM_VK_VOLUME_UP}. */
664     @JsxConstant({FF, FF_ESR})
665     public static final int DOM_VK_VOLUME_UP = 183;
666 
667     /** Constant for {@code DOM_VK_COMMA}. */
668     @JsxConstant({FF, FF_ESR})
669     public static final int DOM_VK_COMMA = 188;
670 
671     /** Constant for {@code DOM_VK_PERIOD}. */
672     @JsxConstant({FF, FF_ESR})
673     public static final int DOM_VK_PERIOD = 190;
674 
675     /** Constant for {@code DOM_VK_SLASH}. */
676     @JsxConstant({FF, FF_ESR})
677     public static final int DOM_VK_SLASH = 191;
678 
679     /** Constant for {@code DOM_VK_BACK_QUOTE}. */
680     @JsxConstant({FF, FF_ESR})
681     public static final int DOM_VK_BACK_QUOTE = 192;
682 
683     /** Constant for {@code DOM_VK_OPEN_BRACKET}. */
684     @JsxConstant({FF, FF_ESR})
685     public static final int DOM_VK_OPEN_BRACKET = 219;
686 
687     /** Constant for {@code DOM_VK_BACK_SLASH}. */
688     @JsxConstant({FF, FF_ESR})
689     public static final int DOM_VK_BACK_SLASH = 220;
690 
691     /** Constant for {@code DOM_VK_CLOSE_BRACKET}. */
692     @JsxConstant({FF, FF_ESR})
693     public static final int DOM_VK_CLOSE_BRACKET = 221;
694 
695     /** Constant for {@code DOM_VK_QUOTE}. */
696     @JsxConstant({FF, FF_ESR})
697     public static final int DOM_VK_QUOTE = 222;
698 
699     /** Constant for {@code DOM_VK_META}. */
700     @JsxConstant({FF, FF_ESR})
701     public static final int DOM_VK_META = 224;
702 
703     /** Constant for {@code DOM_VK_ALTGR}. */
704     @JsxConstant({FF, FF_ESR})
705     public static final int DOM_VK_ALTGR = 225;
706 
707     /** Constant for {@code DOM_VK_WIN_ICO_HELP}. */
708     @JsxConstant({FF, FF_ESR})
709     public static final int DOM_VK_WIN_ICO_HELP = 227;
710 
711     /** Constant for {@code DOM_VK_WIN_ICO_00}. */
712     @JsxConstant({FF, FF_ESR})
713     public static final int DOM_VK_WIN_ICO_00 = 228;
714 
715     /** Constant for {@code DOM_VK_PROCESSKEY}. */
716     @JsxConstant({FF, FF_ESR})
717     public static final int DOM_VK_PROCESSKEY = 229;
718 
719     /** Constant for {@code DOM_VK_WIN_ICO_CLEAR}. */
720     @JsxConstant({FF, FF_ESR})
721     public static final int DOM_VK_WIN_ICO_CLEAR = 230;
722 
723     /** Constant for {@code DOM_VK_WIN_OEM_RESET}. */
724     @JsxConstant({FF, FF_ESR})
725     public static final int DOM_VK_WIN_OEM_RESET = 233;
726 
727     /** Constant for {@code DOM_VK_WIN_OEM_JUMP}. */
728     @JsxConstant({FF, FF_ESR})
729     public static final int DOM_VK_WIN_OEM_JUMP = 234;
730 
731     /** Constant for {@code DOM_VK_WIN_OEM_PA1}. */
732     @JsxConstant({FF, FF_ESR})
733     public static final int DOM_VK_WIN_OEM_PA1 = 235;
734 
735     /** Constant for {@code DOM_VK_WIN_OEM_PA2}. */
736     @JsxConstant({FF, FF_ESR})
737     public static final int DOM_VK_WIN_OEM_PA2 = 236;
738 
739     /** Constant for {@code DOM_VK_WIN_OEM_PA3}. */
740     @JsxConstant({FF, FF_ESR})
741     public static final int DOM_VK_WIN_OEM_PA3 = 237;
742 
743     /** Constant for {@code DOM_VK_WIN_OEM_WSCTRL}. */
744     @JsxConstant({FF, FF_ESR})
745     public static final int DOM_VK_WIN_OEM_WSCTRL = 238;
746 
747     /** Constant for {@code DOM_VK_WIN_OEM_CUSEL}. */
748     @JsxConstant({FF, FF_ESR})
749     public static final int DOM_VK_WIN_OEM_CUSEL = 239;
750 
751     /** Constant for {@code DOM_VK_WIN_OEM_ATTN}. */
752     @JsxConstant({FF, FF_ESR})
753     public static final int DOM_VK_WIN_OEM_ATTN = 240;
754 
755     /** Constant for {@code DOM_VK_WIN_OEM_FINISH}. */
756     @JsxConstant({FF, FF_ESR})
757     public static final int DOM_VK_WIN_OEM_FINISH = 241;
758 
759     /** Constant for {@code DOM_VK_WIN_OEM_COPY}. */
760     @JsxConstant({FF, FF_ESR})
761     public static final int DOM_VK_WIN_OEM_COPY = 242;
762 
763     /** Constant for {@code DOM_VK_WIN_OEM_AUTO}. */
764     @JsxConstant({FF, FF_ESR})
765     public static final int DOM_VK_WIN_OEM_AUTO = 243;
766 
767     /** Constant for {@code DOM_VK_WIN_OEM_ENLW}. */
768     @JsxConstant({FF, FF_ESR})
769     public static final int DOM_VK_WIN_OEM_ENLW = 244;
770 
771     /** Constant for {@code DOM_VK_WIN_OEM_BACKTAB}. */
772     @JsxConstant({FF, FF_ESR})
773     public static final int DOM_VK_WIN_OEM_BACKTAB = 245;
774 
775     /** Constant for {@code DOM_VK_ATTN}. */
776     @JsxConstant({FF, FF_ESR})
777     public static final int DOM_VK_ATTN = 246;
778 
779     /** Constant for {@code DOM_VK_CRSEL}. */
780     @JsxConstant({FF, FF_ESR})
781     public static final int DOM_VK_CRSEL = 247;
782 
783     /** Constant for {@code DOM_VK_EXSEL}. */
784     @JsxConstant({FF, FF_ESR})
785     public static final int DOM_VK_EXSEL = 248;
786 
787     /** Constant for {@code DOM_VK_EREOF}. */
788     @JsxConstant({FF, FF_ESR})
789     public static final int DOM_VK_EREOF = 249;
790 
791     /** Constant for {@code DOM_VK_PLAY}. */
792     @JsxConstant({FF, FF_ESR})
793     public static final int DOM_VK_PLAY = 250;
794 
795     /** Constant for {@code DOM_VK_ZOOM}. */
796     @JsxConstant({FF, FF_ESR})
797     public static final int DOM_VK_ZOOM = 251;
798 
799     /** Constant for {@code DOM_VK_PA1}. */
800     @JsxConstant({FF, FF_ESR})
801     public static final int DOM_VK_PA1 = 253;
802 
803     /** Constant for {@code DOM_VK_WIN_OEM_CLEAR}. */
804     @JsxConstant({FF, FF_ESR})
805     public static final int DOM_VK_WIN_OEM_CLEAR = 254;
806 
807     /**
808      * For {@link #TYPE_KEY_DOWN} and {@link #TYPE_KEY_UP}, this map stores {@link #setKeyCode(int)} associated with
809      * the character (if they are not the same).
810      * You can verify this <a href="http://www.asquare.net/javascript/tests/KeyCode.html">here</a>
811      */
812     private static final Map<Character, Integer> KEX_CODE_MAP = new HashMap<>();
813     static {
814         KEX_CODE_MAP.put('`', DOM_VK_BACK_QUOTE);
815         KEX_CODE_MAP.put('~', DOM_VK_BACK_QUOTE);
816         KEX_CODE_MAP.put('!', DOM_VK_1);
817         KEX_CODE_MAP.put('@', DOM_VK_2);
818         KEX_CODE_MAP.put('#', DOM_VK_3);
819         KEX_CODE_MAP.put('$', DOM_VK_4);
820         KEX_CODE_MAP.put('%', DOM_VK_5);
821         KEX_CODE_MAP.put('^', DOM_VK_6);
822         KEX_CODE_MAP.put('&', DOM_VK_7);
823         KEX_CODE_MAP.put('*', DOM_VK_8);
824         KEX_CODE_MAP.put('(', DOM_VK_9);
825         KEX_CODE_MAP.put(')', DOM_VK_0);
826         //Chrome/IE 189
827         KEX_CODE_MAP.put('-', DOM_VK_HYPHEN_MINUS);
828         KEX_CODE_MAP.put('_', DOM_VK_HYPHEN_MINUS);
829         //Chrome/IE 187
830         KEX_CODE_MAP.put('+', DOM_VK_EQUALS);
831         KEX_CODE_MAP.put('[', DOM_VK_OPEN_BRACKET);
832         KEX_CODE_MAP.put('{', DOM_VK_OPEN_BRACKET);
833         KEX_CODE_MAP.put(']', DOM_VK_CLOSE_BRACKET);
834         KEX_CODE_MAP.put('}', DOM_VK_CLOSE_BRACKET);
835         //Chrome/IE 186
836         KEX_CODE_MAP.put(':', DOM_VK_SEMICOLON);
837         KEX_CODE_MAP.put('\'', DOM_VK_QUOTE);
838         KEX_CODE_MAP.put('"', DOM_VK_QUOTE);
839         KEX_CODE_MAP.put(',', DOM_VK_COMMA);
840         KEX_CODE_MAP.put('<', DOM_VK_COMMA);
841         KEX_CODE_MAP.put('.', DOM_VK_PERIOD);
842         KEX_CODE_MAP.put('>', DOM_VK_PERIOD);
843         KEX_CODE_MAP.put('/', DOM_VK_SLASH);
844         KEX_CODE_MAP.put('?', DOM_VK_SLASH);
845         KEX_CODE_MAP.put('\\', DOM_VK_BACK_SLASH);
846         KEX_CODE_MAP.put('|', DOM_VK_BACK_SLASH);
847     }
848 
849     /*
850      * Standard properties
851      */
852 
853     /** The key value of the key represented by the event. */
854     private String key_ = "";
855 
856     /** The code value of the physical key represented by the event. */
857     private String code_ = "";
858 
859     /** The location of the key on the keyboard or other input device. See DOM_KEY_LOCATION_* constants. */
860     private int location_;
861 
862     /** Whether or not the "meta" key was pressed during the firing of the event. */
863     private boolean metaKey_;
864 
865     /** Whether the key is being held down such that it is automatically repeating. */
866     private boolean repeat_;
867 
868     /** Whether the event is fired after the compositionstart and before the compositionend events. */
869     private boolean isComposing_;
870 
871     /*
872      * Deprecated properties
873      */
874 
875     /** The Unicode reference number of the key. */
876     private int charCode_;
877 
878     /** The unmodified value of the pressed key. This is usually the same as keyCode. */
879     private int which_;
880 
881     /**
882      * Creates a new keyboard event instance.
883      */
884     public KeyboardEvent() {
885         super();
886     }
887 
888     /**
889      * Creates a new keyboard event instance.
890      *
891      * @param domNode the DOM node that triggered the event
892      * @param type the event type
893      * @param character the character associated with the event
894      * @param shiftKey true if SHIFT is pressed
895      * @param ctrlKey true if CTRL is pressed
896      * @param altKey true if ALT is pressed
897      */
898     public KeyboardEvent(final DomNode domNode, final String type, final char character,
899             final boolean shiftKey, final boolean ctrlKey, final boolean altKey) {
900         super(domNode, type);
901 
902         setShiftKey(shiftKey);
903         setCtrlKey(ctrlKey);
904         setAltKey(altKey);
905 
906         if ('\n' == character) {
907             setKeyCode(DOM_VK_RETURN);
908             charCode_ = DOM_VK_RETURN;
909             which_ = DOM_VK_RETURN;
910             return;
911         }
912 
913         final int keyCode;
914         if (Event.TYPE_KEY_PRESS.equals(getType())) {
915             keyCode = Integer.valueOf(character);
916         }
917         else {
918             keyCode = Integer.valueOf(charToKeyCode(character));
919         }
920         setKeyCode(keyCode);
921         if (Event.TYPE_KEY_PRESS.equals(getType())) {
922             charCode_ = character;
923         }
924         which_ = charCode_ == 0 ? keyCode : Integer.valueOf(charCode_);
925 
926         key_ = determineKey();
927         code_ = determineCode();
928     }
929 
930     /**
931      * Creates a new keyboard event instance.
932      *
933      * @param domNode the DOM node that triggered the event
934      * @param type the event type
935      * @param keyCode the key code associated with the event
936      * @param shiftKey true if SHIFT is pressed
937      * @param ctrlKey true if CTRL is pressed
938      * @param altKey true if ALT is pressed
939      */
940     public KeyboardEvent(final DomNode domNode, final String type, final int keyCode,
941             final boolean shiftKey, final boolean ctrlKey, final boolean altKey) {
942         super(domNode, type);
943 
944         if (isAmbiguousKeyCode(keyCode)) {
945             throw new IllegalArgumentException("Please use the 'char' constructor instead of int");
946         }
947         setKeyCode(keyCode);
948         if (Event.TYPE_KEY_PRESS.equals(getType())) {
949             which_ = 0;
950         }
951         else {
952             which_ = keyCode;
953         }
954         setShiftKey(shiftKey);
955         setCtrlKey(ctrlKey);
956         setAltKey(altKey);
957 
958         key_ = determineKey();
959         code_ = determineCode();
960     }
961 
962     /**
963      * Returns whether the specified character can be written only when {@code SHIFT} key is pressed.
964      * @param ch the character
965      * @param shiftKey is shift key pressed
966      * @return whether the specified character can be written only when {@code SHIFT} key is pressed
967      */
968     public static boolean isShiftNeeded(final char ch, final boolean shiftKey) {
969         return "~!@#$%^&*()_+{}:\"<>?|".indexOf(ch) != -1
970                 || (!shiftKey && ch >= 'A' && ch <= 'Z');
971     }
972 
973     /** We can not accept DOM_VK_A, because is it 'A' or 'a', so the character constructor should be used. */
974     private static boolean isAmbiguousKeyCode(final int keyCode) {
975         return (keyCode >= DOM_VK_0 && keyCode <= DOM_VK_9) || (keyCode >= DOM_VK_A && keyCode <= DOM_VK_Z);
976     }
977 
978     /**
979      * Converts a Java character to a keyCode.
980      * @see <a href="http://www.w3.org/TR/DOM-Level-3-Events/#keyset-keyidentifiers">DOM 3 Events</a>
981      * @param c the character
982      * @return the corresponding keycode
983      */
984     private static int charToKeyCode(final char c) {
985         if (c >= 'a' && c <= 'z') {
986             return 'A' + c - 'a';
987         }
988 
989         final Integer i = KEX_CODE_MAP.get(c);
990         if (i != null) {
991             return i;
992         }
993         return c;
994     }
995 
996     /**
997      * Determines the value of the 'key' property from the current value of 'keyCode', 'charCode', or 'which'.
998      * @return the key value
999      */
1000     private String determineKey() {
1001         int code = getKeyCode();
1002         if (code == 0) {
1003             code = getCharCode();
1004         }
1005         switch (code) {
1006             case DOM_VK_SHIFT:
1007                 return "Shift";
1008             case DOM_VK_PERIOD:
1009                 return ".";
1010             case DOM_VK_RETURN:
1011                 return "Enter";
1012 
1013             default:
1014                 return String.valueOf(isShiftKey() ? (char) which_ : Character.toLowerCase((char) which_));
1015         }
1016     }
1017 
1018     /**
1019      * Determines the value of the 'code' property from the current value of 'keyCode', 'charCode', or 'which'.
1020      * @return the code value
1021      */
1022     private String determineCode() {
1023         int code = getKeyCode();
1024         if (code == 0) {
1025             code = getCharCode();
1026         }
1027         switch (code) {
1028             case DOM_VK_SHIFT:
1029                 return "ShiftLeft";
1030             case DOM_VK_PERIOD:
1031             case '.':
1032                 return "Period";
1033             case DOM_VK_RETURN:
1034                 return "Enter";
1035 
1036             default:
1037                 return "Key" + Character.toUpperCase((char) which_);
1038         }
1039     }
1040 
1041     /**
1042      * JavaScript constructor.
1043      *
1044      * @param type the event type
1045      * @param details the event details (optional)
1046      */
1047     @JsxConstructor
1048     @Override
1049     public void jsConstructor(final String type, final ScriptableObject details) {
1050         super.jsConstructor(type, details);
1051 
1052         if (details != null && !JavaScriptEngine.isUndefined(details)) {
1053 
1054             final Object key = details.get("key", details);
1055             if (!isMissingOrUndefined(key)) {
1056                 setKey(JavaScriptEngine.toString(key));
1057             }
1058 
1059             final Object code = details.get("code", details);
1060             if (!isMissingOrUndefined(code)) {
1061                 setCode(JavaScriptEngine.toString(code));
1062             }
1063 
1064             final Object location = details.get("location", details);
1065             if (!isMissingOrUndefined(location)) {
1066                 setLocation(JavaScriptEngine.toInt32(location));
1067             }
1068 
1069             final Object ctrlKey = details.get("ctrlKey", details);
1070             if (!isMissingOrUndefined(ctrlKey)) {
1071                 setCtrlKey(JavaScriptEngine.toBoolean(ctrlKey));
1072             }
1073 
1074             final Object shiftKey = details.get("shiftKey", details);
1075             if (!isMissingOrUndefined(shiftKey)) {
1076                 setShiftKey(JavaScriptEngine.toBoolean(shiftKey));
1077             }
1078 
1079             final Object altKey = details.get("altKey", details);
1080             if (!isMissingOrUndefined(altKey)) {
1081                 setAltKey(JavaScriptEngine.toBoolean(altKey));
1082             }
1083 
1084             final Object metaKey = details.get("metaKey", details);
1085             if (!isMissingOrUndefined(metaKey)) {
1086                 setMetaKey(JavaScriptEngine.toBoolean(metaKey));
1087             }
1088 
1089             final Object repeat = details.get("repeat", details);
1090             if (!isMissingOrUndefined(repeat)) {
1091                 setRepeat(JavaScriptEngine.toBoolean(repeat));
1092             }
1093 
1094             final Object isComposing = details.get("isComposing", details);
1095             if (!isMissingOrUndefined(isComposing)) {
1096                 setIsComposing(JavaScriptEngine.toBoolean(isComposing));
1097             }
1098 
1099             final Object charCode = details.get("charCode", details);
1100             if (!isMissingOrUndefined(charCode)) {
1101                 setCharCode(JavaScriptEngine.toInt32(charCode));
1102             }
1103 
1104             final Object keyCode = details.get("keyCode", details);
1105             if (!isMissingOrUndefined(keyCode)) {
1106                 setKeyCode(JavaScriptEngine.toInt32(keyCode));
1107             }
1108 
1109             if (getBrowserVersion().hasFeature(JS_EVENT_KEYBOARD_CTOR_WHICH)) {
1110                 final Object which = details.get("which", details);
1111                 if (!isMissingOrUndefined(which)) {
1112                     setWhich(JavaScriptEngine.toInt32(which));
1113                 }
1114             }
1115         }
1116     }
1117 
1118     /**
1119      * Implementation of the DOM Level 3 Event method for initializing the key event.
1120      *
1121      * @param type the event type
1122      * @param bubbles can the event bubble
1123      * @param cancelable can the event be canceled
1124      * @param view the view to use for this event
1125      * @param key the value of the key attribute. Defaults to ""
1126      * @param location the value of the location attribute. Defaults to 0
1127      * @param ctrlKey is the control key pressed
1128      * @param altKey is the alt key pressed
1129      * @param shiftKey is the shift key pressed
1130      * @param metaKey is the meta key pressed
1131      */
1132     @JsxFunction
1133     public void initKeyboardEvent(
1134             final String type,
1135             final boolean bubbles,
1136             final boolean cancelable,
1137             final Object view,
1138             final String key,
1139             final int location,
1140             final boolean ctrlKey,
1141             final boolean altKey,
1142             final boolean shiftKey,
1143             final boolean metaKey) {
1144 
1145         initUIEvent(type, bubbles, cancelable, view, 0);
1146         setKey(key);
1147         setLocation(location);
1148         setCtrlKey(ctrlKey);
1149         setAltKey(altKey);
1150         setShiftKey(shiftKey);
1151         setKeyCode(0);
1152         setMetaKey(metaKey);
1153         charCode_ = 0;
1154     }
1155 
1156     /**
1157      * Returns the char code associated with the event.
1158      * @return the char code associated with the event
1159      */
1160     @JsxGetter
1161     public int getCharCode() {
1162         return charCode_;
1163     }
1164 
1165     /**
1166      * Sets the char code associated with the event.
1167      * @param charCode the char code associated with the event
1168      */
1169     protected void setCharCode(final int charCode) {
1170         charCode_ = charCode;
1171     }
1172 
1173     /**
1174      * Returns the numeric keyCode of the key pressed, or the charCode for an alphanumeric key pressed.
1175      * @return the numeric keyCode of the key pressed, or the charCode for an alphanumeric key pressed
1176      */
1177     @Override
1178     public int getWhich() {
1179         return which_;
1180     }
1181 
1182     /**
1183      * Sets the numeric keyCode of the key pressed, or the charCode for an alphanumeric key pressed.
1184      * @param which the numeric keyCode of the key pressed, or the charCode for an alphanumeric key pressed
1185      */
1186     protected void setWhich(final int which) {
1187         which_ = which;
1188     }
1189 
1190     /**
1191      * {@inheritDoc} Overridden to modify browser configurations.
1192      */
1193     @Override
1194     @JsxGetter
1195     public int getKeyCode() {
1196         return super.getKeyCode();
1197     }
1198 
1199     /**
1200      * {@inheritDoc}
1201      */
1202     @Override
1203     @JsxGetter
1204     public boolean isShiftKey() {
1205         return super.isShiftKey();
1206     }
1207 
1208     /**
1209      * {@inheritDoc}
1210      */
1211     @Override
1212     @JsxGetter
1213     public boolean isCtrlKey() {
1214         return super.isCtrlKey();
1215     }
1216 
1217     /**
1218      * {@inheritDoc}
1219      */
1220     @Override
1221     @JsxGetter
1222     public boolean isAltKey() {
1223         return super.isAltKey();
1224     }
1225 
1226     /**
1227      * Returns the value of a key or keys pressed by the user.
1228      * @return the value of a key or keys pressed by the user
1229      */
1230     @JsxGetter
1231     public String getKey() {
1232         return key_;
1233     }
1234 
1235     /**
1236      * Sets the value of a key or keys pressed by the user.
1237      * @param key the value of a key or keys pressed by the user
1238      */
1239     protected void setKey(final String key) {
1240         key_ = key;
1241     }
1242 
1243     /**
1244      * Returns a physical key on the keyboard.
1245      * @return a physical key on the keyboard
1246      */
1247     @JsxGetter
1248     public String getCode() {
1249         return code_;
1250     }
1251 
1252     /**
1253      * Sets a physical key on the keyboard.
1254      * @param code a physical key on the keyboard
1255      */
1256     protected void setCode(final String code) {
1257         code_ = code;
1258     }
1259 
1260     /**
1261      * Returns whether or not the "meta" key was pressed during the event firing.
1262      * @return whether or not the "meta" key was pressed during the event firing
1263      */
1264     @JsxGetter
1265     public boolean getMetaKey() {
1266         return metaKey_;
1267     }
1268 
1269     /**
1270      * Sets whether or not the "meta" key was pressed during the event firing.
1271      * @param metaKey whether or not the "meta" was pressed during the event firing
1272      */
1273     protected void setMetaKey(final boolean metaKey) {
1274         metaKey_ = metaKey;
1275     }
1276 
1277     /**
1278      * Returns the location of the key on the keyboard.
1279      * @return the location of the key on the keyboard
1280      */
1281     @JsxGetter
1282     public int getLocation() {
1283         return location_;
1284     }
1285 
1286     /**
1287      * Sets the location of the key on the keyboard.
1288      * @param location the location of the key on the keyboard
1289      */
1290     protected void setLocation(final int location) {
1291         location_ = location;
1292     }
1293 
1294     /**
1295      * Returns whether or not the key is being held down such that it is automatically repeating.
1296      * @return whether or not the key is being held down
1297      */
1298     @JsxGetter
1299     public boolean isRepeat() {
1300         return repeat_;
1301     }
1302 
1303     /**
1304      * Sets whether or not the key is being held down such that it is automatically repeating.
1305      * @param repeat whether or not the key is being held down
1306      */
1307     protected void setRepeat(final boolean repeat) {
1308         repeat_ = repeat;
1309     }
1310 
1311     /**
1312      * Returns whether or not the event is fired after the compositionstart and before the compositionend events.
1313      * @return whether or not the event is fired while composing
1314      */
1315     @JsxGetter
1316     public boolean getIsComposing() {
1317         return isComposing_;
1318     }
1319 
1320     /**
1321      * Sets whether or not this event is fired after the compositionstart and before the compositionend events.
1322      * @param isComposing whether or not this event is fired while composing
1323      */
1324     protected void setIsComposing(final boolean isComposing) {
1325         isComposing_ = isComposing;
1326     }
1327 }