2 * xhr.js - XMLHttpRequest helper class
3 * (c) 2008-2018 Jo-Philipp Wich <jo@mein.io>
7 _encode: function(obj
) {
9 obj
['_'] = Math
.random();
11 if (typeof obj
== 'object') {
16 code
+= (code
? '&' : '') +
17 k
+ '=' + encodeURIComponent(obj
[k
]);
25 _response: function(callback
, ts
) {
26 if (this._xmlHttp
.readyState
!== 4)
29 var status
= this._xmlHttp
.status
,
30 login
= this._xmlHttp
.getResponseHeader("X-LuCI-Login-Required"),
31 type
= this._xmlHttp
.getResponseHeader("Content-Type"),
34 if (status
=== 403 && login
=== 'yes') {
37 showModal(_('Session expired'), [
38 E('div', { class: 'alert-message warning' },
39 _('A new login is required since the authentication session expired.')),
40 E('div', { class: 'right' },
44 var loc
= window
.location
;
45 window
.location
= loc
.protocol
+ '//' + loc
.host
+ loc
.pathname
+ loc
.search
;
50 else if (type
&& type
.toLowerCase().match(/^application\/json\b/)) {
52 json
= JSON
.parse(this._xmlHttp
.responseText
);
59 callback(this._xmlHttp
, json
, Date
.now() - ts
);
66 switch (this._xmlHttp
.readyState
)
80 this._xmlHttp
.abort();
83 get: function(url
, data
, callback
, timeout
) {
84 this._xmlHttp
= new XMLHttpRequest();
86 var xhr
= this._xmlHttp
,
87 code
= this._encode(data
);
89 url
= location
.protocol
+ '//' + location
.host
+ url
;
92 if (url
.substr(url
.length
-1,1) == '&')
97 xhr
.open('GET', url
, true);
100 xhr
.timeout
= timeout
;
102 xhr
.onreadystatechange
= this._response
.bind(this, callback
, Date
.now());
106 post: function(url
, data
, callback
, timeout
) {
107 this._xmlHttp
= new XMLHttpRequest();
109 var xhr
= this._xmlHttp
,
110 code
= this._encode(data
);
112 xhr
.open('POST', url
, true);
115 xhr
.timeout
= timeout
;
117 xhr
.onreadystatechange
= this._response
.bind(this, callback
, Date
.now());
118 xhr
.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
123 this._xmlHttp
.onreadystatechange = function() {};
124 this._xmlHttp
.abort();
127 send_form: function(form
, callback
, extra_values
) {
130 for (var i
= 0; i
< form
.elements
.length
; i
++) {
131 var e
= form
.elements
[i
];
134 code
+= (code
? '&' : '') +
135 form
.elements
[i
].name
+ '=' + encodeURIComponent(
136 e
.options
[e
.selectedIndex
].value
140 for (var j
= 0; j
< e
.length
; j
++)
142 code
+= (code
? '&' : '') +
143 e
[j
].name
+ '=' + encodeURIComponent(e
[j
].value
);
147 code
+= (code
? '&' : '') +
148 e
.name
+ '=' + encodeURIComponent(e
.value
);
152 if (typeof extra_values
== 'object')
153 for (var key
in extra_values
)
154 code
+= (code
? '&' : '') +
155 key
+ '=' + encodeURIComponent(extra_values
[key
]);
157 return (form
.method
== 'get'
158 ? this.get(form
.getAttribute('action'), code
, callback
)
159 : this.post(form
.getAttribute('action'), code
, callback
));
163 XHR
.get = function(url
, data
, callback
) {
164 (new XHR()).get(url
, data
, callback
);
167 XHR
.post = function(url
, data
, callback
) {
168 (new XHR()).post(url
, data
, callback
);
171 XHR
.poll = function(interval
, url
, data
, callback
, post
) {
172 if (isNaN(interval
) || interval
< 1)
178 XHR
._r = function() {
179 for (var i
= 0, e
= XHR
._q
[0]; i
< XHR
._q
.length
; e
= XHR
._q
[++i
])
181 if (!(XHR
._t
% e
.interval
) && !e
.xhr
.busy())
182 e
.xhr
[post
? 'post' : 'get'](e
.url
, e
.data
, e
.callback
, e
.interval
* 1000 * 5 - 5);
202 XHR
.stop = function(e
) {
203 for (var i
= 0; XHR
._q
&& XHR
._q
[i
]; i
++) {
204 if (XHR
._q
[i
] === e
) {
214 XHR
.halt = function() {
216 /* show & set poll indicator */
218 document
.getElementById('xhr_poll_status').style
.display
= '';
219 document
.getElementById('xhr_poll_status_on').style
.display
= 'none';
220 document
.getElementById('xhr_poll_status_off').style
.display
= '';
223 window
.clearInterval(XHR
._i
);
228 XHR
.run = function() {
229 if (XHR
._r
&& !XHR
._i
) {
230 /* show & set poll indicator */
232 document
.getElementById('xhr_poll_status').style
.display
= '';
233 document
.getElementById('xhr_poll_status_on').style
.display
= '';
234 document
.getElementById('xhr_poll_status_off').style
.display
= 'none';
237 /* kick first round manually to prevent one second lag when setting up
238 * the poll interval */
240 XHR
._i
= window
.setInterval(XHR
._r
, 1000);
244 XHR
.running = function() {
245 return !!(XHR
._r
&& XHR
._i
);
250 document
.addEventListener('DOMContentLoaded', XHR
.run
);