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