@novnc/novnc 1.2.0-beta → 1.3.0-g99cf540

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 (63) hide show
  1. package/LICENSE.txt +0 -6
  2. package/README.md +4 -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/display.js +9 -151
  8. package/core/input/domkeytable.js +25 -21
  9. package/core/input/keyboard.js +12 -127
  10. package/core/input/util.js +18 -35
  11. package/core/input/vkeys.js +0 -1
  12. package/core/input/xtscancodes.js +5 -3
  13. package/core/rfb.js +113 -106
  14. package/core/util/browser.js +0 -17
  15. package/core/util/cursor.js +1 -11
  16. package/core/util/events.js +0 -4
  17. package/core/websock.js +76 -17
  18. package/docs/API.md +2 -2
  19. package/docs/LIBRARY.md +3 -7
  20. package/lib/base64.js +4 -4
  21. package/lib/decoders/copyrect.js +7 -2
  22. package/lib/decoders/hextile.js +63 -7
  23. package/lib/decoders/raw.js +13 -4
  24. package/lib/decoders/rre.js +2 -2
  25. package/lib/decoders/tight.js +38 -20
  26. package/lib/decoders/tightpng.js +8 -8
  27. package/lib/deflator.js +4 -4
  28. package/lib/des.js +2 -2
  29. package/lib/display.js +45 -212
  30. package/lib/inflator.js +4 -4
  31. package/lib/input/domkeytable.js +197 -194
  32. package/lib/input/fixedkeys.js +2 -2
  33. package/lib/input/gesturehandler.js +2 -2
  34. package/lib/input/keyboard.js +38 -158
  35. package/lib/input/keysym.js +2 -2
  36. package/lib/input/keysymdef.js +2 -2
  37. package/lib/input/util.js +34 -79
  38. package/lib/input/vkeys.js +2 -4
  39. package/lib/input/xtscancodes.js +11 -5
  40. package/lib/rfb.js +287 -283
  41. package/lib/util/browser.js +8 -26
  42. package/lib/util/cursor.js +4 -16
  43. package/lib/util/events.js +3 -5
  44. package/lib/util/eventtarget.js +3 -3
  45. package/lib/util/int.js +1 -1
  46. package/lib/util/logging.js +2 -2
  47. package/lib/vendor/pako/lib/utils/common.js +2 -2
  48. package/lib/vendor/pako/lib/zlib/adler32.js +1 -1
  49. package/lib/vendor/pako/lib/zlib/constants.js +2 -2
  50. package/lib/vendor/pako/lib/zlib/crc32.js +1 -1
  51. package/lib/vendor/pako/lib/zlib/deflate.js +113 -112
  52. package/lib/vendor/pako/lib/zlib/gzheader.js +1 -1
  53. package/lib/vendor/pako/lib/zlib/inffast.js +5 -5
  54. package/lib/vendor/pako/lib/zlib/inflate.js +50 -48
  55. package/lib/vendor/pako/lib/zlib/inftrees.js +3 -3
  56. package/lib/vendor/pako/lib/zlib/messages.js +2 -2
  57. package/lib/vendor/pako/lib/zlib/trees.js +4 -4
  58. package/lib/vendor/pako/lib/zlib/zstream.js +1 -1
  59. package/lib/websock.js +105 -44
  60. package/package.json +2 -7
  61. package/core/util/polyfill.js +0 -61
  62. package/lib/util/polyfill.js +0 -72
  63. 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,11 @@ 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
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
59
59
 
60
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
60
+ 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); }
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; }
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); }
62
+ 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
63
 
66
64
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
67
65
 
@@ -75,11 +73,11 @@ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || func
75
73
 
76
74
  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
75
 
78
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
76
+ 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
77
 
80
78
  function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
81
79
 
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; } }
80
+ 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
81
 
84
82
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
85
83
 
@@ -120,7 +118,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
120
118
 
121
119
  var _super = _createSuper(RFB);
122
120
 
123
- function RFB(target, url, options) {
121
+ function RFB(target, urlOrChannel, options) {
124
122
  var _this;
125
123
 
126
124
  _classCallCheck(this, RFB);
@@ -129,13 +127,20 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
129
127
  throw new Error("Must specify target");
130
128
  }
131
129
 
132
- if (!url) {
133
- throw new Error("Must specify URL");
130
+ if (!urlOrChannel) {
131
+ throw new Error("Must specify URL, WebSocket or RTCDataChannel");
134
132
  }
135
133
 
136
134
  _this = _super.call(this);
137
135
  _this._target = target;
138
- _this._url = url; // Connection details
136
+
137
+ if (typeof urlOrChannel === "string") {
138
+ _this._url = urlOrChannel;
139
+ } else {
140
+ _this._url = null;
141
+ _this._rawChannel = urlOrChannel;
142
+ } // Connection details
143
+
139
144
 
140
145
  options = options || {};
141
146
  _this._rfbCredentials = options.credentials || {};
@@ -179,6 +184,8 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
179
184
  _this._keyboard = null; // Keyboard input handler object
180
185
 
181
186
  _this._gestures = null; // Gesture input handler object
187
+
188
+ _this._resizeObserver = null; // Resize observer object
182
189
  // Timers
183
190
 
184
191
  _this._disconnTimer = null; // disconnection timer
@@ -213,7 +220,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
213
220
 
214
221
  _this._eventHandlers = {
215
222
  focusCanvas: _this._focusCanvas.bind(_assertThisInitialized(_this)),
216
- windowResize: _this._windowResize.bind(_assertThisInitialized(_this)),
223
+ handleResize: _this._handleResize.bind(_assertThisInitialized(_this)),
217
224
  handleMouse: _this._handleMouse.bind(_assertThisInitialized(_this)),
218
225
  handleWheel: _this._handleWheel.bind(_assertThisInitialized(_this)),
219
226
  handleGesture: _this._handleGesture.bind(_assertThisInitialized(_this))
@@ -230,9 +237,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
230
237
  _this._canvas = document.createElement('canvas');
231
238
  _this._canvas.style.margin = 'auto'; // Some browsers add an outline on focus
232
239
 
233
- _this._canvas.style.outline = 'none'; // IE miscalculates width without this :(
234
-
235
- _this._canvas.style.flexShrink = '0';
240
+ _this._canvas.style.outline = 'none';
236
241
  _this._canvas.width = 0;
237
242
  _this._canvas.height = 0;
238
243
  _this._canvas.tabIndex = -1;
@@ -240,7 +245,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
240
245
  _this._screen.appendChild(_this._canvas); // Cursor
241
246
 
242
247
 
243
- _this._cursor = new _cursor.default(); // XXX: TightVNC 2.8.11 sends no cursor at all until Windows changes
248
+ _this._cursor = new _cursor["default"](); // XXX: TightVNC 2.8.11 sends no cursor at all until Windows changes
244
249
  // it. Result: no cursor at all until a window border or an edit field
245
250
  // is hit blindly. But there are also VNC servers that draw the cursor
246
251
  // in the framebuffer and don't send the empty local cursor. There is
@@ -252,95 +257,39 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
252
257
 
253
258
  _this._cursorImage = RFB.cursors.none; // populate decoder array with objects
254
259
 
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
260
+ _this._decoders[_encodings.encodings.encodingRaw] = new _raw["default"]();
261
+ _this._decoders[_encodings.encodings.encodingCopyRect] = new _copyrect["default"]();
262
+ _this._decoders[_encodings.encodings.encodingRRE] = new _rre["default"]();
263
+ _this._decoders[_encodings.encodings.encodingHextile] = new _hextile["default"]();
264
+ _this._decoders[_encodings.encodings.encodingTight] = new _tight["default"]();
265
+ _this._decoders[_encodings.encodings.encodingTightPNG] = new _tightpng["default"](); // NB: nothing that needs explicit teardown should be done
261
266
  // before this point, since this can throw an exception
262
267
 
263
268
  try {
264
- _this._display = new _display.default(_this._canvas);
269
+ _this._display = new _display["default"](_this._canvas);
265
270
  } catch (exc) {
266
271
  Log.Error("Display exception: " + exc);
267
272
  throw exc;
268
273
  }
269
274
 
270
275
  _this._display.onflush = _this._onFlush.bind(_assertThisInitialized(_this));
271
- _this._keyboard = new _keyboard.default(_this._canvas);
276
+ _this._keyboard = new _keyboard["default"](_this._canvas);
272
277
  _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');
312
-
313
- _this._updateConnectionState('disconnected');
314
-
315
- break;
316
-
317
- case 'disconnecting':
318
- // Normal disconnection path
319
- _this._updateConnectionState('disconnected');
320
-
321
- break;
278
+ _this._gestures = new _gesturehandler["default"]();
279
+ _this._sock = new _websock["default"]();
322
280
 
323
- case 'disconnected':
324
- _this._fail("Unexpected server disconnect " + "when already disconnected " + msg);
325
-
326
- break;
281
+ _this._sock.on('open', _this._socketOpen.bind(_assertThisInitialized(_this)));
327
282
 
328
- default:
329
- _this._fail("Unexpected server disconnect before connecting " + msg);
283
+ _this._sock.on('close', _this._socketClose.bind(_assertThisInitialized(_this)));
330
284
 
331
- break;
332
- }
285
+ _this._sock.on('message', _this._handleMessage.bind(_assertThisInitialized(_this)));
333
286
 
334
- _this._sock.off('close');
335
- });
287
+ _this._sock.on('error', _this._socketError.bind(_assertThisInitialized(_this)));
336
288
 
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
289
+ _this._resizeObserver = new ResizeObserver(_this._eventHandlers.handleResize); // All prepared, kick off the connection
341
290
 
291
+ _this._updateConnectionState('connecting');
342
292
 
343
- setTimeout(_this._updateConnectionState.bind(_assertThisInitialized(_this), 'connecting'));
344
293
  Log.Debug("<< RFB.constructor"); // ===== PROPERTIES =====
345
294
 
346
295
  _this.dragViewport = false;
@@ -363,8 +312,138 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
363
312
 
364
313
 
365
314
  _createClass(RFB, [{
315
+ key: "viewOnly",
316
+ get: function get() {
317
+ return this._viewOnly;
318
+ },
319
+ set: function set(viewOnly) {
320
+ this._viewOnly = viewOnly;
321
+
322
+ if (this._rfbConnectionState === "connecting" || this._rfbConnectionState === "connected") {
323
+ if (viewOnly) {
324
+ this._keyboard.ungrab();
325
+ } else {
326
+ this._keyboard.grab();
327
+ }
328
+ }
329
+ }
330
+ }, {
331
+ key: "capabilities",
332
+ get: function get() {
333
+ return this._capabilities;
334
+ }
335
+ }, {
336
+ key: "touchButton",
337
+ get: function get() {
338
+ return 0;
339
+ },
340
+ set: function set(button) {
341
+ Log.Warn("Using old API!");
342
+ }
343
+ }, {
344
+ key: "clipViewport",
345
+ get: function get() {
346
+ return this._clipViewport;
347
+ },
348
+ set: function set(viewport) {
349
+ this._clipViewport = viewport;
350
+
351
+ this._updateClip();
352
+ }
353
+ }, {
354
+ key: "scaleViewport",
355
+ get: function get() {
356
+ return this._scaleViewport;
357
+ },
358
+ set: function set(scale) {
359
+ this._scaleViewport = scale; // Scaling trumps clipping, so we may need to adjust
360
+ // clipping when enabling or disabling scaling
361
+
362
+ if (scale && this._clipViewport) {
363
+ this._updateClip();
364
+ }
365
+
366
+ this._updateScale();
367
+
368
+ if (!scale && this._clipViewport) {
369
+ this._updateClip();
370
+ }
371
+ }
372
+ }, {
373
+ key: "resizeSession",
374
+ get: function get() {
375
+ return this._resizeSession;
376
+ },
377
+ set: function set(resize) {
378
+ this._resizeSession = resize;
379
+
380
+ if (resize) {
381
+ this._requestRemoteResize();
382
+ }
383
+ }
384
+ }, {
385
+ key: "showDotCursor",
386
+ get: function get() {
387
+ return this._showDotCursor;
388
+ },
389
+ set: function set(show) {
390
+ this._showDotCursor = show;
391
+
392
+ this._refreshCursor();
393
+ }
394
+ }, {
395
+ key: "background",
396
+ get: function get() {
397
+ return this._screen.style.background;
398
+ },
399
+ set: function set(cssValue) {
400
+ this._screen.style.background = cssValue;
401
+ }
402
+ }, {
403
+ key: "qualityLevel",
404
+ get: function get() {
405
+ return this._qualityLevel;
406
+ },
407
+ set: function set(qualityLevel) {
408
+ if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) {
409
+ Log.Error("qualityLevel must be an integer between 0 and 9");
410
+ return;
411
+ }
412
+
413
+ if (this._qualityLevel === qualityLevel) {
414
+ return;
415
+ }
416
+
417
+ this._qualityLevel = qualityLevel;
418
+
419
+ if (this._rfbConnectionState === 'connected') {
420
+ this._sendEncodings();
421
+ }
422
+ }
423
+ }, {
424
+ key: "compressionLevel",
425
+ get: function get() {
426
+ return this._compressionLevel;
427
+ },
428
+ set: function set(compressionLevel) {
429
+ if (!Number.isInteger(compressionLevel) || compressionLevel < 0 || compressionLevel > 9) {
430
+ Log.Error("compressionLevel must be an integer between 0 and 9");
431
+ return;
432
+ }
433
+
434
+ if (this._compressionLevel === compressionLevel) {
435
+ return;
436
+ }
437
+
438
+ this._compressionLevel = compressionLevel;
439
+
440
+ if (this._rfbConnectionState === 'connected') {
441
+ this._sendEncodings();
442
+ }
443
+ } // ===== PUBLIC METHODS =====
444
+
445
+ }, {
366
446
  key: "disconnect",
367
- // ===== PUBLIC METHODS =====
368
447
  value: function disconnect() {
369
448
  this._updateConnectionState('disconnecting');
370
449
 
@@ -388,12 +467,12 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
388
467
  }
389
468
 
390
469
  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);
470
+ this.sendKey(_keysym["default"].XK_Control_L, "ControlLeft", true);
471
+ this.sendKey(_keysym["default"].XK_Alt_L, "AltLeft", true);
472
+ this.sendKey(_keysym["default"].XK_Delete, "Delete", true);
473
+ this.sendKey(_keysym["default"].XK_Delete, "Delete", false);
474
+ this.sendKey(_keysym["default"].XK_Alt_L, "AltLeft", false);
475
+ this.sendKey(_keysym["default"].XK_Control_L, "ControlLeft", false);
397
476
  }
398
477
  }, {
399
478
  key: "machineShutdown",
@@ -425,7 +504,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
425
504
  return;
426
505
  }
427
506
 
428
- var scancode = _xtscancodes.default[code];
507
+ var scancode = _xtscancodes["default"][code];
429
508
 
430
509
  if (this._qemuExtKeyEventSupported && scancode) {
431
510
  // 0 is NoSymbol
@@ -477,16 +556,25 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
477
556
  key: "_connect",
478
557
  value: function _connect() {
479
558
  Log.Debug(">> RFB.connect");
480
- Log.Info("connecting to " + this._url);
481
559
 
482
- try {
483
- // WebSocket.onopen transitions to the RFB init states
560
+ if (this._url) {
561
+ Log.Info("connecting to ".concat(this._url));
562
+
484
563
  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 + ")");
564
+ } else {
565
+ Log.Info("attaching ".concat(this._rawChannel, " to Websock"));
566
+
567
+ this._sock.attach(this._rawChannel);
568
+
569
+ if (this._sock.readyState === 'closed') {
570
+ throw Error("Cannot use already closed WebSocket/RTCDataChannel");
571
+ }
572
+
573
+ if (this._sock.readyState === 'open') {
574
+ // FIXME: _socketOpen() can in theory call _fail(), which
575
+ // isn't allowed this early, but I'm not sure that can
576
+ // happen without a bug messing up our state variables
577
+ this._socketOpen();
490
578
  }
491
579
  } // Make our elements part of the page
492
580
 
@@ -497,11 +585,11 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
497
585
 
498
586
  this._cursor.attach(this._canvas);
499
587
 
500
- this._refreshCursor(); // Monitor size changes of the screen
501
- // FIXME: Use ResizeObserver, or hidden overflow
588
+ this._refreshCursor(); // Monitor size changes of the screen element
502
589
 
503
590
 
504
- window.addEventListener('resize', this._eventHandlers.windowResize); // Always grab focus on some kind of click event
591
+ this._resizeObserver.observe(this._screen); // Always grab focus on some kind of click event
592
+
505
593
 
506
594
  this._canvas.addEventListener("mousedown", this._eventHandlers.focusCanvas);
507
595
 
@@ -562,7 +650,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
562
650
 
563
651
  this._canvas.removeEventListener("touchstart", this._eventHandlers.focusCanvas);
564
652
 
565
- window.removeEventListener('resize', this._eventHandlers.windowResize);
653
+ this._resizeObserver.disconnect();
566
654
 
567
655
  this._keyboard.ungrab();
568
656
 
@@ -584,6 +672,73 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
584
672
  clearTimeout(this._mouseMoveTimer);
585
673
  Log.Debug("<< RFB.disconnect");
586
674
  }
675
+ }, {
676
+ key: "_socketOpen",
677
+ value: function _socketOpen() {
678
+ if (this._rfbConnectionState === 'connecting' && this._rfbInitState === '') {
679
+ this._rfbInitState = 'ProtocolVersion';
680
+ Log.Debug("Starting VNC handshake");
681
+ } else {
682
+ this._fail("Unexpected server connection while " + this._rfbConnectionState);
683
+ }
684
+ }
685
+ }, {
686
+ key: "_socketClose",
687
+ value: function _socketClose(e) {
688
+ Log.Debug("WebSocket on-close event");
689
+ var msg = "";
690
+
691
+ if (e.code) {
692
+ msg = "(code: " + e.code;
693
+
694
+ if (e.reason) {
695
+ msg += ", reason: " + e.reason;
696
+ }
697
+
698
+ msg += ")";
699
+ }
700
+
701
+ switch (this._rfbConnectionState) {
702
+ case 'connecting':
703
+ this._fail("Connection closed " + msg);
704
+
705
+ break;
706
+
707
+ case 'connected':
708
+ // Handle disconnects that were initiated server-side
709
+ this._updateConnectionState('disconnecting');
710
+
711
+ this._updateConnectionState('disconnected');
712
+
713
+ break;
714
+
715
+ case 'disconnecting':
716
+ // Normal disconnection path
717
+ this._updateConnectionState('disconnected');
718
+
719
+ break;
720
+
721
+ case 'disconnected':
722
+ this._fail("Unexpected server disconnect " + "when already disconnected " + msg);
723
+
724
+ break;
725
+
726
+ default:
727
+ this._fail("Unexpected server disconnect before connecting " + msg);
728
+
729
+ break;
730
+ }
731
+
732
+ this._sock.off('close'); // Delete reference to raw channel to allow cleanup.
733
+
734
+
735
+ this._rawChannel = null;
736
+ }
737
+ }, {
738
+ key: "_socketError",
739
+ value: function _socketError(e) {
740
+ Log.Warn("WebSocket on-error event");
741
+ }
587
742
  }, {
588
743
  key: "_focusCanvas",
589
744
  value: function _focusCanvas(event) {
@@ -604,8 +759,8 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
604
759
  }));
605
760
  }
606
761
  }, {
607
- key: "_windowResize",
608
- value: function _windowResize(event) {
762
+ key: "_handleResize",
763
+ value: function _handleResize() {
609
764
  var _this2 = this;
610
765
 
611
766
  // If the window resized then our screen element might have
@@ -1275,7 +1430,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1275
1430
  magnitude = Math.hypot(ev.detail.magnitudeX, ev.detail.magnitudeY);
1276
1431
 
1277
1432
  if (Math.abs(magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) {
1278
- this._handleKeyEvent(_keysym.default.XK_Control_L, "ControlLeft", true);
1433
+ this._handleKeyEvent(_keysym["default"].XK_Control_L, "ControlLeft", true);
1279
1434
 
1280
1435
  while (magnitude - this._gestureLastMagnitudeX > GESTURE_ZOOMSENS) {
1281
1436
  this._handleMouseButton(pos.x, pos.y, true, 0x8);
@@ -1294,7 +1449,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1294
1449
  }
1295
1450
  }
1296
1451
 
1297
- this._handleKeyEvent(_keysym.default.XK_Control_L, "ControlLeft", false);
1452
+ this._handleKeyEvent(_keysym["default"].XK_Control_L, "ControlLeft", false);
1298
1453
 
1299
1454
  break;
1300
1455
  }
@@ -1399,18 +1554,6 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1399
1554
  }, {
1400
1555
  key: "_negotiateSecurity",
1401
1556
  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
1557
  if (this._rfbVersion >= 3.7) {
1415
1558
  // Server sends supported list, client decides
1416
1559
  var numTypes = this._sock.rQshift8();
@@ -1430,15 +1573,15 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1430
1573
 
1431
1574
  Log.Debug("Server security types: " + types); // Look for each auth in preferred order
1432
1575
 
1433
- if (includes(1, types)) {
1576
+ if (types.includes(1)) {
1434
1577
  this._rfbAuthScheme = 1; // None
1435
- } else if (includes(22, types)) {
1578
+ } else if (types.includes(22)) {
1436
1579
  this._rfbAuthScheme = 22; // XVP
1437
- } else if (includes(16, types)) {
1580
+ } else if (types.includes(16)) {
1438
1581
  this._rfbAuthScheme = 16; // Tight
1439
- } else if (includes(2, types)) {
1582
+ } else if (types.includes(2)) {
1440
1583
  this._rfbAuthScheme = 2; // VNC Auth
1441
- } else if (includes(19, types)) {
1584
+ } else if (types.includes(19)) {
1442
1585
  this._rfbAuthScheme = 19; // VeNCrypt Auth
1443
1586
  } else {
1444
1587
  return this._fail("Unsupported security types (types: " + types + ")");
@@ -1602,7 +1745,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1602
1745
 
1603
1746
 
1604
1747
  if (this._rfbVeNCryptState == 4) {
1605
- if (!this._rfbCredentials.username || !this._rfbCredentials.password) {
1748
+ if (this._rfbCredentials.username === undefined || this._rfbCredentials.password === undefined) {
1606
1749
  this.dispatchEvent(new CustomEvent("credentialsrequired", {
1607
1750
  detail: {
1608
1751
  types: ["username", "password"]
@@ -1612,11 +1755,11 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
1612
1755
  }
1613
1756
 
1614
1757
  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)
1758
+ var pass = (0, _strings.encodeUTF8)(this._rfbCredentials.password);
1616
1759
 
1617
- this._sock.send([0, 0, 0, user.length]);
1760
+ this._sock.send([user.length >> 24 & 0xFF, user.length >> 16 & 0xFF, user.length >> 8 & 0xFF, user.length & 0xFF]);
1618
1761
 
1619
- this._sock.send([0, 0, 0, pass.length]);
1762
+ this._sock.send([pass.length >> 24 & 0xFF, pass.length >> 16 & 0xFF, pass.length >> 8 & 0xFF, pass.length & 0xFF]);
1620
1763
 
1621
1764
  this._sock.sendString(user);
1622
1765
 
@@ -2199,7 +2342,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
2199
2342
 
2200
2343
  var zlibStream = this._sock.rQshiftBytes(length - 4);
2201
2344
 
2202
- var streamInflator = new _inflator.default();
2345
+ var streamInflator = new _inflator["default"]();
2203
2346
  var textData = null;
2204
2347
  streamInflator.setInput(zlibStream);
2205
2348
 
@@ -2486,16 +2629,7 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
2486
2629
  return this._handleCursor();
2487
2630
 
2488
2631
  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
-
2632
+ this._qemuExtKeyEventSupported = true;
2499
2633
  return true;
2500
2634
 
2501
2635
  case _encodings.encodings.pseudoEncodingDesktopName:
@@ -2882,151 +3016,21 @@ var RFB = /*#__PURE__*/function (_EventTargetMixin) {
2882
3016
 
2883
3017
  this._cursor.change(image.rgbaPixels, image.hotx, image.hoty, image.w, image.h);
2884
3018
  }
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
3019
  }], [{
3016
3020
  key: "genDES",
3017
3021
  value: function genDES(password, challenge) {
3018
3022
  var passwordChars = password.split('').map(function (c) {
3019
3023
  return c.charCodeAt(0);
3020
3024
  });
3021
- return new _des.default(passwordChars).encrypt(challenge);
3025
+ return new _des["default"](passwordChars).encrypt(challenge);
3022
3026
  }
3023
3027
  }]);
3024
3028
 
3025
3029
  return RFB;
3026
- }(_eventtarget.default); // Class Methods
3030
+ }(_eventtarget["default"]); // Class Methods
3027
3031
 
3028
3032
 
3029
- exports.default = RFB;
3033
+ exports["default"] = RFB;
3030
3034
  RFB.messages = {
3031
3035
  keyEvent: function keyEvent(sock, keysym, down) {
3032
3036
  var buff = sock._sQ;
@@ -3114,7 +3118,7 @@ RFB.messages = {
3114
3118
  },
3115
3119
  extendedClipboardProvide: function extendedClipboardProvide(sock, formats, inData) {
3116
3120
  // Deflate incomming data and their sizes
3117
- var deflator = new _deflator.default();
3121
+ var deflator = new _deflator["default"]();
3118
3122
  var dataToDeflate = [];
3119
3123
 
3120
3124
  for (var i = 0; i < formats.length; i++) {
@@ -3350,11 +3354,11 @@ RFB.messages = {
3350
3354
 
3351
3355
  buff[offset + 13] = (1 << bits) - 1; // blue-max
3352
3356
 
3353
- buff[offset + 14] = bits * 2; // red-shift
3357
+ buff[offset + 14] = bits * 0; // red-shift
3354
3358
 
3355
3359
  buff[offset + 15] = bits * 1; // green-shift
3356
3360
 
3357
- buff[offset + 16] = bits * 0; // blue-shift
3361
+ buff[offset + 16] = bits * 2; // blue-shift
3358
3362
 
3359
3363
  buff[offset + 17] = 0; // padding
3360
3364