@novnc/novnc 1.2.0 → 1.3.0-g0ef7582

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 (75) hide show
  1. package/LICENSE.txt +0 -6
  2. package/README.md +16 -6
  3. package/core/decoders/copyrect.js +5 -0
  4. package/core/decoders/hextile.js +57 -3
  5. package/core/decoders/jpeg.js +141 -0
  6. package/core/decoders/raw.js +12 -2
  7. package/core/decoders/tight.js +24 -8
  8. package/core/decoders/zrle.js +185 -0
  9. package/core/display.js +21 -151
  10. package/core/encodings.js +4 -0
  11. package/core/input/domkeytable.js +25 -21
  12. package/core/input/keyboard.js +22 -127
  13. package/core/input/util.js +18 -35
  14. package/core/input/vkeys.js +0 -1
  15. package/core/input/xtscancodes.js +5 -3
  16. package/core/ra2.js +567 -0
  17. package/core/rfb.js +487 -171
  18. package/core/util/browser.js +0 -17
  19. package/core/util/cursor.js +1 -11
  20. package/core/util/events.js +0 -4
  21. package/core/util/md5.js +79 -0
  22. package/core/websock.js +76 -17
  23. package/docs/API.md +107 -6
  24. package/docs/LIBRARY.md +3 -7
  25. package/lib/base64.js +24 -38
  26. package/lib/decoders/copyrect.js +6 -11
  27. package/lib/decoders/hextile.js +68 -44
  28. package/lib/decoders/jpeg.js +146 -0
  29. package/lib/decoders/raw.js +14 -21
  30. package/lib/decoders/rre.js +3 -17
  31. package/lib/decoders/tight.js +43 -93
  32. package/lib/decoders/tightpng.js +11 -33
  33. package/lib/decoders/zrle.js +185 -0
  34. package/lib/deflator.js +9 -26
  35. package/lib/des.js +22 -38
  36. package/lib/display.js +100 -315
  37. package/lib/encodings.js +7 -8
  38. package/lib/inflator.js +6 -22
  39. package/lib/input/domkeytable.js +240 -208
  40. package/lib/input/fixedkeys.js +10 -5
  41. package/lib/input/gesturehandler.js +84 -154
  42. package/lib/input/keyboard.js +87 -238
  43. package/lib/input/keysym.js +16 -272
  44. package/lib/input/keysymdef.js +7 -9
  45. package/lib/input/util.js +69 -156
  46. package/lib/input/vkeys.js +2 -7
  47. package/lib/input/xtscancodes.js +10 -171
  48. package/lib/ra2.js +1033 -0
  49. package/lib/rfb.js +947 -1149
  50. package/lib/util/browser.js +25 -52
  51. package/lib/util/cursor.js +25 -81
  52. package/lib/util/element.js +3 -5
  53. package/lib/util/events.js +26 -35
  54. package/lib/util/eventtarget.js +4 -16
  55. package/lib/util/int.js +2 -3
  56. package/lib/util/logging.js +3 -21
  57. package/lib/util/md5.js +83 -0
  58. package/lib/util/strings.js +3 -5
  59. package/lib/vendor/pako/lib/utils/common.js +10 -19
  60. package/lib/vendor/pako/lib/zlib/adler32.js +4 -8
  61. package/lib/vendor/pako/lib/zlib/constants.js +4 -7
  62. package/lib/vendor/pako/lib/zlib/crc32.js +6 -13
  63. package/lib/vendor/pako/lib/zlib/deflate.js +304 -708
  64. package/lib/vendor/pako/lib/zlib/gzheader.js +2 -14
  65. package/lib/vendor/pako/lib/zlib/inffast.js +61 -177
  66. package/lib/vendor/pako/lib/zlib/inflate.js +421 -909
  67. package/lib/vendor/pako/lib/zlib/inftrees.js +66 -172
  68. package/lib/vendor/pako/lib/zlib/messages.js +3 -13
  69. package/lib/vendor/pako/lib/zlib/trees.js +250 -592
  70. package/lib/vendor/pako/lib/zlib/zstream.js +3 -19
  71. package/lib/websock.js +119 -111
  72. package/package.json +2 -10
  73. package/core/util/polyfill.js +0 -61
  74. package/lib/util/polyfill.js +0 -72
  75. package/lib/vendor/promise.js +0 -255
@@ -45,15 +45,6 @@ try {
45
45
 
46
46
  export const supportsCursorURIs = _supportsCursorURIs;
47
47
 
48
- let _supportsImageMetadata = false;
49
- try {
50
- new ImageData(new Uint8ClampedArray(4), 1, 1);
51
- _supportsImageMetadata = true;
52
- } catch (ex) {
53
- // ignore failure
54
- }
55
- export const supportsImageMetadata = _supportsImageMetadata;
56
-
57
48
  let _hasScrollbarGutter = true;
58
49
  try {
59
50
  // Create invisible container
@@ -106,14 +97,6 @@ export function isSafari() {
106
97
  navigator.userAgent.indexOf('Chrome') === -1);
107
98
  }
108
99
 
109
- export function isIE() {
110
- return navigator && !!(/trident/i).exec(navigator.userAgent);
111
- }
112
-
113
- export function isEdge() {
114
- return navigator && !!(/edge/i).exec(navigator.userAgent);
115
- }
116
-
117
100
  export function isFirefox() {
118
101
  return navigator && !!(/firefox/i).exec(navigator.userAgent);
119
102
  }
@@ -43,9 +43,6 @@ export default class Cursor {
43
43
  if (useFallback) {
44
44
  document.body.appendChild(this._canvas);
45
45
 
46
- // FIXME: These don't fire properly except for mouse
47
- /// movement in IE. We want to also capture element
48
- // movement, size changes, visibility, etc.
49
46
  const options = { capture: true, passive: true };
50
47
  this._target.addEventListener('mouseover', this._eventHandlers.mouseover, options);
51
48
  this._target.addEventListener('mouseleave', this._eventHandlers.mouseleave, options);
@@ -90,14 +87,7 @@ export default class Cursor {
90
87
  this._canvas.width = w;
91
88
  this._canvas.height = h;
92
89
 
93
- let img;
94
- try {
95
- // IE doesn't support this
96
- img = new ImageData(new Uint8ClampedArray(rgba), w, h);
97
- } catch (ex) {
98
- img = ctx.createImageData(w, h);
99
- img.data.set(new Uint8ClampedArray(rgba));
100
- }
90
+ let img = new ImageData(new Uint8ClampedArray(rgba), w, h);
101
91
  ctx.clearRect(0, 0, w, h);
102
92
  ctx.putImageData(img, 0, 0);
103
93
 
@@ -65,10 +65,6 @@ export function setCapture(target) {
65
65
 
66
66
  target.setCapture();
67
67
  document.captureElement = target;
68
-
69
- // IE releases capture on 'click' events which might not trigger
70
- target.addEventListener('mouseup', releaseCapture);
71
-
72
68
  } else {
73
69
  // Release any existing capture in case this method is
74
70
  // called multiple times without coordination
@@ -0,0 +1,79 @@
1
+ /*
2
+ * noVNC: HTML5 VNC client
3
+ * Copyright (C) 2021 The noVNC Authors
4
+ * Licensed under MPL 2.0 (see LICENSE.txt)
5
+ *
6
+ * See README.md for usage and integration instructions.
7
+ */
8
+
9
+ /*
10
+ * Performs MD5 hashing on a string of binary characters, returns an array of bytes
11
+ */
12
+
13
+ export function MD5(d) {
14
+ let r = M(V(Y(X(d), 8 * d.length)));
15
+ return r;
16
+ }
17
+
18
+ function M(d) {
19
+ let f = new Uint8Array(d.length);
20
+ for (let i=0;i<d.length;i++) {
21
+ f[i] = d.charCodeAt(i);
22
+ }
23
+ return f;
24
+ }
25
+
26
+ function X(d) {
27
+ let r = Array(d.length >> 2);
28
+ for (let m = 0; m < r.length; m++) r[m] = 0;
29
+ for (let m = 0; m < 8 * d.length; m += 8) r[m >> 5] |= (255 & d.charCodeAt(m / 8)) << m % 32;
30
+ return r;
31
+ }
32
+
33
+ function V(d) {
34
+ let r = "";
35
+ for (let m = 0; m < 32 * d.length; m += 8) r += String.fromCharCode(d[m >> 5] >>> m % 32 & 255);
36
+ return r;
37
+ }
38
+
39
+ function Y(d, g) {
40
+ d[g >> 5] |= 128 << g % 32, d[14 + (g + 64 >>> 9 << 4)] = g;
41
+ let m = 1732584193, f = -271733879, r = -1732584194, i = 271733878;
42
+ for (let n = 0; n < d.length; n += 16) {
43
+ let h = m,
44
+ t = f,
45
+ g = r,
46
+ e = i;
47
+ f = ii(f = ii(f = ii(f = ii(f = hh(f = hh(f = hh(f = hh(f = gg(f = gg(f = gg(f = gg(f = ff(f = ff(f = ff(f = ff(f, r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 0], 7, -680876936), f, r, d[n + 1], 12, -389564586), m, f, d[n + 2], 17, 606105819), i, m, d[n + 3], 22, -1044525330), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 4], 7, -176418897), f, r, d[n + 5], 12, 1200080426), m, f, d[n + 6], 17, -1473231341), i, m, d[n + 7], 22, -45705983), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 8], 7, 1770035416), f, r, d[n + 9], 12, -1958414417), m, f, d[n + 10], 17, -42063), i, m, d[n + 11], 22, -1990404162), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 12], 7, 1804603682), f, r, d[n + 13], 12, -40341101), m, f, d[n + 14], 17, -1502002290), i, m, d[n + 15], 22, 1236535329), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 1], 5, -165796510), f, r, d[n + 6], 9, -1069501632), m, f, d[n + 11], 14, 643717713), i, m, d[n + 0], 20, -373897302), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 5], 5, -701558691), f, r, d[n + 10], 9, 38016083), m, f, d[n + 15], 14, -660478335), i, m, d[n + 4], 20, -405537848), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 9], 5, 568446438), f, r, d[n + 14], 9, -1019803690), m, f, d[n + 3], 14, -187363961), i, m, d[n + 8], 20, 1163531501), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 13], 5, -1444681467), f, r, d[n + 2], 9, -51403784), m, f, d[n + 7], 14, 1735328473), i, m, d[n + 12], 20, -1926607734), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 5], 4, -378558), f, r, d[n + 8], 11, -2022574463), m, f, d[n + 11], 16, 1839030562), i, m, d[n + 14], 23, -35309556), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 1], 4, -1530992060), f, r, d[n + 4], 11, 1272893353), m, f, d[n + 7], 16, -155497632), i, m, d[n + 10], 23, -1094730640), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 13], 4, 681279174), f, r, d[n + 0], 11, -358537222), m, f, d[n + 3], 16, -722521979), i, m, d[n + 6], 23, 76029189), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 9], 4, -640364487), f, r, d[n + 12], 11, -421815835), m, f, d[n + 15], 16, 530742520), i, m, d[n + 2], 23, -995338651), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 0], 6, -198630844), f, r, d[n + 7], 10, 1126891415), m, f, d[n + 14], 15, -1416354905), i, m, d[n + 5], 21, -57434055), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 12], 6, 1700485571), f, r, d[n + 3], 10, -1894986606), m, f, d[n + 10], 15, -1051523), i, m, d[n + 1], 21, -2054922799), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 8], 6, 1873313359), f, r, d[n + 15], 10, -30611744), m, f, d[n + 6], 15, -1560198380), i, m, d[n + 13], 21, 1309151649), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 4], 6, -145523070), f, r, d[n + 11], 10, -1120210379), m, f, d[n + 2], 15, 718787259), i, m, d[n + 9], 21, -343485551), m = add(m, h), f = add(f, t), r = add(r, g), i = add(i, e);
48
+ }
49
+ return Array(m, f, r, i);
50
+ }
51
+
52
+ function cmn(d, g, m, f, r, i) {
53
+ return add(rol(add(add(g, d), add(f, i)), r), m);
54
+ }
55
+
56
+ function ff(d, g, m, f, r, i, n) {
57
+ return cmn(g & m | ~g & f, d, g, r, i, n);
58
+ }
59
+
60
+ function gg(d, g, m, f, r, i, n) {
61
+ return cmn(g & f | m & ~f, d, g, r, i, n);
62
+ }
63
+
64
+ function hh(d, g, m, f, r, i, n) {
65
+ return cmn(g ^ m ^ f, d, g, r, i, n);
66
+ }
67
+
68
+ function ii(d, g, m, f, r, i, n) {
69
+ return cmn(m ^ (g | ~f), d, g, r, i, n);
70
+ }
71
+
72
+ function add(d, g) {
73
+ let m = (65535 & d) + (65535 & g);
74
+ return (d >> 16) + (g >> 16) + (m >> 16) << 16 | 65535 & m;
75
+ }
76
+
77
+ function rol(d, g) {
78
+ return d << g | d >>> 32 - g;
79
+ }
package/core/websock.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /*
2
- * Websock: high-performance binary WebSockets
2
+ * Websock: high-performance buffering wrapper
3
3
  * Copyright (C) 2019 The noVNC Authors
4
4
  * Licensed under MPL 2.0 (see LICENSE.txt)
5
5
  *
6
- * Websock is similar to the standard WebSocket object but with extra
7
- * buffer handling.
6
+ * Websock is similar to the standard WebSocket / RTCDataChannel object
7
+ * but with extra buffer handling.
8
8
  *
9
9
  * Websock has built-in receive queue buffering; the message event
10
10
  * does not contain actual data but is simply a notification that
@@ -17,14 +17,39 @@ import * as Log from './util/logging.js';
17
17
  // this has performance issues in some versions Chromium, and
18
18
  // doesn't gain a tremendous amount of performance increase in Firefox
19
19
  // at the moment. It may be valuable to turn it on in the future.
20
- // Also copyWithin() for TypedArrays is not supported in IE 11 or
21
- // Safari 13 (at the moment we want to support Safari 11).
22
- const ENABLE_COPYWITHIN = false;
23
20
  const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
24
21
 
22
+ // Constants pulled from RTCDataChannelState enum
23
+ // https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/readyState#RTCDataChannelState_enum
24
+ const DataChannel = {
25
+ CONNECTING: "connecting",
26
+ OPEN: "open",
27
+ CLOSING: "closing",
28
+ CLOSED: "closed"
29
+ };
30
+
31
+ const ReadyStates = {
32
+ CONNECTING: [WebSocket.CONNECTING, DataChannel.CONNECTING],
33
+ OPEN: [WebSocket.OPEN, DataChannel.OPEN],
34
+ CLOSING: [WebSocket.CLOSING, DataChannel.CLOSING],
35
+ CLOSED: [WebSocket.CLOSED, DataChannel.CLOSED],
36
+ };
37
+
38
+ // Properties a raw channel must have, WebSocket and RTCDataChannel are two examples
39
+ const rawChannelProps = [
40
+ "send",
41
+ "close",
42
+ "binaryType",
43
+ "onerror",
44
+ "onmessage",
45
+ "onopen",
46
+ "protocol",
47
+ "readyState",
48
+ ];
49
+
25
50
  export default class Websock {
26
51
  constructor() {
27
- this._websocket = null; // WebSocket object
52
+ this._websocket = null; // WebSocket or RTCDataChannel object
28
53
 
29
54
  this._rQi = 0; // Receive queue index
30
55
  this._rQlen = 0; // Next write position in the receive queue
@@ -46,6 +71,29 @@ export default class Websock {
46
71
  }
47
72
 
48
73
  // Getters and Setters
74
+
75
+ get readyState() {
76
+ let subState;
77
+
78
+ if (this._websocket === null) {
79
+ return "unused";
80
+ }
81
+
82
+ subState = this._websocket.readyState;
83
+
84
+ if (ReadyStates.CONNECTING.includes(subState)) {
85
+ return "connecting";
86
+ } else if (ReadyStates.OPEN.includes(subState)) {
87
+ return "open";
88
+ } else if (ReadyStates.CLOSING.includes(subState)) {
89
+ return "closing";
90
+ } else if (ReadyStates.CLOSED.includes(subState)) {
91
+ return "closed";
92
+ }
93
+
94
+ return "unknown";
95
+ }
96
+
49
97
  get sQ() {
50
98
  return this._sQ;
51
99
  }
@@ -143,7 +191,7 @@ export default class Websock {
143
191
  // Send Queue
144
192
 
145
193
  flush() {
146
- if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
194
+ if (this._sQlen > 0 && this.readyState === 'open') {
147
195
  this._websocket.send(this._encodeMessage());
148
196
  this._sQlen = 0;
149
197
  }
@@ -180,12 +228,25 @@ export default class Websock {
180
228
  }
181
229
 
182
230
  open(uri, protocols) {
231
+ this.attach(new WebSocket(uri, protocols));
232
+ }
233
+
234
+ attach(rawChannel) {
183
235
  this.init();
184
236
 
185
- this._websocket = new WebSocket(uri, protocols);
186
- this._websocket.binaryType = 'arraybuffer';
237
+ // Must get object and class methods to be compatible with the tests.
238
+ const channelProps = [...Object.keys(rawChannel), ...Object.getOwnPropertyNames(Object.getPrototypeOf(rawChannel))];
239
+ for (let i = 0; i < rawChannelProps.length; i++) {
240
+ const prop = rawChannelProps[i];
241
+ if (channelProps.indexOf(prop) < 0) {
242
+ throw new Error('Raw channel missing property: ' + prop);
243
+ }
244
+ }
187
245
 
246
+ this._websocket = rawChannel;
247
+ this._websocket.binaryType = "arraybuffer";
188
248
  this._websocket.onmessage = this._recvMessage.bind(this);
249
+
189
250
  this._websocket.onopen = () => {
190
251
  Log.Debug('>> WebSock.onopen');
191
252
  if (this._websocket.protocol) {
@@ -195,11 +256,13 @@ export default class Websock {
195
256
  this._eventHandlers.open();
196
257
  Log.Debug("<< WebSock.onopen");
197
258
  };
259
+
198
260
  this._websocket.onclose = (e) => {
199
261
  Log.Debug(">> WebSock.onclose");
200
262
  this._eventHandlers.close(e);
201
263
  Log.Debug("<< WebSock.onclose");
202
264
  };
265
+
203
266
  this._websocket.onerror = (e) => {
204
267
  Log.Debug(">> WebSock.onerror: " + e);
205
268
  this._eventHandlers.error(e);
@@ -209,8 +272,8 @@ export default class Websock {
209
272
 
210
273
  close() {
211
274
  if (this._websocket) {
212
- if ((this._websocket.readyState === WebSocket.OPEN) ||
213
- (this._websocket.readyState === WebSocket.CONNECTING)) {
275
+ if (this.readyState === 'connecting' ||
276
+ this.readyState === 'open') {
214
277
  Log.Info("Closing WebSocket connection");
215
278
  this._websocket.close();
216
279
  }
@@ -256,11 +319,7 @@ export default class Websock {
256
319
  this._rQ = new Uint8Array(this._rQbufferSize);
257
320
  this._rQ.set(new Uint8Array(oldRQbuffer, this._rQi, this._rQlen - this._rQi));
258
321
  } else {
259
- if (ENABLE_COPYWITHIN) {
260
- this._rQ.copyWithin(0, this._rQi, this._rQlen);
261
- } else {
262
- this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi, this._rQlen - this._rQi));
263
- }
322
+ this._rQ.copyWithin(0, this._rQi, this._rQlen);
264
323
  }
265
324
 
266
325
  this._rQlen = this._rQlen - this._rQi;
package/docs/API.md CHANGED
@@ -86,9 +86,13 @@ protocol stream.
86
86
  - The `connect` event is fired when the `RFB` object has completed
87
87
  the connection and handshaking with the server.
88
88
 
89
- [`disconnect`](#disconnected)
89
+ [`disconnect`](#disconnect)
90
90
  - The `disconnect` event is fired when the `RFB` object disconnects.
91
91
 
92
+ [`serververification`](#serververification)
93
+ - The `serververification` event is fired when the server identity
94
+ must be confirmed by the user.
95
+
92
96
  [`credentialsrequired`](#credentialsrequired)
93
97
  - The `credentialsrequired` event is fired when more credentials must
94
98
  be given to continue.
@@ -118,11 +122,16 @@ protocol stream.
118
122
  [`RFB.disconnect()`](#rfbdisconnect)
119
123
  - Disconnect from the server.
120
124
 
125
+ [`RFB.approveServer()`](#rfbapproveserver)
126
+ - Proceed connecting to the server. Should be called after the
127
+ [`serververification`](#serververification) event has fired and the
128
+ user has verified the identity of the server.
129
+
121
130
  [`RFB.sendCredentials()`](#rfbsendcredentials)
122
131
  - Send credentials to server. Should be called after the
123
132
  [`credentialsrequired`](#credentialsrequired) event has fired.
124
133
 
125
- [`RFB.sendKey()`](#rfbsendKey)
134
+ [`RFB.sendKey()`](#rfbsendkey)
126
135
  - Send a key event.
127
136
 
128
137
  [`RFB.sendCtrlAltDel()`](#rfbsendctrlaltdel)
@@ -143,9 +152,18 @@ protocol stream.
143
152
  [`RFB.machineReset()`](#rfbmachinereset)
144
153
  - Request a reset of the remote machine.
145
154
 
146
- [`RFB.clipboardPasteFrom()`](#rfbclipboardPasteFrom)
155
+ [`RFB.clipboardPasteFrom()`](#rfbclipboardpastefrom)
147
156
  - Send clipboard contents to server.
148
157
 
158
+ [`RFB.getImageData()`](#rfbgetimagedata)
159
+ - Return the current content of the screen as an ImageData array.
160
+
161
+ [`RFB.toDataURL()`](#rfbtodataurl)
162
+ - Return the current content of the screen as data-url encoded image file.
163
+
164
+ [`RFB.toBlob()`](#rfbtoblob)
165
+ - Return the current content of the screen as Blob encoded image file.
166
+
149
167
  ### Details
150
168
 
151
169
  #### RFB()
@@ -165,9 +183,9 @@ connection to a specified VNC server.
165
183
  existing contents of the `HTMLElement` will be untouched, but new
166
184
  elements will be added during the lifetime of the `RFB` object.
167
185
 
168
- **`url`**
186
+ **`urlOrDataChannel`**
169
187
  - A `DOMString` specifying the VNC server to connect to. This must be
170
- a valid WebSocket URL.
188
+ a valid WebSocket URL. This can also be a `WebSocket` or `RTCDataChannel`.
171
189
 
172
190
  **`options`** *Optional*
173
191
  - An `Object` specifying extra details about how the connection
@@ -212,6 +230,20 @@ property `clean`. `clean` is a `boolean` indicating if the termination
212
230
  was clean or not. In the event of an unexpected termination or an error
213
231
  `clean` will be set to false.
214
232
 
233
+ #### serververification
234
+
235
+ The `serververification` event is fired when the server provides
236
+ information that allows the user to verify that it is the correct server
237
+ and protect against a man-in-the-middle attack. The `detail` property is
238
+ an `Object` containing the property `type` which is a `DOMString`
239
+ specifying which type of information the server has provided. Other
240
+ properties are also available, depending on the value of `type`:
241
+
242
+ `"RSA"`
243
+ - The server identity is verified using just a RSA key. The property
244
+ `publickey` is a `Uint8Array` containing the public key in a unsigned
245
+ big endian representation.
246
+
215
247
  #### credentialsrequired
216
248
 
217
249
  The `credentialsrequired` event is fired when the server requests more
@@ -271,6 +303,16 @@ connected server.
271
303
 
272
304
  RFB.disconnect( );
273
305
 
306
+ #### RFB.approveServer()
307
+
308
+ The `RFB.approveServer()` method is used to signal that the user has
309
+ verified the server identity provided in a `serververification` event
310
+ and that the connection can continue.
311
+
312
+ ##### Syntax
313
+
314
+ RFB.approveServer( );
315
+
274
316
  #### RFB.sendCredentials()
275
317
 
276
318
  The `RFB.sendCredentials()` method is used to provide the missing
@@ -328,7 +370,14 @@ Keyboard events will be sent to the remote server after this point.
328
370
 
329
371
  ##### Syntax
330
372
 
331
- RFB.focus( );
373
+ RFB.focus( [options] );
374
+
375
+ ###### Parameters
376
+
377
+ **`options`** *Optional*
378
+ - A `object` providing options to control how the focus will be
379
+ performed. Please see [`HTMLElement.focus()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus)
380
+ for available options.
332
381
 
333
382
  #### RFB.blur()
334
383
 
@@ -383,3 +432,55 @@ to the remote server.
383
432
 
384
433
  **`text`**
385
434
  - A `DOMString` specifying the clipboard data to send.
435
+
436
+ #### RFB.getImageData()
437
+
438
+ The `RFB.getImageData()` method is used to return the current content of the
439
+ screen encoded as [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData).
440
+
441
+ ##### Syntax
442
+
443
+ RFB.getImageData();
444
+
445
+ #### RFB.toDataURL()
446
+
447
+ The `RFB.toDataURL()` method is used to return the current content of the
448
+ screen encoded as a data URL that could for example be put in the `src` attribute
449
+ of an `img` tag.
450
+
451
+ ##### Syntax
452
+
453
+ RFB.toDataURL();
454
+ RFB.toDataURL(type);
455
+ RFB.toDataURL(type, encoderOptions);
456
+
457
+ ###### Parameters
458
+
459
+ **`type`** *Optional*
460
+ - A string indicating the requested MIME type of the image
461
+
462
+ **`encoderOptions`** *Optional*
463
+ - A number between 0 and 1 indicating the image quality.
464
+
465
+ #### RFB.toBlob()
466
+
467
+ The `RFB.toBlob()` method is used to return the current content of the
468
+ screen encoded as [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
469
+
470
+ ##### Syntax
471
+
472
+ RFB.toDataURL(callback);
473
+ RFB.toDataURL(callback, type);
474
+ RFB.toDataURL(callback, type, quality);
475
+
476
+ ###### Parameters
477
+
478
+ **`callback`**
479
+ - A callback function which will receive the resulting [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
480
+ as the single argument
481
+
482
+ **`type`** *Optional*
483
+ - A string indicating the requested MIME type of the image
484
+
485
+ **`encoderOptions`** *Optional*
486
+ - A number between 0 and 1 indicating the image quality.
package/docs/LIBRARY.md CHANGED
@@ -18,18 +18,14 @@ do things.
18
18
 
19
19
  ## Conversion of Modules
20
20
 
21
- noVNC is written using ECMAScript 6 modules. Many of the major browsers support
22
- these modules natively, but not all. They are also not supported by Node.js. To
23
- use noVNC in these places the library must first be converted.
21
+ noVNC is written using ECMAScript 6 modules. This is not supported by older
22
+ versions of Node.js. To use noVNC with those older versions of Node.js the
23
+ library must first be converted.
24
24
 
25
25
  Fortunately noVNC includes a script to handle this conversion. Please follow
26
26
  the following steps:
27
27
 
28
28
  1. Install Node.js
29
29
  2. Run `npm install` in the noVNC directory
30
- 3. Run `./utils/use_require.js --as <module format>`
31
-
32
- Several module formats are available. Please run
33
- `./utils/use_require.js --help` to see them all.
34
30
 
35
31
  The result of the conversion is available in the `lib/` directory.
package/lib/base64.js CHANGED
@@ -1,18 +1,13 @@
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
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
- exports.default = void 0;
9
-
7
+ exports["default"] = void 0;
10
8
  var Log = _interopRequireWildcard(require("./util/logging.js"));
11
-
12
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
13
-
14
- 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; }
15
-
9
+ 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); }
10
+ 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; }
16
11
  /* This Source Code Form is subject to the terms of the Mozilla Public
17
12
  * License, v. 2.0. If a copy of the MPL was not distributed with this
18
13
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -26,18 +21,18 @@ var _default = {
26
21
 
27
22
  var result = '';
28
23
  var length = data.length;
29
- var lengthpad = length % 3; // Convert every three bytes to 4 ascii characters.
24
+ var lengthpad = length % 3;
25
+ // Convert every three bytes to 4 ascii characters.
30
26
 
31
27
  for (var i = 0; i < length - 2; i += 3) {
32
28
  result += this.toBase64Table[data[i] >> 2];
33
29
  result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
34
30
  result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
35
31
  result += this.toBase64Table[data[i + 2] & 0x3f];
36
- } // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
37
-
32
+ }
38
33
 
34
+ // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
39
35
  var j = length - lengthpad;
40
-
41
36
  if (lengthpad === 2) {
42
37
  result += this.toBase64Table[data[j] >> 2];
43
38
  result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
@@ -49,67 +44,58 @@ var _default = {
49
44
  result += this.toBase64Table[64];
50
45
  result += this.toBase64Table[64];
51
46
  }
52
-
53
47
  return result;
54
48
  },
55
-
56
49
  /* Convert Base64 data to a string */
57
-
58
50
  /* eslint-disable comma-spacing */
59
51
  toBinaryTable: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1],
60
-
61
- /* eslint-enable comma-spacing */
62
- decode: function decode(data) {
52
+ /* eslint-enable comma-spacing */decode: function decode(data) {
63
53
  var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
64
54
  var dataLength = data.indexOf('=') - offset;
65
-
66
55
  if (dataLength < 0) {
67
56
  dataLength = data.length - offset;
68
57
  }
69
- /* Every four characters is 3 resulting numbers */
70
-
71
58
 
59
+ /* Every four characters is 3 resulting numbers */
72
60
  var resultLength = (dataLength >> 2) * 3 + Math.floor(dataLength % 4 / 1.5);
73
- var result = new Array(resultLength); // Convert one by one.
61
+ var result = new Array(resultLength);
74
62
 
75
- var leftbits = 0; // number of bits decoded, but yet to be appended
63
+ // Convert one by one.
76
64
 
65
+ var leftbits = 0; // number of bits decoded, but yet to be appended
77
66
  var leftdata = 0; // bits decoded, but yet to be appended
78
-
79
67
  for (var idx = 0, i = offset; i < data.length; i++) {
80
68
  var c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
81
- var padding = data.charAt(i) === this.base64Pad; // Skip illegal characters and whitespace
82
-
69
+ var padding = data.charAt(i) === this.base64Pad;
70
+ // Skip illegal characters and whitespace
83
71
  if (c === -1) {
84
72
  Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
85
73
  continue;
86
- } // Collect data into leftdata, update bitcount
87
-
74
+ }
88
75
 
76
+ // Collect data into leftdata, update bitcount
89
77
  leftdata = leftdata << 6 | c;
90
- leftbits += 6; // If we have 8 or more bits, append 8 bits to the result
78
+ leftbits += 6;
91
79
 
80
+ // If we have 8 or more bits, append 8 bits to the result
92
81
  if (leftbits >= 8) {
93
- leftbits -= 8; // Append if not padding.
94
-
82
+ leftbits -= 8;
83
+ // Append if not padding.
95
84
  if (!padding) {
96
85
  result[idx++] = leftdata >> leftbits & 0xff;
97
86
  }
98
-
99
87
  leftdata &= (1 << leftbits) - 1;
100
88
  }
101
- } // If there are any bits left, the base64 string was corrupted
102
-
89
+ }
103
90
 
91
+ // If there are any bits left, the base64 string was corrupted
104
92
  if (leftbits) {
105
93
  var err = new Error('Corrupted base64 string');
106
94
  err.name = 'Base64-Error';
107
95
  throw err;
108
96
  }
109
-
110
97
  return result;
111
98
  }
112
99
  };
113
100
  /* End of Base64 namespace */
114
-
115
- exports.default = _default;
101
+ exports["default"] = _default;