]> git.proxmox.com Git - mirror_novnc.git/blob - core/input/util.js
Merge branch 'style' of https://github.com/CendioOssman/noVNC
[mirror_novnc.git] / core / input / util.js
1 import keysyms from "./keysymdef.js";
2 import vkeys from "./vkeys.js";
3 import fixedkeys from "./fixedkeys.js";
4 import DOMKeyTable from "./domkeytable.js";
5 import * as browser from "../util/browser.js";
6
7 // Get 'KeyboardEvent.code', handling legacy browsers
8 export function getKeycode(evt) {
9 // Are we getting proper key identifiers?
10 // (unfortunately Firefox and Chrome are crappy here and gives
11 // us an empty string on some platforms, rather than leaving it
12 // undefined)
13 if (evt.code) {
14 // Mozilla isn't fully in sync with the spec yet
15 switch (evt.code) {
16 case 'OSLeft': return 'MetaLeft';
17 case 'OSRight': return 'MetaRight';
18 }
19
20 return evt.code;
21 }
22
23 // The de-facto standard is to use Windows Virtual-Key codes
24 // in the 'keyCode' field for non-printable characters. However
25 // Webkit sets it to the same as charCode in 'keypress' events.
26 if ((evt.type !== 'keypress') && (evt.keyCode in vkeys)) {
27 let code = vkeys[evt.keyCode];
28
29 // macOS has messed up this code for some reason
30 if (browser.isMac() && (code === 'ContextMenu')) {
31 code = 'MetaRight';
32 }
33
34 // The keyCode doesn't distinguish between left and right
35 // for the standard modifiers
36 if (evt.location === 2) {
37 switch (code) {
38 case 'ShiftLeft': return 'ShiftRight';
39 case 'ControlLeft': return 'ControlRight';
40 case 'AltLeft': return 'AltRight';
41 }
42 }
43
44 // Nor a bunch of the numpad keys
45 if (evt.location === 3) {
46 switch (code) {
47 case 'Delete': return 'NumpadDecimal';
48 case 'Insert': return 'Numpad0';
49 case 'End': return 'Numpad1';
50 case 'ArrowDown': return 'Numpad2';
51 case 'PageDown': return 'Numpad3';
52 case 'ArrowLeft': return 'Numpad4';
53 case 'ArrowRight': return 'Numpad6';
54 case 'Home': return 'Numpad7';
55 case 'ArrowUp': return 'Numpad8';
56 case 'PageUp': return 'Numpad9';
57 case 'Enter': return 'NumpadEnter';
58 }
59 }
60
61 return code;
62 }
63
64 return 'Unidentified';
65 }
66
67 // Get 'KeyboardEvent.key', handling legacy browsers
68 export function getKey(evt) {
69 // Are we getting a proper key value?
70 if (evt.key !== undefined) {
71 // IE and Edge use some ancient version of the spec
72 // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
73 switch (evt.key) {
74 case 'Spacebar': return ' ';
75 case 'Esc': return 'Escape';
76 case 'Scroll': return 'ScrollLock';
77 case 'Win': return 'Meta';
78 case 'Apps': return 'ContextMenu';
79 case 'Up': return 'ArrowUp';
80 case 'Left': return 'ArrowLeft';
81 case 'Right': return 'ArrowRight';
82 case 'Down': return 'ArrowDown';
83 case 'Del': return 'Delete';
84 case 'Divide': return '/';
85 case 'Multiply': return '*';
86 case 'Subtract': return '-';
87 case 'Add': return '+';
88 case 'Decimal': return evt.char;
89 }
90
91 // Mozilla isn't fully in sync with the spec yet
92 switch (evt.key) {
93 case 'OS': return 'Meta';
94 }
95
96 // iOS leaks some OS names
97 switch (evt.key) {
98 case 'UIKeyInputUpArrow': return 'ArrowUp';
99 case 'UIKeyInputDownArrow': return 'ArrowDown';
100 case 'UIKeyInputLeftArrow': return 'ArrowLeft';
101 case 'UIKeyInputRightArrow': return 'ArrowRight';
102 case 'UIKeyInputEscape': return 'Escape';
103 }
104
105 // IE and Edge have broken handling of AltGraph so we cannot
106 // trust them for printable characters
107 if ((evt.key.length !== 1) || (!browser.isIE() && !browser.isEdge())) {
108 return evt.key;
109 }
110 }
111
112 // Try to deduce it based on the physical key
113 const code = getKeycode(evt);
114 if (code in fixedkeys) {
115 return fixedkeys[code];
116 }
117
118 // If that failed, then see if we have a printable character
119 if (evt.charCode) {
120 return String.fromCharCode(evt.charCode);
121 }
122
123 // At this point we have nothing left to go on
124 return 'Unidentified';
125 }
126
127 // Get the most reliable keysym value we can get from a key event
128 export function getKeysym(evt) {
129 const key = getKey(evt);
130
131 if (key === 'Unidentified') {
132 return null;
133 }
134
135 // First look up special keys
136 if (key in DOMKeyTable) {
137 let location = evt.location;
138
139 // Safari screws up location for the right cmd key
140 if ((key === 'Meta') && (location === 0)) {
141 location = 2;
142 }
143
144 if ((location === undefined) || (location > 3)) {
145 location = 0;
146 }
147
148 return DOMKeyTable[key][location];
149 }
150
151 // Now we need to look at the Unicode symbol instead
152
153 // Special key? (FIXME: Should have been caught earlier)
154 if (key.length !== 1) {
155 return null;
156 }
157
158 const codepoint = key.charCodeAt();
159 if (codepoint) {
160 return keysyms.lookup(codepoint);
161 }
162
163 return null;
164 }