Rework LuCI build system
[project/luci.git] / modules / luci-base / htdocs / luci-static / resources / xhr.js
1 /*
2 * xhr.js - XMLHttpRequest helper class
3 * (c) 2008-2010 Jo-Philipp Wich
4 */
5
6 XHR = function()
7 {
8 this.reinit = function()
9 {
10 if (window.XMLHttpRequest) {
11 this._xmlHttp = new XMLHttpRequest();
12 }
13 else if (window.ActiveXObject) {
14 this._xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
15 }
16 else {
17 alert("xhr.js: XMLHttpRequest is not supported by this browser!");
18 }
19 }
20
21 this.busy = function() {
22 if (!this._xmlHttp)
23 return false;
24
25 switch (this._xmlHttp.readyState)
26 {
27 case 1:
28 case 2:
29 case 3:
30 return true;
31
32 default:
33 return false;
34 }
35 }
36
37 this.abort = function() {
38 if (this.busy())
39 this._xmlHttp.abort();
40 }
41
42 this.get = function(url,data,callback)
43 {
44 this.reinit();
45
46 var xhr = this._xmlHttp;
47 var code = this._encode(data);
48
49 url = location.protocol + '//' + location.host + url;
50
51 if (code)
52 if (url.substr(url.length-1,1) == '&')
53 url += code;
54 else
55 url += '?' + code;
56
57 xhr.open('GET', url, true);
58
59 xhr.onreadystatechange = function()
60 {
61 if (xhr.readyState == 4) {
62 var json = null;
63 if (xhr.getResponseHeader("Content-Type") == "application/json") {
64 try {
65 json = eval('(' + xhr.responseText + ')');
66 }
67 catch(e) {
68 json = null;
69 }
70 }
71
72 callback(xhr, json);
73 }
74 }
75
76 xhr.send(null);
77 }
78
79 this.post = function(url,data,callback)
80 {
81 this.reinit();
82
83 var xhr = this._xmlHttp;
84 var code = this._encode(data);
85
86 xhr.onreadystatechange = function()
87 {
88 if (xhr.readyState == 4)
89 callback(xhr);
90 }
91
92 xhr.open('POST', url, true);
93 xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
94 xhr.setRequestHeader('Content-length', code.length);
95 xhr.setRequestHeader('Connection', 'close');
96 xhr.send(code);
97 }
98
99 this.cancel = function()
100 {
101 this._xmlHttp.onreadystatechange = function(){};
102 this._xmlHttp.abort();
103 }
104
105 this.send_form = function(form,callback,extra_values)
106 {
107 var code = '';
108
109 for (var i = 0; i < form.elements.length; i++)
110 {
111 var e = form.elements[i];
112
113 if (e.options)
114 {
115 code += (code ? '&' : '') +
116 form.elements[i].name + '=' + encodeURIComponent(
117 e.options[e.selectedIndex].value
118 );
119 }
120 else if (e.length)
121 {
122 for (var j = 0; j < e.length; j++)
123 if (e[j].name) {
124 code += (code ? '&' : '') +
125 e[j].name + '=' + encodeURIComponent(e[j].value);
126 }
127 }
128 else
129 {
130 code += (code ? '&' : '') +
131 e.name + '=' + encodeURIComponent(e.value);
132 }
133 }
134
135 if (typeof extra_values == 'object')
136 for (var key in extra_values)
137 code += (code ? '&' : '') +
138 key + '=' + encodeURIComponent(extra_values[key]);
139
140 return(
141 (form.method == 'get')
142 ? this.get(form.getAttribute('action'), code, callback)
143 : this.post(form.getAttribute('action'), code, callback)
144 );
145 }
146
147 this._encode = function(obj)
148 {
149 obj = obj ? obj : { };
150 obj['_'] = Math.random();
151
152 if (typeof obj == 'object')
153 {
154 var code = '';
155 var self = this;
156
157 for (var k in obj)
158 code += (code ? '&' : '') +
159 k + '=' + encodeURIComponent(obj[k]);
160
161 return code;
162 }
163
164 return obj;
165 }
166 }
167
168 XHR.get = function(url, data, callback)
169 {
170 (new XHR()).get(url, data, callback);
171 }
172
173 XHR.poll = function(interval, url, data, callback)
174 {
175 if (isNaN(interval) || interval < 1)
176 interval = 5;
177
178 if (!XHR._q)
179 {
180 XHR._t = 0;
181 XHR._q = [ ];
182 XHR._r = function() {
183 for (var i = 0, e = XHR._q[0]; i < XHR._q.length; e = XHR._q[++i])
184 {
185 if (!(XHR._t % e.interval) && !e.xhr.busy())
186 e.xhr.get(e.url, e.data, e.callback);
187 }
188
189 XHR._t++;
190 };
191 }
192
193 XHR._q.push({
194 interval: interval,
195 callback: callback,
196 url: url,
197 data: data,
198 xhr: new XHR()
199 });
200
201 XHR.run();
202 }
203
204 XHR.halt = function()
205 {
206 if (XHR._i)
207 {
208 /* show & set poll indicator */
209 try {
210 document.getElementById('xhr_poll_status').style.display = '';
211 document.getElementById('xhr_poll_status_on').style.display = 'none';
212 document.getElementById('xhr_poll_status_off').style.display = '';
213 } catch(e) { }
214
215 window.clearInterval(XHR._i);
216 XHR._i = null;
217 }
218 }
219
220 XHR.run = function()
221 {
222 if (XHR._r && !XHR._i)
223 {
224 /* show & set poll indicator */
225 try {
226 document.getElementById('xhr_poll_status').style.display = '';
227 document.getElementById('xhr_poll_status_on').style.display = '';
228 document.getElementById('xhr_poll_status_off').style.display = 'none';
229 } catch(e) { }
230
231 /* kick first round manually to prevent one second lag when setting up
232 * the poll interval */
233 XHR._r();
234 XHR._i = window.setInterval(XHR._r, 1000);
235 }
236 }
237
238 XHR.running = function()
239 {
240 return !!(XHR._r && XHR._i);
241 }