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