]> git.proxmox.com Git - mirror_novnc.git/blob - app/webutil.js
e6e6afb70842af9118bf2c97e5f3f510546edf32
[mirror_novnc.git] / app / webutil.js
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 /* [module]
14 * import Util from "../core/util";
15 */
16
17 // Globals defined here
18 var WebUtil = {};
19
20 /*
21 * ------------------------------------------------------
22 * Namespaced in WebUtil
23 * ------------------------------------------------------
24 */
25
26 // init log level reading the logging HTTP param
27 WebUtil.init_logging = function (level) {
28 "use strict";
29 if (typeof level !== "undefined") {
30 Util._log_level = level;
31 } else {
32 var param = document.location.href.match(/logging=([A-Za-z0-9\._\-]*)/);
33 Util._log_level = (param || ['', Util._log_level])[1];
34 }
35 Util.init_logging();
36 };
37
38
39 WebUtil.dirObj = function (obj, depth, parent) {
40 "use strict";
41 if (! depth) { depth = 2; }
42 if (! parent) { parent = ""; }
43
44 // Print the properties of the passed-in object
45 var msg = "";
46 for (var i in obj) {
47 if ((depth > 1) && (typeof obj[i] === "object")) {
48 // Recurse attributes that are objects
49 msg += WebUtil.dirObj(obj[i], depth - 1, parent + "." + i);
50 } else {
51 //val = new String(obj[i]).replace("\n", " ");
52 var val = "";
53 if (typeof(obj[i]) === "undefined") {
54 val = "undefined";
55 } else {
56 val = obj[i].toString().replace("\n", " ");
57 }
58 if (val.length > 30) {
59 val = val.substr(0, 30) + "...";
60 }
61 msg += parent + "." + i + ": " + val + "\n";
62 }
63 }
64 return msg;
65 };
66
67 // Read a query string variable
68 WebUtil.getQueryVar = function (name, defVal) {
69 "use strict";
70 var re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
71 match = document.location.href.match(re);
72 if (typeof defVal === 'undefined') { defVal = null; }
73 if (match) {
74 return decodeURIComponent(match[1]);
75 } else {
76 return defVal;
77 }
78 };
79
80 // Read a hash fragment variable
81 WebUtil.getHashVar = function (name, defVal) {
82 "use strict";
83 var re = new RegExp('.*[&#]' + name + '=([^&]*)'),
84 match = document.location.hash.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 // Read a variable from the fragment or the query string
94 // Fragment takes precedence
95 WebUtil.getConfigVar = function (name, defVal) {
96 "use strict";
97 var val = WebUtil.getHashVar(name);
98 if (val === null) {
99 val = WebUtil.getQueryVar(name, defVal);
100 }
101 return val;
102 };
103
104 /*
105 * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
106 */
107
108 // No days means only for this browser session
109 WebUtil.createCookie = function (name, value, days) {
110 "use strict";
111 var date, expires;
112 if (days) {
113 date = new Date();
114 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
115 expires = "; expires=" + date.toGMTString();
116 } else {
117 expires = "";
118 }
119
120 var secure;
121 if (document.location.protocol === "https:") {
122 secure = "; secure";
123 } else {
124 secure = "";
125 }
126 document.cookie = name + "=" + value + expires + "; path=/" + secure;
127 };
128
129 WebUtil.readCookie = function (name, defaultValue) {
130 "use strict";
131 var nameEQ = name + "=",
132 ca = document.cookie.split(';');
133
134 for (var i = 0; i < ca.length; i += 1) {
135 var c = ca[i];
136 while (c.charAt(0) === ' ') { c = c.substring(1, c.length); }
137 if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length, c.length); }
138 }
139 return (typeof defaultValue !== 'undefined') ? defaultValue : null;
140 };
141
142 WebUtil.eraseCookie = function (name) {
143 "use strict";
144 WebUtil.createCookie(name, "", -1);
145 };
146
147 /*
148 * Setting handling.
149 */
150
151 WebUtil.initSettings = function (callback /*, ...callbackArgs */) {
152 "use strict";
153 var callbackArgs = Array.prototype.slice.call(arguments, 1);
154 if (window.chrome && window.chrome.storage) {
155 window.chrome.storage.sync.get(function (cfg) {
156 WebUtil.settings = cfg;
157 console.log(WebUtil.settings);
158 if (callback) {
159 callback.apply(this, callbackArgs);
160 }
161 });
162 } else {
163 // No-op
164 if (callback) {
165 callback.apply(this, callbackArgs);
166 }
167 }
168 };
169
170 // No days means only for this browser session
171 WebUtil.writeSetting = function (name, value) {
172 "use strict";
173 if (window.chrome && window.chrome.storage) {
174 //console.log("writeSetting:", name, value);
175 if (WebUtil.settings[name] !== value) {
176 WebUtil.settings[name] = value;
177 window.chrome.storage.sync.set(WebUtil.settings);
178 }
179 } else {
180 localStorage.setItem(name, value);
181 }
182 };
183
184 WebUtil.readSetting = function (name, defaultValue) {
185 "use strict";
186 var value;
187 if (window.chrome && window.chrome.storage) {
188 value = WebUtil.settings[name];
189 } else {
190 value = localStorage.getItem(name);
191 }
192 if (typeof value === "undefined") {
193 value = null;
194 }
195 if (value === null && typeof defaultValue !== undefined) {
196 return defaultValue;
197 } else {
198 return value;
199 }
200 };
201
202 WebUtil.eraseSetting = function (name) {
203 "use strict";
204 if (window.chrome && window.chrome.storage) {
205 window.chrome.storage.sync.remove(name);
206 delete WebUtil.settings[name];
207 } else {
208 localStorage.removeItem(name);
209 }
210 };
211
212 WebUtil.injectParamIfMissing = function (path, param, value) {
213 // force pretend that we're dealing with a relative path
214 // (assume that we wanted an extra if we pass one in)
215 path = "/" + path;
216
217 var elem = document.createElement('a');
218 elem.href = path;
219
220 var param_eq = encodeURIComponent(param) + "=";
221 var query;
222 if (elem.search) {
223 query = elem.search.slice(1).split('&');
224 } else {
225 query = [];
226 }
227
228 if (!query.some(function (v) { return v.startsWith(param_eq); })) {
229 query.push(param_eq + encodeURIComponent(value));
230 elem.search = "?" + query.join("&");
231 }
232
233 // some browsers (e.g. IE11) may occasionally omit the leading slash
234 // in the elem.pathname string. Handle that case gracefully.
235 if (elem.pathname.charAt(0) == "/") {
236 return elem.pathname.slice(1) + elem.search + elem.hash;
237 } else {
238 return elem.pathname + elem.search + elem.hash;
239 }
240 };
241
242 // Dynamically load scripts without using document.write()
243 // Reference: http://unixpapa.com/js/dyna.html
244 //
245 // Handles the case where load_scripts is invoked from a script that
246 // itself is loaded via load_scripts. Once all scripts are loaded the
247 // window.onscriptsloaded handler is called (if set).
248 WebUtil.get_include_uri = function (root_dir) {
249 return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI + root_dir + '/' : root_dir + '/';
250 };
251 WebUtil._loading_scripts = [];
252 WebUtil._pending_scripts = [];
253 WebUtil.load_scripts = function (files_by_dir) {
254 "use strict";
255 var head = document.getElementsByTagName('head')[0], script,
256 ls = WebUtil._loading_scripts, ps = WebUtil._pending_scripts;
257
258 var loadFunc = function (e) {
259 while (ls.length > 0 && (ls[0].readyState === 'loaded' ||
260 ls[0].readyState === 'complete')) {
261 // For IE, append the script to trigger execution
262 var s = ls.shift();
263 //console.log("loaded script: " + s.src);
264 head.appendChild(s);
265 }
266 if (!this.readyState ||
267 (Util.Engine.presto && this.readyState === 'loaded') ||
268 this.readyState === 'complete') {
269 if (ps.indexOf(this) >= 0) {
270 this.onload = this.onreadystatechange = null;
271 //console.log("completed script: " + this.src);
272 ps.splice(ps.indexOf(this), 1);
273
274 // Call window.onscriptsload after last script loads
275 if (ps.length === 0 && window.onscriptsload) {
276 window.onscriptsload();
277 }
278 }
279 }
280 };
281
282 var root_dirs = Object.keys(files_by_dir);
283
284 for (var d = 0; d < root_dirs.length; d++) {
285 var root_dir = root_dirs[d];
286 var files = files_by_dir[root_dir];
287
288 for (var f = 0; f < files.length; f++) {
289 script = document.createElement('script');
290 script.type = 'text/javascript';
291 script.src = WebUtil.get_include_uri(root_dir) + files[f];
292 //console.log("loading script: " + script.src);
293 script.onload = script.onreadystatechange = loadFunc;
294 // In-order script execution tricks
295 if (Util.Engine.trident) {
296 // For IE wait until readyState is 'loaded' before
297 // appending it which will trigger execution
298 // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
299 ls.push(script);
300 } else {
301 // For webkit and firefox set async=false and append now
302 // https://developer.mozilla.org/en-US/docs/HTML/Element/script
303 script.async = false;
304 head.appendChild(script);
305 }
306 ps.push(script);
307 }
308 }
309 };
310
311 /* [module] export default WebUtil; */