453c2ba4e8c4a774a65ac753e87851ab848e08c2
[project/luci.git] / themes / 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         }
183
184         XHR._q.push({
185                 interval: interval,
186                 callback: callback,
187                 url:      url,
188                 data:     data,
189                 xhr:      new XHR()
190         });
191
192         if (!XHR._i)
193         {
194                 XHR._i = window.setInterval(function() {
195                         for (var i = 0, e = XHR._q[0]; i < XHR._q.length; e = XHR._q[++i])
196                         {
197                                 if (!(XHR._t % e.interval) && !e.xhr.busy())
198                                         e.xhr.get(e.url, e.data, e.callback);
199                         }
200
201                         XHR._t++;
202                 }, 1000);
203         }
204 }