1 |
// Set domain at highest level |
/* |
2 |
var domainparts = document.domain.split("."); |
stream: xhrinteractive, iframe, serversent |
3 |
document.domain = domainparts[domainparts.length-2]+"."+domainparts[domainparts.length-1]; |
longpoll |
4 |
|
smartpoll |
5 |
Function.prototype.bind = function(obj) { |
simplepoll |
6 |
var method = this, |
*/ |
7 |
temp = function() { |
|
8 |
return method.apply(obj, arguments); |
Meteor = { |
9 |
}; |
|
10 |
return temp; |
callbacks: { |
11 |
} |
process: function() {}, |
12 |
Function.prototype.andThen=function(g) { |
reset: function() {}, |
13 |
var f=this; |
eof: function() {}, |
14 |
var a=this.arguments |
statuschanged: function() {}, |
15 |
return function(args) { |
changemode: function() {} |
16 |
f(a);g(args); |
}, |
17 |
} |
channelcount: 0, |
18 |
}; |
channels: {}, |
19 |
|
debugmode: false, |
20 |
function Meteor(instID) { |
frameref: null, |
21 |
|
host: null, |
22 |
this.lastmsgreceived = -1; |
hostid: null, |
23 |
this.transferDoc = false; |
maxpollfreq: 60000, |
24 |
this.pingtimer = false; |
minpollfreq: 2000, |
25 |
this.updatepollfreqtimer = false; |
mode: "stream", |
26 |
this.lastrequest = 0; |
pingtimeout: 20000, |
27 |
this.recvtimes = new Array(); |
pingtimer: null, |
28 |
this.MHostId = false; |
pollfreq: 3000, |
29 |
this.callback_process = function() {}; |
port: 80, |
30 |
this.callback_reset = function() {}; |
pollaborted: false, |
31 |
this.callback_eof = function() {}; |
pollhost: null, |
32 |
this.callback_changemode = function() {}; |
pollnum: 0, |
33 |
this.callback_statuschanged = function() {}; |
polltimeout: 30000, |
34 |
this.persist = true; |
polltimer: null, |
35 |
this.frameloadtimer = false; |
recvtimes: [], |
36 |
this.frameurl = false; |
lastrequest: null, |
37 |
this.debugmode = false; |
status: 0, |
38 |
|
updatepollfreqtimer: null, |
39 |
// Documented public properties |
|
40 |
this.channel = false; |
isSupportedBrowser: function() { |
41 |
this.subdomain = "data"; |
var v; |
42 |
this.dynamicpageaddress = "push"; |
if (v = navigator.userAgent.match(/compatible\; MSIE\ ([0-9\.]+)\;/i)) { |
43 |
this.backtrack = 0; |
if (parseFloat(v[1]) <= 5.5) return false; |
44 |
this.smartpoll = true; |
} else if (v = navigator.userAgent.match(/Gecko\/([0-9]+)/i)) { |
45 |
this.pollfreq = 2000; |
if (parseInt(v[1]) <= 20051015) return false; |
46 |
this.minpollfreq = 2000; |
} else if (v = navigator.userAgent.match(/WebKit\/([0-9\.]+)/i)) { |
47 |
this.mode = "poll"; |
if (parseFloat(v[1]) < 400) return false; |
48 |
this.polltimeout=30000; |
} |
49 |
this.maxmessages=0; |
return true; |
50 |
this.pingtimeout = 10000; |
}, |
51 |
this.status = 0; |
|
52 |
|
register: function(ifr) { |
53 |
/* Statuses: 0 = Uninitialised, |
ifr.p = Meteor.process; |
54 |
1 = Loading stream, |
ifr.r = Meteor.reset; |
55 |
2 = Loading controller frame, |
ifr.eof = Meteor.eof; |
56 |
3 = Controller frame timeout, retrying. |
ifr.ch = Meteor.channelInfo; |
57 |
4 = Controller frame loaded and ready |
clearTimeout(Meteor.frameloadtimer); |
58 |
5 = Receiving data |
Meteor.setstatus(4); |
59 |
*/ |
Meteor.log("Frame registered"); |
60 |
|
}, |
61 |
this.instID = (typeof(instID) != "undefined") ? instID : 0; |
|
62 |
this.MHostId = Math.floor(Math.random()*100000000)+""+this.instID; |
joinChannel: function(channelname, backtrack) { |
63 |
} |
if (typeof(Meteor.channels[channelname]) != "undefined") throw "Cannot join channel "+channelname+": already subscribed"; |
64 |
|
Meteor.channels[channelname] = {backtrack:backtrack}; |
65 |
Meteor.instances = new Array(); |
Meteor.log("Joined channel "+channelname); |
66 |
|
Meteor.channelcount++; |
67 |
Meteor.create = function(instID) { |
if (Meteor.status != 0 && Meteor.status != 6) Meteor.connect(); |
68 |
if (!instID) instID = Meteor.instances.length; |
}, |
69 |
Meteor.instances[instID] = new Meteor(instID); |
|
70 |
return Meteor.instances[instID]; |
leaveChannel: function(channelname) { |
71 |
} |
if (typeof(Meteor.channels[channelname]) == "undefined") throw "Cannot leave channel "+channelname+": not subscribed"; |
72 |
|
delete Meteor.channels[channelname]; |
73 |
Meteor.register = function(ifr) { |
Meteor.log("Left channel "+channelname); |
74 |
instid = new String(ifr.window.frameElement.id); |
Meteor.channelcount--; |
75 |
instid = instid.replace(/.*_([0-9]*)$/, "$1"); |
if (Meteor.channelcount && Meteor.status != 0 && Meteor.status != 6) Meteor.connect(); |
76 |
ifr.p = this.instances[instid].process.bind(this.instances[instid]); |
else Meteor.disconnect(); |
77 |
ifr.r = this.instances[instid].reset.bind(this.instances[instid]); |
}, |
78 |
ifr.eof = this.instances[instid].eof.bind(this.instances[instid]); |
|
79 |
ifr.get = this.instances[instid].get.bind(this.instances[instid]); |
connect: function() { |
80 |
ifr.increasepolldelay = this.instances[instid].increasepolldelay.bind(this.instances[instid]); |
if (!Meteor.host) throw "Meteor host not specified"; |
81 |
clearTimeout(this.instances[instid].frameloadtimer); |
if (isNaN(Meteor.port)) throw "Meteor port not specified"; |
82 |
this.instances[instid].setstatus(4); |
if (!Meteor.channelcount) throw "No channels specified"; |
83 |
if (this.debugmode) console.log("Frame registered"); |
if (Meteor.status) Meteor.disconnect(); |
84 |
} |
Meteor.log("Connecting"); |
85 |
|
Meteor.setstatus(1); |
86 |
Meteor.prototype.start = function() { |
if (!Meteor.hostid) Meteor.hostid = Meteor.time()+""+Math.floor(Math.random()*1000000) |
87 |
this.persist = (this.maxmessages)?1:0; |
document.domain = Meteor.extract_xss_domain(document.domain); |
88 |
this.smartpoll = (this.smartpoll)?1:0; |
if (Meteor.mode=="stream") Meteor.mode = Meteor.selectStreamTransport(); |
89 |
this.mode = (this.mode=="stream")?"stream":"poll"; |
Meteor.log("Selected "+Meteor.mode+" transport"); |
90 |
if (!this.subdomain || !this.channel) throw "Channel or Meteor subdomain host not specified"; |
if (Meteor.mode=="xhrinteractive" || Meteor.mode=="iframe" || Meteor.mode=="serversent") { |
91 |
this.stop(); |
if (Meteor.mode == "iframe") { |
92 |
var now = new Date(); |
Meteor.loadFrame(Meteor.getSubsUrl()); |
93 |
var t = now.getTime(); |
} else { |
94 |
this.setstatus(1); |
Meteor.loadFrame("http://"+Meteor.host+((Meteor.port==80)?"":":"+Meteor.port)+"/stream.html"); |
95 |
if (this.mode=="stream") { |
} |
96 |
var surl = "http://"+this.subdomain+"."+location.hostname+"/"+this.dynamicpageaddress+"?channel="+this.channel+"&id="+this.MHostId; |
clearTimeout(Meteor.pingtimer); |
97 |
if (this.lastmsgreceived >= 0) { |
Meteor.pingtimer = setTimeout(Meteor.pollmode, Meteor.pingtimeout); |
98 |
surl += "&restartfrom="+this.lastmsgreceived; |
|
99 |
} else if (this.backtrack > 0) { |
} else { |
100 |
surl += "&backtrack="+this.backtrack; |
Meteor.recvtimes[0] = Meteor.time(); |
101 |
} else if (this.backtrack < 0 || isNaN(this.backtrack)) { |
if (Meteor.updatepollfreqtimer) clearTimeout(Meteor.updatepollfreqtimer); |
102 |
surl += "&restartfrom="; |
if (Meteor.mode=='smartpoll') Meteor.updatepollfreqtimer = setInterval(Meteor.updatepollfreq, 10000); |
103 |
} |
if (Meteor.mode=='longpoll') Meteor.pollfreq = Meteor.minpollfreq; |
104 |
this.createIframe(surl); |
Meteor.poll(); |
105 |
var f = this.pollmode.bind(this); |
} |
106 |
clearTimeout(this.pingtimer); |
}, |
107 |
this.pingtimer = setTimeout(f, this.pingtimeout); |
|
108 |
|
disconnect: function() { |
109 |
} else { |
if (Meteor.status) { |
110 |
this.createIframe("http://"+this.subdomain+"."+location.hostname+"/poll.html"); |
if (Meteor.status != 6) Meteor.setstatus(0); |
111 |
this.recvtimes[0] = t; |
Meteor.clearpoll(); |
112 |
if (this.updatepollfreqtimer) clearTimeout(this.updatepollfreqtimer); |
clearTimeout(Meteor.pingtimer); |
113 |
this.updatepollfreqtimer = setInterval(this.updatepollfreq.bind(this), 2500); |
clearTimeout(Meteor.updatepollfreqtimer); |
114 |
} |
clearTimeout(Meteor.frameloadtimer); |
115 |
this.lastrequest = t; |
if (typeof CollectGarbage == 'function') CollectGarbage(); |
116 |
} |
Meteor.log("Disconnected"); |
117 |
|
try { Meteor.frameref.parentNode.removeChild(Meteor.frameref); delete Meteor.frameref; return true; } catch(e) { } |
118 |
Meteor.prototype.createIframe = function(url) { |
try { Meteor.frameref.open(); Meteor.frameref.close(); return true; } catch(e) {} |
119 |
if (document.all) { |
} |
120 |
this.transferDoc = new ActiveXObject("htmlfile"); |
}, |
121 |
this.transferDoc.open(); |
|
122 |
this.transferDoc.write("<html>"); |
selectStreamTransport: function() { |
123 |
this.transferDoc.write("<script>document.domain=\""+(document.domain)+"\";</"+"script>"); |
try { |
124 |
this.transferDoc.write("</html>"); |
var test = ActiveXObject; |
125 |
var selfref = this; |
return "iframe"; |
126 |
this.transferDoc.parentWindow.Meteor = Meteor; |
} catch (e) {} |
127 |
this.transferDoc.close(); |
if ((typeof window.addEventStream) == "function") return "iframe"; |
128 |
var ifrDiv = this.transferDoc.createElement("div"); |
return "xhrinteractive"; |
129 |
this.transferDoc.appendChild(ifrDiv); |
}, |
130 |
ifrDiv.innerHTML = "<iframe id=\"meteorframe_"+this.instID+"\" src=\""+url+"\" style=\"display: none;\"></iframe>"; |
|
131 |
} else { |
getSubsUrl: function() { |
132 |
var ifr = document.createElement("IFRAME"); |
var host = ((Meteor.mode=='simplepoll' || Meteor.mode=='smartpoll' || Meteor.mode=='longpoll') && Meteor.pollhost) ? Meteor.pollhost : Meteor.host; |
133 |
ifr.style.width = "10px"; |
var surl = "http://" + host + ((Meteor.port==80)?"":":"+Meteor.port) + "/push/" + Meteor.hostid + "/" + Meteor.mode; |
134 |
ifr.style.height = "10px"; |
for (var c in Meteor.channels) { |
135 |
ifr.style.border = "none"; |
surl += "/"+c; |
136 |
ifr.style.position = "absolute"; |
if (typeof Meteor.channels[c].lastmsgreceived != 'undefined') { |
137 |
ifr.style.top = "-10px"; |
surl += ".r"+(Meteor.channels[c].lastmsgreceived+1); |
138 |
ifr.style.marginTop = "-10px"; |
} else if (Meteor.channels[c].backtrack > 0) { |
139 |
ifr.style.zIndex = "-20"; |
surl += ".b"+Meteor.channels[c].backtrack; |
140 |
ifr.setAttribute("id", "meteorframe_"+this.instID); |
} else if (Meteor.channels[c].backtrack != undefined) { |
141 |
ifr.Meteor = Meteor; |
surl += ".h"; |
142 |
var innerifr = document.createElement("IFRAME"); |
} |
143 |
innerifr.setAttribute("src", url); |
} |
144 |
innerifr.setAttribute("id", "meteorinnerframe_"+this.instID); |
surl += "?nc="+Meteor.time(); |
145 |
ifr.appendChild(innerifr); |
return surl; |
146 |
document.body.appendChild(ifr); |
}, |
147 |
} |
|
148 |
if (this.debugmode) console.log("Loading URL '"+url+"' into frame..."); |
loadFrame: function(url) { |
149 |
var f = this.frameloadtimeout.bind(this); |
try { |
150 |
this.frameloadtimer = setTimeout(f, 5000); |
if (!Meteor.frameref) { |
151 |
} |
var transferDoc = new ActiveXObject("htmlfile"); |
152 |
|
Meteor.frameref = transferDoc; |
153 |
Meteor.prototype.stop = function() { |
} |
154 |
if (typeof(this.transferDoc)=="object") { |
Meteor.frameref.open(); |
155 |
this.transferDoc = false; |
Meteor.frameref.write("<html><script>"); |
156 |
} |
Meteor.frameref.write("document.domain=\""+(document.domain)+"\";"); |
157 |
if (document.getElementById("meteorframe_"+this.instID)) { |
Meteor.frameref.write("</"+"script></html>"); |
158 |
document.getElementById("meteorframe_"+this.instID).src="about:blank"; |
Meteor.frameref.parentWindow.Meteor = Meteor; |
159 |
document.body.removeChild(document.getElementById("meteorframe_"+this.instID)); |
Meteor.frameref.close(); |
160 |
} |
var ifrDiv = Meteor.frameref.createElement("div"); |
161 |
if (!isNaN(this.pingtimer)) clearTimeout(this.pingtimer); |
Meteor.frameref.appendChild(ifrDiv); |
162 |
if (!isNaN(this.updatepollfreqtimer)) clearTimeout(this.updatepollfreqtimer); |
ifrDiv.innerHTML = "<iframe src=\""+url+"\"></iframe>"; |
163 |
if (!isNaN(this.frameloadtimer)) clearTimeout(this.frameloadtimer); |
} catch (e) { |
164 |
this.setstatus(0); |
if (!Meteor.frameref) { |
165 |
} |
var ifr = document.createElement("IFRAME"); |
166 |
|
ifr.style.width = "10px"; |
167 |
Meteor.prototype.pollmode = function() { |
ifr.style.height = "10px"; |
168 |
if (this.debugmode) console.log("Ping timeout"); |
ifr.style.border = "none"; |
169 |
this.stop(); |
ifr.style.position = "absolute"; |
170 |
this.mode="poll"; |
ifr.style.top = "-10px"; |
171 |
this.start(); |
ifr.style.marginTop = "-10px"; |
172 |
this.callback_changemode("poll"); |
ifr.style.zIndex = "-20"; |
173 |
this.lastpingtime = false; |
ifr.Meteor = Meteor; |
174 |
} |
document.body.appendChild(ifr); |
175 |
|
Meteor.frameref = ifr; |
176 |
Meteor.prototype.process = function(id, data, timestamp) { |
} |
177 |
if (id > this.lastmsgreceived) { |
Meteor.frameref.setAttribute("src", url); |
178 |
this.callback_process(data, timestamp); |
} |
179 |
if (id != -1) this.lastmsgreceived = id; |
Meteor.log("Loading URL '"+url+"' into frame..."); |
180 |
if (this.mode=="poll") { |
Meteor.frameloadtimer = setTimeout(Meteor.frameloadtimeout, 5000); |
181 |
var now = new Date(); |
}, |
182 |
var t = now.getTime(); |
|
183 |
this.recvtimes[this.recvtimes.length] = t; |
pollmode: function() { |
184 |
while (this.recvtimes.length > 5) this.recvtimes.shift(); |
Meteor.log("Ping timeout"); |
185 |
} |
if (Meteor.mode != "smartpoll") { |
186 |
} else if (id == -1) { |
Meteor.mode="smartpoll"; |
187 |
this.ping(); |
Meteor.callbacks["changemode"]("poll"); |
188 |
} |
clearTimeout(Meteor.pingtimer); |
189 |
this.setstatus(5); |
Meteor.lastpingtime = false; |
190 |
} |
} |
191 |
|
Meteor.connect(); |
192 |
Meteor.prototype.ping = function() { |
}, |
193 |
if (this.mode=="stream" && this.pingtimer) { |
|
194 |
clearTimeout(this.pingtimer); |
process: function(id, channel, data) { |
195 |
var f = this.pollmode.bind(this); |
if (id == -1) { |
196 |
this.pingtimer = setTimeout(f, this.pingtimeout); |
Meteor.log("Ping"); |
197 |
var now = new Date(); |
Meteor.ping(); |
198 |
this.lastpingtime = now.getTime(); |
} else if (typeof(Meteor.channels[channel]) != "undefined") { |
199 |
} |
Meteor.log("Message "+id+" received on channel "+channel+" (last id on channel: "+Meteor.channels[channel].lastmsgreceived+")\n"+data); |
200 |
this.setstatus(5); |
Meteor.callbacks["process"](data); |
201 |
} |
Meteor.channels[channel].lastmsgreceived = id; |
202 |
|
if (Meteor.mode=="smartpoll") { |
203 |
Meteor.prototype.reset = function() { |
Meteor.recvtimes[Meteor.recvtimes.length] = Meteor.time(); |
204 |
if (this.debugmode) console.log("Stream reset"); |
while (Meteor.recvtimes.length > 5) Meteor.recvtimes.shift(); |
205 |
var now = new Date(); |
} |
206 |
var t = now.getTime(); |
} |
207 |
var x = this.pollfreq - (t-this.lastrequest); |
Meteor.setstatus(5); |
208 |
if (x < 10) x = 10; |
}, |
209 |
this.ping(); |
|
210 |
this.callback_reset(); |
ping: function() { |
211 |
setTimeout(this.start.bind(this), x); |
if (Meteor.pingtimer) { |
212 |
} |
clearTimeout(Meteor.pingtimer); |
213 |
|
Meteor.pingtimer = setTimeout(Meteor.pollmode, Meteor.pingtimeout); |
214 |
Meteor.prototype.eof = function() { |
Meteor.lastpingtime = Meteor.time(); |
215 |
this.callback_eof(); |
} |
216 |
} |
Meteor.setstatus(5); |
217 |
|
}, |
218 |
Meteor.prototype.get = function(varname) { |
|
219 |
eval("var a = this."+varname+";"); |
reset: function() { |
220 |
if (typeof(a) == "undefined") throw "Cannot get value of "+varname; |
if (Meteor.status != 6 && Meteor.status != 0) { |
221 |
return a; |
Meteor.log("Stream reset"); |
222 |
} |
Meteor.ping(); |
223 |
|
Meteor.callbacks["reset"](); |
224 |
Meteor.prototype.increasepolldelay = function() { |
var x = Meteor.pollfreq - (Meteor.time()-Meteor.lastrequest); |
225 |
this.pollfreq *= 2; |
if (x < 10) x = 10; |
226 |
} |
setTimeout(Meteor.connect, x); |
227 |
|
} |
228 |
Meteor.prototype.updatepollfreq = function() { |
}, |
229 |
if (this.smartpoll) { |
|
230 |
var now = new Date(); |
eof: function() { |
231 |
var t = now.getTime(); |
Meteor.log("Received end of stream, will not reconnect"); |
232 |
var avg = 0; |
Meteor.callbacks["eof"](); |
233 |
for (var i=1; i<this.recvtimes.length; i++) { |
Meteor.setstatus(6); |
234 |
var x = (this.recvtimes[i]-this.recvtimes[i-1]); |
Meteor.disconnect(); |
235 |
avg += (x>60000)? 60000 : x; |
}, |
236 |
} |
|
237 |
x = (t-this.recvtimes[this.recvtimes.length-1]); |
channelInfo: function(channel, id) { |
238 |
avg += (x>180000)? 180000 : x; |
Meteor.channels[channel].lastmsgreceived = id; |
239 |
avg /= this.recvtimes.length; |
Meteor.log("Received channel info for channel "+channel+": resume from "+id); |
240 |
if ((avg/3) < this.pollfreq && (avg/3) >= this.minpollfreq) this.pollfreq = Math.ceil(this.pollfreq*0.9); |
}, |
241 |
if ((avg/3) > this.pollfreq) this.pollfreq = Math.floor(this.pollfreq*1.05); |
|
242 |
} |
updatepollfreq: function() { |
243 |
} |
var avg = 0; |
244 |
|
for (var i=1; i<Meteor.recvtimes.length; i++) { |
245 |
Meteor.prototype.registerEventCallback = function(evt, funcRef) { |
avg += (Meteor.recvtimes[i]-Meteor.recvtimes[i-1]); |
246 |
if (evt=="process") { |
} |
247 |
this.callback_process = (this.callback_process).andThen(funcRef); |
avg += (Meteor.time()-Meteor.recvtimes[Meteor.recvtimes.length-1]); |
248 |
} else if (evt=="reset") { |
avg /= Meteor.recvtimes.length; |
249 |
this.callback_reset = (this.callback_reset).andThen(funcRef); |
var target = avg/2; |
250 |
} else if (evt=="eof") { |
if (target < Meteor.pollfreq && Meteor.pollfreq > Meteor.minpollfreq) Meteor.pollfreq = Math.ceil(Meteor.pollfreq*0.9); |
251 |
this.callback_eof = (this.callback_eof).andThen(funcRef); |
if (target > Meteor.pollfreq && Meteor.pollfreq < Meteor.maxpollfreq) Meteor.pollfreq = Math.floor(Meteor.pollfreq*1.05); |
252 |
} else if (evt=="changemode") { |
}, |
253 |
this.callback_changemode = (this.callback_changemode).andThen(funcRef); |
|
254 |
} else if (evt=="changestatus") { |
registerEventCallback: function(evt, funcRef) { |
255 |
this.callback_statuschanged = (this.callback_statuschanged).andThen(funcRef); |
Function.prototype.andThen=function(g) { |
256 |
} |
var f=this; |
257 |
} |
var a=Meteor.arguments |
258 |
|
return function(args) { |
259 |
Meteor.prototype.frameloadtimeout = function() { |
f(a);g(args); |
260 |
if (this.debugmode) console.log("Frame load timeout"); |
} |
261 |
if (this.frameloadtimer) clearTimeout(this.frameloadtimer); |
}; |
262 |
this.setstatus(3); |
if (typeof Meteor.callbacks[evt] == "function") { |
263 |
setTimeout(this.start.bind(this), 5000); |
Meteor.callbacks[evt] = (Meteor.callbacks[evt]).andThen(funcRef); |
264 |
} |
} else { |
265 |
Meteor.prototype.setstatus = function(newstatus) { |
Meteor.callbacks[evt] = funcRef; |
266 |
if (this.status != newstatus) { |
} |
267 |
this.status = newstatus; |
}, |
268 |
this.callback_statuschanged(newstatus); |
|
269 |
} |
frameloadtimeout: function() { |
270 |
} |
Meteor.log("Frame load timeout"); |
271 |
|
if (Meteor.frameloadtimer) clearTimeout(Meteor.frameloadtimer); |
272 |
Meteor.createCookie = function(name,value,days) { |
Meteor.setstatus(3); |
273 |
if (days) { |
Meteor.pollmode(); |
274 |
var date = new Date(); |
}, |
275 |
date.setTime(date.getTime()+(days*24*60*60*1000)); |
|
276 |
var expires = "; expires="+date.toGMTString(); |
extract_xss_domain: function(old_domain) { |
277 |
} |
if (old_domain.match(/^(\d{1,3}\.){3}\d{1,3}$/)) return old_domain; |
278 |
else var expires = ""; |
domain_pieces = old_domain.split('.'); |
279 |
document.cookie = name+"="+value+expires+"; path=/"; |
return domain_pieces.slice(-2, domain_pieces.length).join("."); |
280 |
} |
}, |
281 |
|
|
282 |
Meteor.readCookie = function(name) { |
setstatus: function(newstatus) { |
283 |
var nameEQ = name + "="; |
// Statuses: 0 = Uninitialised, |
284 |
var ca = document.cookie.split(';'); |
// 1 = Loading stream, |
285 |
for(var i=0;i < ca.length;i++) { |
// 2 = Loading controller frame, |
286 |
var c = ca[i]; |
// 3 = Controller frame timeout, retrying. |
287 |
while (c.charAt(0)==' ') c = c.substring(1,c.length); |
// 4 = Controller frame loaded and ready |
288 |
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); |
// 5 = Receiving data |
289 |
} |
// 6 = End of stream, will not reconnect |
290 |
return null; |
|
291 |
} |
if (Meteor.status != newstatus) { |
292 |
|
Meteor.status = newstatus; |
293 |
Meteor.eraseCookie = function(name) { |
Meteor.callbacks["statuschanged"](newstatus); |
294 |
createCookie(name,"",-1); |
} |
295 |
|
}, |
296 |
|
|
297 |
|
log: function(logstr) { |
298 |
|
if (Meteor.debugmode) { |
299 |
|
if (window.console) { |
300 |
|
window.console.log(logstr); |
301 |
|
} else if (document.getElementById("meteorlogoutput")) { |
302 |
|
document.getElementById("meteorlogoutput").innerHTML += logstr+"<br/>"; |
303 |
|
} |
304 |
|
} |
305 |
|
}, |
306 |
|
|
307 |
|
poll: function() { |
308 |
|
Meteor.pollaborted = 0; |
309 |
|
try { |
310 |
|
clearTimeout(Meteor.polltimer); |
311 |
|
} catch (e) {}; |
312 |
|
Meteor.lastrequest = Meteor.time(); |
313 |
|
if (Meteor.polltimeout) Meteor.polltimer = setTimeout(Meteor.clearpoll, Meteor.polltimeout); |
314 |
|
var scripttag = document.createElement("SCRIPT"); |
315 |
|
scripttag.type = "text/javascript"; |
316 |
|
scripttag.src = Meteor.getSubsUrl(); |
317 |
|
scripttag.id = "meteorpoll"+(++Meteor.pollnum); |
318 |
|
scripttag.className = "meteorpoll"; |
319 |
|
document.getElementsByTagName("HEAD")[0].appendChild(scripttag); |
320 |
|
}, |
321 |
|
|
322 |
|
clearpoll: function() { |
323 |
|
if (document.getElementById('meteorpoll'+Meteor.pollnum)) { |
324 |
|
var s = document.getElementById('meteorpoll'+Meteor.pollnum); |
325 |
|
s.parentNode.removeChild(s); |
326 |
|
} |
327 |
|
if (Meteor.status == 5) { |
328 |
|
var x = parent.Meteor.pollfreq - (Meteor.time()-Meteor.lastrequest); |
329 |
|
if (x < 10) x = 10; |
330 |
|
setTimeout(Meteor.poll, x); |
331 |
|
} |
332 |
|
}, |
333 |
|
|
334 |
|
time: function() { |
335 |
|
var now = new Date(); |
336 |
|
return now.getTime(); |
337 |
|
} |
338 |
|
} |
339 |
|
|
340 |
|
var oldonunload = window.onunload; |
341 |
|
if (typeof window.onunload != 'function') { |
342 |
|
window.onunload = Meteor.disconnect; |
343 |
|
} else { |
344 |
|
window.onunload = function() { |
345 |
|
if (oldonunload) oldonunload(); |
346 |
|
Meteor.disconnect(); |
347 |
|
} |
348 |
} |
} |