@novnc/novnc 1.2.0 → 1.3.0-g65d6357

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 (67) hide show
  1. package/LICENSE.txt +0 -6
  2. package/README.md +9 -4
  3. package/core/decoders/copyrect.js +5 -0
  4. package/core/decoders/hextile.js +57 -3
  5. package/core/decoders/raw.js +12 -2
  6. package/core/decoders/tight.js +24 -8
  7. package/core/decoders/zrle.js +185 -0
  8. package/core/display.js +9 -151
  9. package/core/encodings.js +2 -0
  10. package/core/input/domkeytable.js +25 -21
  11. package/core/input/keyboard.js +12 -127
  12. package/core/input/util.js +18 -35
  13. package/core/input/vkeys.js +0 -1
  14. package/core/input/xtscancodes.js +5 -3
  15. package/core/rfb.js +119 -109
  16. package/core/util/browser.js +0 -17
  17. package/core/util/cursor.js +1 -11
  18. package/core/util/events.js +0 -4
  19. package/core/websock.js +76 -17
  20. package/docs/API.md +10 -3
  21. package/docs/LIBRARY.md +3 -7
  22. package/lib/base64.js +4 -4
  23. package/lib/decoders/copyrect.js +7 -2
  24. package/lib/decoders/hextile.js +63 -7
  25. package/lib/decoders/raw.js +13 -4
  26. package/lib/decoders/rre.js +2 -2
  27. package/lib/decoders/tight.js +38 -20
  28. package/lib/decoders/tightpng.js +8 -8
  29. package/lib/decoders/zrle.js +234 -0
  30. package/lib/deflator.js +4 -4
  31. package/lib/des.js +2 -2
  32. package/lib/display.js +45 -212
  33. package/lib/encodings.js +4 -0
  34. package/lib/inflator.js +4 -4
  35. package/lib/input/domkeytable.js +197 -194
  36. package/lib/input/fixedkeys.js +2 -2
  37. package/lib/input/gesturehandler.js +2 -2
  38. package/lib/input/keyboard.js +38 -158
  39. package/lib/input/keysym.js +2 -2
  40. package/lib/input/keysymdef.js +2 -2
  41. package/lib/input/util.js +34 -79
  42. package/lib/input/vkeys.js +2 -4
  43. package/lib/input/xtscancodes.js +11 -5
  44. package/lib/rfb.js +295 -285
  45. package/lib/util/browser.js +8 -26
  46. package/lib/util/cursor.js +4 -16
  47. package/lib/util/events.js +3 -5
  48. package/lib/util/eventtarget.js +3 -3
  49. package/lib/util/int.js +1 -1
  50. package/lib/util/logging.js +2 -2
  51. package/lib/vendor/pako/lib/utils/common.js +2 -2
  52. package/lib/vendor/pako/lib/zlib/adler32.js +1 -1
  53. package/lib/vendor/pako/lib/zlib/constants.js +2 -2
  54. package/lib/vendor/pako/lib/zlib/crc32.js +1 -1
  55. package/lib/vendor/pako/lib/zlib/deflate.js +113 -112
  56. package/lib/vendor/pako/lib/zlib/gzheader.js +1 -1
  57. package/lib/vendor/pako/lib/zlib/inffast.js +5 -5
  58. package/lib/vendor/pako/lib/zlib/inflate.js +50 -48
  59. package/lib/vendor/pako/lib/zlib/inftrees.js +3 -3
  60. package/lib/vendor/pako/lib/zlib/messages.js +2 -2
  61. package/lib/vendor/pako/lib/zlib/trees.js +4 -4
  62. package/lib/vendor/pako/lib/zlib/zstream.js +1 -1
  63. package/lib/websock.js +105 -44
  64. package/package.json +2 -7
  65. package/core/util/polyfill.js +0 -61
  66. package/lib/util/polyfill.js +0 -72
  67. package/lib/vendor/promise.js +0 -255
package/lib/rfb.js CHANGED
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
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
+
3
5
  Object.defineProperty(exports, "__esModule", {
4
6
  value: true
5
7
  });
6
- exports.default = void 0;
8
+ exports["default"] = void 0;
7
9
 
8
10
  var _int = require("./util/int.js");
9
11
 
@@ -41,8 +43,6 @@ var _xtscancodes = _interopRequireDefault(require("./input/xtscancodes.js"));
41
43
 
42
44
  var _encodings = require("./encodings.js");
43
45
 
44
- require("./util/polyfill.js");
45
-
46
46
  var _raw = _interopRequireDefault(require("./decoders/raw.js"));
47
47
 
48
48
  var _copyrect = _interopRequireDefault(require("./decoders/copyrect.js"));
@@ -55,13 +55,13 @@ var _tight = _interopRequireDefault(require("./decoders/tight.js"));
55
55
 
56
56
  var _tightpng = _interopRequireDefault(require("./decoders/tightpng.js"));
57
57
 
58
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
58
+ var _zrle = _interopRequireDefault(require("./decoders/zrle.js"));
59
59
 
60
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
60
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
61
61
 
62
- 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; }
62
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
63
63
 
64
- 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); }
64
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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; }
65
65
 
66
66
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
67
67
 
@@ -75,11 +75,11 @@ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || func
75
75
 
76
76
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
77
77
 
78
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
78
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
79
79
 
80
80
  function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
81
81
 
82
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
82
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
83
83
 
84
84
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
85
85
 
@@ -120,7 +120,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
120
120
 
121
121
  var _super = _createSuper(RFB);
122
122
 
123
- function RFB(target, url, options) {
123
+ function RFB(target, urlOrChannel, options) {
124
124
  var _this;
125
125
 
126
126
  _classCallCheck(this, RFB);
@@ -129,13 +129,20 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
129
129
  throw new Error("Must specify target");
130
130
  }
131
131
 
132
- if (!url) {
133
- throw new Error("Must specify URL");
132
+ if (!urlOrChannel) {
133
+ throw new Error("Must specify URL, WebSocket or RTCDataChannel");
134
134
  }
135
135
 
136
136
  _this = _super.call(this);
137
137
  _this._target = target;
138
- _this._url = url; // Connection details
138
+
139
+ if (typeof urlOrChannel === "string") {
140
+ _this._url = urlOrChannel;
141
+ } else {
142
+ _this._url = null;
143
+ _this._rawChannel = urlOrChannel;
144
+ } // Connection details
145
+
139
146
 
140
147
  options = options || {};
141
148
  _this._rfbCredentials = options.credentials || {};
@@ -179,6 +186,8 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
179
186
  _this._keyboard = null; // Keyboard input handler object
180
187
 
181
188
  _this._gestures = null; // Gesture input handler object
189
+
190
+ _this._resizeObserver = null; // Resize observer object
182
191
  // Timers
183
192
 
184
193
  _this._disconnTimer = null; // disconnection timer
@@ -213,7 +222,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
213
222
 
214
223
  _this._eventHandlers = {
215
224
  focusCanvas: _this._focusCanvas.bind(_assertThisInitialized(_this)),
216
- windowResize: _this._windowResize.bind(_assertThisInitialized(_this)),
225
+ handleResize: _this._handleResize.bind(_assertThisInitialized(_this)),
217
226
  handleMouse: _this._handleMouse.bind(_assertThisInitialized(_this)),
218
227
  handleWheel: _this._handleWheel.bind(_assertThisInitialized(_this)),
219
228
  handleGesture: _this._handleGesture.bind(_assertThisInitialized(_this))
@@ -230,9 +239,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
230
239
  _this._canvas = document.createElement('canvas');
231
240
  _this._canvas.style.margin = 'auto'; // Some browsers add an outline on focus
232
241
 
233
- _this._canvas.style.outline = 'none'; // IE miscalculates width without this :(
234
-
235
- _this._canvas.style.flexShrink = '0';
242
+ _this._canvas.style.outline = 'none';
236
243
  _this._canvas.width = 0;
237
244
  _this._canvas.height = 0;
238
245
  _this._canvas.tabIndex = -1;
@@ -240,7 +247,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
240
247
  _this._screen.appendChild(_this._canvas); // Cursor
241
248
 
242
249
 
243
- _this._cursor = new _cursor.default(); // XXX: TightVNC 2.8.11 sends no cursor at all until Windows changes
250
+ _this._cursor = new _cursor["default"](); // XXX: TightVNC 2.8.11 sends no cursor at all until Windows changes
244
251
  // it. Result: no cursor at all until a window border or an edit field
245
252
  // is hit blindly. But there are also VNC servers that draw the cursor
246
253
  // in the framebuffer and don't send the empty local cursor. There is
@@ -252,95 +259,40 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
252
259
 
253
260
  _this._cursorImage = RFB.cursors.none; // populate decoder array with objects
254
261
 
255
- _this._decoders[_encodings.encodings.encodingRaw] = new _raw.default();
256
- _this._decoders[_encodings.encodings.encodingCopyRect] = new _copyrect.default();
257
- _this._decoders[_encodings.encodings.encodingRRE] = new _rre.default();
258
- _this._decoders[_encodings.encodings.encodingHextile] = new _hextile.default();
259
- _this._decoders[_encodings.encodings.encodingTight] = new _tight.default();
260
- _this._decoders[_encodings.encodings.encodingTightPNG] = new _tightpng.default(); // NB: nothing that needs explicit teardown should be done
262
+ _this._decoders[_encodings.encodings.encodingRaw] = new _raw["default"]();
263
+ _this._decoders[_encodings.encodings.encodingCopyRect] = new _copyrect["default"]();
264
+ _this._decoders[_encodings.encodings.encodingRRE] = new _rre["default"]();
265
+ _this._decoders[_encodings.encodings.encodingHextile] = new _hextile["default"]();
266
+ _this._decoders[_encodings.encodings.encodingTight] = new _tight["default"]();
267
+ _this._decoders[_encodings.encodings.encodingTightPNG] = new _tightpng["default"]();
268
+ _this._decoders[_encodings.encodings.encodingZRLE] = new _zrle["default"](); // NB: nothing that needs explicit teardown should be done
261
269
  // before this point, since this can throw an exception
262
270
 
263
271
  try {
264
- _this._display = new _display.default(_this._canvas);
272
+ _this._display = new _display["default"](_this._canvas);
265
273
  } catch (exc) {
266
274
  Log.Error("Display exception: " + exc);
267
275
  throw exc;
268
276
  }
269
277
 
270
278
  _this._display.onflush = _this._onFlush.bind(_assertThisInitialized(_this));
271
- _this._keyboard = new _keyboard.default(_this._canvas);
279
+ _this._keyboard = new _keyboard["default"](_this._canvas);
272
280
  _this._keyboard.onkeyevent = _this._handleKeyEvent.bind(_assertThisInitialized(_this));
273
- _this._gestures = new _gesturehandler.default();
274
- _this._sock = new _websock.default();
275
-
276
- _this._sock.on('message', function () {
277
- _this._handleMessage();
278
- });
279
-
280
- _this._sock.on('open', function () {
281
- if (_this._rfbConnectionState === 'connecting' && _this._rfbInitState === '') {
282
- _this._rfbInitState = 'ProtocolVersion';
283
- Log.Debug("Starting VNC handshake");
284
- } else {
285
- _this._fail("Unexpected server connection while " + _this._rfbConnectionState);
286
- }
287
- });
288
-
289
- _this._sock.on('close', function (e) {
290
- Log.Debug("WebSocket on-close event");
291
- var msg = "";
292
-
293
- if (e.code) {
294
- msg = "(code: " + e.code;
295
-
296
- if (e.reason) {
297
- msg += ", reason: " + e.reason;
298
- }
299
-
300
- msg += ")";
301
- }
302
-
303
- switch (_this._rfbConnectionState) {
304
- case 'connecting':
305
- _this._fail("Connection closed " + msg);
306
-
307
- break;
308
-
309
- case 'connected':
310
- // Handle disconnects that were initiated server-side
311
- _this._updateConnectionState('disconnecting');
281
+ _this._gestures = new _gesturehandler["default"]();
282
+ _this._sock = new _websock["default"]();
312
283
 
313
- _this._updateConnectionState('disconnected');
284
+ _this._sock.on('open', _this._socketOpen.bind(_assertThisInitialized(_this)));
314
285
 
315
- break;
316
-
317
- case 'disconnecting':
318
- // Normal disconnection path
319
- _this._updateConnectionState('disconnected');
320
-
321
- break;
322
-
323
- case 'disconnected':
324
- _this._fail("Unexpected server disconnect " + "when already disconnected " + msg);
325
-
326
- break;
327
-
328
- default:
329
- _this._fail("Unexpected server disconnect before connecting " + msg);
286
+ _this._sock.on('close', _this._socketClose.bind(_assertThisInitialized(_this)));
330
287
 
331
- break;
332
- }
288
+ _this._sock.on('message', _this._handleMessage.bind(_assertThisInitialized(_this)));
333
289
 
334
- _this._sock.off('close');
335
- });
290
+ _this._sock.on('error', _this._socketError.bind(_assertThisInitialized(_this)));
336
291
 
337
- _this._sock.on('error', function (e) {
338
- return Log.Warn("WebSocket on-error event");
339
- }); // Slight delay of the actual connection so that the caller has
340
- // time to set up callbacks
292
+ _this._resizeObserver = new ResizeObserver(_this._eventHandlers.handleResize); // All prepared, kick off the connection
341
293
 
294
+ _this._updateConnectionState('connecting');
342
295
 
343
- setTimeout(_this._updateConnectionState.bind(_assertThisInitialized(_this), 'connecting'));
344
296
  Log.Debug("<< RFB.constructor"); // ===== PROPERTIES =====
345
297
 
346
298
  _this.dragViewport = false;
@@ -363,8 +315,138 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
363
315
 
364
316
 
365
317
  _createClass(RFB, [{
318
+ key: "viewOnly",
319
+ get: function get() {
320
+ return this._viewOnly;
321
+ },
322
+ set: function set(viewOnly) {
323
+ this._viewOnly = viewOnly;
324
+
325
+ if (this._rfbConnectionState === "connecting" || this._rfbConnectionState === "connected") {
326
+ if (viewOnly) {
327
+ this._keyboard.ungrab();
328
+ } else {
329
+ this._keyboard.grab();
330
+ }
331
+ }
332
+ }
333
+ }, {
334
+ key: "capabilities",
335
+ get: function get() {
336
+ return this._capabilities;
337
+ }
338
+ }, {
339
+ key: "touchButton",
340
+ get: function get() {
341
+ return 0;
342
+ },
343
+ set: function set(button) {
344
+ Log.Warn("Using old API!");
345
+ }
346
+ }, {
347
+ key: "clipViewport",
348
+ get: function get() {
349
+ return this._clipViewport;
350
+ },
351
+ set: function set(viewport) {
352
+ this._clipViewport = viewport;
353
+
354
+ this._updateClip();
355
+ }
356
+ }, {
357
+ key: "scaleViewport",
358
+ get: function get() {
359
+ return this._scaleViewport;
360
+ },
361
+ set: function set(scale) {
362
+ this._scaleViewport = scale; // Scaling trumps clipping, so we may need to adjust
363
+ // clipping when enabling or disabling scaling
364
+
365
+ if (scale && this._clipViewport) {
366
+ this._updateClip();
367
+ }
368
+
369
+ this._updateScale();
370
+
371
+ if (!scale && this._clipViewport) {
372
+ this._updateClip();
373
+ }
374
+ }
375
+ }, {
376
+ key: "resizeSession",
377
+ get: function get() {
378
+ return this._resizeSession;
379
+ },
380
+ set: function set(resize) {
381
+ this._resizeSession = resize;
382
+
383
+ if (resize) {
384
+ this._requestRemoteResize();
385
+ }
386
+ }
387
+ }, {
388
+ key: "showDotCursor",
389
+ get: function get() {
390
+ return this._showDotCursor;
391
+ },
392
+ set: function set(show) {
393
+ this._showDotCursor = show;
394
+
395
+ this._refreshCursor();
396
+ }
397
+ }, {
398
+ key: "background",
399
+ get: function get() {
400
+ return this._screen.style.background;
401
+ },
402
+ set: function set(cssValue) {
403
+ this._screen.style.background = cssValue;
404
+ }
405
+ }, {
406
+ key: "qualityLevel",
407
+ get: function get() {
408
+ return this._qualityLevel;
409
+ },
410
+ set: function set(qualityLevel) {
411
+ if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) {
412
+ Log.Error("qualityLevel must be an integer between 0 and 9");
413
+ return;
414
+ }
415
+
416
+ if (this._qualityLevel === qualityLevel) {
417
+ return;
418
+ }
419
+
420
+ this._qualityLevel = qualityLevel;
421
+
422
+ if (this._rfbConnectionState === 'connected') {
423
+ this._sendEncodings();
424
+ }
425
+ }
426
+ }, {
427
+ key: "compressionLevel",
428
+ get: function get() {
429
+ return this._compressionLevel;
430
+ },
431
+ set: function set(compressionLevel) {
432
+ if (!Number.isInteger(compressionLevel) || compressionLevel < 0 || compressionLevel > 9) {
433
+ Log.Error("compressionLevel must be an integer between 0 and 9");
434
+ return;
435
+ }
436
+
437
+ if (this._compressionLevel === compressionLevel) {
438
+ return;
439
+ }
440
+
441
+ this._compressionLevel = compressionLevel;
442
+
443
+ if (this._rfbConnectionState === 'connected') {
444
+ this._sendEncodings();
445
+ }
446
+ } // ===== PUBLIC METHODS =====
447
+
448
+ }, {
366
449
  key: "disconnect",
367
- // ===== PUBLIC METHODS =====
368
450
  value: function disconnect() {
369
451
  this._updateConnectionState('disconnecting');
370
452
 
@@ -388,12 +470,12 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
388
470
  }
389
471
 
390
472
  Log.Info("Sending Ctrl-Alt-Del");
391
- this.sendKey(_keysym.default.XK_Control_L, "ControlLeft", true);
392
- this.sendKey(_keysym.default.XK_Alt_L, "AltLeft", true);
393
- this.sendKey(_keysym.default.XK_Delete, "Delete", true);
394
- this.sendKey(_keysym.default.XK_Delete, "Delete", false);
395
- this.sendKey(_keysym.default.XK_Alt_L, "AltLeft", false);
396
- this.sendKey(_keysym.default.XK_Control_L, "ControlLeft", false);
473
+ this.sendKey(_keysym["default"].XK_Control_L, "ControlLeft", true);
474
+ this.sendKey(_keysym["default"].XK_Alt_L, "AltLeft", true);
475
+ this.sendKey(_keysym["default"].XK_Delete, "Delete", true);
476
+ this.sendKey(_keysym["default"].XK_Delete, "Delete", false);
477
+ this.sendKey(_keysym["default"].XK_Alt_L, "AltLeft", false);
478
+ this.sendKey(_keysym["default"].XK_Control_L, "ControlLeft", false);
397
479
  }
398
480
  }, {
399
481
  key: "machineShutdown",
@@ -425,7 +507,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
425
507
  return;
426
508
  }
427
509
 
428
- var scancode = _xtscancodes.default[code];
510
+ var scancode = _xtscancodes["default"][code];
429
511
 
430
512
  if (this._qemuExtKeyEventSupported && scancode) {
431
513
  // 0 is NoSymbol
@@ -443,8 +525,8 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
443
525
  }
444
526
  }, {
445
527
  key: "focus",
446
- value: function focus() {
447
- this._canvas.focus();
528
+ value: function focus(options) {
529
+ this._canvas.focus(options);
448
530
  }
449
531
  }, {
450
532
  key: "blur",
@@ -477,16 +559,25 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
477
559
  key: "_connect",
478
560
  value: function _connect() {
479
561
  Log.Debug(">> RFB.connect");
480
- Log.Info("connecting to " + this._url);
481
562
 
482
- try {
483
- // WebSocket.onopen transitions to the RFB init states
563
+ if (this._url) {
564
+ Log.Info("connecting to ".concat(this._url));
565
+
484
566
  this._sock.open(this._url, this._wsProtocols);
485
- } catch (e) {
486
- if (e.name === 'SyntaxError') {
487
- this._fail("Invalid host or port (" + e + ")");
488
- } else {
489
- this._fail("Error when opening socket (" + e + ")");
567
+ } else {
568
+ Log.Info("attaching ".concat(this._rawChannel, " to Websock"));
569
+
570
+ this._sock.attach(this._rawChannel);
571
+
572
+ if (this._sock.readyState === 'closed') {
573
+ throw Error("Cannot use already closed WebSocket/RTCDataChannel");
574
+ }
575
+
576
+ if (this._sock.readyState === 'open') {
577
+ // FIXME: _socketOpen() can in theory call _fail(), which
578
+ // isn't allowed this early, but I'm not sure that can
579
+ // happen without a bug messing up our state variables
580
+ this._socketOpen();
490
581
  }
491
582
  } // Make our elements part of the page
492
583
 
@@ -497,11 +588,11 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
497
588
 
498
589
  this._cursor.attach(this._canvas);
499
590
 
500
- this._refreshCursor(); // Monitor size changes of the screen
501
- // FIXME: Use ResizeObserver, or hidden overflow
591
+ this._refreshCursor(); // Monitor size changes of the screen element
592
+
502
593
 
594
+ this._resizeObserver.observe(this._screen); // Always grab focus on some kind of click event
503
595
 
504
- window.addEventListener('resize', this._eventHandlers.windowResize); // Always grab focus on some kind of click event
505
596
 
506
597
  this._canvas.addEventListener("mousedown", this._eventHandlers.focusCanvas);
507
598
 
@@ -562,7 +653,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
562
653
 
563
654
  this._canvas.removeEventListener("touchstart", this._eventHandlers.focusCanvas);
564
655
 
565
- window.removeEventListener('resize', this._eventHandlers.windowResize);
656
+ this._resizeObserver.disconnect();
566
657
 
567
658
  this._keyboard.ungrab();
568
659
 
@@ -584,6 +675,73 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
584
675
  clearTimeout(this._mouseMoveTimer);
585
676
  Log.Debug("<< RFB.disconnect");
586
677
  }
678
+ }, {
679
+ key: "_socketOpen",
680
+ value: function _socketOpen() {
681
+ if (this._rfbConnectionState === 'connecting' && this._rfbInitState === '') {
682
+ this._rfbInitState = 'ProtocolVersion';
683
+ Log.Debug("Starting VNC handshake");
684
+ } else {
685
+ this._fail("Unexpected server connection while " + this._rfbConnectionState);
686
+ }
687
+ }
688
+ }, {
689
+ key: "_socketClose",
690
+ value: function _socketClose(e) {
691
+ Log.Debug("WebSocket on-close event");
692
+ var msg = "";
693
+
694
+ if (e.code) {
695
+ msg = "(code: " + e.code;
696
+
697
+ if (e.reason) {
698
+ msg += ", reason: " + e.reason;
699
+ }
700
+
701
+ msg += ")";
702
+ }
703
+
704
+ switch (this._rfbConnectionState) {
705
+ case 'connecting':
706
+ this._fail("Connection closed " + msg);
707
+
708
+ break;
709
+
710
+ case 'connected':
711
+ // Handle disconnects that were initiated server-side
712
+ this._updateConnectionState('disconnecting');
713
+
714
+ this._updateConnectionState('disconnected');
715
+
716
+ break;
717
+
718
+ case 'disconnecting':
719
+ // Normal disconnection path
720
+ this._updateConnectionState('disconnected');
721
+
722
+ break;
723
+
724
+ case 'disconnected':
725
+ this._fail("Unexpected server disconnect " + "when already disconnected " + msg);
726
+
727
+ break;
728
+
729
+ default:
730
+ this._fail("Unexpected server disconnect before connecting " + msg);
731
+
732
+ break;
733
+ }
734
+
735
+ this._sock.off('close'); // Delete reference to raw channel to allow cleanup.
736
+
737
+
738
+ this._rawChannel = null;
739
+ }
740
+ }, {
741
+ key: "_socketError",
742
+ value: function _socketError(e) {
743
+ Log.Warn("WebSocket on-error event");
744
+ }
587
745
  }, {
588
746
  key: "_focusCanvas",
589
747
  value: function _focusCanvas(event) {
@@ -591,7 +749,9 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
591
749
  return;
592
750
  }
593
751
 
594
- this.focus();
752
+ this.focus({
753
+ preventScroll: true
754
+ });
595
755
  }
596
756
  }, {
597
757
  key: "_setDesktopName",
@@ -604,8 +764,8 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
604
764
  }));
605
765
  }
606
766
  }, {
607
- key: "_windowResize",
608
- value: function _windowResize(event) {
767
+ key: "_handleResize",
768
+ value: function _handleResize() {
609
769
  var _this2 = this;
610
770
 
611
771
  // If the window resized then our screen element might have
@@ -1275,7 +1435,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1275
1435
  magnitude = Math.hypot(ev.detail.magnitudeX, ev.detail.magnitudeY);
1276
1436
 
1277
1437
  if (Math.abs(magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) {
1278
- this._handleKeyEvent(_keysym.default.XK_Control_L, "ControlLeft", true);
1438
+ this._handleKeyEvent(_keysym["default"].XK_Control_L, "ControlLeft", true);
1279
1439
 
1280
1440
  while (magnitude - this._gestureLastMagnitudeX > GESTURE_ZOOMSENS) {
1281
1441
  this._handleMouseButton(pos.x, pos.y, true, 0x8);
@@ -1294,7 +1454,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1294
1454
  }
1295
1455
  }
1296
1456
 
1297
- this._handleKeyEvent(_keysym.default.XK_Control_L, "ControlLeft", false);
1457
+ this._handleKeyEvent(_keysym["default"].XK_Control_L, "ControlLeft", false);
1298
1458
 
1299
1459
  break;
1300
1460
  }
@@ -1399,18 +1559,6 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1399
1559
  }, {
1400
1560
  key: "_negotiateSecurity",
1401
1561
  value: function _negotiateSecurity() {
1402
- // Polyfill since IE and PhantomJS doesn't have
1403
- // TypedArray.includes()
1404
- function includes(item, array) {
1405
- for (var i = 0; i < array.length; i++) {
1406
- if (array[i] === item) {
1407
- return true;
1408
- }
1409
- }
1410
-
1411
- return false;
1412
- }
1413
-
1414
1562
  if (this._rfbVersion >= 3.7) {
1415
1563
  // Server sends supported list, client decides
1416
1564
  var numTypes = this._sock.rQshift8();
@@ -1430,15 +1578,15 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1430
1578
 
1431
1579
  Log.Debug("Server security types: " + types); // Look for each auth in preferred order
1432
1580
 
1433
- if (includes(1, types)) {
1581
+ if (types.includes(1)) {
1434
1582
  this._rfbAuthScheme = 1; // None
1435
- } else if (includes(22, types)) {
1583
+ } else if (types.includes(22)) {
1436
1584
  this._rfbAuthScheme = 22; // XVP
1437
- } else if (includes(16, types)) {
1585
+ } else if (types.includes(16)) {
1438
1586
  this._rfbAuthScheme = 16; // Tight
1439
- } else if (includes(2, types)) {
1587
+ } else if (types.includes(2)) {
1440
1588
  this._rfbAuthScheme = 2; // VNC Auth
1441
- } else if (includes(19, types)) {
1589
+ } else if (types.includes(19)) {
1442
1590
  this._rfbAuthScheme = 19; // VeNCrypt Auth
1443
1591
  } else {
1444
1592
  return this._fail("Unsupported security types (types: " + types + ")");
@@ -1602,7 +1750,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1602
1750
 
1603
1751
 
1604
1752
  if (this._rfbVeNCryptState == 4) {
1605
- if (!this._rfbCredentials.username || !this._rfbCredentials.password) {
1753
+ if (this._rfbCredentials.username === undefined || this._rfbCredentials.password === undefined) {
1606
1754
  this.dispatchEvent(new CustomEvent("credentialsrequired", {
1607
1755
  detail: {
1608
1756
  types: ["username", "password"]
@@ -1612,11 +1760,11 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1612
1760
  }
1613
1761
 
1614
1762
  var user = (0, _strings.encodeUTF8)(this._rfbCredentials.username);
1615
- var pass = (0, _strings.encodeUTF8)(this._rfbCredentials.password); // XXX we assume lengths are <= 255 (should not be an issue in the real world)
1763
+ var pass = (0, _strings.encodeUTF8)(this._rfbCredentials.password);
1616
1764
 
1617
- this._sock.send([0, 0, 0, user.length]);
1765
+ this._sock.send([user.length >> 24 & 0xFF, user.length >> 16 & 0xFF, user.length >> 8 & 0xFF, user.length & 0xFF]);
1618
1766
 
1619
- this._sock.send([0, 0, 0, pass.length]);
1767
+ this._sock.send([pass.length >> 24 & 0xFF, pass.length >> 16 & 0xFF, pass.length >> 8 & 0xFF, pass.length & 0xFF]);
1620
1768
 
1621
1769
  this._sock.sendString(user);
1622
1770
 
@@ -2007,6 +2155,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
2007
2155
  if (this._fbDepth == 24) {
2008
2156
  encs.push(_encodings.encodings.encodingTight);
2009
2157
  encs.push(_encodings.encodings.encodingTightPNG);
2158
+ encs.push(_encodings.encodings.encodingZRLE);
2010
2159
  encs.push(_encodings.encodings.encodingHextile);
2011
2160
  encs.push(_encodings.encodings.encodingRRE);
2012
2161
  }
@@ -2199,7 +2348,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
2199
2348
 
2200
2349
  var zlibStream = this._sock.rQshiftBytes(length - 4);
2201
2350
 
2202
- var streamInflator = new _inflator.default();
2351
+ var streamInflator = new _inflator["default"]();
2203
2352
  var textData = null;
2204
2353
  streamInflator.setInput(zlibStream);
2205
2354
 
@@ -2486,16 +2635,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
2486
2635
  return this._handleCursor();
2487
2636
 
2488
2637
  case _encodings.encodings.pseudoEncodingQEMUExtendedKeyEvent:
2489
- // Old Safari doesn't support creating keyboard events
2490
- try {
2491
- var keyboardEvent = document.createEvent("keyboardEvent");
2492
-
2493
- if (keyboardEvent.code !== undefined) {
2494
- this._qemuExtKeyEventSupported = true;
2495
- }
2496
- } catch (err) {// Do nothing
2497
- }
2498
-
2638
+ this._qemuExtKeyEventSupported = true;
2499
2639
  return true;
2500
2640
 
2501
2641
  case _encodings.encodings.pseudoEncodingDesktopName:
@@ -2882,151 +3022,21 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
2882
3022
 
2883
3023
  this._cursor.change(image.rgbaPixels, image.hotx, image.hoty, image.w, image.h);
2884
3024
  }
2885
- }, {
2886
- key: "viewOnly",
2887
- get: function get() {
2888
- return this._viewOnly;
2889
- },
2890
- set: function set(viewOnly) {
2891
- this._viewOnly = viewOnly;
2892
-
2893
- if (this._rfbConnectionState === "connecting" || this._rfbConnectionState === "connected") {
2894
- if (viewOnly) {
2895
- this._keyboard.ungrab();
2896
- } else {
2897
- this._keyboard.grab();
2898
- }
2899
- }
2900
- }
2901
- }, {
2902
- key: "capabilities",
2903
- get: function get() {
2904
- return this._capabilities;
2905
- }
2906
- }, {
2907
- key: "touchButton",
2908
- get: function get() {
2909
- return 0;
2910
- },
2911
- set: function set(button) {
2912
- Log.Warn("Using old API!");
2913
- }
2914
- }, {
2915
- key: "clipViewport",
2916
- get: function get() {
2917
- return this._clipViewport;
2918
- },
2919
- set: function set(viewport) {
2920
- this._clipViewport = viewport;
2921
-
2922
- this._updateClip();
2923
- }
2924
- }, {
2925
- key: "scaleViewport",
2926
- get: function get() {
2927
- return this._scaleViewport;
2928
- },
2929
- set: function set(scale) {
2930
- this._scaleViewport = scale; // Scaling trumps clipping, so we may need to adjust
2931
- // clipping when enabling or disabling scaling
2932
-
2933
- if (scale && this._clipViewport) {
2934
- this._updateClip();
2935
- }
2936
-
2937
- this._updateScale();
2938
-
2939
- if (!scale && this._clipViewport) {
2940
- this._updateClip();
2941
- }
2942
- }
2943
- }, {
2944
- key: "resizeSession",
2945
- get: function get() {
2946
- return this._resizeSession;
2947
- },
2948
- set: function set(resize) {
2949
- this._resizeSession = resize;
2950
-
2951
- if (resize) {
2952
- this._requestRemoteResize();
2953
- }
2954
- }
2955
- }, {
2956
- key: "showDotCursor",
2957
- get: function get() {
2958
- return this._showDotCursor;
2959
- },
2960
- set: function set(show) {
2961
- this._showDotCursor = show;
2962
-
2963
- this._refreshCursor();
2964
- }
2965
- }, {
2966
- key: "background",
2967
- get: function get() {
2968
- return this._screen.style.background;
2969
- },
2970
- set: function set(cssValue) {
2971
- this._screen.style.background = cssValue;
2972
- }
2973
- }, {
2974
- key: "qualityLevel",
2975
- get: function get() {
2976
- return this._qualityLevel;
2977
- },
2978
- set: function set(qualityLevel) {
2979
- if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) {
2980
- Log.Error("qualityLevel must be an integer between 0 and 9");
2981
- return;
2982
- }
2983
-
2984
- if (this._qualityLevel === qualityLevel) {
2985
- return;
2986
- }
2987
-
2988
- this._qualityLevel = qualityLevel;
2989
-
2990
- if (this._rfbConnectionState === 'connected') {
2991
- this._sendEncodings();
2992
- }
2993
- }
2994
- }, {
2995
- key: "compressionLevel",
2996
- get: function get() {
2997
- return this._compressionLevel;
2998
- },
2999
- set: function set(compressionLevel) {
3000
- if (!Number.isInteger(compressionLevel) || compressionLevel < 0 || compressionLevel > 9) {
3001
- Log.Error("compressionLevel must be an integer between 0 and 9");
3002
- return;
3003
- }
3004
-
3005
- if (this._compressionLevel === compressionLevel) {
3006
- return;
3007
- }
3008
-
3009
- this._compressionLevel = compressionLevel;
3010
-
3011
- if (this._rfbConnectionState === 'connected') {
3012
- this._sendEncodings();
3013
- }
3014
- }
3015
3025
  }], [{
3016
3026
  key: "genDES",
3017
3027
  value: function genDES(password, challenge) {
3018
3028
  var passwordChars = password.split('').map(function (c) {
3019
3029
  return c.charCodeAt(0);
3020
3030
  });
3021
- return new _des.default(passwordChars).encrypt(challenge);
3031
+ return new _des["default"](passwordChars).encrypt(challenge);
3022
3032
  }
3023
3033
  }]);
3024
3034
 
3025
3035
  return RFB;
3026
- }(_eventtarget.default); // Class Methods
3036
+ }(_eventtarget["default"]); // Class Methods
3027
3037
 
3028
3038
 
3029
- exports.default = RFB;
3039
+ exports["default"] = RFB;
3030
3040
  RFB.messages = {
3031
3041
  keyEvent: function keyEvent(sock, keysym, down) {
3032
3042
  var buff = sock._sQ;
@@ -3114,7 +3124,7 @@ RFB.messages = {
3114
3124
  },
3115
3125
  extendedClipboardProvide: function extendedClipboardProvide(sock, formats, inData) {
3116
3126
  // Deflate incomming data and their sizes
3117
- var deflator = new _deflator.default();
3127
+ var deflator = new _deflator["default"]();
3118
3128
  var dataToDeflate = [];
3119
3129
 
3120
3130
  for (var i = 0; i < formats.length; i++) {
@@ -3350,11 +3360,11 @@ RFB.messages = {
3350
3360
 
3351
3361
  buff[offset + 13] = (1 << bits) - 1; // blue-max
3352
3362
 
3353
- buff[offset + 14] = bits * 2; // red-shift
3363
+ buff[offset + 14] = bits * 0; // red-shift
3354
3364
 
3355
3365
  buff[offset + 15] = bits * 1; // green-shift
3356
3366
 
3357
- buff[offset + 16] = bits * 0; // blue-shift
3367
+ buff[offset + 16] = bits * 2; // blue-shift
3358
3368
 
3359
3369
  buff[offset + 17] = 0; // padding
3360
3370