123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- /*
- * noVNC: HTML5 VNC client
- * Copyright (C) 2010 Joel Martin
- * Licensed under LGPL-3 (see LICENSE.LGPL-3)
- *
- * See README.md for usage and integration instructions.
- */
- "use strict";
- /*jslint bitwise: false, white: false */
- /*global window, document, navigator, ActiveXObject*/
- // Globals defined here
- var Util = {}, $;
- /*
- * Logging/debug routines
- */
- Util.init_logging = function (level) {
- if (typeof window.console === "undefined") {
- if (typeof window.opera !== "undefined") {
- window.console = {
- 'log' : window.opera.postError,
- 'warn' : window.opera.postError,
- 'error': window.opera.postError };
- } else {
- window.console = {
- 'log' : function(m) {},
- 'warn' : function(m) {},
- 'error': function(m) {}};
- }
- }
- Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {};
- switch (level) {
- case 'debug': Util.Debug = function (msg) { console.log(msg); };
- case 'info': Util.Info = function (msg) { console.log(msg); };
- case 'warn': Util.Warn = function (msg) { console.warn(msg); };
- case 'error': Util.Error = function (msg) { console.error(msg); };
- break;
- default:
- throw("invalid logging type '" + level + "'");
- }
- }
- // Initialize logging level
- Util.init_logging( (document.location.href.match(
- /logging=([A-Za-z0-9\._\-]*)/) ||
- ['', 'warn'])[1] );
- /*
- * Simple DOM selector by ID
- */
- if (!window.$) {
- $ = function (id) {
- if (document.getElementById) {
- return document.getElementById(id);
- } else if (document.all) {
- return document.all[id];
- } else if (document.layers) {
- return document.layers[id];
- }
- return undefined;
- };
- }
- /*
- * Make arrays quack
- */
- Array.prototype.shift8 = function () {
- return this.shift();
- };
- Array.prototype.push8 = function (num) {
- this.push(num & 0xFF);
- };
- Array.prototype.shift16 = function () {
- return (this.shift() << 8) +
- (this.shift() );
- };
- Array.prototype.push16 = function (num) {
- this.push((num >> 8) & 0xFF,
- (num ) & 0xFF );
- };
- Array.prototype.push16le = function (num) {
- this.push((num ) & 0xFF,
- (num >> 8) & 0xFF );
- };
- Array.prototype.shift32 = function () {
- return (this.shift() << 24) +
- (this.shift() << 16) +
- (this.shift() << 8) +
- (this.shift() );
- };
- Array.prototype.get32 = function (off) {
- return (this[off ] << 24) +
- (this[off + 1] << 16) +
- (this[off + 2] << 8) +
- (this[off + 3] );
- };
- Array.prototype.push32 = function (num) {
- this.push((num >> 24) & 0xFF,
- (num >> 16) & 0xFF,
- (num >> 8) & 0xFF,
- (num ) & 0xFF );
- };
- Array.prototype.push32le = function (num) {
- this.push((num ) & 0xFF,
- (num >> 8) & 0xFF,
- (num >> 16) & 0xFF,
- (num >> 24) & 0xFF );
- };
- Array.prototype.shiftStr = function (len) {
- var arr = this.splice(0, len);
- return arr.map(function (num) {
- return String.fromCharCode(num); } ).join('');
- };
- Array.prototype.pushStr = function (str) {
- var i, n = str.length;
- for (i=0; i < n; i+=1) {
- this.push(str.charCodeAt(i));
- }
- };
- Array.prototype.shiftBytes = function (len) {
- return this.splice(0, len);
- };
- /*
- * ------------------------------------------------------
- * Namespaced in Util
- * ------------------------------------------------------
- */
- Util.dirObj = function (obj, depth, parent) {
- var i, msg = "", val = "";
- if (! depth) { depth=2; }
- if (! parent) { parent= ""; }
- // Print the properties of the passed-in object
- for (i in obj) {
- if ((depth > 1) && (typeof obj[i] === "object")) {
- // Recurse attributes that are objects
- msg += Util.dirObj(obj[i], depth-1, parent + "." + i);
- } else {
- //val = new String(obj[i]).replace("\n", " ");
- val = obj[i].toString().replace("\n", " ");
- if (val.length > 30) {
- val = val.substr(0,30) + "...";
- }
- msg += parent + "." + i + ": " + val + "\n";
- }
- }
- return msg;
- };
- /*
- * Cross-browser routines
- */
- // Get DOM element position on page
- Util.getPosition = function (obj) {
- var x = 0, y = 0;
- if (obj.offsetParent) {
- do {
- x += obj.offsetLeft;
- y += obj.offsetTop;
- obj = obj.offsetParent;
- } while (obj);
- }
- return {'x': x, 'y': y};
- };
- // Get mouse event position in DOM element
- Util.getEventPosition = function (e, obj) {
- var evt, docX, docY, pos;
- //if (!e) evt = window.event;
- evt = (e ? e : window.event);
- if (evt.pageX || evt.pageY) {
- docX = evt.pageX;
- docY = evt.pageY;
- } else if (evt.clientX || evt.clientY) {
- docX = evt.clientX + document.body.scrollLeft +
- document.documentElement.scrollLeft;
- docY = evt.clientY + document.body.scrollTop +
- document.documentElement.scrollTop;
- }
- pos = Util.getPosition(obj);
- return {'x': docX - pos.x, 'y': docY - pos.y};
- };
- // Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events
- Util.addEvent = function (obj, evType, fn){
- if (obj.attachEvent){
- var r = obj.attachEvent("on"+evType, fn);
- return r;
- } else if (obj.addEventListener){
- obj.addEventListener(evType, fn, false);
- return true;
- } else {
- throw("Handler could not be attached");
- }
- };
- Util.removeEvent = function(obj, evType, fn){
- if (obj.detachEvent){
- var r = obj.detachEvent("on"+evType, fn);
- return r;
- } else if (obj.removeEventListener){
- obj.removeEventListener(evType, fn, false);
- return true;
- } else {
- throw("Handler could not be removed");
- }
- };
- Util.stopEvent = function(e) {
- if (e.stopPropagation) { e.stopPropagation(); }
- else { e.cancelBubble = true; }
- if (e.preventDefault) { e.preventDefault(); }
- else { e.returnValue = false; }
- };
- // Set browser engine versions. Based on mootools.
- Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)};
- Util.Engine = {
- 'presto': (function() {
- return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()),
- 'trident': (function() {
- return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }()),
- 'webkit': (function() {
- try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()),
- //'webkit': (function() {
- // return ((typeof navigator.taintEnabled !== "unknown") && navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); }()),
- 'gecko': (function() {
- return (!document.getBoxObjectFor && !window.mozInnerScreenX) ? false : ((document.getElementsByClassName) ? 19 : 18); }())
- };
- Util.Flash = (function(){
- var v, version;
- try {
- v = navigator.plugins['Shockwave Flash'].description;
- } catch(err1) {
- try {
- v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
- } catch(err2) {
- v = '0 r0';
- }
- }
- version = v.match(/\d+/g);
- return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
- }());
- /*
- * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
- */
- // No days means only for this browser session
- Util.createCookie = function(name,value,days) {
- if (days) {
- var date = new Date();
- date.setTime(date.getTime()+(days*24*60*60*1000));
- var expires = "; expires="+date.toGMTString();
- }
- else var expires = "";
- document.cookie = name+"="+value+expires+"; path=/";
- };
- Util.readCookie = function(name, defaultValue) {
- var nameEQ = name + "=";
- var ca = document.cookie.split(';');
- for(var i=0;i < ca.length;i++) {
- var c = ca[i];
- while (c.charAt(0)==' ') c = c.substring(1,c.length);
- if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
- }
- return (typeof defaultValue !== 'undefined') ? defaultValue : null;
- };
- Util.eraseCookie = function(name) {
- createCookie(name,"",-1);
- };
- /*
- * Alternate stylesheet selection
- */
- Util.getStylesheets = function() { var i, links, sheets = [];
- links = document.getElementsByTagName("link")
- for (i = 0; i < links.length; i++) {
- if (links[i].title &&
- links[i].rel.toUpperCase().indexOf("STYLESHEET") > -1) {
- sheets.push(links[i]);
- }
- }
- return sheets;
- };
- // No sheet means try and use value from cookie, null sheet used to
- // clear all alternates.
- Util.selectStylesheet = function(sheet) {
- var i, link, sheets = Util.getStylesheets();
- if (typeof sheet === 'undefined') {
- sheet = 'default';
- }
- for (i=0; i < sheets.length; i++) {
- link = sheets[i];
- if (link.title === sheet) {
- Util.Debug("Using stylesheet " + sheet);
- link.disabled = false;
- } else {
- Util.Debug("Skipping stylesheet " + link.title);
- link.disabled = true;
- }
- }
- return sheet;
- };
- // call once to disable alternates and get around webkit bug
- Util.selectStylesheet(null);
|