/[meteor]/googlecode.com/svn/trunk/public_html/meteor.js
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /googlecode.com/svn/trunk/public_html/meteor.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (hide annotations)
Tue Nov 21 09:49:07 2006 UTC (17 years, 5 months ago) by andrew.betts
File MIME type: application/javascript
File size: 8752 byte(s)
changed line endings

1 andrew.betts 6 // Set domain at highest level
2     var domainparts = document.domain.split(".");
3     document.domain = domainparts[domainparts.length-2]+"."+domainparts[domainparts.length-1];
4    
5     Function.prototype.bind = function(obj) {
6     var method = this,
7     temp = function() {
8     return method.apply(obj, arguments);
9     };
10     return temp;
11     }
12     Function.prototype.andThen=function(g) {
13     var f=this;
14     var a=this.arguments
15     return function(args) {
16     f(a);g(args);
17     }
18     };
19    
20     function Meteor(instID) {
21    
22     this.lastmsgreceived = -1;
23     this.transferDoc = false;
24     this.pingtimer = false;
25     this.updatepollfreqtimer = false;
26     this.lastrequest = 0;
27     this.recvtimes = new Array();
28     this.MHostId = false;
29     this.callback_process = function() {};
30     this.callback_reset = function() {};
31     this.callback_eof = function() {};
32     this.callback_changemode = function() {};
33     this.persist = true;
34    
35     // Documented public properties
36     this.channel = false;
37     this.subdomain = "data";
38     this.dynamicpageaddress = "push";
39     this.backtrack = 0;
40     this.smartpoll = true;
41     this.pollfreq = 2000;
42     this.minpollfreq = 2000;
43     this.mode = "stream";
44     this.polltimeout=30000;
45     this.maxmessages=0;
46     this.pingtimeout = 10000;
47    
48     // Set or retrieve host id. Cookie takes this form:
49     // MeteorID=123:6356353/124:098320454;
50     var MeteIds = Meteor.readCookie("MeteorID");
51     var regex1 = new RegExp("^([0-9\:\/M]+\/)*"+instID+"\:([^\/]+)(\/[0-9\:\/M]+)*$");
52     var regex2 = new RegExp("^([0-9\:\/M]+\/)*M\:([^\/]+)(\/[0-9\:\/M]+)*$");
53     if (typeof(instID) == "Number" && regex1.exec(MeteIds)) {
54     this.MHostId = ma[2];
55     } else if (typeof(instID) == "Number") {
56     this.MHostId = Math.floor(Math.random()*1000000);
57     var newcookie = (MeteIds)?MeteIds+"/":"";
58     newcookie += instID+":"+this.MHostId;
59     Meteor.createCookie("MeteorID", newcookie);
60     } else if (ma = regex2.exec(MeteIds)) {
61     this.MHostId = ma[2];
62     } else {
63     this.MHostId = Math.floor(Math.random()*1000000);
64     var newcookie = (MeteIds)?MeteIds+"/":"";
65     newcookie += "M:"+this.MHostId;
66     Meteor.createCookie("MeteorID", newcookie);
67     }
68     this.instID = (typeof(instID) != "undefined") ? instID : 0;
69     }
70    
71     Meteor.instances = new Array();
72     Meteor.servertimeoffset = 0;
73    
74     Meteor.create = function(instID) {
75     if (!instID) instID = 0;
76     Meteor.instances[instID] = new Meteor(instID);
77     return Meteor.instances[instID];
78     }
79    
80     Meteor.register = function(ifr) {
81     instid = new String(ifr.window.frameElement.id);
82     instid = instid.replace("meteorframe_", "");
83     ifr.p = this.instances[instid].process.bind(this.instances[instid]);
84     ifr.r = this.instances[instid].reset.bind(this.instances[instid]);
85     ifr.eof = this.instances[instid].eof.bind(this.instances[instid]);
86     ifr.get = this.instances[instid].get.bind(this.instances[instid]);
87     ifr.increasepolldelay = this.instances[instid].increasepolldelay.bind(this.instances[instid]);
88     }
89    
90     Meteor.setServerTime = function(timestamp) {
91     var now = new Date();
92     var clienttime = (now.getTime() / 1000);
93     Meteor.servertimeoffset = timestamp - clienttime;
94     }
95    
96     Meteor.prototype.start = function() {
97     this.persist = (this.maxmessages)?1:0;
98     this.smartpoll = (this.smartpoll)?1:0;
99     this.mode = (this.mode=="stream")?"stream":"poll";
100     if (!this.subdomain || !this.channel) throw "Channel or Meteor subdomain host not specified";
101     var now = new Date();
102     var t = now.getTime();
103     if (typeof(this.transferDoc)=="object") {
104     this.transferDoc.open();
105     this.transferDoc.close();
106     delete this.transferDoc;
107     }
108     if (document.getElementById("meteorframe_"+this.instID)) {
109     document.body.removeChild(document.getElementById("meteorframe_"+this.instID));
110     }
111     if (this.mode=="stream") {
112     if (document.all) {
113     this.transferDoc = new ActiveXObject("htmlfile");
114     this.transferDoc.open();
115     this.transferDoc.write("<html>");
116     this.transferDoc.write("<script>document.domain=\""+(document.domain)+"\";</"+"script>");
117     this.transferDoc.write("</html>");
118     var selfref = this;
119     this.transferDoc.parentWindow.Meteor = Meteor;
120     this.transferDoc.close();
121     var ifrDiv = this.transferDoc.createElement("div");
122     this.transferDoc.appendChild(ifrDiv);
123     var url = "http://"+this.subdomain+"."+location.hostname+"/"+this.dynamicpageaddress+"?channel="+this.channel+"&id="+this.MHostId;
124     if (this.lastmsgreceived >= 0) {
125     url += "&restartfrom="+this.lastmsgreceived;
126     } else if (this.backtrack > 0) {
127     url += "&backtrack="+this.backtrack;
128     } else if (this.backtrack < 0 || isNaN(this.backtrack)) {
129     url += "&restartfrom=";
130     }
131     ifrDiv.innerHTML = "<iframe id=\"meteorframe_"+this.instID+"\" src=\""+url+"&nocache="+t+"\" style=\"display: none;\"></iframe>";
132     } else {
133     var ifr = document.createElement("IFRAME");
134     ifr.style.width = "10px";
135     ifr.style.height = "10px";
136     ifr.style.border = "none";
137     ifr.style.position = "absolute";
138     ifr.style.top = "-10px";
139     ifr.style.marginTop = "-10px";
140     ifr.style.zIndex = "-20";
141     ifr.id = "meteorframe_"+this.instID;
142     document.body.appendChild(ifr);
143     ifr.src = "http://"+this.subdomain+"."+location.hostname+"/stream.html?nocache="+t;
144     }
145     var f = this.pollmode.bind(this);
146     clearTimeout(this.pingtimer);
147     this.pingtimer = setTimeout(f, this.pingtimeout);
148    
149     } else {
150     var ifr = document.createElement("IFRAME");
151     ifr.style.width = "10px";
152     ifr.style.height = "10px";
153     ifr.style.border = "none";
154     if (document.all) {
155     ifr.style.display = "none";
156     } else {
157     ifr.style.position = "absolute";
158     ifr.style.marginTop = "-10px";
159     ifr.style.zIndex = "-20";
160     }
161     ifr.id = "meteorframe_"+this.instID;
162     document.body.appendChild(ifr);
163     ifr.src = "http://"+this.subdomain+"."+location.hostname+"/poll.html?nocache="+t;
164     this.recvtimes[0] = t;
165     if (this.updatepollfreqtimer) clearTimeout(this.updatepollfreqtimer);
166     this.updatepollfreqtimer = setInterval(this.updatepollfreq.bind(this), 2500);
167     }
168     this.lastrequest = t;
169     }
170    
171     Meteor.prototype.pollmode = function() {
172     this.mode="poll";
173     this.start();
174     this.callback_changemode("poll");
175     }
176    
177     Meteor.prototype.process = function(id, data) {
178     if (id > this.lastmsgreceived) {
179     this.callback_process(data);
180     if (id != -1) this.lastmsgreceived = id;
181     if (this.mode=="poll") {
182     var now = new Date();
183     var t = now.getTime();
184     this.recvtimes[this.recvtimes.length] = t;
185     while (this.recvtimes.length > 5) this.recvtimes.shift();
186     }
187     } else if (id == -1) {
188     this.ping();
189     }
190     }
191    
192     Meteor.prototype.ping = function() {
193     if (this.mode=="stream" && this.pingtimer) {
194     clearTimeout(this.pingtimer);
195     var f = this.pollmode.bind(this);
196     this.pingtimer = setTimeout(f, this.pingtimeout);
197     var now = new Date();
198     this.lastpingtime = now.getTime();
199     }
200     }
201    
202     Meteor.prototype.reset = function() {
203     var now = new Date();
204     var t = now.getTime();
205     var x = this.pollfreq - (t-this.lastrequest);
206     if (x < 10) x = 10;
207     this.ping();
208     this.callback_reset();
209     setTimeout(this.start.bind(this), x);
210     }
211    
212     Meteor.prototype.eof = function() {
213     this.callback_eof();
214     }
215    
216     Meteor.prototype.get = function(varname) {
217     eval("var a = this."+varname+";");
218     if (typeof(a) == "undefined") throw "Cannot get value of "+varname;
219     return a;
220     }
221    
222     Meteor.prototype.increasepolldelay = function() {
223     this.pollfreq *= 2;
224     }
225    
226     Meteor.prototype.updatepollfreq = function() {
227     if (this.smartpoll) {
228     var now = new Date();
229     var t = now.getTime();
230     var avg = 0;
231     for (var i=1; i<this.recvtimes.length; i++) {
232     var x = (this.recvtimes[i]-this.recvtimes[i-1]);
233     avg += (x>60000)? 60000 : x;
234     }
235     x = (t-this.recvtimes[this.recvtimes.length-1]);
236     avg += (x>180000)? 180000 : x;
237     avg /= this.recvtimes.length;
238     if ((avg/3) < this.pollfreq && (avg/3) >= this.minpollfreq) this.pollfreq = Math.ceil(this.pollfreq*0.9);
239     if ((avg/3) > this.pollfreq) this.pollfreq = Math.floor(this.pollfreq*1.05);
240     }
241     }
242    
243     Meteor.prototype.registerEventCallback = function(evt, funcRef) {
244     if (evt=="process") {
245     this.callback_process = (this.callback_process).andThen(funcRef);
246     } else if (evt=="reset") {
247     this.callback_reset = (this.callback_reset).andThen(funcRef);
248     } else if (evt=="eof") {
249     this.callback_eof = (this.callback_eof).andThen(funcRef);
250     } else if (evt=="changemode") {
251     this.callback_changemode = (this.callback_changemode).andThen(funcRef);
252     }
253     }
254    
255    
256     Meteor.createCookie = function(name,value,days) {
257     if (days) {
258     var date = new Date();
259     date.setTime(date.getTime()+(days*24*60*60*1000));
260     var expires = "; expires="+date.toGMTString();
261     }
262     else var expires = "";
263     document.cookie = name+"="+value+expires+"; path=/";
264     }
265    
266     Meteor.readCookie = function(name) {
267     var nameEQ = name + "=";
268     var ca = document.cookie.split(';');
269     for(var i=0;i < ca.length;i++) {
270     var c = ca[i];
271     while (c.charAt(0)==' ') c = c.substring(1,c.length);
272     if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
273     }
274     return null;
275     }
276    
277     Meteor.eraseCookie = function(name) {
278     createCookie(name,"",-1);
279 andrew.betts 3 }

  ViewVC Help
Powered by ViewVC 1.1.26