novnc-rails 0.1

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 (31) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +0 -0
  3. data/LICENSE.txt +0 -0
  4. data/README.md +0 -0
  5. data/lib/novnc-rails.rb +8 -0
  6. data/lib/novnc-rails/version.rb +5 -0
  7. data/vendor/assets/javascripts/noVNC/Orbitron700.ttf +0 -0
  8. data/vendor/assets/javascripts/noVNC/Orbitron700.woff +0 -0
  9. data/vendor/assets/javascripts/noVNC/base.css +512 -0
  10. data/vendor/assets/javascripts/noVNC/base64.js +113 -0
  11. data/vendor/assets/javascripts/noVNC/black.css +71 -0
  12. data/vendor/assets/javascripts/noVNC/blue.css +64 -0
  13. data/vendor/assets/javascripts/noVNC/des.js +276 -0
  14. data/vendor/assets/javascripts/noVNC/display.js +751 -0
  15. data/vendor/assets/javascripts/noVNC/input.js +388 -0
  16. data/vendor/assets/javascripts/noVNC/jsunzip.js +676 -0
  17. data/vendor/assets/javascripts/noVNC/keyboard.js +543 -0
  18. data/vendor/assets/javascripts/noVNC/keysym.js +378 -0
  19. data/vendor/assets/javascripts/noVNC/keysymdef.js +15 -0
  20. data/vendor/assets/javascripts/noVNC/logo.js +1 -0
  21. data/vendor/assets/javascripts/noVNC/playback.js +102 -0
  22. data/vendor/assets/javascripts/noVNC/rfb.js +1889 -0
  23. data/vendor/assets/javascripts/noVNC/ui.js +979 -0
  24. data/vendor/assets/javascripts/noVNC/util.js +656 -0
  25. data/vendor/assets/javascripts/noVNC/web-socket-js/README.txt +109 -0
  26. data/vendor/assets/javascripts/noVNC/web-socket-js/WebSocketMain.swf +0 -0
  27. data/vendor/assets/javascripts/noVNC/web-socket-js/swfobject.js +4 -0
  28. data/vendor/assets/javascripts/noVNC/web-socket-js/web_socket.js +391 -0
  29. data/vendor/assets/javascripts/noVNC/websock.js +388 -0
  30. data/vendor/assets/javascripts/noVNC/webutil.js +239 -0
  31. metadata +86 -0
@@ -0,0 +1,388 @@
1
+ /*
2
+ * Websock: high-performance binary WebSockets
3
+ * Copyright (C) 2012 Joel Martin
4
+ * Licensed under MPL 2.0 (see LICENSE.txt)
5
+ *
6
+ * Websock is similar to the standard WebSocket object but Websock
7
+ * enables communication with raw TCP sockets (i.e. the binary stream)
8
+ * via websockify. This is accomplished by base64 encoding the data
9
+ * stream between Websock and websockify.
10
+ *
11
+ * Websock has built-in receive queue buffering; the message event
12
+ * does not contain actual data but is simply a notification that
13
+ * there is new data available. Several rQ* methods are available to
14
+ * read binary data off of the receive queue.
15
+ */
16
+
17
+ /*jslint browser: true, bitwise: true */
18
+ /*global Util, Base64 */
19
+
20
+
21
+ // Load Flash WebSocket emulator if needed
22
+
23
+ // To force WebSocket emulator even when native WebSocket available
24
+ //window.WEB_SOCKET_FORCE_FLASH = true;
25
+ // To enable WebSocket emulator debug:
26
+ //window.WEB_SOCKET_DEBUG=1;
27
+
28
+ if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) {
29
+ Websock_native = true;
30
+ } else if (window.MozWebSocket && !window.WEB_SOCKET_FORCE_FLASH) {
31
+ Websock_native = true;
32
+ window.WebSocket = window.MozWebSocket;
33
+ } else {
34
+ /* no builtin WebSocket so load web_socket.js */
35
+
36
+ Websock_native = false;
37
+ (function () {
38
+ window.WEB_SOCKET_SWF_LOCATION = Util.get_include_uri() +
39
+ "web-socket-js/WebSocketMain.swf";
40
+ if (Util.Engine.trident) {
41
+ Util.Debug("Forcing uncached load of WebSocketMain.swf");
42
+ window.WEB_SOCKET_SWF_LOCATION += "?" + Math.random();
43
+ }
44
+ Util.load_scripts(["web-socket-js/swfobject.js",
45
+ "web-socket-js/web_socket.js"]);
46
+ })();
47
+ }
48
+
49
+
50
+ function Websock() {
51
+ "use strict";
52
+
53
+ this._websocket = null; // WebSocket object
54
+ this._rQ = []; // Receive queue
55
+ this._rQi = 0; // Receive queue index
56
+ this._rQmax = 10000; // Max receive queue size before compacting
57
+ this._sQ = []; // Send queue
58
+
59
+ this._mode = 'base64'; // Current WebSocket mode: 'binary', 'base64'
60
+ this.maxBufferedAmount = 200;
61
+
62
+ this._eventHandlers = {
63
+ 'message': function () {},
64
+ 'open': function () {},
65
+ 'close': function () {},
66
+ 'error': function () {}
67
+ };
68
+ }
69
+
70
+ (function () {
71
+ "use strict";
72
+ Websock.prototype = {
73
+ // Getters and Setters
74
+ get_sQ: function () {
75
+ return this._sQ;
76
+ },
77
+
78
+ get_rQ: function () {
79
+ return this._rQ;
80
+ },
81
+
82
+ get_rQi: function () {
83
+ return this._rQi;
84
+ },
85
+
86
+ set_rQi: function (val) {
87
+ this._rQi = val;
88
+ },
89
+
90
+ // Receive Queue
91
+ rQlen: function () {
92
+ return this._rQ.length - this._rQi;
93
+ },
94
+
95
+ rQpeek8: function () {
96
+ return this._rQ[this._rQi];
97
+ },
98
+
99
+ rQshift8: function () {
100
+ return this._rQ[this._rQi++];
101
+ },
102
+
103
+ rQskip8: function () {
104
+ this._rQi++;
105
+ },
106
+
107
+ rQskipBytes: function (num) {
108
+ this._rQi += num;
109
+ },
110
+
111
+ rQunshift8: function (num) {
112
+ if (this._rQi === 0) {
113
+ this._rQ.unshift(num);
114
+ } else {
115
+ this._rQi--;
116
+ this._rQ[this._rQi] = num;
117
+ }
118
+ },
119
+
120
+ rQshift16: function () {
121
+ return (this._rQ[this._rQi++] << 8) +
122
+ this._rQ[this._rQi++];
123
+ },
124
+
125
+ rQshift32: function () {
126
+ return (this._rQ[this._rQi++] << 24) +
127
+ (this._rQ[this._rQi++] << 16) +
128
+ (this._rQ[this._rQi++] << 8) +
129
+ this._rQ[this._rQi++];
130
+ },
131
+
132
+ rQshiftStr: function (len) {
133
+ if (typeof(len) === 'undefined') { len = this.rQlen(); }
134
+ var arr = this._rQ.slice(this._rQi, this._rQi + len);
135
+ this._rQi += len;
136
+ return String.fromCharCode.apply(null, arr);
137
+ },
138
+
139
+ rQshiftBytes: function (len) {
140
+ if (typeof(len) === 'undefined') { len = this.rQlen(); }
141
+ this._rQi += len;
142
+ return this._rQ.slice(this._rQi - len, this._rQi);
143
+ },
144
+
145
+ rQslice: function (start, end) {
146
+ if (end) {
147
+ return this._rQ.slice(this._rQi + start, this._rQi + end);
148
+ } else {
149
+ return this._rQ.slice(this._rQi + start);
150
+ }
151
+ },
152
+
153
+ // Check to see if we must wait for 'num' bytes (default to FBU.bytes)
154
+ // to be available in the receive queue. Return true if we need to
155
+ // wait (and possibly print a debug message), otherwise false.
156
+ rQwait: function (msg, num, goback) {
157
+ var rQlen = this._rQ.length - this._rQi; // Skip rQlen() function call
158
+ if (rQlen < num) {
159
+ if (goback) {
160
+ if (this._rQi < goback) {
161
+ throw new Error("rQwait cannot backup " + goback + " bytes");
162
+ }
163
+ this._rQi -= goback;
164
+ }
165
+ return true; // true means need more data
166
+ }
167
+ return false;
168
+ },
169
+
170
+ // Send Queue
171
+
172
+ flush: function () {
173
+ if (this._websocket.bufferedAmount !== 0) {
174
+ Util.Debug("bufferedAmount: " + this._websocket.bufferedAmount);
175
+ }
176
+
177
+ if (this._websocket.bufferedAmount < this.maxBufferedAmount) {
178
+ if (this._sQ.length > 0) {
179
+ this._websocket.send(this._encode_message());
180
+ this._sQ = [];
181
+ }
182
+
183
+ return true;
184
+ } else {
185
+ Util.Info("Delaying send, bufferedAmount: " +
186
+ this._websocket.bufferedAmount);
187
+ return false;
188
+ }
189
+ },
190
+
191
+ send: function (arr) {
192
+ this._sQ = this._sQ.concat(arr);
193
+ return this.flush();
194
+ },
195
+
196
+ send_string: function (str) {
197
+ this.send(str.split('').map(function (chr) {
198
+ return chr.charCodeAt(0);
199
+ }));
200
+ },
201
+
202
+ // Event Handlers
203
+ off: function (evt) {
204
+ this._eventHandlers[evt] = function () {};
205
+ },
206
+
207
+ on: function (evt, handler) {
208
+ this._eventHandlers[evt] = handler;
209
+ },
210
+
211
+ init: function (protocols, ws_schema) {
212
+ this._rQ = [];
213
+ this._rQi = 0;
214
+ this._sQ = [];
215
+ this._websocket = null;
216
+
217
+ // Check for full typed array support
218
+ var bt = false;
219
+ if (('Uint8Array' in window) &&
220
+ ('set' in Uint8Array.prototype)) {
221
+ bt = true;
222
+ }
223
+
224
+ // Check for full binary type support in WebSockets
225
+ // Inspired by:
226
+ // https://github.com/Modernizr/Modernizr/issues/370
227
+ // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/websockets/binary.js
228
+ var wsbt = false;
229
+ try {
230
+ if (bt && ('binaryType' in WebSocket.prototype ||
231
+ !!(new WebSocket(ws_schema + '://.').binaryType))) {
232
+ Util.Info("Detected binaryType support in WebSockets");
233
+ wsbt = true;
234
+ }
235
+ } catch (exc) {
236
+ // Just ignore failed test localhost connection
237
+ }
238
+
239
+ // Default protocols if not specified
240
+ if (typeof(protocols) === "undefined") {
241
+ if (wsbt) {
242
+ protocols = ['binary', 'base64'];
243
+ } else {
244
+ protocols = 'base64';
245
+ }
246
+ }
247
+
248
+ if (!wsbt) {
249
+ if (protocols === 'binary') {
250
+ throw new Error('WebSocket binary sub-protocol requested but not supported');
251
+ }
252
+
253
+ if (typeof(protocols) === 'object') {
254
+ var new_protocols = [];
255
+
256
+ for (var i = 0; i < protocols.length; i++) {
257
+ if (protocols[i] === 'binary') {
258
+ Util.Error('Skipping unsupported WebSocket binary sub-protocol');
259
+ } else {
260
+ new_protocols.push(protocols[i]);
261
+ }
262
+ }
263
+
264
+ if (new_protocols.length > 0) {
265
+ protocols = new_protocols;
266
+ } else {
267
+ throw new Error("Only WebSocket binary sub-protocol was requested and is not supported.");
268
+ }
269
+ }
270
+ }
271
+
272
+ return protocols;
273
+ },
274
+
275
+ open: function (uri, protocols) {
276
+ var ws_schema = uri.match(/^([a-z]+):\/\//)[1];
277
+ protocols = this.init(protocols, ws_schema);
278
+
279
+ this._websocket = new WebSocket(uri, protocols);
280
+
281
+ if (protocols.indexOf('binary') >= 0) {
282
+ this._websocket.binaryType = 'arraybuffer';
283
+ }
284
+
285
+ this._websocket.onmessage = this._recv_message.bind(this);
286
+ this._websocket.onopen = (function () {
287
+ Util.Debug('>> WebSock.onopen');
288
+ if (this._websocket.protocol) {
289
+ this._mode = this._websocket.protocol;
290
+ Util.Info("Server choose sub-protocol: " + this._websocket.protocol);
291
+ } else {
292
+ this._mode = 'base64';
293
+ Util.Error('Server select no sub-protocol!: ' + this._websocket.protocol);
294
+ }
295
+ this._eventHandlers.open();
296
+ Util.Debug("<< WebSock.onopen");
297
+ }).bind(this);
298
+ this._websocket.onclose = (function (e) {
299
+ Util.Debug(">> WebSock.onclose");
300
+ this._eventHandlers.close(e);
301
+ Util.Debug("<< WebSock.onclose");
302
+ }).bind(this);
303
+ this._websocket.onerror = (function (e) {
304
+ Util.Debug(">> WebSock.onerror: " + e);
305
+ this._eventHandlers.error(e);
306
+ Util.Debug("<< WebSock.onerror: " + e);
307
+ }).bind(this);
308
+ },
309
+
310
+ close: function () {
311
+ if (this._websocket) {
312
+ if ((this._websocket.readyState === WebSocket.OPEN) ||
313
+ (this._websocket.readyState === WebSocket.CONNECTING)) {
314
+ Util.Info("Closing WebSocket connection");
315
+ this._websocket.close();
316
+ }
317
+
318
+ this._websocket.onmessage = function (e) { return; };
319
+ }
320
+ },
321
+
322
+ // private methods
323
+ _encode_message: function () {
324
+ if (this._mode === 'binary') {
325
+ // Put in a binary arraybuffer
326
+ return (new Uint8Array(this._sQ)).buffer;
327
+ } else {
328
+ // base64 encode
329
+ return Base64.encode(this._sQ);
330
+ }
331
+ },
332
+
333
+ _decode_message: function (data) {
334
+ if (this._mode === 'binary') {
335
+ // push arraybuffer values onto the end
336
+ var u8 = new Uint8Array(data);
337
+ for (var i = 0; i < u8.length; i++) {
338
+ this._rQ.push(u8[i]);
339
+ }
340
+ } else {
341
+ // base64 decode and concat to end
342
+ this._rQ = this._rQ.concat(Base64.decode(data, 0));
343
+ }
344
+ },
345
+
346
+ _recv_message: function (e) {
347
+ try {
348
+ this._decode_message(e.data);
349
+ if (this.rQlen() > 0) {
350
+ this._eventHandlers.message();
351
+ // Compact the receive queue
352
+ if (this._rQ.length > this._rQmax) {
353
+ this._rQ = this._rQ.slice(this._rQi);
354
+ this._rQi = 0;
355
+ }
356
+ } else {
357
+ Util.Debug("Ignoring empty message");
358
+ }
359
+ } catch (exc) {
360
+ var exception_str = "";
361
+ if (exc.name) {
362
+ exception_str += "\n name: " + exc.name + "\n";
363
+ exception_str += " message: " + exc.message + "\n";
364
+ }
365
+
366
+ if (typeof exc.description !== 'undefined') {
367
+ exception_str += " description: " + exc.description + "\n";
368
+ }
369
+
370
+ if (typeof exc.stack !== 'undefined') {
371
+ exception_str += exc.stack;
372
+ }
373
+
374
+ if (exception_str.length > 0) {
375
+ Util.Error("recv_message, caught exception: " + exception_str);
376
+ } else {
377
+ Util.Error("recv_message, caught exception: " + exc);
378
+ }
379
+
380
+ if (typeof exc.name !== 'undefined') {
381
+ this._eventHandlers.error(exc.name + ": " + exc.message);
382
+ } else {
383
+ this._eventHandlers.error(exc);
384
+ }
385
+ }
386
+ }
387
+ };
388
+ })();
@@ -0,0 +1,239 @@
1
+ /*
2
+ * noVNC: HTML5 VNC client
3
+ * Copyright (C) 2012 Joel Martin
4
+ * Copyright (C) 2013 NTT corp.
5
+ * Licensed under MPL 2.0 (see LICENSE.txt)
6
+ *
7
+ * See README.md for usage and integration instructions.
8
+ */
9
+
10
+ /*jslint bitwise: false, white: false, browser: true, devel: true */
11
+ /*global Util, window, document */
12
+
13
+ // Globals defined here
14
+ var WebUtil = {}, $D;
15
+
16
+ /*
17
+ * Simple DOM selector by ID
18
+ */
19
+ if (!window.$D) {
20
+ window.$D = function (id) {
21
+ if (document.getElementById) {
22
+ return document.getElementById(id);
23
+ } else if (document.all) {
24
+ return document.all[id];
25
+ } else if (document.layers) {
26
+ return document.layers[id];
27
+ }
28
+ return undefined;
29
+ };
30
+ }
31
+
32
+
33
+ /*
34
+ * ------------------------------------------------------
35
+ * Namespaced in WebUtil
36
+ * ------------------------------------------------------
37
+ */
38
+
39
+ // init log level reading the logging HTTP param
40
+ WebUtil.init_logging = function (level) {
41
+ "use strict";
42
+ if (typeof level !== "undefined") {
43
+ Util._log_level = level;
44
+ } else {
45
+ var param = document.location.href.match(/logging=([A-Za-z0-9\._\-]*)/);
46
+ Util._log_level = (param || ['', Util._log_level])[1];
47
+ }
48
+ Util.init_logging();
49
+ };
50
+
51
+
52
+ WebUtil.dirObj = function (obj, depth, parent) {
53
+ "use strict";
54
+ if (! depth) { depth = 2; }
55
+ if (! parent) { parent = ""; }
56
+
57
+ // Print the properties of the passed-in object
58
+ var msg = "";
59
+ for (var i in obj) {
60
+ if ((depth > 1) && (typeof obj[i] === "object")) {
61
+ // Recurse attributes that are objects
62
+ msg += WebUtil.dirObj(obj[i], depth - 1, parent + "." + i);
63
+ } else {
64
+ //val = new String(obj[i]).replace("\n", " ");
65
+ var val = "";
66
+ if (typeof(obj[i]) === "undefined") {
67
+ val = "undefined";
68
+ } else {
69
+ val = obj[i].toString().replace("\n", " ");
70
+ }
71
+ if (val.length > 30) {
72
+ val = val.substr(0, 30) + "...";
73
+ }
74
+ msg += parent + "." + i + ": " + val + "\n";
75
+ }
76
+ }
77
+ return msg;
78
+ };
79
+
80
+ // Read a query string variable
81
+ WebUtil.getQueryVar = function (name, defVal) {
82
+ "use strict";
83
+ var re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
84
+ match = document.location.href.match(re);
85
+ if (typeof defVal === 'undefined') { defVal = null; }
86
+ if (match) {
87
+ return decodeURIComponent(match[1]);
88
+ } else {
89
+ return defVal;
90
+ }
91
+ };
92
+
93
+
94
+ /*
95
+ * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
96
+ */
97
+
98
+ // No days means only for this browser session
99
+ WebUtil.createCookie = function (name, value, days) {
100
+ "use strict";
101
+ var date, expires;
102
+ if (days) {
103
+ date = new Date();
104
+ date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
105
+ expires = "; expires=" + date.toGMTString();
106
+ } else {
107
+ expires = "";
108
+ }
109
+
110
+ var secure;
111
+ if (document.location.protocol === "https:") {
112
+ secure = "; secure";
113
+ } else {
114
+ secure = "";
115
+ }
116
+ document.cookie = name + "=" + value + expires + "; path=/" + secure;
117
+ };
118
+
119
+ WebUtil.readCookie = function (name, defaultValue) {
120
+ "use strict";
121
+ var nameEQ = name + "=",
122
+ ca = document.cookie.split(';');
123
+
124
+ for (var i = 0; i < ca.length; i += 1) {
125
+ var c = ca[i];
126
+ while (c.charAt(0) === ' ') { c = c.substring(1, c.length); }
127
+ if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length, c.length); }
128
+ }
129
+ return (typeof defaultValue !== 'undefined') ? defaultValue : null;
130
+ };
131
+
132
+ WebUtil.eraseCookie = function (name) {
133
+ "use strict";
134
+ WebUtil.createCookie(name, "", -1);
135
+ };
136
+
137
+ /*
138
+ * Setting handling.
139
+ */
140
+
141
+ WebUtil.initSettings = function (callback /*, ...callbackArgs */) {
142
+ "use strict";
143
+ var callbackArgs = Array.prototype.slice.call(arguments, 1);
144
+ if (window.chrome && window.chrome.storage) {
145
+ window.chrome.storage.sync.get(function (cfg) {
146
+ WebUtil.settings = cfg;
147
+ console.log(WebUtil.settings);
148
+ if (callback) {
149
+ callback.apply(this, callbackArgs);
150
+ }
151
+ });
152
+ } else {
153
+ // No-op
154
+ if (callback) {
155
+ callback.apply(this, callbackArgs);
156
+ }
157
+ }
158
+ };
159
+
160
+ // No days means only for this browser session
161
+ WebUtil.writeSetting = function (name, value) {
162
+ "use strict";
163
+ if (window.chrome && window.chrome.storage) {
164
+ //console.log("writeSetting:", name, value);
165
+ if (WebUtil.settings[name] !== value) {
166
+ WebUtil.settings[name] = value;
167
+ window.chrome.storage.sync.set(WebUtil.settings);
168
+ }
169
+ } else {
170
+ localStorage.setItem(name, value);
171
+ }
172
+ };
173
+
174
+ WebUtil.readSetting = function (name, defaultValue) {
175
+ "use strict";
176
+ var value;
177
+ if (window.chrome && window.chrome.storage) {
178
+ value = WebUtil.settings[name];
179
+ } else {
180
+ value = localStorage.getItem(name);
181
+ }
182
+ if (typeof value === "undefined") {
183
+ value = null;
184
+ }
185
+ if (value === null && typeof defaultValue !== undefined) {
186
+ return defaultValue;
187
+ } else {
188
+ return value;
189
+ }
190
+ };
191
+
192
+ WebUtil.eraseSetting = function (name) {
193
+ "use strict";
194
+ if (window.chrome && window.chrome.storage) {
195
+ window.chrome.storage.sync.remove(name);
196
+ delete WebUtil.settings[name];
197
+ } else {
198
+ localStorage.removeItem(name);
199
+ }
200
+ };
201
+
202
+ /*
203
+ * Alternate stylesheet selection
204
+ */
205
+ WebUtil.getStylesheets = function () {
206
+ "use strict";
207
+ var links = document.getElementsByTagName("link");
208
+ var sheets = [];
209
+
210
+ for (var i = 0; i < links.length; i += 1) {
211
+ if (links[i].title &&
212
+ links[i].rel.toUpperCase().indexOf("STYLESHEET") > -1) {
213
+ sheets.push(links[i]);
214
+ }
215
+ }
216
+ return sheets;
217
+ };
218
+
219
+ // No sheet means try and use value from cookie, null sheet used to
220
+ // clear all alternates.
221
+ WebUtil.selectStylesheet = function (sheet) {
222
+ "use strict";
223
+ if (typeof sheet === 'undefined') {
224
+ sheet = 'default';
225
+ }
226
+
227
+ var sheets = WebUtil.getStylesheets();
228
+ for (var i = 0; i < sheets.length; i += 1) {
229
+ var link = sheets[i];
230
+ if (link.title === sheet) {
231
+ Util.Debug("Using stylesheet " + sheet);
232
+ link.disabled = false;
233
+ } else {
234
+ //Util.Debug("Skipping stylesheet " + link.title);
235
+ link.disabled = true;
236
+ }
237
+ }
238
+ return sheet;
239
+ };