xhr refactoring: renaming xhr_rd to xhr, remove all xhr_rd_ prefixies from http_strea...
[brisk.git] / web / xhr.js
1 /*
2  *  brisk - xhr.js
3  *
4  *  Copyright (C) 2006-2011 Matteo Nastasi
5  *                          mailto: nastasi@alternativeoutput.it 
6  *                                  matteo.nastasi@milug.org
7  *                          web: http://www.alternativeoutput.it
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details. You should have received a
18  * copy of the GNU General Public License along with this program; if
19  * not, write to the Free Software Foundation, Inc, 59 Temple Place -
20  * Suite 330, Boston, MA 02111-1307, USA.
21  *
22  * TODO:
23  *
24  *   MANDATORY
25  *
26  *   NOT MANDATORY
27  *   - remove hbit imple
28  *   - gst management
29  *   - sandbox management
30  *   - myfrom into the constructor
31  *   - target page into the constructor
32  *   - type of streaming into the constructor
33  *   - all iframe related streaming add
34  *   - substitute fixed "eval" with a generic command hunks processor
35  *
36  *   DONE - xhr_rd prefix remove from inner class attrs
37  *
38  */
39
40 function hbit(symb)
41 {
42     if ($("heartbit").innerHTML.length >= 120) {
43         $("heartbit").innerHTML = $("heartbit").innerHTML.substring(10);
44         $("heartbit").innerHTML += symb;
45     }
46     else {
47         $("heartbit").innerHTML += symb;
48     }
49 }
50
51 function http_streaming(cookiename)
52 {
53     this.xhr = createXMLHttpRequest();
54     this.cookiename = cookiename;
55 }
56
57 http_streaming.prototype = {
58     cookiename: null,
59     cookiepath: "/brisk/",
60     xhr: null,
61     watchdog: null,
62     delay: 0,
63     delayed: null,
64     stopped: true,
65     the_end: false,
66     oldctx: "",
67     newctx: "",
68     cur_n: -1,
69     old_n: -1,
70     checkedlen: 0,
71     /* watchdog_old: 0, */
72     ct: 0,
73
74     hbit: function () {
75     },
76
77     hbit_set: function (hbit) {
78         this.hbit = hbit;
79     },
80
81     xhr_cb: function () {
82         var ret;
83         
84         if (this.xhr.readyState == 4) {
85             if (this.watchdog != null) {
86                 this.hbit('C');
87                 clearTimeout(this.watchdog);
88                 this.watchdog = null;
89             }
90             
91             // console.log("SS: "+safestatus(xhr));
92             
93             try {
94                 if ((ret = safestatus(this.xhr)) == 200) {
95                     this.delay = 0;
96                     // console.log("del a null "+this.delayed);
97                 } else if (ret != -1) {
98                     this.delay = 5000;
99                     this.hbit('X');
100                     // alert('There was a problem with the request.' + ret);
101                 }
102             } catch(b) {};
103             
104             this.delayed = null;
105             this.stopped = true;
106         }
107     },
108
109     xhr_abort: function()
110     {
111         this.hbit('A');
112         if (this.xhr != null)
113             this.xhr.abort();
114         // alert("de che");
115     },
116
117     run: function(sess, stat, subst, step) 
118     {
119         if (this.the_end) {
120             //x alert("the_end1");
121             if (this.watchdog != null) {
122                 this.hbit('C');
123                 clearTimeout(this.watchdog);
124                 this.watchdog = null;
125             }
126             return;
127         }
128         createCookie(this.cookie_name, sess, 24*365, this.cookiepath);
129         
130         // NOTE: *ctx = "" to prevent konqueror stream commands duplication.
131         this.oldctx = "";
132         this.newctx = "";
133         
134         /* NOTE document.uniqueID exists only under IE  */
135         // if (g_is_spawn == 1)
136         // alert("di qui3: "+(g_is_spawn == 1 ? "&table_idx="+g_table_idx : ""));
137         this.xhr.open('GET', 'index_rd.php?sess='+sess+"&stat="+stat+"&subst="+subst+"&step="+step+"&onlyone="+(document.uniqueID ? "TRUE" : "FALSE")+"&myfrom="+myfrom, true);
138         //    try { 
139
140         var self = this;
141         this.xhr.onreadystatechange = function () { self.xhr_cb(); };
142         this.xhr.send(null);
143         // 
144         // TODO: qui avvio del timer per riavviare xhr
145         // 
146         this.watchdog = setTimeout(function(obj){ obj.xhr_abort(); }, 60000, this);
147         this.cur_n++;
148         this.stopped = false;
149         // } catch (e) {}
150     },
151     
152     /* WORK HERE TO RUN WIN OR LIN STREAM */
153     
154     start: function(sess)
155     {
156         this.poll(sess);
157     },
158
159     stop: function()
160     {
161         this.the_end = true;
162     },
163
164     poll: function(sess)
165     {
166         var tout = 100;
167         var again;
168         var xhrrestart;
169         
170         this.ct++;
171         
172         /*
173           if (this.watchdog_old >= 50) {
174           this.watchdog_old = 0;
175           // alert("ABORT XHR");
176           this.stopped = true;
177           this.xhr.abort();     
178           }
179         */
180         var zug = "POLL sess = "+sess+" stat = "+stat+" subst = "+subst+" step = "+gst.st+" step_loc = "+gst.st_loc+" step_loc_new = "+gst.st_loc_new+" STOP: "+this.stopped;
181         
182         if (zug != $("sandbox").innerHTML)
183             $("sandbox").innerHTML = zug;
184         
185         /* heartbit log */
186         this.hbit("_");
187         do {
188             again = 0;
189             xhrrestart = 0;
190             if (gst.st_loc < gst.st_loc_new) {
191                 // there is some slow actions running
192                 break;
193             }
194             else if (gst.comms.length > 0) {
195                 var singlecomm;
196                 
197                 singlecomm = gst.comms.shift();
198                 // alert("EXE"+gugu);
199                 // $("xhrdeltalog").innerHTML = "EVALL: "+singlecomm.replace("<", "&lt;", "g"); +"<br>";
200                 this.hbit("+");
201                 
202                 eval(singlecomm);
203                 again = 1;
204             }
205             else {
206                 xhrrestart = 1;
207                 try { 
208                     if (this.xhr == null)
209                         throw "restart";
210                     if (this.xhr.responseText != null)
211                         this.newctx = this.xhr.responseText;
212                 }
213                 catch (e) {
214                     if (this.stopped == true) {
215                         this.stopped = false;
216                         // XX $("xhrstart").innerHTML += "XHRSTART: da catch<br>";
217                         if (this.delay > 0) {
218                             if (this.delayed == null) {
219                                 // console.log("XXX DI QUI "+this.delay);
220
221                                 this.delayed = setTimeout(
222                                     function(f_obj, f_sess, f_stat, f_subst, f_step){ f_obj.run(f_sess, f_stat, f_subst, f_step); },
223                                     this.delay, this, sess, stat, subst, gst.st);
224                                 // console.log("XXX DI QUI post"+this.delayed);
225                             }
226                         }
227                         else {
228                             // console.log("yyy DI QUI "+this.delay);
229                             this.run(sess, stat, subst, gst.st);
230                         }
231                     }
232                     
233                     
234                     // $("sandbox").innerHTML += "return 1<br>";
235                     if (this.the_end != true) {
236                         /* this.watchdog_old = 0; */
237                         setTimeout(function(obj, sess){ obj.poll(sess); }, tout, this, sess);
238                         
239                         // this.hbit(".");
240                         
241                     }
242                     else {
243                         //x alert("the_end2");
244                         if (this.watchdog != null) {
245                             clearTimeout(this.watchdog);
246                             this.watchdog = null;
247                         }
248                     }    
249                     return;
250                 }
251                 
252                 
253                 // no new char from the last loop, break
254                 if (this.old_n == this.cur_n && 
255                     this.newctx.length == this.checkedlen) {
256                     /* this.watchdog++; */
257                     break;
258                 }
259                 else {
260                     // $("sandbox").innerHTML += "BIG IF<br>";
261                     var comm_match;
262                     var comm_clean;
263                     var comm_len;
264                     var comm_newpart;
265                     var comm_arr;
266                     var i;
267                     var delta = 0;
268                     var match_lines = /^_*$/;
269                     
270                     /* this.watchdog = 0; */
271                     this.hbit("/\\");
272                     
273                     // check for the same command group
274                     if (this.old_n != this.cur_n) {
275                         this.old_n = this.cur_n;
276                         this.checkedlen = 0;
277                         this.oldctx = "";
278                     }
279                     else
280                         delta = this.oldctx.length;
281                     
282                     // $("xhrlog").innerHTML += "EVERY SEC<br>";                
283                     for (i = delta ; i < this.newctx.length ; i++) {
284                         if (this.newctx[i] != '_') 
285                             break;
286                     }
287                     if (i == this.newctx.length) {
288                         this.checkedlen = i;
289                         break;
290                     }
291                     
292                     // $("xhrlog").innerHTML += "CHECK COM<br>";                
293                     // extracts the new part of the command string
294                     comm_newpart = this.newctx.substr(delta);
295                     
296                     // XX $("xhrlog").innerHTML = newctx.replace("<", "&lt;", "g");
297                     
298                     // $("response").innerHTML = comm_newpart;
299                     comm_match = /_*@BEGIN@(.*?)@END@/g;
300                     comm_clean = /_*@BEGIN@(.*?)@END@/;
301                     comm_len = 0;
302                     comm_arr = comm_newpart.match(comm_match);
303                     
304                     // $("sandbox").innerHTML += "PRE COMMARR<br>";
305                     if (comm_arr) {
306                         // XX $("xhrdeltalog").innerHTML += "DELTA: "+delta +"<br>";
307                         // XX alert("newctx: "+this.newctx);
308                         // $("sandbox").innerHTML += "POST COMMARR<br>";
309                         for (i = 0 ; i < comm_arr.length ; i++) {
310                             var temp = comm_arr[i].replace(comm_clean,"$1").split("|");
311                             gst.comms = gst.comms.concat(temp);
312                             // XX alert("COMM_ARR["+i+"]: "+comm_arr[i]+"  LEN:"+comm_arr[i].length);
313                             comm_len += comm_arr[i].length;
314                         }
315                         tout = 0;
316                         this.oldctx += comm_newpart.substr(0,comm_len);
317                         // XX alert("OLDCTX: "+this.oldctx);
318                         again = 1;
319                     }
320                     this.checkedlen = this.oldctx.length;
321                 }
322             }
323         } while (again);
324
325         if (xhrrestart == 1 && this.stopped == true) {
326             // $("sandbox").innerHTML += "LITTLE IF<br>";
327             // alert("di qui");
328             // XX $("xhrstart").innerHTML += "XHRSTART: da end poll<br>";
329             if (this.delay > 0) {
330                 if (this.delayed == null) {
331                     // console.log("XXX DI QUO "+this.delay);
332                     
333                     this.delayed = setTimeout(
334                         function(obj, sess, stat, subst, step){ obj.run(sess, stat, subst, step); },
335                         this.delay, this, sess, stat, subst, gst.st);
336                     // console.log("XXX DI QUO post"+this.delayed);
337                 }
338             }
339             else {
340                 // console.log("yyy DI QUO "+this.delay);
341                 this.run(sess, stat, subst, gst.st);
342             }
343             
344         }
345         
346         if (this.the_end != true) {
347             setTimeout(function(obj, sess){ obj.poll(sess); }, tout, this, sess);
348         }
349         else {
350             //x alert("the_end3");
351             if (this.watchdog != null) {
352                 clearTimeout(this.watchdog);
353                 this.watchdog = null;
354             }
355         }
356         return;
357     }
358 }
359     
360 /*
361   window.onload = function () {
362   xhr = createXMLHttpRequest();
363
364   sess = $("user").value;
365   window.setTimeout(poll, 0, sess);
366   };
367 */