]>
Commit | Line | Data |
---|---|---|
8d5d2c82 AM |
1 | /* |
2 | * noVNC: HTML5 VNC client | |
d58f8b51 | 3 | * Copyright (C) 2012 Joel Martin |
ad941fad | 4 | * Copyright (C) 2013 NTT corp. |
1d728ace | 5 | * Licensed under MPL 2.0 (see LICENSE.txt) |
8d5d2c82 AM |
6 | * |
7 | * See README.md for usage and integration instructions. | |
8 | */ | |
9 | ||
ee7d4c61 | 10 | /*jslint bitwise: false, white: false, browser: true, devel: true */ |
ff4bfcb7 | 11 | /*global Util, window, document */ |
8d5d2c82 | 12 | |
c464f47e | 13 | import { init_logging as main_init_logging } from '../core/util/logging.js'; |
8d5d2c82 AM |
14 | |
15 | // init log level reading the logging HTTP param | |
6d6f0db0 | 16 | export function init_logging (level) { |
ee7d4c61 | 17 | "use strict"; |
2cde6e43 | 18 | if (typeof level !== "undefined") { |
6d6f0db0 | 19 | main_init_logging(level); |
2cde6e43 | 20 | } else { |
ee7d4c61 | 21 | var param = document.location.href.match(/logging=([A-Za-z0-9\._\-]*)/); |
6d6f0db0 | 22 | main_init_logging(param || undefined); |
2cde6e43 | 23 | } |
ff4bfcb7 | 24 | }; |
8d5d2c82 | 25 | |
8d5d2c82 | 26 | // Read a query string variable |
6d6f0db0 | 27 | export function getQueryVar (name, defVal) { |
ee7d4c61 | 28 | "use strict"; |
d8c09535 | 29 | var re = new RegExp('.*[?&]' + name + '=([^&#]*)'), |
fa5b334d | 30 | match = document.location.href.match(re); |
8d5d2c82 | 31 | if (typeof defVal === 'undefined') { defVal = null; } |
fa5b334d JM |
32 | if (match) { |
33 | return decodeURIComponent(match[1]); | |
34 | } else { | |
35 | return defVal; | |
36 | } | |
8d5d2c82 AM |
37 | }; |
38 | ||
494b407a | 39 | // Read a hash fragment variable |
6d6f0db0 | 40 | export function getHashVar (name, defVal) { |
494b407a GV |
41 | "use strict"; |
42 | var re = new RegExp('.*[&#]' + name + '=([^&]*)'), | |
43 | match = document.location.hash.match(re); | |
44 | if (typeof defVal === 'undefined') { defVal = null; } | |
45 | if (match) { | |
46 | return decodeURIComponent(match[1]); | |
47 | } else { | |
48 | return defVal; | |
49 | } | |
50 | }; | |
51 | ||
52 | // Read a variable from the fragment or the query string | |
53 | // Fragment takes precedence | |
6d6f0db0 | 54 | export function getConfigVar (name, defVal) { |
494b407a | 55 | "use strict"; |
6d6f0db0 | 56 | var val = getHashVar(name); |
494b407a | 57 | if (val === null) { |
6d6f0db0 | 58 | val = getQueryVar(name, defVal); |
494b407a GV |
59 | } |
60 | return val; | |
61 | }; | |
8d5d2c82 AM |
62 | |
63 | /* | |
64 | * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html | |
65 | */ | |
66 | ||
67 | // No days means only for this browser session | |
6d6f0db0 | 68 | export function createCookie (name, value, days) { |
ee7d4c61 SR |
69 | "use strict"; |
70 | var date, expires; | |
8d5d2c82 AM |
71 | if (days) { |
72 | date = new Date(); | |
ee7d4c61 SR |
73 | date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); |
74 | expires = "; expires=" + date.toGMTString(); | |
ad941fad | 75 | } else { |
8d5d2c82 AM |
76 | expires = ""; |
77 | } | |
ee7d4c61 SR |
78 | |
79 | var secure; | |
ad941fad TN |
80 | if (document.location.protocol === "https:") { |
81 | secure = "; secure"; | |
82 | } else { | |
83 | secure = ""; | |
84 | } | |
ee7d4c61 | 85 | document.cookie = name + "=" + value + expires + "; path=/" + secure; |
8d5d2c82 AM |
86 | }; |
87 | ||
6d6f0db0 | 88 | export function readCookie (name, defaultValue) { |
ee7d4c61 SR |
89 | "use strict"; |
90 | var nameEQ = name + "=", | |
91 | ca = document.cookie.split(';'); | |
92 | ||
93 | for (var i = 0; i < ca.length; i += 1) { | |
94 | var c = ca[i]; | |
95 | while (c.charAt(0) === ' ') { c = c.substring(1, c.length); } | |
96 | if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length, c.length); } | |
8d5d2c82 AM |
97 | } |
98 | return (typeof defaultValue !== 'undefined') ? defaultValue : null; | |
99 | }; | |
100 | ||
6d6f0db0 | 101 | export function eraseCookie (name) { |
ee7d4c61 | 102 | "use strict"; |
6d6f0db0 | 103 | createCookie(name, "", -1); |
8d5d2c82 AM |
104 | }; |
105 | ||
3af1c275 JM |
106 | /* |
107 | * Setting handling. | |
108 | */ | |
109 | ||
6d6f0db0 SR |
110 | var settings = {}; |
111 | ||
112 | export function initSettings (callback /*, ...callbackArgs */) { | |
ee7d4c61 | 113 | "use strict"; |
3af1c275 | 114 | var callbackArgs = Array.prototype.slice.call(arguments, 1); |
d5fe1509 JM |
115 | if (window.chrome && window.chrome.storage) { |
116 | window.chrome.storage.sync.get(function (cfg) { | |
6d6f0db0 | 117 | settings = cfg; |
3af1c275 JM |
118 | if (callback) { |
119 | callback.apply(this, callbackArgs); | |
120 | } | |
121 | }); | |
122 | } else { | |
123 | // No-op | |
124 | if (callback) { | |
125 | callback.apply(this, callbackArgs); | |
126 | } | |
127 | } | |
128 | }; | |
129 | ||
130 | // No days means only for this browser session | |
6d6f0db0 | 131 | export function writeSetting (name, value) { |
ee7d4c61 | 132 | "use strict"; |
d5fe1509 | 133 | if (window.chrome && window.chrome.storage) { |
6d6f0db0 SR |
134 | if (settings[name] !== value) { |
135 | settings[name] = value; | |
136 | window.chrome.storage.sync.set(settings); | |
3af1c275 JM |
137 | } |
138 | } else { | |
139 | localStorage.setItem(name, value); | |
140 | } | |
141 | }; | |
142 | ||
6d6f0db0 | 143 | export function readSetting (name, defaultValue) { |
ee7d4c61 | 144 | "use strict"; |
3af1c275 | 145 | var value; |
d5fe1509 | 146 | if (window.chrome && window.chrome.storage) { |
6d6f0db0 | 147 | value = settings[name]; |
3af1c275 JM |
148 | } else { |
149 | value = localStorage.getItem(name); | |
150 | } | |
151 | if (typeof value === "undefined") { | |
152 | value = null; | |
153 | } | |
eb533b2b | 154 | if (value === null && typeof defaultValue !== "undefined") { |
3af1c275 JM |
155 | return defaultValue; |
156 | } else { | |
157 | return value; | |
158 | } | |
159 | }; | |
160 | ||
6d6f0db0 | 161 | export function eraseSetting (name) { |
ee7d4c61 | 162 | "use strict"; |
d5fe1509 JM |
163 | if (window.chrome && window.chrome.storage) { |
164 | window.chrome.storage.sync.remove(name); | |
6d6f0db0 | 165 | delete settings[name]; |
3af1c275 JM |
166 | } else { |
167 | localStorage.removeItem(name); | |
168 | } | |
169 | }; | |
170 | ||
6d6f0db0 | 171 | export function injectParamIfMissing (path, param, value) { |
c55f05f6 MXPN |
172 | // force pretend that we're dealing with a relative path |
173 | // (assume that we wanted an extra if we pass one in) | |
174 | path = "/" + path; | |
175 | ||
176 | var elem = document.createElement('a'); | |
177 | elem.href = path; | |
178 | ||
179 | var param_eq = encodeURIComponent(param) + "="; | |
180 | var query; | |
181 | if (elem.search) { | |
182 | query = elem.search.slice(1).split('&'); | |
183 | } else { | |
184 | query = []; | |
185 | } | |
186 | ||
187 | if (!query.some(function (v) { return v.startsWith(param_eq); })) { | |
188 | query.push(param_eq + encodeURIComponent(value)); | |
189 | elem.search = "?" + query.join("&"); | |
190 | } | |
191 | ||
c8294760 JB |
192 | // some browsers (e.g. IE11) may occasionally omit the leading slash |
193 | // in the elem.pathname string. Handle that case gracefully. | |
194 | if (elem.pathname.charAt(0) == "/") { | |
195 | return elem.pathname.slice(1) + elem.search + elem.hash; | |
196 | } else { | |
197 | return elem.pathname + elem.search + elem.hash; | |
3c955844 | 198 | } |
c55f05f6 | 199 | }; |
ae510306 | 200 | |
2a7c6d20 SR |
201 | // sadly, we can't use the Fetch API until we decide to drop |
202 | // IE11 support or polyfill promises and fetch in IE11. | |
203 | // resolve will receive an object on success, while reject | |
204 | // will receive either an event or an error on failure. | |
6d6f0db0 | 205 | export function fetchJSON(path, resolve, reject) { |
2a7c6d20 | 206 | // NB: IE11 doesn't support JSON as a responseType |
858ea4a7 | 207 | var req = new XMLHttpRequest(); |
2a7c6d20 SR |
208 | req.open('GET', path); |
209 | ||
210 | req.onload = function () { | |
211 | if (req.status === 200) { | |
212 | try { | |
213 | var resObj = JSON.parse(req.responseText); | |
214 | } catch (err) { | |
215 | reject(err); | |
216 | return; | |
217 | } | |
218 | resolve(resObj); | |
219 | } else { | |
220 | reject(new Error("XHR got non-200 status while trying to load '" + path + "': " + req.status)); | |
221 | } | |
222 | }; | |
223 | ||
224 | req.onerror = function (evt) { | |
225 | reject(new Error("XHR encountered an error while trying to load '" + path + "': " + evt.message)); | |
226 | }; | |
227 | ||
228 | req.ontimeout = function (evt) { | |
229 | reject(new Error("XHR timed out while trying to load '" + path + "'")); | |
230 | }; | |
231 | ||
232 | req.send(); | |
6d6f0db0 | 233 | } |