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