]>
Commit | Line | Data |
---|---|---|
61dd52c9 | 1 | /* |
15046f00 JM |
2 | * noVNC: HTML5 VNC client |
3 | * Copyright (C) 2010 Joel Martin | |
5f409eee | 4 | * Licensed under LGPL-3 (see LICENSE.txt) |
15046f00 JM |
5 | * |
6 | * See README.md for usage and integration instructions. | |
61dd52c9 JM |
7 | */ |
8 | ||
15046f00 JM |
9 | "use strict"; |
10 | /*jslint bitwise: false, white: false */ | |
a7a89626 | 11 | /*global window, console, document, navigator, ActiveXObject*/ |
61dd52c9 | 12 | |
15046f00 JM |
13 | // Globals defined here |
14 | var Util = {}, $; | |
15 | ||
81e5adaf | 16 | |
da6dd893 JM |
17 | /* |
18 | * Simple DOM selector by ID | |
19 | */ | |
15046f00 JM |
20 | if (!window.$) { |
21 | $ = function (id) { | |
22 | if (document.getElementById) { | |
23 | return document.getElementById(id); | |
24 | } else if (document.all) { | |
25 | return document.all[id]; | |
26 | } else if (document.layers) { | |
27 | return document.layers[id]; | |
28 | } | |
29 | return undefined; | |
30 | }; | |
31 | } | |
56ec48be JM |
32 | |
33 | /* | |
34 | * Make arrays quack | |
35 | */ | |
36 | ||
56ec48be JM |
37 | Array.prototype.push8 = function (num) { |
38 | this.push(num & 0xFF); | |
39 | }; | |
40 | ||
56ec48be JM |
41 | Array.prototype.push16 = function (num) { |
42 | this.push((num >> 8) & 0xFF, | |
43 | (num ) & 0xFF ); | |
44 | }; | |
56ec48be JM |
45 | Array.prototype.push32 = function (num) { |
46 | this.push((num >> 24) & 0xFF, | |
47 | (num >> 16) & 0xFF, | |
48 | (num >> 8) & 0xFF, | |
49 | (num ) & 0xFF ); | |
50 | }; | |
56ec48be | 51 | |
15046f00 JM |
52 | /* |
53 | * ------------------------------------------------------ | |
54 | * Namespaced in Util | |
55 | * ------------------------------------------------------ | |
56 | */ | |
57 | ||
8db09746 JM |
58 | /* |
59 | * Logging/debug routines | |
60 | */ | |
61 | ||
c1eba48f | 62 | Util._log_level = 'warn'; |
8db09746 | 63 | Util.init_logging = function (level) { |
c1eba48f | 64 | if (typeof level === 'undefined') { |
c1eba48f JM |
65 | level = Util._log_level; |
66 | } else { | |
67 | Util._log_level = level; | |
68 | } | |
8db09746 JM |
69 | if (typeof window.console === "undefined") { |
70 | if (typeof window.opera !== "undefined") { | |
71 | window.console = { | |
72 | 'log' : window.opera.postError, | |
73 | 'warn' : window.opera.postError, | |
74 | 'error': window.opera.postError }; | |
75 | } else { | |
76 | window.console = { | |
77 | 'log' : function(m) {}, | |
78 | 'warn' : function(m) {}, | |
79 | 'error': function(m) {}}; | |
80 | } | |
81 | } | |
82 | ||
83 | Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {}; | |
84 | switch (level) { | |
85 | case 'debug': Util.Debug = function (msg) { console.log(msg); }; | |
86 | case 'info': Util.Info = function (msg) { console.log(msg); }; | |
87 | case 'warn': Util.Warn = function (msg) { console.warn(msg); }; | |
88 | case 'error': Util.Error = function (msg) { console.error(msg); }; | |
89 | case 'none': | |
90 | break; | |
91 | default: | |
92 | throw("invalid logging type '" + level + "'"); | |
93 | } | |
94 | }; | |
c1eba48f | 95 | Util.get_logging = function () { |
8d5d2c82 AM |
96 | return Util._log_level; |
97 | } | |
8db09746 | 98 | // Initialize logging level |
c1eba48f | 99 | Util.init_logging(); |
8db09746 | 100 | |
a8edf9d8 | 101 | |
125d8bbb | 102 | // Set defaults for Crockford style function namespaces |
ff36b127 JM |
103 | Util.conf_default = function(cfg, api, v, type, defval, desc) { |
104 | // Description | |
105 | api['get_' + v + '_desc'] = desc; | |
125d8bbb JM |
106 | // Default getter |
107 | if (typeof api['get_' + v] === 'undefined') { | |
108 | api['get_' + v] = function () { | |
109 | return cfg[v]; | |
110 | }; | |
111 | } | |
112 | // Default setter | |
113 | if (typeof api['set_' + v] === 'undefined') { | |
114 | api['set_' + v] = function (val) { | |
ff36b127 | 115 | if (type in {'boolean':1, 'bool':1}) { |
8db09746 JM |
116 | if ((!val) || (val in {'0':1, 'no':1, 'false':1})) { |
117 | val = false; | |
118 | } else { | |
119 | val = true; | |
120 | } | |
ff36b127 JM |
121 | } else if (type in {'integer':1, 'int':1}) { |
122 | val = parseInt(val, 10); | |
8db09746 | 123 | } |
125d8bbb JM |
124 | cfg[v] = val; |
125 | }; | |
126 | } | |
ff36b127 JM |
127 | |
128 | if (typeof cfg[v] === 'undefined') { | |
129 | // Set to default | |
130 | api['set_' + v](defval); | |
131 | } else { | |
132 | // Coerce existing setting to the right type | |
133 | api['set_' + v](cfg[v]); | |
134 | } | |
125d8bbb JM |
135 | }; |
136 | ||
137 | ||
a8edf9d8 | 138 | |
15046f00 JM |
139 | /* |
140 | * Cross-browser routines | |
141 | */ | |
142 | ||
143 | // Get DOM element position on page | |
144 | Util.getPosition = function (obj) { | |
145 | var x = 0, y = 0; | |
146 | if (obj.offsetParent) { | |
147 | do { | |
148 | x += obj.offsetLeft; | |
149 | y += obj.offsetTop; | |
150 | obj = obj.offsetParent; | |
151 | } while (obj); | |
152 | } | |
153 | return {'x': x, 'y': y}; | |
154 | }; | |
155 | ||
156 | // Get mouse event position in DOM element | |
125d8bbb | 157 | Util.getEventPosition = function (e, obj, scale) { |
15046f00 JM |
158 | var evt, docX, docY, pos; |
159 | //if (!e) evt = window.event; | |
160 | evt = (e ? e : window.event); | |
161 | if (evt.pageX || evt.pageY) { | |
162 | docX = evt.pageX; | |
163 | docY = evt.pageY; | |
164 | } else if (evt.clientX || evt.clientY) { | |
165 | docX = evt.clientX + document.body.scrollLeft + | |
166 | document.documentElement.scrollLeft; | |
167 | docY = evt.clientY + document.body.scrollTop + | |
168 | document.documentElement.scrollTop; | |
169 | } | |
170 | pos = Util.getPosition(obj); | |
125d8bbb JM |
171 | if (typeof scale === "undefined") { |
172 | scale = 1; | |
173 | } | |
174 | return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale}; | |
15046f00 JM |
175 | }; |
176 | ||
177 | ||
178 | // Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events | |
179 | Util.addEvent = function (obj, evType, fn){ | |
d93d3e09 | 180 | if (obj.attachEvent){ |
15046f00 JM |
181 | var r = obj.attachEvent("on"+evType, fn); |
182 | return r; | |
d93d3e09 JM |
183 | } else if (obj.addEventListener){ |
184 | obj.addEventListener(evType, fn, false); | |
185 | return true; | |
15046f00 JM |
186 | } else { |
187 | throw("Handler could not be attached"); | |
188 | } | |
189 | }; | |
190 | ||
191 | Util.removeEvent = function(obj, evType, fn){ | |
d93d3e09 | 192 | if (obj.detachEvent){ |
15046f00 JM |
193 | var r = obj.detachEvent("on"+evType, fn); |
194 | return r; | |
d93d3e09 JM |
195 | } else if (obj.removeEventListener){ |
196 | obj.removeEventListener(evType, fn, false); | |
197 | return true; | |
15046f00 JM |
198 | } else { |
199 | throw("Handler could not be removed"); | |
200 | } | |
201 | }; | |
202 | ||
203 | Util.stopEvent = function(e) { | |
204 | if (e.stopPropagation) { e.stopPropagation(); } | |
205 | else { e.cancelBubble = true; } | |
206 | ||
207 | if (e.preventDefault) { e.preventDefault(); } | |
208 | else { e.returnValue = false; } | |
209 | }; | |
210 | ||
211 | ||
212 | // Set browser engine versions. Based on mootools. | |
213 | Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}; | |
214 | ||
215 | Util.Engine = { | |
216 | 'presto': (function() { | |
217 | return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()), | |
218 | 'trident': (function() { | |
219 | return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }()), | |
220 | 'webkit': (function() { | |
11bb7a4a JM |
221 | try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()), |
222 | //'webkit': (function() { | |
223 | // return ((typeof navigator.taintEnabled !== "unknown") && navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); }()), | |
15046f00 | 224 | 'gecko': (function() { |
8787e49b | 225 | return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }()) |
15046f00 JM |
226 | }; |
227 | ||
228 | Util.Flash = (function(){ | |
229 | var v, version; | |
230 | try { | |
231 | v = navigator.plugins['Shockwave Flash'].description; | |
232 | } catch(err1) { | |
233 | try { | |
234 | v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); | |
235 | } catch(err2) { | |
236 | v = '0 r0'; | |
237 | } | |
238 | } | |
239 | version = v.match(/\d+/g); | |
240 | return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; | |
8d5d2c82 | 241 | }()); |