clean of string stream added (we still need <script> objects clean)
[xynt.git] / web / xynt / xynt-http-streaming.js
1 function globst() {
2     this.st = -1;
3     this.st_loc = -1;
4     this.st_loc_new = -1;
5     this.comms  = new Array;
6 }
7
8 globst.prototype = {
9     st: -1,
10     st_loc: -1,
11     st_loc_new: -1,
12     comms: null,
13     sleep_hd: null,
14
15     sleep: function(delay) {
16         st.st_loc_new++;
17
18         this.sleep_hdl = setTimeout(function(obj){ if (obj.st_loc_new > obj.st_loc) { obj.st_loc++; obj.sleep_hdl = null; }},
19                                    delay, this);
20     },
21
22     abort: function() {
23         if (this.sleep_hdl != null) {
24             clearTimeout(this.sleep_hdl);
25             this.sleep_hdl = null;
26         }
27     }
28 }
29
30 function http_streaming(win, gst, sess, cons)
31 {
32     this.console = cons;
33     this.win = win;
34     this.sess = sess;
35     this.doc = win.document;
36     this.keepalive_old = -1;
37     this.keepalive_new = -1;
38     this.gst = gst;
39     this.cmdproc = function(com){eval(com);}
40 }
41
42 http_streaming.prototype = {
43     console:           null,
44     win:               null,
45     doc:               null,
46     sess:              null,
47     ifra:              null,
48     page:              null,
49     watchdog_hdl:      null,
50     keepalive_old:    -1,
51     keepalive_new:    -1,
52     keepalives_equal:  0,
53     keepalives_eq_max: 6,
54     watchdog_timeout:  100,
55     watchdog_ct:       0,
56     watchdog_checktm:  20,
57     watchable:         false,
58     gst:               null,
59     restart_n:         0,
60     cmdproc:           null,
61     comm_match:        /_*@BEGIN@(.*?)@END@/g, 
62     comm_clean:        /_*@BEGIN@(.*?)@END@/,
63     stream:            "",
64
65     start: function(page) {
66         this.log("http_streaming:start restart: "+this.restart_n);
67         this.keepalives_equal = 0;
68         this.ifra = this.doc.createElement("iframe");
69         this.ifra.style.visibility = "hidden";
70         this.doc.body.appendChild(this.ifra);
71         if (page != null)
72             this.page = url_complete(this.win.location.href, page);
73         this.page = url_append_args(this.page, "sess", this.sess, "st", this.gst.st);
74         this.log(this.page);
75
76         // this.log(this.ifra);
77         this.ifra.contentWindow.location.href = this.page;
78         this.watchdog_ct  = 0;
79         this.watchdog_hdl = setTimeout(function(obj) { obj.log("tout1"); obj.watchdog(); }, this.watchdog_timeout, this);
80     },
81
82     watchdog: function () {
83         var i, again;
84         var comm_newpart, comm_len, comm_arr;
85         var ctx_new_len;
86
87         // WATCHDOGING THE CONNECTION
88         this.log("hs::watchdog: start, cur equal times: "+this.keepalives_equal);
89         if ( (this.watchdog_ct % this.watchdog_checktm) == 0 || !this.watchable) {
90             if (!this.watchable) {
91                 do {
92                     if (typeof(this.ifra.contentWindow.http_streaming) == 'undefined')
93                         break;
94                     /*
95                       on IE7 the the window frame scope is cleaned after the href is set, so we wait 
96                       for a well know variable value before assign this object value to it (OO is a passion)
97                     */
98                     if (this.ifra.contentWindow.http_streaming == "ready") {
99                         this.ifra.contentWindow.http_streaming = this;
100                         this.watchable = true;
101                         this.log("hs::watchdog: watchable = yes");
102                     }
103                 } while (false);
104             }
105             this.log("hs::watchdog: this.keepalive_old: "+this.keepalive_old+" this.keepalive_new: "+this.keepalive_new);
106             if (this.keepalive_old == this.keepalive_new) {
107                 this.keepalives_equal++;
108             }
109             else {
110                 this.keepalive_old = this.keepalive_new;
111                 this.keepalives_equal = 0;
112             }
113             
114             if (this.keepalives_equal > this.keepalives_eq_max) {
115                 this.log("hs::watchdog: MAX ACHIEVED "+this.keepalives_equal);
116                 this.reload();
117                 return;
118             }
119         }
120
121         // PICK COMMANDS FROM STREAM
122         do {
123             // CHECK: maybe again here isn't needed 
124             again = 0;
125             if (typeof(this.ifra.contentWindow.ctx_new)     == 'undefined' ||
126                 typeof(this.ifra.contentWindow.ctx_old_len) == 'undefined')
127                 break;
128             
129             ctx_new_len = this.ifra.contentWindow.ctx_new.length;
130             if (ctx_new_len <= this.ifra.contentWindow.ctx_old_len) {
131                 break;
132             }
133             this.log("new: "+ ctx_new_len + "  old: "+this.ifra.contentWindow.ctx_old_len);
134             this.keepalive_new++;            
135             for (i = this.ifra.contentWindow.ctx_old_len ; i < ctx_new_len ; i++) {
136                 if (this.ifra.contentWindow.ctx_new.charAt(i) != '_') {
137                     this.log("ctx_new.char(i) != '_' ["+this.ifra.contentWindow.ctx_new.charAt(i)+"]");
138                     break;
139                 }
140                 else {
141                     this.log("ctx_new.charAt(i) == '_'");
142                 }
143             }
144             this.ifra.contentWindow.ctx_old_len = i;
145             if (i == ctx_new_len) {
146                 this.log("old_len == i");
147                 break;
148             }
149             else {
150                 this.log("old_len != i: "+i);
151             }
152             comm_newpart = this.ifra.contentWindow.ctx_new.substr(this.ifra.contentWindow.ctx_old_len);    
153             comm_len = 0;
154             comm_arr = comm_newpart.match(this.comm_match);
155
156             if (comm_arr) {
157                 for (i = 0 ; i < comm_arr.length ; i++) {
158                     var temp = comm_arr[i].replace(this.comm_clean,"$1").split("|");
159
160                     this.gst.comms = this.gst.comms.concat(temp);
161                     // XX alert("COMM_ARR["+i+"]: "+comm_arr[i]+"  LEN:"+comm_arr[i].length);
162                     comm_len += comm_arr[i].length;
163                 }
164                 again = 1;
165             }
166             this.ifra.contentWindow.ctx_old_len += comm_len;
167         } while (again);
168         
169
170
171         // EXECUTION OF STREAM COMMANDS
172         do {
173             again = 0;
174             //MOP ?? xhrrestart = 0;
175             if (this.gst.st_loc < this.gst.st_loc_new) {
176                 // there is some slow actions running
177                 break;
178             }
179             else if (this.gst.comms.length > 0) {
180                 var singlecomm;
181                 
182                 singlecomm = this.gst.comms.shift();
183                 // alert("EXE"+gugu);
184                 // $("xhrdeltalog").innerHTML = "EVALL: "+singlecomm.replace("<", "&lt;", "g"); +"<br>";
185                 //xx this.hbit("+");
186                 
187                 this.cmdproc(singlecomm);
188                 again = 1;
189             }
190         } while (again);
191
192
193         this.watchdog_ct++;
194         this.watchdog_hdl = setTimeout(function(obj) { /* obj.log("tout2"); */ obj.watchdog(); }, this.watchdog_timeout, this);
195         return;
196     },
197     
198     keepalive: function (s) {
199         this.log("hs::keepalive");
200         if (s != null) {
201             this.log(s);
202             this.ifra.contentWindow.ctx_new += "@BEGIN@"+s+"@END@";
203         }
204         else {
205             this.ifra.contentWindow.ctx_new += "_";
206         }
207         // this.keepalive_new++;
208     },
209
210     abort: function () {
211         // this.log("PATH: "+this.ifra.contentWindow.location.protocol + "://" + this.ifra.contentWindow.location.host + "/" + this.ifra.contentWindow.location.pathname);
212
213         this.gst.abort();
214         if (this.watchdog_hdl != null) {
215             clearTimeout(this.watchdog_hdl);
216             this.watchdog_hdl = null;
217         }
218
219         this.restart_n++;
220         this.log("hs::reload");
221         this.watchable = false;
222         if (this.ifra != null) {
223             this.doc.body.removeChild(this.ifra);
224             delete this.ifra;
225             this.ifra = null;
226         }
227     },
228
229     reload: function () {
230         this.abort();
231         this.start(null);
232     },
233
234     log: function (s) {
235         if (this.console != null) {
236             return (this.console.log(s));
237         }
238     }
239 }