1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * noVNC: HTML5 VNC client
3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Copyright (C) 2011 Joel Martin
4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Licensed under LGPL-3 (see LICENSE.txt)
5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * See README.md for usage and integration instructions.
7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat"use strict";
10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*jslint bitwise: false, white: false */
11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*global window, console, document, navigator, ActiveXObject */
12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat// Globals defined here
14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvar Util = {};
15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Make arrays quack
19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatArray.prototype.push8 = function (num) {
22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    this.push(num & 0xFF);
23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatArray.prototype.push16 = function (num) {
26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    this.push((num >> 8) & 0xFF,
27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              (num     ) & 0xFF  );
28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatArray.prototype.push32 = function (num) {
30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    this.push((num >> 24) & 0xFF,
31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              (num >> 16) & 0xFF,
32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              (num >>  8) & 0xFF,
33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              (num      ) & 0xFF  );
34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat// IE does not support map (even in IE9)
37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat//This prototype is provided by the Mozilla foundation and
38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat//is distributed under the MIT license.
39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (!Array.prototype.map)
41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  Array.prototype.map = function(fun /*, thisp*/)
43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    var len = this.length;
45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (typeof fun != "function")
46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      throw new TypeError();
47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    var res = new Array(len);
49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    var thisp = arguments[1];
50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    for (var i = 0; i < len; i++)
51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (i in this)
53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        res[i] = fun.call(thisp, this[i], i, this);
54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return res;
57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  };
58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ------------------------------------------------------
62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Namespaced in Util
63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ------------------------------------------------------
64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Logging/debug routines
68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil._log_level = 'warn';
71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.init_logging = function (level) {
72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (typeof level === 'undefined') {
73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        level = Util._log_level;
74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else {
75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        Util._log_level = level;
76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (typeof window.console === "undefined") {
78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (typeof window.opera !== "undefined") {
79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            window.console = {
80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                'log'  : window.opera.postError,
81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                'warn' : window.opera.postError,
82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                'error': window.opera.postError };
83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } else {
84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            window.console = {
85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                'log'  : function(m) {},
86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                'warn' : function(m) {},
87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                'error': function(m) {}};
88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {};
92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    switch (level) {
93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 'debug': Util.Debug = function (msg) { console.log(msg); };
94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 'info':  Util.Info  = function (msg) { console.log(msg); };
95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 'warn':  Util.Warn  = function (msg) { console.warn(msg); };
96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 'error': Util.Error = function (msg) { console.error(msg); };
97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 'none':
98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            break;
99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        default:
100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            throw("invalid logging type '" + level + "'");
101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.get_logging = function () {
104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return Util._log_level;
105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat// Initialize logging level
107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.init_logging();
108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat// Set configuration default for Crockford style function namespaces
111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.conf_default = function(cfg, api, defaults, v, mode, type, defval, desc) {
112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    var getter, setter;
113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Default getter function
115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    getter = function (idx) {
116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if ((type in {'arr':1, 'array':1}) &&
117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            (typeof idx !== 'undefined')) {
118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return cfg[v][idx];
119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } else {
120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return cfg[v];
121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    };
123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Default setter function
125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    setter = function (val, idx) {
126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (type in {'boolean':1, 'bool':1}) {
127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            if ((!val) || (val in {'0':1, 'no':1, 'false':1})) {
128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                val = false;
129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            } else {
130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                val = true;
131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            }
132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } else if (type in {'integer':1, 'int':1}) {
133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            val = parseInt(val, 10);
134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } else if (type === 'func') {
135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            if (!val) {
136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                val = function () {};
137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            }
138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (typeof idx !== 'undefined') {
140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            cfg[v][idx] = val;
141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } else {
142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            cfg[v] = val;
143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    };
145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Set the description
147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    api[v + '_description'] = desc;
148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Set the getter function
150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (typeof api['get_' + v] === 'undefined') {
151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        api['get_' + v] = getter;
152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Set the setter function with extra sanity checks
155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (typeof api['set_' + v] === 'undefined') {
156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        api['set_' + v] = function (val, idx) {
157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            if (mode in {'RO':1, 'ro':1}) {
158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                throw(v + " is read-only");
159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            } else if ((mode in {'WO':1, 'wo':1}) &&
160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                       (typeof cfg[v] !== 'undefined')) {
161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                throw(v + " can only be set once");
162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            }
163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            setter(val, idx);
164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        };
165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Set the default value
168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (typeof defaults[v] !== 'undefined') {
169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        defval = defaults[v];
170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else if ((type in {'arr':1, 'array':1}) &&
171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            (! (defval instanceof Array))) {
172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        defval = [];
173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Coerce existing setting to the right type
175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    //Util.Debug("v: " + v + ", defval: " + defval + ", defaults[v]: " + defaults[v]);
176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    setter(defval);
177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat// Set group of configuration defaults
180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.conf_defaults = function(cfg, api, defaults, arr) {
181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    var i;
182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    for (i = 0; i < arr.length; i++) {
183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        Util.conf_default(cfg, api, defaults, arr[i][0], arr[i][1],
184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                arr[i][2], arr[i][3], arr[i][4]);
185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Cross-browser routines
191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat// Get DOM element position on page
194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.getPosition = function (obj) {
195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    var x = 0, y = 0;
196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (obj.offsetParent) {
197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        do {
198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            x += obj.offsetLeft;
199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            y += obj.offsetTop;
200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            obj = obj.offsetParent;
201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } while (obj);
202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return {'x': x, 'y': y};
204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat// Get mouse event position in DOM element
207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.getEventPosition = function (e, obj, scale) {
208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    var evt, docX, docY, pos;
209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    //if (!e) evt = window.event;
210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    evt = (e ? e : window.event);
211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    evt = (evt.changedTouches ? evt.changedTouches[0] : evt.touches ? evt.touches[0] : evt);
212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (evt.pageX || evt.pageY) {
213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        docX = evt.pageX;
214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        docY = evt.pageY;
215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else if (evt.clientX || evt.clientY) {
216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        docX = evt.clientX + document.body.scrollLeft +
217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            document.documentElement.scrollLeft;
218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        docY = evt.clientY + document.body.scrollTop +
219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            document.documentElement.scrollTop;
220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    pos = Util.getPosition(obj);
222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (typeof scale === "undefined") {
223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        scale = 1;
224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale};
226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events
230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.addEvent = function (obj, evType, fn){
231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (obj.attachEvent){
232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        var r = obj.attachEvent("on"+evType, fn);
233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return r;
234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else if (obj.addEventListener){
235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        obj.addEventListener(evType, fn, false);
236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return true;
237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else {
238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        throw("Handler could not be attached");
239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.removeEvent = function(obj, evType, fn){
243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (obj.detachEvent){
244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        var r = obj.detachEvent("on"+evType, fn);
245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return r;
246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else if (obj.removeEventListener){
247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        obj.removeEventListener(evType, fn, false);
248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return true;
249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else {
250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        throw("Handler could not be removed");
251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.stopEvent = function(e) {
255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (e.stopPropagation) { e.stopPropagation(); }
256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    else                   { e.cancelBubble = true; }
257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (e.preventDefault)  { e.preventDefault(); }
259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    else                   { e.returnValue = false; }
260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat// Set browser engine versions. Based on mootools.
264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)};
265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.Engine = {
267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Version detection break in Opera 11.60 (errors on arguments.callee.caller reference)
268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    //'presto': (function() {
269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    //         return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()),
270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    'presto': (function() { return (!window.opera) ? false : true; }()),
271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    'trident': (function() {
273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }()),
274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    'webkit': (function() {
275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()),
276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    //'webkit': (function() {
277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    //        return ((typeof navigator.taintEnabled !== "unknown") && navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); }()),
278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    'gecko': (function() {
279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }())
280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (Util.Engine.webkit) {
282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    // Extract actual webkit version if available
283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    Util.Engine.webkit = (function(v) {
284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            var re = new RegExp('WebKit/([0-9\.]*) ');
285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            v = (navigator.userAgent.match(re) || ['', v])[1];
286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return parseFloat(v, 10);
287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        })(Util.Engine.webkit);
288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatUtil.Flash = (function(){
291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    var v, version;
292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    try {
293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        v = navigator.plugins['Shockwave Flash'].description;
294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } catch(err1) {
295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        try {
296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } catch(err2) {
298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            v = '0 r0';
299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    version = v.match(/\d+/g);
302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}());
304