novnc-rails 0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
};
|