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.
- checksums.yaml +7 -0
- data/COPYING +0 -0
- data/LICENSE.txt +0 -0
- data/README.md +0 -0
- data/lib/novnc-rails.rb +8 -0
- data/lib/novnc-rails/version.rb +5 -0
- data/vendor/assets/javascripts/noVNC/Orbitron700.ttf +0 -0
- data/vendor/assets/javascripts/noVNC/Orbitron700.woff +0 -0
- data/vendor/assets/javascripts/noVNC/base.css +512 -0
- data/vendor/assets/javascripts/noVNC/base64.js +113 -0
- data/vendor/assets/javascripts/noVNC/black.css +71 -0
- data/vendor/assets/javascripts/noVNC/blue.css +64 -0
- data/vendor/assets/javascripts/noVNC/des.js +276 -0
- data/vendor/assets/javascripts/noVNC/display.js +751 -0
- data/vendor/assets/javascripts/noVNC/input.js +388 -0
- data/vendor/assets/javascripts/noVNC/jsunzip.js +676 -0
- data/vendor/assets/javascripts/noVNC/keyboard.js +543 -0
- data/vendor/assets/javascripts/noVNC/keysym.js +378 -0
- data/vendor/assets/javascripts/noVNC/keysymdef.js +15 -0
- data/vendor/assets/javascripts/noVNC/logo.js +1 -0
- data/vendor/assets/javascripts/noVNC/playback.js +102 -0
- data/vendor/assets/javascripts/noVNC/rfb.js +1889 -0
- data/vendor/assets/javascripts/noVNC/ui.js +979 -0
- data/vendor/assets/javascripts/noVNC/util.js +656 -0
- data/vendor/assets/javascripts/noVNC/web-socket-js/README.txt +109 -0
- data/vendor/assets/javascripts/noVNC/web-socket-js/WebSocketMain.swf +0 -0
- data/vendor/assets/javascripts/noVNC/web-socket-js/swfobject.js +4 -0
- data/vendor/assets/javascripts/noVNC/web-socket-js/web_socket.js +391 -0
- data/vendor/assets/javascripts/noVNC/websock.js +388 -0
- data/vendor/assets/javascripts/noVNC/webutil.js +239 -0
- 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
|
+
};
|