?? repubsubio.js
字號:
// Copyright (c) 2004 Friendster Inc., Licensed under the Academic Free// License version 2.0 or later dojo.require("dojo.event.Event");dojo.require("dojo.event.BrowserEvent");dojo.require("dojo.io.BrowserIO");dojo.provide("dojo.io.RepubsubIO");dojo.provide("dojo.io.repubsub");dojo.provide("dojo.io.repubsubTransport");dojo.io.repubsubTranport = new function(){ var rps = dojo.io.repubsub; this.canHandle = function(kwArgs){ if((kwArgs["mimetype"] == "text/javascript")&&(kwArgs["method"] == "repubsub")){ return true; } return false; } this.bind = function(kwArgs){ if(!rps.isInitialized){ // open up our tunnel, queue up requests anyway rps.init(); } // FIXME: we need to turn this into a topic subscription // var tgtURL = kwArgs.url+"?"+dojo.io.argsFromMap(kwArgs.content); // sampleTransport.sendRequest(tgtURL, hdlrFunc); // a normal "bind()" call in a request-response transport layer is // something that (usually) encodes most of it's payload with the // request. Multi-event systems like repubsub are a bit more complex, // and repubsub in particular distinguishes the publish and subscribe // portions of thep rocess with different method calls to handle each. // Therefore, a "bind" in the sense of repubsub must first determine if // we have an open subscription to a channel provided by the server, // and then "publish" the request payload if there is any. We therefore // must take care not to incorrectly or too agressively register or // file event handlers which are provided with the kwArgs method. // NOTE: we ONLY pay attention to those event handlers that are // registered with the bind request that subscribes to the channel. If // event handlers are provided with subsequent requests, we might in // the future support some additive or replacement syntax, but for now // they get dropped on the floor. // NOTE: in this case, url MUST be the "topic" to which we // subscribe/publish for this channel if(!rps.topics[kwArgs.url]){ kwArgs.rpsLoad = function(evt){ kwArgs.load("load", evt); } rps.subscribe(kwArgs.url, kwArgs, "rpsLoad"); } if(kwArgs["content"]){ // what we wanted to send var cEvt = dojo.io.repubsubEvent.initFromProperties(kwArgs.content); rps.publish(kwArgs.url, cEvt); } } dojo.io.transports.addTransport("repubsubTranport");}dojo.io.repubsub = new function(){ this.initDoc = "init.html"; this.isInitialized = false; this.subscriptionBacklog = []; this.debug = true; this.rcvNodeName = null; this.sndNodeName = null; this.rcvNode = null; this.sndNode = null; this.canRcv = false; this.canSnd = false; this.canLog = false; this.sndTimer = null; this.windowRef = window; this.backlog = []; this.tunnelInitCount = 0; this.tunnelFrameKey = "tunnel_frame"; this.serverBaseURL = location.protocol+"//"+location.host+location.pathname; this.logBacklog = []; this.getRandStr = function(){ return Math.random().toString().substring(2, 10); } this.userid = "guest"; this.tunnelID = this.getRandStr(); this.attachPathList = []; this.topics = []; // list of topics we have listeners to // actually, now that I think about it a little bit more, it would sure be // useful to parse out the <script> src attributes. We're looking for // something with a "do_method=lib", since that's what would have included // us in the first place (in the common case). this.parseGetStr = function(){ var baseUrl = document.location.toString(); var params = baseUrl.split("?", 2); if(params.length > 1){ var paramStr = params[1]; var pairs = paramStr.split("&"); var opts = []; for(var x in pairs){ var sp = pairs[x].split("="); // FIXME: is this eval dangerous? try{ opts[sp[0]]=eval(sp[1]); }catch(e){ opts[sp[0]]=sp[1]; } } return opts; }else{ return []; } } // parse URL params and use them as default vals var getOpts = this.parseGetStr(); for(var x in getOpts){ // FIXME: should I be checking for undefined here before setting? Does // that buy me anything? this[x] = getOpts[x]; } if(!this["tunnelURI"]){ this.tunnelURI = [ "/who/", escape(this.userid), "/s/", this.getRandStr(), "/kn_journal"].join(""); // this.tunnelURI = this.absoluteTopicURI(this.tunnelURI); } /* if (self.kn_tunnelID) kn.tunnelID = self.kn_tunnelID; // the server says if (kn._argv.kn_tunnelID) kn.tunnelID = kn._argv.kn_tunnelID; // the url says */ // check the options object if it exists and use its properties as an // over-ride if(window["repubsubOpts"]||window["rpsOpts"]){ var optObj = window["repubsubOpts"]||window["rpsOpts"]; for(var x in optObj){ this[x] = optObj[x]; // copy the option object properties } } // things that get called directly from our iframe to inform us of events this.tunnelCloseCallback = function(){ // when we get this callback, we should immediately attempt to re-start // our tunnel connection dojo.io.setIFrameSrc(this.rcvNode, this.initDoc+"?callback=repubsub.rcvNodeReady&domain="+document.domain); } this.receiveEventFromTunnel = function(evt, srcWindow){ // we should never be getting events from windows we didn't create // NOTE: events sourced from the local window are also supported for // debugging purposes // any event object MUST have a an "elements" property if(!evt["elements"]){ this.log("bailing! event received without elements!", "error"); return; } // if the event passes some minimal sanity tests, we need to attempt to // dispatch it! // first, it seems we have to munge the event object a bit var e = {}; for(var i=0; i<evt.elements.length; i++){ var ee = evt.elements[i]; e[ee.name||ee.nameU] = (ee.value||ee.valueU); // FIXME: need to enable this only in some extreme debugging mode! this.log("[event]: "+(ee.name||ee.nameU)+": "+e[ee.name||ee.nameU]); } // NOTE: the previous version of this library put a bunch of code here // to manage state that tried to make sure that we never, ever, lost // any info about an event. If we unload RIGHT HERE, I don't think it's // going to make a huge difference one way or another. Time will tell. // and with THAT out of the way, dispatch it! this.dispatch(e); // TODO: remove the script block that created the event obj to save // memory, etc. } this.widenDomain = function(domainStr){ // the purpose of this is to set the most liberal domain policy // available var cd = domainStr||document.domain; if(cd.indexOf(".")==-1){ return; } // probably file:/// or localhost var dps = cd.split("."); if(dps.length<=2){ return; } // probably file:/// or an RFC 1918 address dps = dps.slice(dps.length-2); document.domain = dps.join("."); } // FIXME: parseCookie and setCookie should be methods that are more broadly // available. Perhaps in htmlUtils? this.parseCookie = function(){ var cs = document.cookie; var keypairs = cs.split(";"); for(var x=0; x<keypairs.length; x++){ keypairs[x] = keypairs[x].split("="); if(x!=keypairs.length-1){ cs+=";"; } } return keypairs; } this.setCookie = function(keypairs, clobber){ // NOTE: we want to only ever set session cookies, so never provide an // expires date if((clobber)&&(clobber==true)){ document.cookie = ""; } var cs = ""; for(var x=0; x<keypairs.length; x++){ cs += keypairs[x][0]+"="+keypairs[x][1]; if(x!=keypairs.length-1){ cs+=";"; } } document.cookie = cs; } // FIXME: need to replace w/ dojo.log.* this.log = function(str, lvl){ if(!this.debug){ return; } // we of course only care if we're in debug mode while(this.logBacklog.length>0){ if(!this.canLog){ break; } var blo = this.logBacklog.shift(); this.writeLog("["+blo[0]+"]: "+blo[1], blo[2]); } this.writeLog(str, lvl); } this.writeLog = function(str, lvl){ dojo.debug(((new Date()).toLocaleTimeString())+": "+str); } this.init = function(){ this.widenDomain(); // this.findPeers(); this.openTunnel(); this.isInitialized = true; // FIXME: this seems like entirely the wrong place to replay the backlog while(this.subscriptionBacklog.length){ this.subscribe.apply(this, this.subscriptionBacklog.shift()); } } this.clobber = function(){ if(this.rcvNode){ this.setCookie( [ [this.tunnelFrameKey,"closed"], ["path","/"] ], false ); } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -