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