a72599ce06b627a4d8f60aa3f0513256491a9aee
[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  *   - gst management
28  *   - sandbox management
29  *   - myfrom into the constructor
30  *   - target page into the constructor
31  *   - type of streaming into the constructor
32  *   - all iframe related streaming add
33  *   - xhr_rd prefix remove from inner class attrs
34  *   - substitute fixed "eval" with a generic command hunks processor
35  *
36  */
37
38 function hbit(symb)
39 {
40     if ($("heartbit").innerHTML.length >= 120) {
41         $("heartbit").innerHTML = $("heartbit").innerHTML.substring(10);
42         $("heartbit").innerHTML += symb;
43     }
44     else {
45         $("heartbit").innerHTML += symb;
46     }
47     // $("heartbit").innerHTML = $("heartbit").innerHTML.substring(20,20); // DA METTERE APPOSTO!!!!
48     // console.log($("heartbit").innerHTML);
49         
50 }
51
52 function http_streaming()
53 {
54     this.xhr_rd = createXMLHttpRequest();
55 }
56
57 http_streaming.prototype = {
58     xhr_rd_cookiepath: "/brisk/",
59
60     xhr_rd: null,
61     xhr_rd_watchdog: null,
62     xhr_rd_delay: 0,
63     xhr_rd_delayed: null,
64     xhr_rd_stopped: true,
65     the_end: false,
66     xhr_rd_oldctx: "",
67     xhr_rd_newctx: "",
68     xhr_rd_cur_n: -1,
69     xhr_rd_old_n: -1,
70     xhr_rd_checkedlen: 0,
71     watchdog: 0,
72     ct: 0,
73
74     hbit: function () {
75     },
76
77     hbit_set: function (hbit) {
78         this.hbit = hbit;
79     },
80
81     xhr_rd_cb: function () {
82         var ret;
83         
84         if (this.xhr_rd.readyState == 4) {
85             if (this.xhr_rd_watchdog != null) {
86                 this.hbit('C');
87                 clearTimeout(this.xhr_rd_watchdog);
88                 this.xhr_rd_watchdog = null;
89             }
90             
91             // console.log("SS: "+safestatus(xhr_rd));
92             
93             try {
94                 if ((ret = safestatus(this.xhr_rd)) == 200) {
95                     this.xhr_rd_delay = 0;
96                     // console.log("del a null "+this.xhr_rd_delayed);
97                 } else if (ret != -1) {
98                     this.xhr_rd_delay = 5000;
99                     this.hbit('X');
100                     // alert('There was a problem with the request.' + ret);
101                 }
102             } catch(b) {};
103             
104             this.xhr_rd_delayed = null;
105             this.xhr_rd_stopped = true;
106         }
107     },
108
109     xhr_rd_abort: function()
110     {
111         this.hbit('A');
112         if (this.xhr_rd != null)
113             this.xhr_rd.abort();
114         // alert("de che");
115     },
116
117     xhr_rd_start: function(sess, stat, subst, step) 
118     {
119         if (this.the_end) {
120             //x alert("the_end1");
121             if (this.xhr_rd_watchdog != null) {
122                 this.hbit('C');
123                 clearTimeout(this.xhr_rd_watchdog);
124                 this.xhr_rd_watchdog = null;
125             }
126             return;
127         }
128         createCookie("sess", sess, 24*365, this.xhr_rd_cookiepath);
129         
130         // NOTE: *ctx = "" to prevent konqueror stream commands duplication.
131         this.xhr_rd_oldctx = "";
132         this.xhr_rd_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_rd.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_rd.onreadystatechange = function () { self.xhr_rd_cb(); };
142         this.xhr_rd.send(null);
143         // 
144         // TODO: qui avvio del timer per riavviare xhr
145         // 
146         this.xhr_rd_watchdog = setTimeout(function(obj){ obj.xhr_rd_abort(); }, 60000, this);
147         this.xhr_rd_cur_n++;
148         this.xhr_rd_stopped = false;
149         // } catch (e) {}
150     },
151     
152     /* WORK HERE TO RUN WIN OR LIN STREAM */
153     
154     xhr_rd_poll: function(sess)
155     {
156         var tout = 100;
157         var again;
158         var xhrrestart;
159         
160         this.ct++;
161         
162         /*
163           if (this.watchdog >= 50) {
164           this.watchdog = 0;
165           // alert("ABORT XHR_RD");
166           this.xhr_rd_stopped = true;
167           this.xhr_rd.abort();  
168           }
169         */
170         var zug = "XHR_RD_POLL sess = "+sess+" stat = "+stat+" subst = "+subst+" step = "+gst.st+" step_loc = "+gst.st_loc+" step_loc_new = "+gst.st_loc_new+" STOP: "+this.xhr_rd_stopped;
171         
172         if (zug != $("sandbox").innerHTML)
173             $("sandbox").innerHTML = zug;
174         
175         /* heartbit log */
176         this.hbit("_");
177         do {
178             again = 0;
179             xhrrestart = 0;
180             if (gst.st_loc < gst.st_loc_new) {
181                 // there is some slow actions running
182                 break;
183             }
184             else if (gst.comms.length > 0) {
185                 var singlecomm;
186                 
187                 singlecomm = gst.comms.shift();
188                 // alert("EXE"+gugu);
189                 // $("xhrdeltalog").innerHTML = "EVALL: "+singlecomm.replace("<", "&lt;", "g"); +"<br>";
190                 this.hbit("+");
191                 
192                 eval(singlecomm);
193                 again = 1;
194             }
195             else {
196                 xhrrestart = 1;
197                 try { 
198                     if (this.xhr_rd == null)
199                         throw "restart";
200                     if (this.xhr_rd.responseText != null)
201                         this.xhr_rd_newctx = this.xhr_rd.responseText;
202                 }
203                 catch (e) {
204                     if (this.xhr_rd_stopped == true) {
205                         this.xhr_rd_stopped = false;
206                         // XX $("xhrstart").innerHTML += "XHRSTART: da catch<br>";
207                         if (this.xhr_rd_delay > 0) {
208                             if (this.xhr_rd_delayed == null) {
209                                 // console.log("XXX DI QUI "+this.xhr_rd_delay);
210
211                                 this.xhr_rd_delayed = setTimeout(
212                                     function(f_obj, f_sess, f_stat, f_subst, f_step){ f_obj.xhr_rd_start(f_sess, f_stat, f_subst, f_step); },
213                                     this.xhr_rd_delay, this, sess, stat, subst, gst.st);
214                                 // console.log("XXX DI QUI post"+this.xhr_rd_delayed);
215                             }
216                         }
217                         else {
218                             // console.log("yyy DI QUI "+this.xhr_rd_delay);
219                             this.xhr_rd_start(sess, stat, subst, gst.st);
220                         }
221                     }
222                     
223                     
224                     // $("sandbox").innerHTML += "return 1<br>";
225                     if (this.the_end != true) {
226                         this.watchdog = 0;
227                         setTimeout(function(obj, sess){ obj.xhr_rd_poll(sess); }, tout, this, sess);
228                         
229                         // this.hbit(".");
230                         
231                     }
232                     else {
233                         //x alert("the_end2");
234                         if (this.xhr_rd_watchdog != null) {
235                             clearTimeout(this.xhr_rd_watchdog);
236                             this.xhr_rd_watchdog = null;
237                         }
238                     }    
239                     return;
240                 }
241                 
242                 
243                 // no new char from the last loop, break
244                 if (this.xhr_rd_old_n == this.xhr_rd_cur_n && 
245                     this.xhr_rd_newctx.length == this.xhr_rd_checkedlen) {
246                     this.watchdog++;
247                     break;
248                 }
249                 else {
250                     // $("sandbox").innerHTML += "BIG IF<br>";
251                     var comm_match;
252                     var comm_clean;
253                     var comm_len;
254                     var comm_newpart;
255                     var comm_arr;
256                     var i;
257                     var delta = 0;
258                     var match_lines = /^_*$/;
259                     
260                     this.watchdog = 0;
261                     this.hbit("/\\");
262                     
263                     // check for the same command group
264                     if (this.xhr_rd_old_n != this.xhr_rd_cur_n) {
265                         this.xhr_rd_old_n = this.xhr_rd_cur_n;
266                         this.xhr_rd_checkedlen = 0;
267                         this.xhr_rd_oldctx = "";
268                     }
269                     else
270                         delta = this.xhr_rd_oldctx.length;
271                     
272                     // $("xhrlog").innerHTML += "EVERY SEC<br>";                
273                     for (i = delta ; i < this.xhr_rd_newctx.length ; i++) {
274                         if (this.xhr_rd_newctx[i] != '_') 
275                             break;
276                     }
277                     if (i == this.xhr_rd_newctx.length) {
278                         this.xhr_rd_checkedlen = i;
279                         break;
280                     }
281                     
282                     // $("xhrlog").innerHTML += "CHECK COM<br>";                
283                     // extracts the new part of the command string
284                     comm_newpart = this.xhr_rd_newctx.substr(delta);
285                     
286                     // XX $("xhrlog").innerHTML = xhr_rd_newctx.replace("<", "&lt;", "g");
287                     
288                     // $("response").innerHTML = comm_newpart;
289                     comm_match = /_*@BEGIN@(.*?)@END@/g;
290                     comm_clean = /_*@BEGIN@(.*?)@END@/;
291                     comm_len = 0;
292                     comm_arr = comm_newpart.match(comm_match);
293                     
294                     // $("sandbox").innerHTML += "PRE COMMARR<br>";
295                     if (comm_arr) {
296                         // XX $("xhrdeltalog").innerHTML += "DELTA: "+delta +"<br>";
297                         // XX alert("xhr_rd_newctx: "+this.xhr_rd_newctx);
298                         // $("sandbox").innerHTML += "POST COMMARR<br>";
299                         for (i = 0 ; i < comm_arr.length ; i++) {
300                             var temp = comm_arr[i].replace(comm_clean,"$1").split("|");
301                             gst.comms = gst.comms.concat(temp);
302                             // XX alert("COMM_ARR["+i+"]: "+comm_arr[i]+"  LEN:"+comm_arr[i].length);
303                             comm_len += comm_arr[i].length;
304                         }
305                         tout = 0;
306                         this.xhr_rd_oldctx += comm_newpart.substr(0,comm_len);
307                         // XX alert("XHR_RD_OLDCTX: "+this.xhr_rd_oldctx);
308                         again = 1;
309                     }
310                     this.xhr_rd_checkedlen = this.xhr_rd_oldctx.length;
311                 }
312             }
313         } while (again);
314
315         if (xhrrestart == 1 && this.xhr_rd_stopped == true) {
316             // $("sandbox").innerHTML += "LITTLE IF<br>";
317             // alert("di qui");
318             // XX $("xhrstart").innerHTML += "XHRSTART: da end poll<br>";
319             if (this.xhr_rd_delay > 0) {
320                 if (this.xhr_rd_delayed == null) {
321                     // console.log("XXX DI QUO "+this.xhr_rd_delay);
322                     
323                     this.xhr_rd_delayed = setTimeout(
324                         function(obj, sess, stat, subst, step){ obj.xhr_rd_start(sess, stat, subst, step); },
325                         this.xhr_rd_delay, this, sess, stat, subst, gst.st);
326                     // console.log("XXX DI QUO post"+this.xhr_rd_delayed);
327                 }
328             }
329             else {
330                 // console.log("yyy DI QUO "+this.xhr_rd_delay);
331                 this.xhr_rd_start(sess, stat, subst, gst.st);
332             }
333             
334         }
335         
336         if (this.the_end != true) {
337             setTimeout(function(obj, sess){ obj.xhr_rd_poll(sess); }, tout, this, sess);
338         }
339         else {
340             //x alert("the_end3");
341             if (this.xhr_rd_watchdog != null) {
342                 clearTimeout(this.xhr_rd_watchdog);
343                 this.xhr_rd_watchdog = null;
344             }
345         }
346         return;
347     }
348 }
349     
350 /*
351   window.onload = function () {
352   xhr_rd = createXMLHttpRequest();
353
354   sess = $("user").value;
355   window.setTimeout(xhr_rd_poll, 0, sess);
356   };
357 */