@novnc/novnc 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/AUTHORS +13 -0
  2. package/LICENSE.txt +2 -1
  3. package/README.md +69 -3
  4. package/core/base64.js +35 -41
  5. package/core/decoders/copyrect.js +22 -0
  6. package/core/decoders/hextile.js +137 -0
  7. package/core/decoders/raw.js +56 -0
  8. package/core/decoders/rre.js +44 -0
  9. package/core/decoders/tight.js +315 -0
  10. package/core/decoders/tightpng.js +27 -0
  11. package/core/deflator.js +85 -0
  12. package/core/des.js +90 -95
  13. package/core/display.js +254 -297
  14. package/core/encodings.js +7 -3
  15. package/core/inflator.js +48 -20
  16. package/core/input/domkeytable.js +21 -24
  17. package/core/input/fixedkeys.js +3 -1
  18. package/core/input/gesturehandler.js +567 -0
  19. package/core/input/keyboard.js +194 -120
  20. package/core/input/keysym.js +2 -0
  21. package/core/input/keysymdef.js +3 -3
  22. package/core/input/util.js +53 -12
  23. package/core/input/vkeys.js +2 -1
  24. package/core/rfb.js +1937 -1496
  25. package/core/util/browser.js +80 -29
  26. package/core/util/cursor.js +253 -0
  27. package/core/util/element.js +32 -0
  28. package/core/util/events.js +59 -55
  29. package/core/util/eventtarget.js +25 -30
  30. package/core/util/int.js +15 -0
  31. package/core/util/logging.js +21 -16
  32. package/core/util/polyfill.js +15 -8
  33. package/core/util/strings.js +21 -8
  34. package/core/websock.js +145 -167
  35. package/docs/API.md +31 -10
  36. package/lib/base64.js +115 -0
  37. package/lib/decoders/copyrect.js +44 -0
  38. package/lib/decoders/hextile.js +173 -0
  39. package/lib/decoders/raw.js +78 -0
  40. package/lib/decoders/rre.js +65 -0
  41. package/lib/decoders/tight.js +350 -0
  42. package/lib/decoders/tightpng.js +67 -0
  43. package/lib/deflator.js +99 -0
  44. package/lib/des.js +314 -0
  45. package/lib/display.js +733 -0
  46. package/lib/encodings.js +64 -0
  47. package/lib/inflator.js +87 -0
  48. package/lib/input/domkeytable.js +282 -0
  49. package/lib/input/fixedkeys.js +123 -0
  50. package/lib/input/gesturehandler.js +642 -0
  51. package/lib/input/keyboard.js +429 -0
  52. package/lib/input/keysym.js +1135 -0
  53. package/lib/input/keysymdef.js +1354 -0
  54. package/lib/input/util.js +304 -0
  55. package/lib/input/vkeys.js +127 -0
  56. package/lib/input/xtscancodes.js +505 -0
  57. package/lib/rfb.js +3448 -0
  58. package/lib/util/browser.js +131 -0
  59. package/lib/util/cursor.js +314 -0
  60. package/lib/util/element.js +43 -0
  61. package/lib/util/events.js +142 -0
  62. package/lib/util/eventtarget.js +64 -0
  63. package/lib/util/int.js +22 -0
  64. package/lib/util/logging.js +79 -0
  65. package/lib/util/polyfill.js +72 -0
  66. package/lib/util/strings.js +38 -0
  67. package/lib/vendor/pako/lib/utils/common.js +67 -0
  68. package/lib/vendor/pako/lib/zlib/adler32.js +33 -0
  69. package/lib/vendor/pako/lib/zlib/constants.js +51 -0
  70. package/lib/vendor/pako/lib/zlib/crc32.js +42 -0
  71. package/lib/vendor/pako/lib/zlib/deflate.js +2159 -0
  72. package/lib/vendor/pako/lib/zlib/gzheader.js +53 -0
  73. package/lib/vendor/pako/lib/zlib/inffast.js +445 -0
  74. package/lib/vendor/pako/lib/zlib/inflate.js +2114 -0
  75. package/lib/vendor/pako/lib/zlib/inftrees.js +418 -0
  76. package/lib/vendor/pako/lib/zlib/messages.js +36 -0
  77. package/lib/vendor/pako/lib/zlib/trees.js +1499 -0
  78. package/lib/vendor/pako/lib/zlib/zstream.js +46 -0
  79. package/lib/vendor/promise.js +255 -0
  80. package/lib/websock.js +374 -0
  81. package/package.json +48 -28
  82. package/vendor/pako/lib/zlib/deflate.js +30 -30
  83. package/vendor/pako/lib/zlib/inflate.js +17 -17
  84. package/core/input/mouse.js +0 -280
  85. package/docs/API-internal.md +0 -125
  86. package/docs/EMBEDDING.md +0 -83
  87. package/docs/VERSION +0 -1
@@ -0,0 +1,429 @@
1
+ "use strict";
2
+
3
+ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var Log = _interopRequireWildcard(require("../util/logging.js"));
11
+
12
+ var _events = require("../util/events.js");
13
+
14
+ var KeyboardUtil = _interopRequireWildcard(require("./util.js"));
15
+
16
+ var _keysym = _interopRequireDefault(require("./keysym.js"));
17
+
18
+ var browser = _interopRequireWildcard(require("../util/browser.js"));
19
+
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
+
22
+ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
23
+
24
+ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
+
26
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
27
+
28
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
29
+
30
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
31
+
32
+ //
33
+ // Keyboard event handler
34
+ //
35
+ var Keyboard = /*#__PURE__*/function () {
36
+ function Keyboard(target) {
37
+ _classCallCheck(this, Keyboard);
38
+
39
+ this._target = target || null;
40
+ this._keyDownList = {}; // List of depressed keys
41
+ // (even if they are happy)
42
+
43
+ this._pendingKey = null; // Key waiting for keypress
44
+
45
+ this._altGrArmed = false; // Windows AltGr detection
46
+ // keep these here so we can refer to them later
47
+
48
+ this._eventHandlers = {
49
+ 'keyup': this._handleKeyUp.bind(this),
50
+ 'keydown': this._handleKeyDown.bind(this),
51
+ 'keypress': this._handleKeyPress.bind(this),
52
+ 'blur': this._allKeysUp.bind(this),
53
+ 'checkalt': this._checkAlt.bind(this)
54
+ }; // ===== EVENT HANDLERS =====
55
+
56
+ this.onkeyevent = function () {}; // Handler for key press/release
57
+
58
+ } // ===== PRIVATE METHODS =====
59
+
60
+
61
+ _createClass(Keyboard, [{
62
+ key: "_sendKeyEvent",
63
+ value: function _sendKeyEvent(keysym, code, down) {
64
+ if (down) {
65
+ this._keyDownList[code] = keysym;
66
+ } else {
67
+ // Do we really think this key is down?
68
+ if (!(code in this._keyDownList)) {
69
+ return;
70
+ }
71
+
72
+ delete this._keyDownList[code];
73
+ }
74
+
75
+ Log.Debug("onkeyevent " + (down ? "down" : "up") + ", keysym: " + keysym, ", code: " + code);
76
+ this.onkeyevent(keysym, code, down);
77
+ }
78
+ }, {
79
+ key: "_getKeyCode",
80
+ value: function _getKeyCode(e) {
81
+ var code = KeyboardUtil.getKeycode(e);
82
+
83
+ if (code !== 'Unidentified') {
84
+ return code;
85
+ } // Unstable, but we don't have anything else to go on
86
+ // (don't use it for 'keypress' events thought since
87
+ // WebKit sets it to the same as charCode)
88
+
89
+
90
+ if (e.keyCode && e.type !== 'keypress') {
91
+ // 229 is used for composition events
92
+ if (e.keyCode !== 229) {
93
+ return 'Platform' + e.keyCode;
94
+ }
95
+ } // A precursor to the final DOM3 standard. Unfortunately it
96
+ // is not layout independent, so it is as bad as using keyCode
97
+
98
+
99
+ if (e.keyIdentifier) {
100
+ // Non-character key?
101
+ if (e.keyIdentifier.substr(0, 2) !== 'U+') {
102
+ return e.keyIdentifier;
103
+ }
104
+
105
+ var codepoint = parseInt(e.keyIdentifier.substr(2), 16);
106
+ var char = String.fromCharCode(codepoint).toUpperCase();
107
+ return 'Platform' + char.charCodeAt();
108
+ }
109
+
110
+ return 'Unidentified';
111
+ }
112
+ }, {
113
+ key: "_handleKeyDown",
114
+ value: function _handleKeyDown(e) {
115
+ var code = this._getKeyCode(e);
116
+
117
+ var keysym = KeyboardUtil.getKeysym(e); // Windows doesn't have a proper AltGr, but handles it using
118
+ // fake Ctrl+Alt. However the remote end might not be Windows,
119
+ // so we need to merge those in to a single AltGr event. We
120
+ // detect this case by seeing the two key events directly after
121
+ // each other with a very short time between them (<50ms).
122
+
123
+ if (this._altGrArmed) {
124
+ this._altGrArmed = false;
125
+ clearTimeout(this._altGrTimeout);
126
+
127
+ if (code === "AltRight" && e.timeStamp - this._altGrCtrlTime < 50) {
128
+ // FIXME: We fail to detect this if either Ctrl key is
129
+ // first manually pressed as Windows then no
130
+ // longer sends the fake Ctrl down event. It
131
+ // does however happily send real Ctrl events
132
+ // even when AltGr is already down. Some
133
+ // browsers detect this for us though and set the
134
+ // key to "AltGraph".
135
+ keysym = _keysym.default.XK_ISO_Level3_Shift;
136
+ } else {
137
+ this._sendKeyEvent(_keysym.default.XK_Control_L, "ControlLeft", true);
138
+ }
139
+ } // We cannot handle keys we cannot track, but we also need
140
+ // to deal with virtual keyboards which omit key info
141
+
142
+
143
+ if (code === 'Unidentified') {
144
+ if (keysym) {
145
+ // If it's a virtual keyboard then it should be
146
+ // sufficient to just send press and release right
147
+ // after each other
148
+ this._sendKeyEvent(keysym, code, true);
149
+
150
+ this._sendKeyEvent(keysym, code, false);
151
+ }
152
+
153
+ (0, _events.stopEvent)(e);
154
+ return;
155
+ } // Alt behaves more like AltGraph on macOS, so shuffle the
156
+ // keys around a bit to make things more sane for the remote
157
+ // server. This method is used by RealVNC and TigerVNC (and
158
+ // possibly others).
159
+
160
+
161
+ if (browser.isMac() || browser.isIOS()) {
162
+ switch (keysym) {
163
+ case _keysym.default.XK_Super_L:
164
+ keysym = _keysym.default.XK_Alt_L;
165
+ break;
166
+
167
+ case _keysym.default.XK_Super_R:
168
+ keysym = _keysym.default.XK_Super_L;
169
+ break;
170
+
171
+ case _keysym.default.XK_Alt_L:
172
+ keysym = _keysym.default.XK_Mode_switch;
173
+ break;
174
+
175
+ case _keysym.default.XK_Alt_R:
176
+ keysym = _keysym.default.XK_ISO_Level3_Shift;
177
+ break;
178
+ }
179
+ } // Is this key already pressed? If so, then we must use the
180
+ // same keysym or we'll confuse the server
181
+
182
+
183
+ if (code in this._keyDownList) {
184
+ keysym = this._keyDownList[code];
185
+ } // macOS doesn't send proper key events for modifiers, only
186
+ // state change events. That gets extra confusing for CapsLock
187
+ // which toggles on each press, but not on release. So pretend
188
+ // it was a quick press and release of the button.
189
+
190
+
191
+ if ((browser.isMac() || browser.isIOS()) && code === 'CapsLock') {
192
+ this._sendKeyEvent(_keysym.default.XK_Caps_Lock, 'CapsLock', true);
193
+
194
+ this._sendKeyEvent(_keysym.default.XK_Caps_Lock, 'CapsLock', false);
195
+
196
+ (0, _events.stopEvent)(e);
197
+ return;
198
+ } // If this is a legacy browser then we'll need to wait for
199
+ // a keypress event as well
200
+ // (IE and Edge has a broken KeyboardEvent.key, so we can't
201
+ // just check for the presence of that field)
202
+
203
+
204
+ if (!keysym && (!e.key || browser.isIE() || browser.isEdge())) {
205
+ this._pendingKey = code; // However we might not get a keypress event if the key
206
+ // is non-printable, which needs some special fallback
207
+ // handling
208
+
209
+ setTimeout(this._handleKeyPressTimeout.bind(this), 10, e);
210
+ return;
211
+ }
212
+
213
+ this._pendingKey = null;
214
+ (0, _events.stopEvent)(e); // Possible start of AltGr sequence? (see above)
215
+
216
+ if (code === "ControlLeft" && browser.isWindows() && !("ControlLeft" in this._keyDownList)) {
217
+ this._altGrArmed = true;
218
+ this._altGrTimeout = setTimeout(this._handleAltGrTimeout.bind(this), 100);
219
+ this._altGrCtrlTime = e.timeStamp;
220
+ return;
221
+ }
222
+
223
+ this._sendKeyEvent(keysym, code, true);
224
+ } // Legacy event for browsers without code/key
225
+
226
+ }, {
227
+ key: "_handleKeyPress",
228
+ value: function _handleKeyPress(e) {
229
+ (0, _events.stopEvent)(e); // Are we expecting a keypress?
230
+
231
+ if (this._pendingKey === null) {
232
+ return;
233
+ }
234
+
235
+ var code = this._getKeyCode(e);
236
+
237
+ var keysym = KeyboardUtil.getKeysym(e); // The key we were waiting for?
238
+
239
+ if (code !== 'Unidentified' && code != this._pendingKey) {
240
+ return;
241
+ }
242
+
243
+ code = this._pendingKey;
244
+ this._pendingKey = null;
245
+
246
+ if (!keysym) {
247
+ Log.Info('keypress with no keysym:', e);
248
+ return;
249
+ }
250
+
251
+ this._sendKeyEvent(keysym, code, true);
252
+ }
253
+ }, {
254
+ key: "_handleKeyPressTimeout",
255
+ value: function _handleKeyPressTimeout(e) {
256
+ // Did someone manage to sort out the key already?
257
+ if (this._pendingKey === null) {
258
+ return;
259
+ }
260
+
261
+ var keysym;
262
+ var code = this._pendingKey;
263
+ this._pendingKey = null; // We have no way of knowing the proper keysym with the
264
+ // information given, but the following are true for most
265
+ // layouts
266
+
267
+ if (e.keyCode >= 0x30 && e.keyCode <= 0x39) {
268
+ // Digit
269
+ keysym = e.keyCode;
270
+ } else if (e.keyCode >= 0x41 && e.keyCode <= 0x5a) {
271
+ // Character (A-Z)
272
+ var char = String.fromCharCode(e.keyCode); // A feeble attempt at the correct case
273
+
274
+ if (e.shiftKey) {
275
+ char = char.toUpperCase();
276
+ } else {
277
+ char = char.toLowerCase();
278
+ }
279
+
280
+ keysym = char.charCodeAt();
281
+ } else {
282
+ // Unknown, give up
283
+ keysym = 0;
284
+ }
285
+
286
+ this._sendKeyEvent(keysym, code, true);
287
+ }
288
+ }, {
289
+ key: "_handleKeyUp",
290
+ value: function _handleKeyUp(e) {
291
+ (0, _events.stopEvent)(e);
292
+
293
+ var code = this._getKeyCode(e); // We can't get a release in the middle of an AltGr sequence, so
294
+ // abort that detection
295
+
296
+
297
+ if (this._altGrArmed) {
298
+ this._altGrArmed = false;
299
+ clearTimeout(this._altGrTimeout);
300
+
301
+ this._sendKeyEvent(_keysym.default.XK_Control_L, "ControlLeft", true);
302
+ } // See comment in _handleKeyDown()
303
+
304
+
305
+ if ((browser.isMac() || browser.isIOS()) && code === 'CapsLock') {
306
+ this._sendKeyEvent(_keysym.default.XK_Caps_Lock, 'CapsLock', true);
307
+
308
+ this._sendKeyEvent(_keysym.default.XK_Caps_Lock, 'CapsLock', false);
309
+
310
+ return;
311
+ }
312
+
313
+ this._sendKeyEvent(this._keyDownList[code], code, false); // Windows has a rather nasty bug where it won't send key
314
+ // release events for a Shift button if the other Shift is still
315
+ // pressed
316
+
317
+
318
+ if (browser.isWindows() && (code === 'ShiftLeft' || code === 'ShiftRight')) {
319
+ if ('ShiftRight' in this._keyDownList) {
320
+ this._sendKeyEvent(this._keyDownList['ShiftRight'], 'ShiftRight', false);
321
+ }
322
+
323
+ if ('ShiftLeft' in this._keyDownList) {
324
+ this._sendKeyEvent(this._keyDownList['ShiftLeft'], 'ShiftLeft', false);
325
+ }
326
+ }
327
+ }
328
+ }, {
329
+ key: "_handleAltGrTimeout",
330
+ value: function _handleAltGrTimeout() {
331
+ this._altGrArmed = false;
332
+ clearTimeout(this._altGrTimeout);
333
+
334
+ this._sendKeyEvent(_keysym.default.XK_Control_L, "ControlLeft", true);
335
+ }
336
+ }, {
337
+ key: "_allKeysUp",
338
+ value: function _allKeysUp() {
339
+ Log.Debug(">> Keyboard.allKeysUp");
340
+
341
+ for (var code in this._keyDownList) {
342
+ this._sendKeyEvent(this._keyDownList[code], code, false);
343
+ }
344
+
345
+ Log.Debug("<< Keyboard.allKeysUp");
346
+ } // Alt workaround for Firefox on Windows, see below
347
+
348
+ }, {
349
+ key: "_checkAlt",
350
+ value: function _checkAlt(e) {
351
+ if (e.skipCheckAlt) {
352
+ return;
353
+ }
354
+
355
+ if (e.altKey) {
356
+ return;
357
+ }
358
+
359
+ var target = this._target;
360
+ var downList = this._keyDownList;
361
+ ['AltLeft', 'AltRight'].forEach(function (code) {
362
+ if (!(code in downList)) {
363
+ return;
364
+ }
365
+
366
+ var event = new KeyboardEvent('keyup', {
367
+ key: downList[code],
368
+ code: code
369
+ });
370
+ event.skipCheckAlt = true;
371
+ target.dispatchEvent(event);
372
+ });
373
+ } // ===== PUBLIC METHODS =====
374
+
375
+ }, {
376
+ key: "grab",
377
+ value: function grab() {
378
+ //Log.Debug(">> Keyboard.grab");
379
+ this._target.addEventListener('keydown', this._eventHandlers.keydown);
380
+
381
+ this._target.addEventListener('keyup', this._eventHandlers.keyup);
382
+
383
+ this._target.addEventListener('keypress', this._eventHandlers.keypress); // Release (key up) if window loses focus
384
+
385
+
386
+ window.addEventListener('blur', this._eventHandlers.blur); // Firefox on Windows has broken handling of Alt, so we need to
387
+ // poll as best we can for releases (still doesn't prevent the
388
+ // menu from popping up though as we can't call
389
+ // preventDefault())
390
+
391
+ if (browser.isWindows() && browser.isFirefox()) {
392
+ var handler = this._eventHandlers.checkalt;
393
+ ['mousedown', 'mouseup', 'mousemove', 'wheel', 'touchstart', 'touchend', 'touchmove', 'keydown', 'keyup'].forEach(function (type) {
394
+ return document.addEventListener(type, handler, {
395
+ capture: true,
396
+ passive: true
397
+ });
398
+ });
399
+ } //Log.Debug("<< Keyboard.grab");
400
+
401
+ }
402
+ }, {
403
+ key: "ungrab",
404
+ value: function ungrab() {
405
+ //Log.Debug(">> Keyboard.ungrab");
406
+ if (browser.isWindows() && browser.isFirefox()) {
407
+ var handler = this._eventHandlers.checkalt;
408
+ ['mousedown', 'mouseup', 'mousemove', 'wheel', 'touchstart', 'touchend', 'touchmove', 'keydown', 'keyup'].forEach(function (type) {
409
+ return document.removeEventListener(type, handler);
410
+ });
411
+ }
412
+
413
+ this._target.removeEventListener('keydown', this._eventHandlers.keydown);
414
+
415
+ this._target.removeEventListener('keyup', this._eventHandlers.keyup);
416
+
417
+ this._target.removeEventListener('keypress', this._eventHandlers.keypress);
418
+
419
+ window.removeEventListener('blur', this._eventHandlers.blur); // Release (key up) all keys that are in a down state
420
+
421
+ this._allKeysUp(); //Log.Debug(">> Keyboard.ungrab");
422
+
423
+ }
424
+ }]);
425
+
426
+ return Keyboard;
427
+ }();
428
+
429
+ exports.default = Keyboard;