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,656 @@
|
|
1
|
+
/*
|
2
|
+
* noVNC: HTML5 VNC client
|
3
|
+
* Copyright (C) 2012 Joel Martin
|
4
|
+
* Licensed under MPL 2.0 (see LICENSE.txt)
|
5
|
+
*
|
6
|
+
* See README.md for usage and integration instructions.
|
7
|
+
*/
|
8
|
+
|
9
|
+
/* jshint white: false, nonstandard: true */
|
10
|
+
/*global window, console, document, navigator, ActiveXObject, INCLUDE_URI */
|
11
|
+
|
12
|
+
// Globals defined here
|
13
|
+
var Util = {};
|
14
|
+
|
15
|
+
|
16
|
+
/*
|
17
|
+
* Make arrays quack
|
18
|
+
*/
|
19
|
+
|
20
|
+
var addFunc = function (cl, name, func) {
|
21
|
+
if (!cl.prototype[name]) {
|
22
|
+
Object.defineProperty(cl.prototype, name, { enumerable: false, value: func });
|
23
|
+
}
|
24
|
+
};
|
25
|
+
|
26
|
+
addFunc(Array, 'push8', function (num) {
|
27
|
+
"use strict";
|
28
|
+
this.push(num & 0xFF);
|
29
|
+
});
|
30
|
+
|
31
|
+
addFunc(Array, 'push16', function (num) {
|
32
|
+
"use strict";
|
33
|
+
this.push((num >> 8) & 0xFF,
|
34
|
+
num & 0xFF);
|
35
|
+
});
|
36
|
+
|
37
|
+
addFunc(Array, 'push32', function (num) {
|
38
|
+
"use strict";
|
39
|
+
this.push((num >> 24) & 0xFF,
|
40
|
+
(num >> 16) & 0xFF,
|
41
|
+
(num >> 8) & 0xFF,
|
42
|
+
num & 0xFF);
|
43
|
+
});
|
44
|
+
|
45
|
+
// IE does not support map (even in IE9)
|
46
|
+
//This prototype is provided by the Mozilla foundation and
|
47
|
+
//is distributed under the MIT license.
|
48
|
+
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
|
49
|
+
addFunc(Array, 'map', function (fun /*, thisp*/) {
|
50
|
+
"use strict";
|
51
|
+
var len = this.length;
|
52
|
+
if (typeof fun != "function") {
|
53
|
+
throw new TypeError();
|
54
|
+
}
|
55
|
+
|
56
|
+
var res = new Array(len);
|
57
|
+
var thisp = arguments[1];
|
58
|
+
for (var i = 0; i < len; i++) {
|
59
|
+
if (i in this) {
|
60
|
+
res[i] = fun.call(thisp, this[i], i, this);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
return res;
|
65
|
+
});
|
66
|
+
|
67
|
+
// IE <9 does not support indexOf
|
68
|
+
//This prototype is provided by the Mozilla foundation and
|
69
|
+
//is distributed under the MIT license.
|
70
|
+
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
|
71
|
+
addFunc(Array, 'indexOf', function (elt /*, from*/) {
|
72
|
+
"use strict";
|
73
|
+
var len = this.length >>> 0;
|
74
|
+
|
75
|
+
var from = Number(arguments[1]) || 0;
|
76
|
+
from = (from < 0) ? Math.ceil(from) : Math.floor(from);
|
77
|
+
if (from < 0) {
|
78
|
+
from += len;
|
79
|
+
}
|
80
|
+
|
81
|
+
for (; from < len; from++) {
|
82
|
+
if (from in this &&
|
83
|
+
this[from] === elt) {
|
84
|
+
return from;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
return -1;
|
88
|
+
});
|
89
|
+
|
90
|
+
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
|
91
|
+
if (!Object.keys) {
|
92
|
+
Object.keys = (function () {
|
93
|
+
'use strict';
|
94
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty,
|
95
|
+
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
|
96
|
+
dontEnums = [
|
97
|
+
'toString',
|
98
|
+
'toLocaleString',
|
99
|
+
'valueOf',
|
100
|
+
'hasOwnProperty',
|
101
|
+
'isPrototypeOf',
|
102
|
+
'propertyIsEnumerable',
|
103
|
+
'constructor'
|
104
|
+
],
|
105
|
+
dontEnumsLength = dontEnums.length;
|
106
|
+
|
107
|
+
return function (obj) {
|
108
|
+
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
|
109
|
+
throw new TypeError('Object.keys called on non-object');
|
110
|
+
}
|
111
|
+
|
112
|
+
var result = [], prop, i;
|
113
|
+
|
114
|
+
for (prop in obj) {
|
115
|
+
if (hasOwnProperty.call(obj, prop)) {
|
116
|
+
result.push(prop);
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
if (hasDontEnumBug) {
|
121
|
+
for (i = 0; i < dontEnumsLength; i++) {
|
122
|
+
if (hasOwnProperty.call(obj, dontEnums[i])) {
|
123
|
+
result.push(dontEnums[i]);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
return result;
|
128
|
+
};
|
129
|
+
})();
|
130
|
+
}
|
131
|
+
|
132
|
+
// PhantomJS 1.x doesn't support bind,
|
133
|
+
// so leave this in until PhantomJS 2.0 is released
|
134
|
+
//This prototype is provided by the Mozilla foundation and
|
135
|
+
//is distributed under the MIT license.
|
136
|
+
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
|
137
|
+
addFunc(Function, 'bind', function (oThis) {
|
138
|
+
if (typeof this !== "function") {
|
139
|
+
// closest thing possible to the ECMAScript 5
|
140
|
+
// internal IsCallable function
|
141
|
+
throw new TypeError("Function.prototype.bind - " +
|
142
|
+
"what is trying to be bound is not callable");
|
143
|
+
}
|
144
|
+
|
145
|
+
var aArgs = Array.prototype.slice.call(arguments, 1),
|
146
|
+
fToBind = this,
|
147
|
+
fNOP = function () {},
|
148
|
+
fBound = function () {
|
149
|
+
return fToBind.apply(this instanceof fNOP && oThis ? this
|
150
|
+
: oThis,
|
151
|
+
aArgs.concat(Array.prototype.slice.call(arguments)));
|
152
|
+
};
|
153
|
+
|
154
|
+
fNOP.prototype = this.prototype;
|
155
|
+
fBound.prototype = new fNOP();
|
156
|
+
|
157
|
+
return fBound;
|
158
|
+
});
|
159
|
+
|
160
|
+
//
|
161
|
+
// requestAnimationFrame shim with setTimeout fallback
|
162
|
+
//
|
163
|
+
|
164
|
+
window.requestAnimFrame = (function () {
|
165
|
+
"use strict";
|
166
|
+
return window.requestAnimationFrame ||
|
167
|
+
window.webkitRequestAnimationFrame ||
|
168
|
+
window.mozRequestAnimationFrame ||
|
169
|
+
window.oRequestAnimationFrame ||
|
170
|
+
window.msRequestAnimationFrame ||
|
171
|
+
function (callback) {
|
172
|
+
window.setTimeout(callback, 1000 / 60);
|
173
|
+
};
|
174
|
+
})();
|
175
|
+
|
176
|
+
/*
|
177
|
+
* ------------------------------------------------------
|
178
|
+
* Namespaced in Util
|
179
|
+
* ------------------------------------------------------
|
180
|
+
*/
|
181
|
+
|
182
|
+
/*
|
183
|
+
* Logging/debug routines
|
184
|
+
*/
|
185
|
+
|
186
|
+
Util._log_level = 'warn';
|
187
|
+
Util.init_logging = function (level) {
|
188
|
+
"use strict";
|
189
|
+
if (typeof level === 'undefined') {
|
190
|
+
level = Util._log_level;
|
191
|
+
} else {
|
192
|
+
Util._log_level = level;
|
193
|
+
}
|
194
|
+
if (typeof window.console === "undefined") {
|
195
|
+
if (typeof window.opera !== "undefined") {
|
196
|
+
window.console = {
|
197
|
+
'log' : window.opera.postError,
|
198
|
+
'warn' : window.opera.postError,
|
199
|
+
'error': window.opera.postError
|
200
|
+
};
|
201
|
+
} else {
|
202
|
+
window.console = {
|
203
|
+
'log' : function (m) {},
|
204
|
+
'warn' : function (m) {},
|
205
|
+
'error': function (m) {}
|
206
|
+
};
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {};
|
211
|
+
/* jshint -W086 */
|
212
|
+
switch (level) {
|
213
|
+
case 'debug':
|
214
|
+
Util.Debug = function (msg) { console.log(msg); };
|
215
|
+
case 'info':
|
216
|
+
Util.Info = function (msg) { console.log(msg); };
|
217
|
+
case 'warn':
|
218
|
+
Util.Warn = function (msg) { console.warn(msg); };
|
219
|
+
case 'error':
|
220
|
+
Util.Error = function (msg) { console.error(msg); };
|
221
|
+
case 'none':
|
222
|
+
break;
|
223
|
+
default:
|
224
|
+
throw new Error("invalid logging type '" + level + "'");
|
225
|
+
}
|
226
|
+
/* jshint +W086 */
|
227
|
+
};
|
228
|
+
Util.get_logging = function () {
|
229
|
+
return Util._log_level;
|
230
|
+
};
|
231
|
+
// Initialize logging level
|
232
|
+
Util.init_logging();
|
233
|
+
|
234
|
+
Util.make_property = function (proto, name, mode, type) {
|
235
|
+
"use strict";
|
236
|
+
|
237
|
+
var getter;
|
238
|
+
if (type === 'arr') {
|
239
|
+
getter = function (idx) {
|
240
|
+
if (typeof idx !== 'undefined') {
|
241
|
+
return this['_' + name][idx];
|
242
|
+
} else {
|
243
|
+
return this['_' + name];
|
244
|
+
}
|
245
|
+
};
|
246
|
+
} else {
|
247
|
+
getter = function () {
|
248
|
+
return this['_' + name];
|
249
|
+
};
|
250
|
+
}
|
251
|
+
|
252
|
+
var make_setter = function (process_val) {
|
253
|
+
if (process_val) {
|
254
|
+
return function (val, idx) {
|
255
|
+
if (typeof idx !== 'undefined') {
|
256
|
+
this['_' + name][idx] = process_val(val);
|
257
|
+
} else {
|
258
|
+
this['_' + name] = process_val(val);
|
259
|
+
}
|
260
|
+
};
|
261
|
+
} else {
|
262
|
+
return function (val, idx) {
|
263
|
+
if (typeof idx !== 'undefined') {
|
264
|
+
this['_' + name][idx] = val;
|
265
|
+
} else {
|
266
|
+
this['_' + name] = val;
|
267
|
+
}
|
268
|
+
};
|
269
|
+
}
|
270
|
+
};
|
271
|
+
|
272
|
+
var setter;
|
273
|
+
if (type === 'bool') {
|
274
|
+
setter = make_setter(function (val) {
|
275
|
+
if (!val || (val in {'0': 1, 'no': 1, 'false': 1})) {
|
276
|
+
return false;
|
277
|
+
} else {
|
278
|
+
return true;
|
279
|
+
}
|
280
|
+
});
|
281
|
+
} else if (type === 'int') {
|
282
|
+
setter = make_setter(function (val) { return parseInt(val, 10); });
|
283
|
+
} else if (type === 'float') {
|
284
|
+
setter = make_setter(parseFloat);
|
285
|
+
} else if (type === 'str') {
|
286
|
+
setter = make_setter(String);
|
287
|
+
} else if (type === 'func') {
|
288
|
+
setter = make_setter(function (val) {
|
289
|
+
if (!val) {
|
290
|
+
return function () {};
|
291
|
+
} else {
|
292
|
+
return val;
|
293
|
+
}
|
294
|
+
});
|
295
|
+
} else if (type === 'arr' || type === 'dom' || type == 'raw') {
|
296
|
+
setter = make_setter();
|
297
|
+
} else {
|
298
|
+
throw new Error('Unknown property type ' + type); // some sanity checking
|
299
|
+
}
|
300
|
+
|
301
|
+
// set the getter
|
302
|
+
if (typeof proto['get_' + name] === 'undefined') {
|
303
|
+
proto['get_' + name] = getter;
|
304
|
+
}
|
305
|
+
|
306
|
+
// set the setter if needed
|
307
|
+
if (typeof proto['set_' + name] === 'undefined') {
|
308
|
+
if (mode === 'rw') {
|
309
|
+
proto['set_' + name] = setter;
|
310
|
+
} else if (mode === 'wo') {
|
311
|
+
proto['set_' + name] = function (val, idx) {
|
312
|
+
if (typeof this['_' + name] !== 'undefined') {
|
313
|
+
throw new Error(name + " can only be set once");
|
314
|
+
}
|
315
|
+
setter.call(this, val, idx);
|
316
|
+
};
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
// make a special setter that we can use in set defaults
|
321
|
+
proto['_raw_set_' + name] = function (val, idx) {
|
322
|
+
setter.call(this, val, idx);
|
323
|
+
//delete this['_init_set_' + name]; // remove it after use
|
324
|
+
};
|
325
|
+
};
|
326
|
+
|
327
|
+
Util.make_properties = function (constructor, arr) {
|
328
|
+
"use strict";
|
329
|
+
for (var i = 0; i < arr.length; i++) {
|
330
|
+
Util.make_property(constructor.prototype, arr[i][0], arr[i][1], arr[i][2]);
|
331
|
+
}
|
332
|
+
};
|
333
|
+
|
334
|
+
Util.set_defaults = function (obj, conf, defaults) {
|
335
|
+
var defaults_keys = Object.keys(defaults);
|
336
|
+
var conf_keys = Object.keys(conf);
|
337
|
+
var keys_obj = {};
|
338
|
+
var i;
|
339
|
+
for (i = 0; i < defaults_keys.length; i++) { keys_obj[defaults_keys[i]] = 1; }
|
340
|
+
for (i = 0; i < conf_keys.length; i++) { keys_obj[conf_keys[i]] = 1; }
|
341
|
+
var keys = Object.keys(keys_obj);
|
342
|
+
|
343
|
+
for (i = 0; i < keys.length; i++) {
|
344
|
+
var setter = obj['_raw_set_' + keys[i]];
|
345
|
+
if (!setter) {
|
346
|
+
Util.Warn('Invalid property ' + keys[i]);
|
347
|
+
continue;
|
348
|
+
}
|
349
|
+
|
350
|
+
if (keys[i] in conf) {
|
351
|
+
setter.call(obj, conf[keys[i]]);
|
352
|
+
} else {
|
353
|
+
setter.call(obj, defaults[keys[i]]);
|
354
|
+
}
|
355
|
+
}
|
356
|
+
};
|
357
|
+
|
358
|
+
/*
|
359
|
+
* Decode from UTF-8
|
360
|
+
*/
|
361
|
+
Util.decodeUTF8 = function (utf8string) {
|
362
|
+
"use strict";
|
363
|
+
return decodeURIComponent(escape(utf8string));
|
364
|
+
};
|
365
|
+
|
366
|
+
|
367
|
+
|
368
|
+
/*
|
369
|
+
* Cross-browser routines
|
370
|
+
*/
|
371
|
+
|
372
|
+
|
373
|
+
// Dynamically load scripts without using document.write()
|
374
|
+
// Reference: http://unixpapa.com/js/dyna.html
|
375
|
+
//
|
376
|
+
// Handles the case where load_scripts is invoked from a script that
|
377
|
+
// itself is loaded via load_scripts. Once all scripts are loaded the
|
378
|
+
// window.onscriptsloaded handler is called (if set).
|
379
|
+
Util.get_include_uri = function () {
|
380
|
+
return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI : "include/";
|
381
|
+
};
|
382
|
+
Util._loading_scripts = [];
|
383
|
+
Util._pending_scripts = [];
|
384
|
+
Util.load_scripts = function (files) {
|
385
|
+
"use strict";
|
386
|
+
var head = document.getElementsByTagName('head')[0], script,
|
387
|
+
ls = Util._loading_scripts, ps = Util._pending_scripts;
|
388
|
+
|
389
|
+
var loadFunc = function (e) {
|
390
|
+
while (ls.length > 0 && (ls[0].readyState === 'loaded' ||
|
391
|
+
ls[0].readyState === 'complete')) {
|
392
|
+
// For IE, append the script to trigger execution
|
393
|
+
var s = ls.shift();
|
394
|
+
//console.log("loaded script: " + s.src);
|
395
|
+
head.appendChild(s);
|
396
|
+
}
|
397
|
+
if (!this.readyState ||
|
398
|
+
(Util.Engine.presto && this.readyState === 'loaded') ||
|
399
|
+
this.readyState === 'complete') {
|
400
|
+
if (ps.indexOf(this) >= 0) {
|
401
|
+
this.onload = this.onreadystatechange = null;
|
402
|
+
//console.log("completed script: " + this.src);
|
403
|
+
ps.splice(ps.indexOf(this), 1);
|
404
|
+
|
405
|
+
// Call window.onscriptsload after last script loads
|
406
|
+
if (ps.length === 0 && window.onscriptsload) {
|
407
|
+
window.onscriptsload();
|
408
|
+
}
|
409
|
+
}
|
410
|
+
}
|
411
|
+
};
|
412
|
+
|
413
|
+
for (var f = 0; f < files.length; f++) {
|
414
|
+
script = document.createElement('script');
|
415
|
+
script.type = 'text/javascript';
|
416
|
+
script.src = Util.get_include_uri() + files[f];
|
417
|
+
//console.log("loading script: " + script.src);
|
418
|
+
script.onload = script.onreadystatechange = loadFunc;
|
419
|
+
// In-order script execution tricks
|
420
|
+
if (Util.Engine.trident) {
|
421
|
+
// For IE wait until readyState is 'loaded' before
|
422
|
+
// appending it which will trigger execution
|
423
|
+
// http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
|
424
|
+
ls.push(script);
|
425
|
+
} else {
|
426
|
+
// For webkit and firefox set async=false and append now
|
427
|
+
// https://developer.mozilla.org/en-US/docs/HTML/Element/script
|
428
|
+
script.async = false;
|
429
|
+
head.appendChild(script);
|
430
|
+
}
|
431
|
+
ps.push(script);
|
432
|
+
}
|
433
|
+
};
|
434
|
+
|
435
|
+
|
436
|
+
// Get DOM element position on page
|
437
|
+
// This solution is based based on http://www.greywyvern.com/?post=331
|
438
|
+
// Thanks to Brian Huisman AKA GreyWyvern!
|
439
|
+
Util.getPosition = (function () {
|
440
|
+
"use strict";
|
441
|
+
function getStyle(obj, styleProp) {
|
442
|
+
var y;
|
443
|
+
if (obj.currentStyle) {
|
444
|
+
y = obj.currentStyle[styleProp];
|
445
|
+
} else if (window.getComputedStyle)
|
446
|
+
y = window.getComputedStyle(obj, null)[styleProp];
|
447
|
+
return y;
|
448
|
+
}
|
449
|
+
|
450
|
+
function scrollDist() {
|
451
|
+
var myScrollTop = 0, myScrollLeft = 0;
|
452
|
+
var html = document.getElementsByTagName('html')[0];
|
453
|
+
|
454
|
+
// get the scrollTop part
|
455
|
+
if (html.scrollTop && document.documentElement.scrollTop) {
|
456
|
+
myScrollTop = html.scrollTop;
|
457
|
+
} else if (html.scrollTop || document.documentElement.scrollTop) {
|
458
|
+
myScrollTop = html.scrollTop + document.documentElement.scrollTop;
|
459
|
+
} else if (document.body.scrollTop) {
|
460
|
+
myScrollTop = document.body.scrollTop;
|
461
|
+
} else {
|
462
|
+
myScrollTop = 0;
|
463
|
+
}
|
464
|
+
|
465
|
+
// get the scrollLeft part
|
466
|
+
if (html.scrollLeft && document.documentElement.scrollLeft) {
|
467
|
+
myScrollLeft = html.scrollLeft;
|
468
|
+
} else if (html.scrollLeft || document.documentElement.scrollLeft) {
|
469
|
+
myScrollLeft = html.scrollLeft + document.documentElement.scrollLeft;
|
470
|
+
} else if (document.body.scrollLeft) {
|
471
|
+
myScrollLeft = document.body.scrollLeft;
|
472
|
+
} else {
|
473
|
+
myScrollLeft = 0;
|
474
|
+
}
|
475
|
+
|
476
|
+
return [myScrollLeft, myScrollTop];
|
477
|
+
}
|
478
|
+
|
479
|
+
return function (obj) {
|
480
|
+
var curleft = 0, curtop = 0, scr = obj, fixed = false;
|
481
|
+
while ((scr = scr.parentNode) && scr != document.body) {
|
482
|
+
curleft -= scr.scrollLeft || 0;
|
483
|
+
curtop -= scr.scrollTop || 0;
|
484
|
+
if (getStyle(scr, "position") == "fixed") {
|
485
|
+
fixed = true;
|
486
|
+
}
|
487
|
+
}
|
488
|
+
if (fixed && !window.opera) {
|
489
|
+
var scrDist = scrollDist();
|
490
|
+
curleft += scrDist[0];
|
491
|
+
curtop += scrDist[1];
|
492
|
+
}
|
493
|
+
|
494
|
+
do {
|
495
|
+
curleft += obj.offsetLeft;
|
496
|
+
curtop += obj.offsetTop;
|
497
|
+
} while ((obj = obj.offsetParent));
|
498
|
+
|
499
|
+
return {'x': curleft, 'y': curtop};
|
500
|
+
};
|
501
|
+
})();
|
502
|
+
|
503
|
+
|
504
|
+
// Get mouse event position in DOM element
|
505
|
+
Util.getEventPosition = function (e, obj, scale) {
|
506
|
+
"use strict";
|
507
|
+
var evt, docX, docY, pos;
|
508
|
+
//if (!e) evt = window.event;
|
509
|
+
evt = (e ? e : window.event);
|
510
|
+
evt = (evt.changedTouches ? evt.changedTouches[0] : evt.touches ? evt.touches[0] : evt);
|
511
|
+
if (evt.pageX || evt.pageY) {
|
512
|
+
docX = evt.pageX;
|
513
|
+
docY = evt.pageY;
|
514
|
+
} else if (evt.clientX || evt.clientY) {
|
515
|
+
docX = evt.clientX + document.body.scrollLeft +
|
516
|
+
document.documentElement.scrollLeft;
|
517
|
+
docY = evt.clientY + document.body.scrollTop +
|
518
|
+
document.documentElement.scrollTop;
|
519
|
+
}
|
520
|
+
pos = Util.getPosition(obj);
|
521
|
+
if (typeof scale === "undefined") {
|
522
|
+
scale = 1;
|
523
|
+
}
|
524
|
+
var realx = docX - pos.x;
|
525
|
+
var realy = docY - pos.y;
|
526
|
+
var x = Math.max(Math.min(realx, obj.width - 1), 0);
|
527
|
+
var y = Math.max(Math.min(realy, obj.height - 1), 0);
|
528
|
+
return {'x': x / scale, 'y': y / scale, 'realx': realx / scale, 'realy': realy / scale};
|
529
|
+
};
|
530
|
+
|
531
|
+
|
532
|
+
// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events
|
533
|
+
Util.addEvent = function (obj, evType, fn) {
|
534
|
+
"use strict";
|
535
|
+
if (obj.attachEvent) {
|
536
|
+
var r = obj.attachEvent("on" + evType, fn);
|
537
|
+
return r;
|
538
|
+
} else if (obj.addEventListener) {
|
539
|
+
obj.addEventListener(evType, fn, false);
|
540
|
+
return true;
|
541
|
+
} else {
|
542
|
+
throw new Error("Handler could not be attached");
|
543
|
+
}
|
544
|
+
};
|
545
|
+
|
546
|
+
Util.removeEvent = function (obj, evType, fn) {
|
547
|
+
"use strict";
|
548
|
+
if (obj.detachEvent) {
|
549
|
+
var r = obj.detachEvent("on" + evType, fn);
|
550
|
+
return r;
|
551
|
+
} else if (obj.removeEventListener) {
|
552
|
+
obj.removeEventListener(evType, fn, false);
|
553
|
+
return true;
|
554
|
+
} else {
|
555
|
+
throw new Error("Handler could not be removed");
|
556
|
+
}
|
557
|
+
};
|
558
|
+
|
559
|
+
Util.stopEvent = function (e) {
|
560
|
+
"use strict";
|
561
|
+
if (e.stopPropagation) { e.stopPropagation(); }
|
562
|
+
else { e.cancelBubble = true; }
|
563
|
+
|
564
|
+
if (e.preventDefault) { e.preventDefault(); }
|
565
|
+
else { e.returnValue = false; }
|
566
|
+
};
|
567
|
+
|
568
|
+
|
569
|
+
// Set browser engine versions. Based on mootools.
|
570
|
+
Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)};
|
571
|
+
|
572
|
+
(function () {
|
573
|
+
"use strict";
|
574
|
+
// 'presto': (function () { return (!window.opera) ? false : true; }()),
|
575
|
+
var detectPresto = function () {
|
576
|
+
return !!window.opera;
|
577
|
+
};
|
578
|
+
|
579
|
+
// 'trident': (function () { return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4);
|
580
|
+
var detectTrident = function () {
|
581
|
+
if (!window.ActiveXObject) {
|
582
|
+
return false;
|
583
|
+
} else {
|
584
|
+
if (window.XMLHttpRequest) {
|
585
|
+
return (document.querySelectorAll) ? 6 : 5;
|
586
|
+
} else {
|
587
|
+
return 4;
|
588
|
+
}
|
589
|
+
}
|
590
|
+
};
|
591
|
+
|
592
|
+
// 'webkit': (function () { try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()),
|
593
|
+
var detectInitialWebkit = function () {
|
594
|
+
try {
|
595
|
+
if (navigator.taintEnabled) {
|
596
|
+
return false;
|
597
|
+
} else {
|
598
|
+
if (Util.Features.xpath) {
|
599
|
+
return (Util.Features.query) ? 525 : 420;
|
600
|
+
} else {
|
601
|
+
return 419;
|
602
|
+
}
|
603
|
+
}
|
604
|
+
} catch (e) {
|
605
|
+
return false;
|
606
|
+
}
|
607
|
+
};
|
608
|
+
|
609
|
+
var detectActualWebkit = function (initial_ver) {
|
610
|
+
var re = /WebKit\/([0-9\.]*) /;
|
611
|
+
var str_ver = (navigator.userAgent.match(re) || ['', initial_ver])[1];
|
612
|
+
return parseFloat(str_ver, 10);
|
613
|
+
};
|
614
|
+
|
615
|
+
// 'gecko': (function () { return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19ssName) ? 19 : 18 : 18); }())
|
616
|
+
var detectGecko = function () {
|
617
|
+
/* jshint -W041 */
|
618
|
+
if (!document.getBoxObjectFor && window.mozInnerScreenX == null) {
|
619
|
+
return false;
|
620
|
+
} else {
|
621
|
+
return (document.getElementsByClassName) ? 19 : 18;
|
622
|
+
}
|
623
|
+
/* jshint +W041 */
|
624
|
+
};
|
625
|
+
|
626
|
+
Util.Engine = {
|
627
|
+
// Version detection break in Opera 11.60 (errors on arguments.callee.caller reference)
|
628
|
+
//'presto': (function() {
|
629
|
+
// return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()),
|
630
|
+
'presto': detectPresto(),
|
631
|
+
'trident': detectTrident(),
|
632
|
+
'webkit': detectInitialWebkit(),
|
633
|
+
'gecko': detectGecko(),
|
634
|
+
};
|
635
|
+
|
636
|
+
if (Util.Engine.webkit) {
|
637
|
+
// Extract actual webkit version if available
|
638
|
+
Util.Engine.webkit = detectActualWebkit(Util.Engine.webkit);
|
639
|
+
}
|
640
|
+
})();
|
641
|
+
|
642
|
+
Util.Flash = (function () {
|
643
|
+
"use strict";
|
644
|
+
var v, version;
|
645
|
+
try {
|
646
|
+
v = navigator.plugins['Shockwave Flash'].description;
|
647
|
+
} catch (err1) {
|
648
|
+
try {
|
649
|
+
v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
|
650
|
+
} catch (err2) {
|
651
|
+
v = '0 r0';
|
652
|
+
}
|
653
|
+
}
|
654
|
+
version = v.match(/\d+/g);
|
655
|
+
return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
|
656
|
+
}());
|