diff --git a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js index 5dd0724cb..20766a736 100644 --- a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js +++ b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js @@ -1,20 +1,20 @@ /* - Copyright (c) 2004-2006, The Dojo Foundation - All Rights Reserved. + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. - Licensed under the Academic Free License version 2.1 or above OR the - modified BSD license. For more information on Dojo licensing, see: + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: - http://dojotoolkit.org/community/licensing.shtml + http://dojotoolkit.org/community/licensing.shtml */ /* - This is a compiled version of Dojo, built for deployment and not for - development. To get an editable version, please visit: + This is a compiled version of Dojo, built for deployment and not for + development. To get an editable version, please visit: - http://dojotoolkit.org + http://dojotoolkit.org - for documentation and information on getting the source. + for documentation and information on getting the source. */ if(typeof dojo=="undefined"){ @@ -482,7 +482,7 @@ break; } } }; -dojo.hostenv.localesGenerated=["ROOT","es-es","es","it-it","pt-br","de","fr-fr","zh-cn","pt","en-us","zh","fr","zh-tw","it","en-gb","xx","de-de","ko-kr","ja-jp","ko","en","ja"]; +dojo.hostenv.localesGenerated; dojo.hostenv.registerNlsPrefix=function(){ dojo.registerModulePath("nls","nls"); }; @@ -13628,5156 +13628,4 @@ self.addKeyHandler(item[1]?item[1]:item[0].charAt(0),item[2]==undefined?self.KEY } }); }}); -dojo.provide("struts.widget.Bind"); -dojo.widget.defineWidget("struts.widget.Bind",dojo.widget.HtmlWidget,{widgetType:"Bind",executeScripts:false,scriptSeparation:false,targets:"",targetsArray:null,href:"",handler:"",loadingText:"Loading...",errorText:"",showError:true,showLoading:false,listenTopics:"",notifyTopics:"",notifyTopicsArray:null,beforeNotifyTopics:"",beforeNotifyTopicsArray:null,afterNotifyTopics:"",afterNotifyTopicsArray:null,errorNotifyTopics:"",errorNotifyTopicsArray:null,formId:"",formFilter:"",formNode:null,events:"",indicator:"",parseContent:true,highlightColor:"",highlightDuration:2000,validate:false,ajaxAfterValidation:false,cacheContent:true,scriptSeparation:true,scriptScope:null,transport:"",postCreate:function(){ -var self=this; -if(!dojo.string.isBlank(this.listenTopics)){ -this.log("Listening to "+this.listenTopics+" to refresh"); -var _b7b=this.listenTopics.split(","); -if(_b7b){ -dojo.lang.forEach(_b7b,function(_b7c){ -dojo.event.topic.subscribe(_b7c,self,"reloadContents"); -}); -} -} -if(!dojo.string.isBlank(this.notifyTopics)){ -this.notifyTopicsArray=this.notifyTopics.split(","); -} -if(!dojo.string.isBlank(this.beforeNotifyTopics)){ -this.beforeNotifyTopicsArray=this.beforeNotifyTopics.split(","); -} -if(!dojo.string.isBlank(this.afterNotifyTopics)){ -this.afterNotifyTopicsArray=this.afterNotifyTopics.split(","); -} -if(!dojo.string.isBlank(this.errorNotifyTopics)){ -this.errorNotifyTopicsArray=this.errorNotifyTopics.split(","); -} -if(!dojo.string.isBlank(this.targets)){ -this.targetsArray=this.targets.split(","); -} -if(!dojo.string.isBlank(this.events)){ -var _b7d=this.events.split(","); -if(_b7d&&this.domNode){ -dojo.lang.forEach(_b7d,function(_b7e){ -dojo.event.connect(self.domNode,_b7e,function(evt){ -evt.preventDefault(); -evt.stopPropagation(); -self.reloadContents(); -}); -}); -} -} -if(dojo.string.isBlank(this.formId)){ -this.formNode=dojo.dom.getFirstAncestorByTag(this.domNode,"form"); -}else{ -this.formNode=dojo.byId(this.formId); -} -if(this.formNode&&dojo.string.isBlank(this.href)){ -this.href=this.formNode.action; -} -},highlight:function(){ -if(!dojo.string.isBlank(this.highlightColor)){ -var _b80=[]; -dojo.lang.forEach(this.targetsArray,function(_b81){ -var node=dojo.byId(_b81); -if(node){ -_b80.push(node); -} -}); -var _b83=dojo.lfx.html.highlight(_b80,this.highlightColor,this.highlightDuration); -_b83.play(); -} -},log:function(text){ -dojo.debug("["+(this.widgetId?this.widgetId:"unknown")+"] "+text); -},setContent:function(text){ -if(this.targetsArray){ -var self=this; -var _b87=new dojo.xml.Parse(); -dojo.lang.forEach(this.targetsArray,function(_b88){ -var node=dojo.byId(_b88); -if(node){ -node.innerHTML=text; -if(self.parseContent&&text!=self.loadingText){ -var frag=_b87.parseElement(node,null,true); -dojo.widget.getParser().createSubComponents(frag,dojo.widget.byId(_b88)); -} -}else{ -self.log("Unable to find target: "+node); -} -}); -} -},bindHandler:function(type,data,e){ -dojo.html.hide(this.indicator); -this.notify(data,type,e); -if(type=="load"){ -if(this.validate){ -StrutsUtils.clearValidationErrors(this.formNode); -var _b8e=StrutsUtils.getValidationErrors(data); -if(_b8e&&_b8e.fieldErrors){ -StrutsUtils.showValidationErrors(this.formNode,_b8e); -return; -}else{ -if(!this.ajaxAfterValidation&&this.formNode){ -this.formNode.submit(); -return; -} -} -} -if(this.executeScripts){ -var _b8f=this.parse(data); -this.setContent(_b8f.text); -this._executeScripts(_b8f.scripts); -}else{ -this.setContent(data); -} -this.highlight(); -}else{ -if(this.showError){ -var _b90=dojo.string.isBlank(this.errorText)?e.message:this.errorText; -this.setContent(_b90); -} -} -},notify:function(data,type,e){ -var self=this; -if(this.notifyTopicsArray){ -dojo.lang.forEach(this.notifyTopicsArray,function(_b95){ -try{ -dojo.event.topic.publish(_b95,data,type,e,self); -} -catch(ex){ -self.log(ex); -} -}); -} -var _b96=null; -switch(type){ -case "before": -this.notifyTo(this.beforeNotifyTopicsArray,null,e); -break; -case "load": -this.notifyTo(this.afterNotifyTopicsArray,data,e); -break; -case "error": -this.notifyTo(this.errorNotifyTopicsArray,data,e); -break; -} -},notifyTo:function(_b97,data,e){ -var self=this; -if(_b97){ -dojo.lang.forEach(_b97,function(_b9b){ -try{ -if(data!=null){ -dojo.event.topic.publish(_b9b,data,e,self); -}else{ -dojo.event.topic.publish(_b9b,e,self); -} -} -catch(ex){ -self.log(ex); -} -}); -} -},onDownloadStart:function(_b9c){ -if(this.showLoading&&!dojo.string.isBlank(this.loadingText)){ -_b9c.text=this.loadingText; -} -},reloadContents:function(evt){ -if(!dojo.string.isBlank(this.handler)){ -this.log("Invoking handler: "+this.handler); -window[this.handler](this,this.domNode); -}else{ -try{ -var self=this; -var _b9f={cancel:false}; -this.notify(this.widgetId,"before",_b9f); -if(_b9f.cancel){ -this.log("Request canceled"); -return; -} -if(dojo.string.isBlank(this.href)){ -return; -} -if(!this.validate&&this.formNode&&this.formNode.onsubmit!=null){ -var _ba0=this.formNode.onsubmit.call(evt); -if(_ba0!=null&&!_ba0){ -this.log("Request canceled by 'onsubmit' of the form"); -return; -} -} -dojo.html.show(this.indicator); -if(this.showLoading){ -this.setContent(this.loadingText); -} -var _ba1=this.href; -_ba1=_ba1+(_ba1.indexOf("?")>-1?"&":"?")+"struts.enableJSONValidation=true"; -if(!this.ajaxAfterValidation&&this.validate){ -_ba1=_ba1+(_ba1.indexOf("?")>-1?"&":"?")+"struts.validateOnly=true"; -} -if(dojo.dom.isTag(this.domNode,"INPUT","input")&&this.events=="onclick"&&this.domNode.type=="submit"&&!dojo.string.isBlank(this.domNode.name)&&!dojo.string.isBlank(this.domNode.value)){ -var enc=/utf/i.test("")?encodeURIComponent:dojo.string.encodeAscii; -_ba1=_ba1+(_ba1.indexOf("?")>-1?"&":"?")+enc(this.domNode.name)+"="+enc(this.domNode.value); -} -dojo.io.bind({url:_ba1,useCache:false,preventCache:true,formNode:self.formNode,formFilter:window[self.formFilter],transport:self.transport,handler:function(type,data,e){ -dojo.lang.hitch(self,"bindHandler")(type,data,e); -},mimetype:"text/html"}); -} -catch(ex){ -if(this.showError){ -var _ba6=dojo.string.isBlank(this.errorText)?ex:this.errorText; -this.setContent(_ba6); -} -} -} -},parse:function(s){ -this.log("Parsing: "+s); -var _ba8=[]; -var tmp=[]; -var _baa=[]; -while(_ba8){ -_ba8=s.match(/]*)>([\s\S]*?)<\/script>/i); -if(!_ba8){ -break; -} -if(_ba8[1]){ -attr=_ba8[1].match(/src=(['"]?)([^"']*)\1/i); -if(attr){ -var tmp2=attr[2].search(/.*(\bdojo\b(?:\.uncompressed)?\.js)$/); -if(tmp2>-1){ -this.log("Security note! inhibit:"+attr[2]+" from beeing loaded again."); -} -} -} -if(_ba8[2]){ -var sc=_ba8[2].replace(/(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g,""); -if(!sc){ -continue; -} -tmp=[]; -while(tmp){ -tmp=sc.match(/dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix))\((['"]).*?\1\)\s*;?/); -if(!tmp){ -break; -} -sc=sc.replace(tmp[0],""); -} -_baa.push(sc); -} -s=s.replace(/]*>[\s\S]*?<\/script>/i,""); -} -return {text:s,scripts:_baa}; -},_executeScripts:function(_bad){ -var self=this; -var tmp="",code=""; -for(var i=0;i<_bad.length;i++){ -if(_bad[i].path){ -dojo.io.bind(this._cacheSetting({"url":_bad[i].path,"load":function(type,_bb3){ -dojo.lang.hitch(self,tmp=";"+_bb3); -},"error":function(type,_bb5){ -_bb5.text=type+" downloading remote script"; -self._handleDefaults.call(self,_bb5,"onExecError","debug"); -},"mimetype":"text/plain","sync":true},this.cacheContent)); -code+=tmp; -}else{ -code+=_bad[i]; -} -} -try{ -if(this.scriptSeparation){ -delete this.scriptScope; -this.scriptScope=new (new Function("_container_",code+"; return this;"))(self); -}else{ -var djg=dojo.global(); -if(djg.execScript){ -djg.execScript(code); -}else{ -var djd=dojo.doc(); -var sc=djd.createElement("script"); -sc.appendChild(djd.createTextNode(code)); -(this.containerNode||this.domNode).appendChild(sc); -} -} -} -catch(e){ -e.text="Error running scripts from content:\n"+e.description; -this.log(e); -} -},_cacheSetting:function(_bb9,_bba){ -for(var x in this.bindArgs){ -if(dojo.lang.isUndefined(_bb9[x])){ -_bb9[x]=this.bindArgs[x]; -} -} -if(dojo.lang.isUndefined(_bb9.useCache)){ -_bb9.useCache=_bba; -} -if(dojo.lang.isUndefined(_bb9.preventCache)){ -_bb9.preventCache=!_bba; -} -if(dojo.lang.isUndefined(_bb9.mimetype)){ -_bb9.mimetype="text/html"; -} -return _bb9; -}}); -dojo.provide("dojo.lang.timing.Timer"); -dojo.lang.timing.Timer=function(_bbc){ -this.timer=null; -this.isRunning=false; -this.interval=_bbc; -this.onStart=null; -this.onStop=null; -}; -dojo.extend(dojo.lang.timing.Timer,{onTick:function(){ -},setInterval:function(_bbd){ -if(this.isRunning){ -dj_global.clearInterval(this.timer); -} -this.interval=_bbd; -if(this.isRunning){ -this.timer=dj_global.setInterval(dojo.lang.hitch(this,"onTick"),this.interval); -} -},start:function(){ -if(typeof this.onStart=="function"){ -this.onStart(); -} -this.isRunning=true; -this.timer=dj_global.setInterval(dojo.lang.hitch(this,"onTick"),this.interval); -},stop:function(){ -if(typeof this.onStop=="function"){ -this.onStop(); -} -this.isRunning=false; -dj_global.clearInterval(this.timer); -}}); -dojo.provide("struts.widget.BindDiv"); -dojo.widget.defineWidget("struts.widget.BindDiv",dojo.widget.ContentPane,{widgetType:"BindDiv",href:"",extractContent:false,parseContent:false,cacheContent:false,refreshOnShow:false,executeScripts:false,preload:true,updateFreq:0,delay:0,autoStart:true,timer:null,loadingText:"Loading...",showLoading:false,errorText:"",showError:true,listenTopics:"",notifyTopics:"",notifyTopicsArray:null,stopTimerListenTopics:"",startTimerListenTopics:"",beforeNotifyTopics:"",beforeNotifyTopicsArray:null,afterNotifyTopics:"",afterNotifyTopicsArray:null,errorNotifyTopics:"",errorNotifyTopicsArray:null,beforeLoading:"",afterLoading:"",formId:"",formFilter:"",indicator:"",parseContent:true,highlightColor:"",highlightDuration:2000,disabled:false,transport:"",onDownloadStart:function(_bbe){ -if(!this.showLoading){ -_bbe.returnValue=false; -return; -} -if(this.showLoading&&!dojo.string.isBlank(this.loadingText)){ -_bbe.text=this.loadingText; -} -},highlight:function(){ -if(!dojo.string.isBlank(this.highlightColor)){ -var _bbf=dojo.lfx.html.highlight([this.domNode],this.highlightColor,this.highlightDuration); -_bbf.play(); -} -},onDownloadError:function(_bc0){ -this.onError(_bc0); -},onContentError:function(_bc1){ -this.onError(_bc1); -},onExecError:function(_bc2){ -this.onError(_bc2); -},onError:function(_bc3){ -if(this.showError){ -if(!dojo.string.isBlank(this.errorText)){ -_bc3.text=this.errorText; -} -}else{ -_bc3.text=""; -} -},notify:function(data,type,e){ -if(this.notifyTopicsArray){ -var self=this; -dojo.lang.forEach(this.notifyTopicsArray,function(_bc8){ -try{ -dojo.event.topic.publish(_bc8,data,type,e,self); -} -catch(ex){ -self.log(ex); -} -}); -} -var _bc9=null; -switch(type){ -case "before": -this.notifyTo(this.beforeNotifyTopicsArray,null,e); -break; -case "load": -this.notifyTo(this.afterNotifyTopicsArray,data,e); -break; -case "error": -this.notifyTo(this.errorNotifyTopicsArray,data,e); -break; -} -},notifyTo:function(_bca,data,e){ -var self=this; -if(_bca){ -dojo.lang.forEach(_bca,function(_bce){ -try{ -if(data!=null){ -dojo.event.topic.publish(_bce,data,e,self); -}else{ -dojo.event.topic.publish(_bce,e,self); -} -} -catch(ex){ -self.log(ex); -} -}); -} -},postCreate:function(args,frag){ -if(this.handler!==""){ -this.setHandler(this.handler); -} -var self=this; -var _bd2=function(){ -dojo.lang.hitch(self,"refresh")(); -}; -var _bd3=function(){ -dojo.lang.hitch(self,"startTimer")(); -}; -if(this.updateFreq>0){ -this.timer=new dojo.lang.timing.Timer(this.updateFreq); -this.timer.onTick=_bd2; -if(this.autoStart){ -if(this.delay>0){ -dojo.lang.setTimeout(_bd3,this.delay); -}else{ -this.startTimer(); -} -} -}else{ -if(this.delay>0){ -dojo.lang.setTimeout(_bd2,this.delay); -} -} -if(!dojo.string.isBlank(this.listenTopics)){ -this.log("Listening to "+this.listenTopics+" to refresh"); -var _bd4=this.listenTopics.split(","); -if(_bd4){ -dojo.lang.forEach(_bd4,function(_bd5){ -dojo.event.topic.subscribe(_bd5,self,"refresh"); -}); -} -} -if(!dojo.string.isBlank(this.stopTimerListenTopics)){ -this.log("Listening to "+this.stopTimerListenTopics+" to stop timer"); -var _bd6=this.stopTimerListenTopics.split(","); -if(_bd6){ -dojo.lang.forEach(_bd6,function(_bd7){ -dojo.event.topic.subscribe(_bd7,self,"stopTimer"); -}); -} -} -if(!dojo.string.isBlank(this.startTimerListenTopics)){ -this.log("Listening to "+this.stopTimerListenTopics+" to start timer"); -var _bd8=this.startTimerListenTopics.split(","); -if(_bd8){ -dojo.lang.forEach(_bd8,function(_bd9){ -dojo.event.topic.subscribe(_bd9,self,"startTimer"); -}); -} -} -if(!dojo.string.isBlank(this.notifyTopics)){ -this.notifyTopicsArray=this.notifyTopics.split(","); -} -if(!dojo.string.isBlank(this.beforeNotifyTopics)){ -this.beforeNotifyTopicsArray=this.beforeNotifyTopics.split(","); -} -if(!dojo.string.isBlank(this.afterNotifyTopics)){ -this.afterNotifyTopicsArray=this.afterNotifyTopics.split(","); -} -if(!dojo.string.isBlank(this.errorNotifyTopics)){ -this.errorNotifyTopicsArray=this.errorNotifyTopics.split(","); -} -if(this.isShowing()&&this.preload&&this.updateFreq<=0&&this.delay<=0){ -this.refresh(); -} -},_downloadExternalContent:function(url,_bdb){ -var _bdc={cancel:false}; -this.notify(this.widgetId,"before",_bdc); -if(_bdc.cancel){ -return; -} -dojo.html.show(this.indicator); -this._handleDefaults("Loading...","onDownloadStart"); -var self=this; -dojo.io.bind({url:url,useCache:_bdb,preventCache:!_bdb,mimetype:"text/html",formNode:dojo.byId(self.formId),formFilter:window[self.formFilter],transport:self.transport,handler:function(type,data,e){ -dojo.html.hide(self.indicator); -self.notify(data,type,e); -if(type=="load"){ -self.onDownloadEnd.call(self,url,data); -self.highlight(); -}else{ -self._handleDefaults.call(self,"Error loading '"+url+"' ("+e.status+" "+e.statusText+")","onDownloadError"); -self.onLoad(); -} -}}); -},log:function(text){ -dojo.debug("["+this.widgetId+"] "+text); -},stopTimer:function(){ -if(this.timer&&this.timer.isRunning){ -this.log("stopping timer"); -this.timer.stop(); -} -},startTimer:function(){ -if(this.timer&&!this.timer.isRunning){ -this.log("starting timer with update interval "+this.updateFreq); -this.timer.start(); -} -},splitAndFixPaths:function(s,url){ -var _be4=[],_be5=[],tmp=[]; -var _be7=[],_be8=[],attr=[],_bea=[]; -var str="",path="",fix="",_bee="",tag="",_bf0=""; -if(!url){ -url="./"; -} -if(s){ -var _bf1=/]*>([\s\S]*?)<\/title>/i; -while(_be7=_bf1.exec(s)){ -_be4.push(_be7[1]); -s=s.substring(0,_be7.index)+s.substr(_be7.index+_be7[0].length); -} -if(this.adjustPaths){ -var _bf2=/<[a-z][a-z0-9]*[^>]*\s(?:(?:src|href|style)=[^>])+[^>]*>/i; -var _bf3=/\s(src|href|style)=(['"]?)([\w()\[\]\/.,\\'"-:;#=&?\s@!]+?)\2/i; -var _bf4=/^(?:[#]|(?:(?:https?|ftps?|file|javascript|mailto|news):))/; -while(tag=_bf2.exec(s)){ -str+=s.substring(0,tag.index); -s=s.substring((tag.index+tag[0].length),s.length); -tag=tag[0]; -_bee=""; -while(attr=_bf3.exec(tag)){ -path=""; -_bf0=attr[3]; -switch(attr[1].toLowerCase()){ -case "src": -case "href": -if(_bf4.exec(_bf0)){ -path=_bf0; -}else{ -path=(new dojo.uri.Uri(url,_bf0).toString()); -} -break; -case "style": -path=dojo.html.fixPathsInCssText(_bf0,url); -break; -default: -path=_bf0; -} -fix=" "+attr[1]+"="+attr[2]+path+attr[2]; -_bee+=tag.substring(0,attr.index)+fix; -tag=tag.substring((attr.index+attr[0].length),tag.length); -} -str+=_bee+tag; -} -s=str+s; -} -_bf1=/(?:<(style)[^>]*>([\s\S]*?)<\/style>|]*rel=['"]?stylesheet['"]?[^>]*)>)/i; -while(_be7=_bf1.exec(s)){ -if(_be7[1]&&_be7[1].toLowerCase()=="style"){ -_bea.push(dojo.html.fixPathsInCssText(_be7[2],url)); -}else{ -if(attr=_be7[3].match(/href=(['"]?)([^'">]*)\1/i)){ -_bea.push({path:attr[2]}); -} -} -s=s.substring(0,_be7.index)+s.substr(_be7.index+_be7[0].length); -} -var _bf1=/]*)>([\s\S]*?)<\/script>/i; -var _bf5=/src=(['"]?)([^"']*)\1/i; -var _bf6=/.*(\bdojo\b\.js(?:\.uncompressed\.js)?)$/; -var _bf7=/(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g; -var _bf8=/dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix|registerModulePath)|defineNamespace)\((['"]).*?\1\)\s*;?/; -while(_be7=_bf1.exec(s)){ -if(this.executeScripts&&_be7[1]){ -if(attr=_bf5.exec(_be7[1])){ -if(_bf6.exec(attr[2])){ -dojo.debug("Security note! inhibit:"+attr[2]+" from being loaded again."); -}else{ -_be5.push({path:attr[2]}); -} -} -} -if(_be7[2]){ -var sc=_be7[2].replace(_bf7,""); -if(!sc){ -continue; -} -while(tmp=_bf8.exec(sc)){ -_be8.push(tmp[0]); -sc=sc.substring(0,tmp.index)+sc.substr(tmp.index+tmp[0].length); -} -if(this.executeScripts){ -_be5.push(sc); -} -} -s=s.substr(0,_be7.index)+s.substr(_be7.index+_be7[0].length); -} -if(this.extractContent){ -_be7=s.match(/]*>\s*([\s\S]+)\s*<\/body>/im); -if(_be7){ -s=_be7[1]; -} -} -if(this.executeScripts&&this.scriptSeparation){ -var _bf1=/(<[a-zA-Z][a-zA-Z0-9]*\s[^>]*?\S=)((['"])[^>]*scriptScope[^>]*>)/; -var _bfa=/([\s'";:\(])scriptScope(.*)/; -str=""; -while(tag=_bf1.exec(s)){ -tmp=((tag[3]=="'")?"\"":"'"); -fix=""; -str+=s.substring(0,tag.index)+tag[1]; -while(attr=_bfa.exec(tag[2])){ -tag[2]=tag[2].substring(0,attr.index)+attr[1]+"dojo.widget.byId("+tmp+this.widgetId+tmp+").scriptScope"+attr[2]; -} -str+=tag[2]; -s=s.substr(tag.index+tag[0].length); -} -s=str+s; -} -} -return {"xml":s,"styles":_bea,"titles":_be4,"requires":_be8,"scripts":_be5,"url":url}; -}}); -dojo.provide("struts.widget.BindAnchor"); -dojo.widget.defineWidget("struts.widget.BindAnchor",struts.widget.Bind,{widgetType:"BindAnchor",events:"onclick",postCreate:function(){ -struts.widget.BindAnchor.superclass.postCreate.apply(this); -this.domNode.href="#"; -}}); -dojo.provide("dojo.widget.html.stabile"); -dojo.widget.html.stabile={_sqQuotables:new RegExp("([\\\\'])","g"),_depth:0,_recur:false,depthLimit:2}; -dojo.widget.html.stabile.getState=function(id){ -dojo.widget.html.stabile.setup(); -return dojo.widget.html.stabile.widgetState[id]; -}; -dojo.widget.html.stabile.setState=function(id,_bfd,_bfe){ -dojo.widget.html.stabile.setup(); -dojo.widget.html.stabile.widgetState[id]=_bfd; -if(_bfe){ -dojo.widget.html.stabile.commit(dojo.widget.html.stabile.widgetState); -} -}; -dojo.widget.html.stabile.setup=function(){ -if(!dojo.widget.html.stabile.widgetState){ -var text=dojo.widget.html.stabile._getStorage().value; -dojo.widget.html.stabile.widgetState=text?dj_eval("("+text+")"):{}; -} -}; -dojo.widget.html.stabile.commit=function(_c00){ -dojo.widget.html.stabile._getStorage().value=dojo.widget.html.stabile.description(_c00); -}; -dojo.widget.html.stabile.description=function(v,_c02){ -var _c03=dojo.widget.html.stabile._depth; -var _c04=function(){ -return this.description(this,true); -}; -try{ -if(v===void (0)){ -return "undefined"; -} -if(v===null){ -return "null"; -} -if(typeof (v)=="boolean"||typeof (v)=="number"||v instanceof Boolean||v instanceof Number){ -return v.toString(); -} -if(typeof (v)=="string"||v instanceof String){ -var v1=v.replace(dojo.widget.html.stabile._sqQuotables,"\\$1"); -v1=v1.replace(/\n/g,"\\n"); -v1=v1.replace(/\r/g,"\\r"); -return "'"+v1+"'"; -} -if(v instanceof Date){ -return "new Date("+d.getFullYear+","+d.getMonth()+","+d.getDate()+")"; -} -var d; -if(v instanceof Array||v.push){ -if(_c03>=dojo.widget.html.stabile.depthLimit){ -return "[ ... ]"; -} -d="["; -var _c07=true; -dojo.widget.html.stabile._depth++; -for(var i=0;i=dojo.widget.html.stabile.depthLimit){ -return "{ ... }"; -} -if(typeof (v.hasOwnProperty)!="function"&&v.prototype){ -throw new Error("description: "+v+" not supported by script engine"); -} -var _c07=true; -d="{"; -dojo.widget.html.stabile._depth++; -for(var key in v){ -if(v[key]==void (0)||typeof (v[key])=="function"){ -continue; -} -if(_c07){ -_c07=false; -}else{ -d+=", "; -} -var kd=key; -if(!kd.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)){ -kd=arguments.callee(key,_c02); -} -d+=kd+": "+arguments.callee(v[key],_c02); -} -return d+"}"; -} -if(_c02){ -if(dojo.widget.html.stabile._recur){ -var _c0b=Object.prototype.toString; -return _c0b.apply(v,[]); -}else{ -dojo.widget.html.stabile._recur=true; -return v.toString(); -} -}else{ -throw new Error("Unknown type: "+v); -return "'unknown'"; -} -} -finally{ -dojo.widget.html.stabile._depth=_c03; -} -}; -dojo.widget.html.stabile._getStorage=function(){ -if(dojo.widget.html.stabile.dataField){ -return dojo.widget.html.stabile.dataField; -} -var form=document.forms._dojo_form; -return dojo.widget.html.stabile.dataField=form?form.stabile:{value:""}; -}; -dojo.provide("dojo.widget.ComboBox"); -dojo.declare("dojo.widget.incrementalComboBoxDataProvider",null,function(_c0d){ -this.searchUrl=_c0d.dataUrl; -this._cache={}; -this._inFlight=false; -this._lastRequest=null; -this.allowCache=false; -},{_addToCache:function(_c0e,data){ -if(this.allowCache){ -this._cache[_c0e]=data; -} -},startSearch:function(_c10,_c11){ -if(this._inFlight){ -} -var tss=encodeURIComponent(_c10); -var _c13=dojo.string.substituteParams(this.searchUrl,{"searchString":tss}); -var _c14=this; -var _c15=this._lastRequest=dojo.io.bind({url:_c13,method:"get",mimetype:"text/json",load:function(type,data,evt){ -_c14._inFlight=false; -if(!dojo.lang.isArray(data)){ -var _c19=[]; -for(var key in data){ -_c19.push([data[key],key]); -} -data=_c19; -} -_c14._addToCache(_c10,data); -if(_c15==_c14._lastRequest){ -_c11(data); -} -}}); -this._inFlight=true; -}}); -dojo.declare("dojo.widget.basicComboBoxDataProvider",null,function(_c1b,node){ -this._data=[]; -this.searchLimit=30; -this.searchType="STARTSTRING"; -this.caseSensitive=false; -if(!dj_undef("dataUrl",_c1b)&&!dojo.string.isBlank(_c1b.dataUrl)){ -this._getData(_c1b.dataUrl); -}else{ -if((node)&&(node.nodeName.toLowerCase()=="select")){ -var opts=node.getElementsByTagName("option"); -var ol=opts.length; -var data=[]; -for(var x=0;x0)&&(ret.length>=this.searchLimit)){ -break; -} -var _c30=new String((!this.caseSensitive)?this._data[x][0].toLowerCase():this._data[x][0]); -if(_c30.length<_c2b.length){ -continue; -} -if(st=="STARTSTRING"){ -if(_c2b==_c30.substr(0,_c2b.length)){ -ret.push(this._data[x]); -} -}else{ -if(st=="SUBSTRING"){ -if(_c30.indexOf(_c2b)>=0){ -ret.push(this._data[x]); -} -}else{ -if(st=="STARTWORD"){ -var idx=_c30.indexOf(_c2b); -if(idx==0){ -ret.push(this._data[x]); -} -if(idx<=0){ -continue; -} -var _c32=false; -while(idx!=-1){ -if(" ,/(".indexOf(_c30.charAt(idx-1))!=-1){ -_c32=true; -break; -} -idx=_c30.indexOf(_c2b,idx+1); -} -if(!_c32){ -continue; -}else{ -ret.push(this._data[x]); -} -} -} -} -} -_c2c(ret); -},setData:function(_c33){ -this._data=_c33; -}}); -dojo.widget.defineWidget("dojo.widget.ComboBox",dojo.widget.HtmlWidget,{forceValidOption:false,searchType:"stringstart",dataProvider:null,autoComplete:true,searchDelay:100,dataUrl:"",fadeTime:200,maxListLength:8,mode:"local",selectedResult:null,dataProviderClass:"",buttonSrc:dojo.uri.moduleUri("dojo.widget","templates/images/combo_box_arrow.png"),dropdownToggle:"fade",templateString:"\r\n",templateCssString:".dojoComboBoxOuter {\r\n\tborder: 0px !important;\r\n\tmargin: 0px !important;\r\n\tpadding: 0px !important;\r\n\tbackground: transparent !important;\r\n\twhite-space: nowrap !important;\r\n}\r\n\r\n.dojoComboBox {\r\n\tborder: 1px inset #afafaf;\r\n\tmargin: 0px;\r\n\tpadding: 0px;\r\n\tvertical-align: middle !important;\r\n\tfloat: none !important;\r\n\tposition: static !important;\r\n\tdisplay: inline !important;\r\n}\r\n\r\n/* the input box */\r\ninput.dojoComboBox {\r\n\tborder-right-width: 0px !important; \r\n\tmargin-right: 0px !important;\r\n\tpadding-right: 0px !important;\r\n}\r\n\r\n/* the down arrow */\r\nimg.dojoComboBox {\r\n\tborder-left-width: 0px !important;\r\n\tpadding-left: 0px !important;\r\n\tmargin-left: 0px !important;\r\n}\r\n\r\n/* IE vertical-alignment calculations can be off by +-1 but these margins are collapsed away */\r\n.dj_ie img.dojoComboBox {\r\n\tmargin-top: 1px; \r\n\tmargin-bottom: 1px; \r\n}\r\n\r\n/* the drop down */\r\n.dojoComboBoxOptions {\r\n\tfont-family: Verdana, Helvetica, Garamond, sans-serif;\r\n\t/* font-size: 0.7em; */\r\n\tbackground-color: white;\r\n\tborder: 1px solid #afafaf;\r\n\tposition: absolute;\r\n\tz-index: 1000; \r\n\toverflow: auto;\r\n\tcursor: default;\r\n}\r\n\r\n.dojoComboBoxItem {\r\n\tpadding-left: 2px;\r\n\tpadding-top: 2px;\r\n\tmargin: 0px;\r\n}\r\n\r\n.dojoComboBoxItemEven {\r\n\tbackground-color: #f4f4f4;\r\n}\r\n\r\n.dojoComboBoxItemOdd {\r\n\tbackground-color: white;\r\n}\r\n\r\n.dojoComboBoxItemHighlight {\r\n\tbackground-color: #63709A;\r\n\tcolor: white;\r\n}\r\n",templateCssPath:dojo.uri.moduleUri("dojo.widget","templates/ComboBox.css"),setValue:function(_c34){ -this.comboBoxValue.value=_c34; -if(this.textInputNode.value!=_c34){ -this.textInputNode.value=_c34; -dojo.widget.html.stabile.setState(this.widgetId,this.getState(),true); -this.onValueChanged(_c34); -} -},onValueChanged:function(_c35){ -},getValue:function(){ -return this.comboBoxValue.value; -},getState:function(){ -return {value:this.getValue()}; -},setState:function(_c36){ -this.setValue(_c36.value); -},enable:function(){ -this.disabled=false; -this.textInputNode.removeAttribute("disabled"); -},disable:function(){ -this.disabled=true; -this.textInputNode.setAttribute("disabled",true); -},_getCaretPos:function(_c37){ -if(dojo.lang.isNumber(_c37.selectionStart)){ -return _c37.selectionStart; -}else{ -if(dojo.render.html.ie){ -var tr=document.selection.createRange().duplicate(); -var ntr=_c37.createTextRange(); -tr.move("character",0); -ntr.move("character",0); -try{ -ntr.setEndPoint("EndToEnd",tr); -return String(ntr.text).replace(/\r/g,"").length; -} -catch(e){ -return 0; -} -} -} -},_setCaretPos:function(_c3a,_c3b){ -_c3b=parseInt(_c3b); -this._setSelectedRange(_c3a,_c3b,_c3b); -},_setSelectedRange:function(_c3c,_c3d,end){ -if(!end){ -end=_c3c.value.length; -} -if(_c3c.setSelectionRange){ -_c3c.focus(); -_c3c.setSelectionRange(_c3d,end); -}else{ -if(_c3c.createTextRange){ -var _c3f=_c3c.createTextRange(); -with(_c3f){ -collapse(true); -moveEnd("character",end); -moveStart("character",_c3d); -select(); -} -}else{ -_c3c.value=_c3c.value; -_c3c.blur(); -_c3c.focus(); -var dist=parseInt(_c3c.value.length)-end; -var _c41=String.fromCharCode(37); -var tcc=_c41.charCodeAt(0); -for(var x=0;x0)){ -var cpos=this._getCaretPos(this.textInputNode); -if((cpos+1)>this.textInputNode.value.length){ -this.textInputNode.value+=_c56[0][0].substr(cpos); -this._setSelectedRange(this.textInputNode,cpos,this.textInputNode.value.length); -} -} -var even=true; -while(_c56.length){ -var tr=_c56.shift(); -if(tr){ -var td=document.createElement("div"); -td.appendChild(document.createTextNode(tr[0])); -td.setAttribute("resultName",tr[0]); -td.setAttribute("resultValue",tr[1]); -td.className="dojoComboBoxItem "+((even)?"dojoComboBoxItemEven":"dojoComboBoxItemOdd"); -even=(!even); -this.optionsListNode.appendChild(td); -} -} -this._showResultList(); -},_onFocusInput:function(){ -this._hasFocus=true; -},_onBlurInput:function(){ -this._hasFocus=false; -this._handleBlurTimer(true,500); -},_handleBlurTimer:function(_c5b,_c5c){ -if(this.blurTimer&&(_c5b||_c5c)){ -clearTimeout(this.blurTimer); -} -if(_c5c){ -this.blurTimer=dojo.lang.setTimeout(this,"_checkBlurred",_c5c); -} -},_onMouseOver:function(evt){ -if(!this._mouseover_list){ -this._handleBlurTimer(true,0); -this._mouseover_list=true; -} -},_onMouseOut:function(evt){ -var _c5f=evt.relatedTarget; -try{ -if(!_c5f||_c5f.parentNode!=this.optionsListNode){ -this._mouseover_list=false; -this._handleBlurTimer(true,100); -this._tryFocus(); -} -} -catch(e){ -} -},_isInputEqualToResult:function(_c60){ -var _c61=this.textInputNode.value; -if(!this.dataProvider.caseSensitive){ -_c61=_c61.toLowerCase(); -_c60=_c60.toLowerCase(); -} -return (_c61==_c60); -},_isValidOption:function(){ -var tgt=dojo.html.firstElement(this.optionsListNode); -var _c63=false; -while(!_c63&&tgt){ -if(this._isInputEqualToResult(tgt.getAttribute("resultName"))){ -_c63=true; -}else{ -tgt=dojo.html.nextElement(tgt); -} -} -return _c63; -},_checkBlurred:function(){ -if(!this._hasFocus&&!this._mouseover_list){ -this._hideResultList(); -if(!this.textInputNode.value.length){ -this.setAllValues("",""); -return; -} -var _c64=this._isValidOption(); -if(this.forceValidOption&&!_c64){ -this.setAllValues("",""); -return; -} -if(!_c64){ -this.setSelectedValue(""); -} -} -},_selectOption:function(evt){ -var tgt=null; -if(!evt){ -evt={target:this._highlighted_option}; -} -if(!dojo.html.isDescendantOf(evt.target,this.optionsListNode)){ -if(!this.textInputNode.value.length){ -return; -} -tgt=dojo.html.firstElement(this.optionsListNode); -if(!tgt||!this._isInputEqualToResult(tgt.getAttribute("resultName"))){ -return; -} -}else{ -tgt=evt.target; -} -while((tgt.nodeType!=1)||(!tgt.getAttribute("resultName"))){ -tgt=tgt.parentNode; -if(tgt===dojo.body()){ -return false; -} -} -this.selectedResult=[tgt.getAttribute("resultName"),tgt.getAttribute("resultValue")]; -this.setAllValues(tgt.getAttribute("resultName"),tgt.getAttribute("resultValue")); -if(!evt.noHide){ -this._hideResultList(); -this._setSelectedRange(this.textInputNode,0,null); -} -this._tryFocus(); -},_clearResultList:function(){ -if(this.optionsListNode.innerHTML){ -this.optionsListNode.innerHTML=""; -} -},_hideResultList:function(){ -this.popupWidget.close(); -},_showResultList:function(){ -var _c67=this.optionsListNode.childNodes; -if(_c67.length){ -var _c68=Math.min(_c67.length,this.maxListLength); -with(this.optionsListNode.style){ -display=""; -if(_c68==_c67.length){ -height=""; -}else{ -height=_c68*dojo.html.getMarginBox(_c67[0]).height+"px"; -} -width=(dojo.html.getMarginBox(this.domNode).width-2)+"px"; -} -this.popupWidget.open(this.domNode,this,this.downArrowNode); -}else{ -this._hideResultList(); -} -},handleArrowClick:function(){ -this._handleBlurTimer(true,0); -this._tryFocus(); -if(this.popupWidget.isShowingNow){ -this._hideResultList(); -}else{ -this._startSearch(""); -} -},_tryFocus:function(){ -try{ -this.textInputNode.focus(); -} -catch(e){ -} -},_startSearchFromInput:function(){ -this._startSearch(this.textInputNode.value); -},_startSearch:function(key){ -this.dataProvider.startSearch(key,dojo.lang.hitch(this,"_openResultList")); -},postCreate:function(){ -this.onResize(); -dojo.event.connect(this.textInputNode,"onblur",this,"_onBlurInput"); -dojo.event.connect(this.textInputNode,"onfocus",this,"_onFocusInput"); -if(this.disabled){ -this.disable(); -} -var s=dojo.widget.html.stabile.getState(this.widgetId); -if(s){ -this.setState(s); -} -}}); -dojo.provide("struts.widget.ComboBox"); -struts.widget.ComboBoxDataProvider=function(_c6b,node){ -this.data=[]; -this.searchLimit=_c6b.searchLimit; -this.searchType="STARTSTRING"; -this.caseSensitive=false; -this._lastSearch=""; -this._lastSearchResults=null; -this.firstRequest=true; -this.cbox=_c6b; -this.formId=this.cbox.formId; -this.formFilter=this.cbox.formFilter; -this.transport=this.cbox.transport; -this.getData=function(url){ -dojo.html.show(this.cbox.indicator); -dojo.io.bind({url:url,formNode:dojo.byId(this.formId),formFilter:window[this.formFilter],transport:this.transport,handler:dojo.lang.hitch(this,function(type,data,evt){ -dojo.html.hide(this.cbox.indicator); -if(!this.firstRequest||type=="error"){ -this.cbox.notify.apply(this.cbox,[data,type,evt]); -} -this.firstRequest=false; -var _c71=null; -var _c72=data[dojo.string.isBlank(this.cbox.dataFieldName)?this.cbox.name:this.cbox.dataFieldName]; -if(!dojo.lang.isArray(data)){ -if(_c72){ -if(dojo.lang.isArray(_c72)){ -_c71=_c72; -}else{ -if(dojo.lang.isObject(_c72)){ -_c71=[]; -for(var key in _c72){ -_c71.push([key,_c72[key]]); -} -} -} -}else{ -var _c74=[]; -for(var key in data){ -if(dojo.string.startsWith(key,this.cbox.name)){ -_c71=data[key]; -break; -}else{ -_c74.push([key,data[key]]); -} -if(!_c71&&dojo.lang.isArray(data[key])&&!dojo.lang.isString(data[key])){ -_c71=data[key]; -} -} -if(!_c71){ -_c71=_c74; -} -} -data=_c71; -} -this.setData(data); -}),mimetype:"text/json"}); -}; -this.startSearch=function(_c75,_c76){ -this._preformSearch(_c75,_c76); -}; -this._preformSearch=function(_c77,_c78){ -var st=this.searchType; -var ret=[]; -if(!this.caseSensitive){ -_c77=_c77.toLowerCase(); -} -for(var x=0;x0)&&(ret.length>=this.searchLimit)){ -break; -} -var _c7c=new String((!this.caseSensitive)?this.data[x][0].toLowerCase():this.data[x][0]); -if(_c7c.length<_c77.length){ -continue; -} -if(st=="STARTSTRING"){ -if(_c77==_c7c.substr(0,_c77.length)){ -ret.push(this.data[x]); -} -}else{ -if(st=="SUBSTRING"){ -if(_c7c.indexOf(_c77)>=0){ -ret.push(this.data[x]); -} -}else{ -if(st=="STARTWORD"){ -var idx=_c7c.indexOf(_c77); -if(idx==0){ -ret.push(this.data[x]); -} -if(idx<=0){ -continue; -} -var _c7e=false; -while(idx!=-1){ -if(" ,/(".indexOf(_c7c.charAt(idx-1))!=-1){ -_c7e=true; -break; -} -idx=_c7c.indexOf(_c77,idx+1); -} -if(!_c7e){ -continue; -}else{ -ret.push(this.data[x]); -} -} -} -} -} -_c78(ret); -}; -this.addData=function(_c7f){ -this.data=this.data.concat(_c7f); -}; -this.setData=function(_c80){ -this.data=_c80; -for(var i=0;i0)){ -var cpos=this._getCaretPos(this.textInputNode); -if((cpos+1)>this.textInputNode.value.length){ -this.textInputNode.value+=_c8b[0][0].substr(cpos); -this._setSelectedRange(this.textInputNode,cpos,this.textInputNode.value.length); -} -} -var _c8d=this.textInputNode.value; -var even=true; -while(_c8b.length){ -var tr=_c8b.shift(); -if(tr){ -var td=document.createElement("div"); -var text=tr[0]; -var i=text.toLowerCase().indexOf(_c8d.toLowerCase()); -if(i>=0){ -var pre=text.substring(0,i); -var _c94=text.substring(i,i+_c8d.length); -var post=text.substring(i+_c8d.length); -if(!dojo.string.isBlank(pre)){ -td.appendChild(document.createTextNode(pre)); -} -var _c96=document.createElement("b"); -td.appendChild(_c96); -_c96.appendChild(document.createTextNode(_c94)); -td.appendChild(document.createTextNode(post)); -}else{ -td.appendChild(document.createTextNode(tr[0])); -} -td.setAttribute("resultName",tr[0]); -td.setAttribute("resultValue",tr[1]); -td.className="dojoComboBoxItem "+((even)?"dojoComboBoxItemEven":"dojoComboBoxItemOdd"); -even=(!even); -this.optionsListNode.appendChild(td); -} -} -this.showResultList(); -},postCreate:function(){ -struts.widget.ComboBox.superclass.postCreate.apply(this); -var self=this; -if(!dojo.string.isBlank(this.listenTopics)){ -var _c98=this.listenTopics.split(","); -for(var i=0;i<_c98.length;i++){ -dojo.event.topic.subscribe(_c98[i],function(){ -var _c9a={cancel:false}; -self.notify(this.widgetId,"before",_c9a); -if(_c9a.cancel){ -return; -} -self.clearValues(); -self.dataProvider.getData(self.dataUrl); -}); -} -} -if(!dojo.string.isBlank(this.notifyTopics)){ -this.notifyTopicsArray=this.notifyTopics.split(","); -} -if(!dojo.string.isBlank(this.beforeNotifyTopics)){ -this.beforeNotifyTopicsArray=this.beforeNotifyTopics.split(","); -} -if(!dojo.string.isBlank(this.afterNotifyTopics)){ -this.afterNotifyTopicsArray=this.afterNotifyTopics.split(","); -} -if(!dojo.string.isBlank(this.errorNotifyTopics)){ -this.errorNotifyTopicsArray=this.errorNotifyTopics.split(","); -} -if(!dojo.string.isBlank(this.valueNotifyTopics)){ -this.valueNotifyTopicsArray=this.valueNotifyTopics.split(","); -} -this.comboBoxSelectionValue.name=dojo.string.isBlank(this.keyName)?this.name+"Key":this.keyName; -this.comboBoxValue.value=this.initialValue; -this.comboBoxSelectionValue.value=this.initialKey; -this.textInputNode.value=this.initialValue; -if(!this.visibleDownArrow){ -dojo.html.hide(this.downArrowNode); -} -if(!dojo.string.isBlank(this.searchType)){ -this.dataProvider.searchType=this.searchType.toUpperCase(); -} -},clearValues:function(){ -this.comboBoxValue.value=""; -this.comboBoxSelectionValue.value=""; -this.textInputNode.value=""; -},onValueChanged:function(data){ -this.notify(data,"valuechanged",null); -},notify:function(data,type,e){ -var self=this; -if(this.notifyTopicsArray){ -dojo.lang.forEach(this.notifyTopicsArray,function(_ca0){ -try{ -dojo.event.topic.publish(_ca0,data,type,e,self); -} -catch(ex){ -self.log(ex); -} -}); -} -var _ca1=null; -switch(type){ -case "before": -this.notifyTo(this.beforeNotifyTopicsArray,[e,this]); -break; -case "load": -this.notifyTo(this.afterNotifyTopicsArray,[data,e,this]); -break; -case "error": -this.notifyTo(this.errorNotifyTopicsArray,[data,e,this]); -break; -case "valuechanged": -this.notifyTo(this.valueNotifyTopicsArray,[this.getSelectedValue(),this.getSelectedKey(),this.getText(),this]); -break; -} -},notifyTo:function(_ca2,_ca3){ -var self=this; -if(_ca2){ -dojo.lang.forEach(_ca2,function(_ca5){ -try{ -dojo.event.topic.publishApply(_ca5,_ca3); -} -catch(ex){ -self.log(ex); -} -}); -} -},log:function(text){ -dojo.debug("["+(this.widgetId?this.widgetId:"unknown")+"] "+text); -},_startSearchFromInput:function(){ -var _ca7=this.textInputNode.value; -if(this.loadOnType){ -if(_ca7.length>=this.loadMinimum){ -var _ca8=this.dataUrl+(this.dataUrl.indexOf("?")>-1?"&":"?"); -_ca8+=this.name+"="+encodeURIComponent(_ca7); -this.dataProvider.getData(_ca8); -this._startSearch(_ca7); -}else{ -this._hideResultList(); -} -}else{ -this._startSearch(_ca7); -} -},setSelectedKey:function(key){ -var data=this.dataProvider.data; -for(element in data){ -var obj=data[element]; -if(obj[1].toString()==key){ -this.setValue(obj[0].toString()); -this.comboBoxSelectionValue.value=obj[1].toString(); -} -} -},getSelectedKey:function(){ -return this.comboBoxSelectionValue.value; -},getSelectedValue:function(){ -return this.comboBoxValue.value; -},getText:function(){ -return this.textInputNode.value; -}}); -dojo.provide("dojo.widget.DropdownContainer"); -dojo.widget.defineWidget("dojo.widget.DropdownContainer",dojo.widget.HtmlWidget,{inputWidth:"7em",id:"",inputId:"",inputName:"",iconURL:dojo.uri.moduleUri("dojo.widget","templates/images/combo_box_arrow.png"),copyClasses:false,iconAlt:"",containerToggle:"plain",containerToggleDuration:150,templateString:" \"${this.iconAlt}\"",templateCssPath:"",isContainer:true,attachTemplateNodes:function(){ -dojo.widget.DropdownContainer.superclass.attachTemplateNodes.apply(this,arguments); -this.popup=dojo.widget.createWidget("PopupContainer",{toggle:this.containerToggle,toggleDuration:this.containerToggleDuration}); -this.containerNode=this.popup.domNode; -},fillInTemplate:function(args,frag){ -this.domNode.appendChild(this.popup.domNode); -if(this.id){ -this.domNode.id=this.id; -} -if(this.inputId){ -this.inputNode.id=this.inputId; -} -if(this.inputName){ -this.inputNode.name=this.inputName; -} -this.inputNode.style.width=this.inputWidth; -this.inputNode.disabled=this.disabled; -if(this.copyClasses){ -this.inputNode.style=""; -this.inputNode.className=this.getFragNodeRef(frag).className; -} -dojo.event.connect(this.inputNode,"onchange",this,"onInputChange"); -},onIconClick:function(evt){ -if(this.disabled){ -return; -} -if(!this.popup.isShowingNow){ -this.popup.open(this.inputNode,this,this.buttonNode); -}else{ -this.popup.close(); -} -},hideContainer:function(){ -if(this.popup.isShowingNow){ -this.popup.close(); -} -},onInputChange:function(){ -},enable:function(){ -this.inputNode.disabled=false; -dojo.widget.DropdownContainer.superclass.enable.apply(this,arguments); -},disable:function(){ -this.inputNode.disabled=true; -dojo.widget.DropdownContainer.superclass.disable.apply(this,arguments); -}}); -dojo.provide("dojo.date.serialize"); -dojo.date.setIso8601=function(_caf,_cb0){ -var _cb1=(_cb0.indexOf("T")==-1)?_cb0.split(" "):_cb0.split("T"); -_caf=dojo.date.setIso8601Date(_caf,_cb1[0]); -if(_cb1.length==2){ -_caf=dojo.date.setIso8601Time(_caf,_cb1[1]); -} -return _caf; -}; -dojo.date.fromIso8601=function(_cb2){ -return dojo.date.setIso8601(new Date(0,0),_cb2); -}; -dojo.date.setIso8601Date=function(_cb3,_cb4){ -var _cb5="^([0-9]{4})((-?([0-9]{2})(-?([0-9]{2}))?)|"+"(-?([0-9]{3}))|(-?W([0-9]{2})(-?([1-7]))?))?$"; -var d=_cb4.match(new RegExp(_cb5)); -if(!d){ -dojo.debug("invalid date string: "+_cb4); -return null; -} -var year=d[1]; -var _cb8=d[4]; -var date=d[6]; -var _cba=d[8]; -var week=d[10]; -var _cbc=d[12]?d[12]:1; -_cb3.setFullYear(year); -if(_cba){ -_cb3.setMonth(0); -_cb3.setDate(Number(_cba)); -}else{ -if(week){ -_cb3.setMonth(0); -_cb3.setDate(1); -var gd=_cb3.getDay(); -var day=gd?gd:7; -var _cbf=Number(_cbc)+(7*Number(week)); -if(day<=4){ -_cb3.setDate(_cbf+1-day); -}else{ -_cb3.setDate(_cbf+8-day); -} -}else{ -if(_cb8){ -_cb3.setDate(1); -_cb3.setMonth(_cb8-1); -} -if(date){ -_cb3.setDate(date); -} -} -} -return _cb3; -}; -dojo.date.fromIso8601Date=function(_cc0){ -return dojo.date.setIso8601Date(new Date(0,0),_cc0); -}; -dojo.date.setIso8601Time=function(_cc1,_cc2){ -var _cc3="Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$"; -var d=_cc2.match(new RegExp(_cc3)); -var _cc5=0; -if(d){ -if(d[0]!="Z"){ -_cc5=(Number(d[3])*60)+Number(d[5]); -_cc5*=((d[2]=="-")?1:-1); -} -_cc5-=_cc1.getTimezoneOffset(); -_cc2=_cc2.substr(0,_cc2.length-d[0].length); -} -var _cc6="^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(.([0-9]+))?)?)?$"; -d=_cc2.match(new RegExp(_cc6)); -if(!d){ -dojo.debug("invalid time string: "+_cc2); -return null; -} -var _cc7=d[1]; -var mins=Number((d[3])?d[3]:0); -var secs=(d[5])?d[5]:0; -var ms=d[7]?(Number("0."+d[7])*1000):0; -_cc1.setHours(_cc7); -_cc1.setMinutes(mins); -_cc1.setSeconds(secs); -_cc1.setMilliseconds(ms); -if(_cc5!==0){ -_cc1.setTime(_cc1.getTime()+_cc5*60000); -} -return _cc1; -}; -dojo.date.fromIso8601Time=function(_ccb){ -return dojo.date.setIso8601Time(new Date(0,0),_ccb); -}; -dojo.date.toRfc3339=function(_ccc,_ccd){ -if(!_ccc){ -_ccc=new Date(); -} -var _=dojo.string.pad; -var _ccf=[]; -if(_ccd!="timeOnly"){ -var date=[_(_ccc.getFullYear(),4),_(_ccc.getMonth()+1,2),_(_ccc.getDate(),2)].join("-"); -_ccf.push(date); -} -if(_ccd!="dateOnly"){ -var time=[_(_ccc.getHours(),2),_(_ccc.getMinutes(),2),_(_ccc.getSeconds(),2)].join(":"); -var _cd2=_ccc.getTimezoneOffset(); -time+=(_cd2>0?"-":"+")+_(Math.floor(Math.abs(_cd2)/60),2)+":"+_(Math.abs(_cd2)%60,2); -_ccf.push(time); -} -return _ccf.join("T"); -}; -dojo.date.fromRfc3339=function(_cd3){ -if(_cd3.indexOf("Tany")!=-1){ -_cd3=_cd3.replace("Tany",""); -} -var _cd4=new Date(); -return dojo.date.setIso8601(_cd4,_cd3); -}; -dojo.provide("dojo.date.common"); -dojo.date.setDayOfYear=function(_cd5,_cd6){ -_cd5.setMonth(0); -_cd5.setDate(_cd6); -return _cd5; -}; -dojo.date.getDayOfYear=function(_cd7){ -var _cd8=_cd7.getFullYear(); -var _cd9=new Date(_cd8-1,11,31); -return Math.floor((_cd7.getTime()-_cd9.getTime())/86400000); -}; -dojo.date.setWeekOfYear=function(_cda,week,_cdc){ -if(arguments.length==1){ -_cdc=0; -} -dojo.unimplemented("dojo.date.setWeekOfYear"); -}; -dojo.date.getWeekOfYear=function(_cdd,_cde){ -if(arguments.length==1){ -_cde=0; -} -var _cdf=new Date(_cdd.getFullYear(),0,1); -var day=_cdf.getDay(); -_cdf.setDate(_cdf.getDate()-day+_cde-(day>_cde?7:0)); -return Math.floor((_cdd.getTime()-_cdf.getTime())/604800000); -}; -dojo.date.setIsoWeekOfYear=function(_ce1,week,_ce3){ -if(arguments.length==1){ -_ce3=1; -} -dojo.unimplemented("dojo.date.setIsoWeekOfYear"); -}; -dojo.date.getIsoWeekOfYear=function(_ce4,_ce5){ -if(arguments.length==1){ -_ce5=1; -} -dojo.unimplemented("dojo.date.getIsoWeekOfYear"); -}; -dojo.date.shortTimezones=["IDLW","BET","HST","MART","AKST","PST","MST","CST","EST","AST","NFT","BST","FST","AT","GMT","CET","EET","MSK","IRT","GST","AFT","AGTT","IST","NPT","ALMT","MMT","JT","AWST","JST","ACST","AEST","LHST","VUT","NFT","NZT","CHAST","PHOT","LINT"]; -dojo.date.timezoneOffsets=[-720,-660,-600,-570,-540,-480,-420,-360,-300,-240,-210,-180,-120,-60,0,60,120,180,210,240,270,300,330,345,360,390,420,480,540,570,600,630,660,690,720,765,780,840]; -dojo.date.getDaysInMonth=function(_ce6){ -var _ce7=_ce6.getMonth(); -var days=[31,28,31,30,31,30,31,31,30,31,30,31]; -if(_ce7==1&&dojo.date.isLeapYear(_ce6)){ -return 29; -}else{ -return days[_ce7]; -} -}; -dojo.date.isLeapYear=function(_ce9){ -var year=_ce9.getFullYear(); -return (year%400==0)?true:(year%100==0)?false:(year%4==0)?true:false; -}; -dojo.date.getTimezoneName=function(_ceb){ -var str=_ceb.toString(); -var tz=""; -var _cee; -var pos=str.indexOf("("); -if(pos>-1){ -pos++; -tz=str.substring(pos,str.indexOf(")")); -}else{ -var pat=/([A-Z\/]+) \d{4}$/; -if((_cee=str.match(pat))){ -tz=_cee[1]; -}else{ -str=_ceb.toLocaleString(); -pat=/ ([A-Z\/]+)$/; -if((_cee=str.match(pat))){ -tz=_cee[1]; -} -} -} -return tz=="AM"||tz=="PM"?"":tz; -}; -dojo.date.getOrdinal=function(_cf1){ -var date=_cf1.getDate(); -if(date%100!=11&&date%10==1){ -return "st"; -}else{ -if(date%100!=12&&date%10==2){ -return "nd"; -}else{ -if(date%100!=13&&date%10==3){ -return "rd"; -}else{ -return "th"; -} -} -} -}; -dojo.date.compareTypes={DATE:1,TIME:2}; -dojo.date.compare=function(_cf3,_cf4,_cf5){ -var dA=_cf3; -var dB=_cf4||new Date(); -var now=new Date(); -with(dojo.date.compareTypes){ -var opt=_cf5||(DATE|TIME); -var d1=new Date((opt&DATE)?dA.getFullYear():now.getFullYear(),(opt&DATE)?dA.getMonth():now.getMonth(),(opt&DATE)?dA.getDate():now.getDate(),(opt&TIME)?dA.getHours():0,(opt&TIME)?dA.getMinutes():0,(opt&TIME)?dA.getSeconds():0); -var d2=new Date((opt&DATE)?dB.getFullYear():now.getFullYear(),(opt&DATE)?dB.getMonth():now.getMonth(),(opt&DATE)?dB.getDate():now.getDate(),(opt&TIME)?dB.getHours():0,(opt&TIME)?dB.getMinutes():0,(opt&TIME)?dB.getSeconds():0); -} -if(d1.valueOf()>d2.valueOf()){ -return 1; -} -if(d1.valueOf()0)?5:-5; -_d01=(incr>0)?((incr-5)/5):((incr+5)/5); -}else{ -days=mod; -_d01=parseInt(incr/5); -} -strt=dt.getDay(); -if(strt==6&&incr>0){ -adj=1; -}else{ -if(strt==0&&incr<0){ -adj=-1; -} -} -trgt=(strt+days); -if(trgt==0||trgt==6){ -adj=(incr>0)?2:-2; -} -sum.setDate(dat+(7*_d01)+days+adj); -break; -case HOUR: -sum.setHours(sum.getHours()+incr); -break; -case MINUTE: -sum.setMinutes(sum.getMinutes()+incr); -break; -case SECOND: -sum.setSeconds(sum.getSeconds()+incr); -break; -case MILLISECOND: -sum.setMilliseconds(sum.getMilliseconds()+incr); -break; -default: -break; -} -} -return sum; -}; -dojo.date.diff=function(dtA,dtB,_d09){ -if(typeof dtA=="number"){ -dtA=new Date(dtA); -} -if(typeof dtB=="number"){ -dtB=new Date(dtB); -} -var _d0a=dtB.getFullYear()-dtA.getFullYear(); -var _d0b=(dtB.getMonth()-dtA.getMonth())+(_d0a*12); -var _d0c=dtB.getTime()-dtA.getTime(); -var _d0d=_d0c/1000; -var _d0e=_d0d/60; -var _d0f=_d0e/60; -var _d10=_d0f/24; -var _d11=_d10/7; -var _d12=0; -with(dojo.date.dateParts){ -switch(_d09){ -case YEAR: -_d12=_d0a; -break; -case QUARTER: -var mA=dtA.getMonth(); -var mB=dtB.getMonth(); -var qA=Math.floor(mA/3)+1; -var qB=Math.floor(mB/3)+1; -qB+=(_d0a*4); -_d12=qB-qA; -break; -case MONTH: -_d12=_d0b; -break; -case WEEK: -_d12=parseInt(_d11); -break; -case DAY: -_d12=_d10; -break; -case WEEKDAY: -var days=Math.round(_d10); -var _d18=parseInt(days/7); -var mod=days%7; -if(mod==0){ -days=_d18*5; -}else{ -var adj=0; -var aDay=dtA.getDay(); -var bDay=dtB.getDay(); -_d18=parseInt(days/7); -mod=days%7; -var _d1d=new Date(dtA); -_d1d.setDate(_d1d.getDate()+(_d18*7)); -var _d1e=_d1d.getDay(); -if(_d10>0){ -switch(true){ -case aDay==6: -adj=-1; -break; -case aDay==0: -adj=0; -break; -case bDay==6: -adj=-1; -break; -case bDay==0: -adj=-2; -break; -case (_d1e+mod)>5: -adj=-2; -break; -default: -break; -} -}else{ -if(_d10<0){ -switch(true){ -case aDay==6: -adj=0; -break; -case aDay==0: -adj=1; -break; -case bDay==6: -adj=2; -break; -case bDay==0: -adj=1; -break; -case (_d1e+mod)<0: -adj=2; -break; -default: -break; -} -} -} -days+=adj; -days-=(_d18*2); -} -_d12=days; -break; -case HOUR: -_d12=_d0f; -break; -case MINUTE: -_d12=_d0e; -break; -case SECOND: -_d12=_d0d; -break; -case MILLISECOND: -_d12=_d0c; -break; -default: -break; -} -} -return Math.round(_d12); -}; -dojo.provide("dojo.date.supplemental"); -dojo.date.getFirstDayOfWeek=function(_d1f){ -var _d20={mv:5,ae:6,af:6,bh:6,dj:6,dz:6,eg:6,er:6,et:6,iq:6,ir:6,jo:6,ke:6,kw:6,lb:6,ly:6,ma:6,om:6,qa:6,sa:6,sd:6,so:6,tn:6,ye:6,as:0,au:0,az:0,bw:0,ca:0,cn:0,fo:0,ge:0,gl:0,gu:0,hk:0,ie:0,il:0,is:0,jm:0,jp:0,kg:0,kr:0,la:0,mh:0,mo:0,mp:0,mt:0,nz:0,ph:0,pk:0,sg:0,th:0,tt:0,tw:0,um:0,us:0,uz:0,vi:0,za:0,zw:0,et:0,mw:0,ng:0,tj:0,gb:0,sy:4}; -_d1f=dojo.hostenv.normalizeLocale(_d1f); -var _d21=_d1f.split("-")[1]; -var dow=_d20[_d21]; -return (typeof dow=="undefined")?1:dow; -}; -dojo.date.getWeekend=function(_d23){ -var _d24={eg:5,il:5,sy:5,"in":0,ae:4,bh:4,dz:4,iq:4,jo:4,kw:4,lb:4,ly:4,ma:4,om:4,qa:4,sa:4,sd:4,tn:4,ye:4}; -var _d25={ae:5,bh:5,dz:5,iq:5,jo:5,kw:5,lb:5,ly:5,ma:5,om:5,qa:5,sa:5,sd:5,tn:5,ye:5,af:5,ir:5,eg:6,il:6,sy:6}; -_d23=dojo.hostenv.normalizeLocale(_d23); -var _d26=_d23.split("-")[1]; -var _d27=_d24[_d26]; -var end=_d25[_d26]; -if(typeof _d27=="undefined"){ -_d27=6; -} -if(typeof end=="undefined"){ -end=0; -} -return {start:_d27,end:end}; -}; -dojo.date.isWeekend=function(_d29,_d2a){ -var _d2b=dojo.date.getWeekend(_d2a); -var day=(_d29||new Date()).getDay(); -if(_d2b.end<_d2b.start){ -_d2b.end+=7; -if(day<_d2b.start){ -day+=7; -} -} -return day>=_d2b.start&&day<=_d2b.end; -}; -dojo.provide("dojo.i18n.common"); -dojo.i18n.getLocalization=function(_d2d,_d2e,_d2f){ -dojo.hostenv.preloadLocalizations(); -_d2f=dojo.hostenv.normalizeLocale(_d2f); -var _d30=_d2f.split("-"); -var _d31=[_d2d,"nls",_d2e].join("."); -var _d32=dojo.hostenv.findModule(_d31,true); -var _d33; -for(var i=_d30.length;i>0;i--){ -var loc=_d30.slice(0,i).join("_"); -if(_d32[loc]){ -_d33=_d32[loc]; -break; -} -} -if(!_d33){ -_d33=_d32.ROOT; -} -if(_d33){ -var _d36=function(){ -}; -_d36.prototype=_d33; -return new _d36(); -} -dojo.raise("Bundle not found: "+_d2e+" in "+_d2d+" , locale="+_d2f); -}; -dojo.i18n.isLTR=function(_d37){ -var lang=dojo.hostenv.normalizeLocale(_d37).split("-")[0]; -var RTL={ar:true,fa:true,he:true,ur:true,yi:true}; -return !RTL[lang]; -}; -dojo.provide("dojo.date.format"); -(function(){ -dojo.date.format=function(_d3a,_d3b){ -if(typeof _d3b=="string"){ -dojo.deprecated("dojo.date.format","To format dates with POSIX-style strings, please use dojo.date.strftime instead","0.5"); -return dojo.date.strftime(_d3a,_d3b); -} -function formatPattern(_d3c,_d3d){ -return _d3d.replace(/([a-z])\1*/ig,function(_d3e){ -var s; -var c=_d3e.charAt(0); -var l=_d3e.length; -var pad; -var _d43=["abbr","wide","narrow"]; -switch(c){ -case "G": -if(l>3){ -dojo.unimplemented("Era format not implemented"); -} -s=info.eras[_d3c.getFullYear()<0?1:0]; -break; -case "y": -s=_d3c.getFullYear(); -switch(l){ -case 1: -break; -case 2: -s=String(s).substr(-2); -break; -default: -pad=true; -} -break; -case "Q": -case "q": -s=Math.ceil((_d3c.getMonth()+1)/3); -switch(l){ -case 1: -case 2: -pad=true; -break; -case 3: -case 4: -dojo.unimplemented("Quarter format not implemented"); -} -break; -case "M": -case "L": -var m=_d3c.getMonth(); -var _d46; -switch(l){ -case 1: -case 2: -s=m+1; -pad=true; -break; -case 3: -case 4: -case 5: -_d46=_d43[l-3]; -break; -} -if(_d46){ -var type=(c=="L")?"standalone":"format"; -var prop=["months",type,_d46].join("-"); -s=info[prop][m]; -} -break; -case "w": -var _d49=0; -s=dojo.date.getWeekOfYear(_d3c,_d49); -pad=true; -break; -case "d": -s=_d3c.getDate(); -pad=true; -break; -case "D": -s=dojo.date.getDayOfYear(_d3c); -pad=true; -break; -case "E": -case "e": -case "c": -var d=_d3c.getDay(); -var _d46; -switch(l){ -case 1: -case 2: -if(c=="e"){ -var _d4b=dojo.date.getFirstDayOfWeek(_d3b.locale); -d=(d-_d4b+7)%7; -} -if(c!="c"){ -s=d+1; -pad=true; -break; -} -case 3: -case 4: -case 5: -_d46=_d43[l-3]; -break; -} -if(_d46){ -var type=(c=="c")?"standalone":"format"; -var prop=["days",type,_d46].join("-"); -s=info[prop][d]; -} -break; -case "a": -var _d4c=(_d3c.getHours()<12)?"am":"pm"; -s=info[_d4c]; -break; -case "h": -case "H": -case "K": -case "k": -var h=_d3c.getHours(); -switch(c){ -case "h": -s=(h%12)||12; -break; -case "H": -s=h; -break; -case "K": -s=(h%12); -break; -case "k": -s=h||24; -break; -} -pad=true; -break; -case "m": -s=_d3c.getMinutes(); -pad=true; -break; -case "s": -s=_d3c.getSeconds(); -pad=true; -break; -case "S": -s=Math.round(_d3c.getMilliseconds()*Math.pow(10,l-3)); -break; -case "v": -case "z": -s=dojo.date.getTimezoneName(_d3c); -if(s){ -break; -} -l=4; -case "Z": -var _d4e=_d3c.getTimezoneOffset(); -var tz=[(_d4e<=0?"+":"-"),dojo.string.pad(Math.floor(Math.abs(_d4e)/60),2),dojo.string.pad(Math.abs(_d4e)%60,2)]; -if(l==4){ -tz.splice(0,0,"GMT"); -tz.splice(3,0,":"); -} -s=tz.join(""); -break; -case "Y": -case "u": -case "W": -case "F": -case "g": -case "A": -dojo.debug(_d3e+" modifier not yet implemented"); -s="?"; -break; -default: -dojo.raise("dojo.date.format: invalid pattern char: "+_d3d); -} -if(pad){ -s=dojo.string.pad(s,l); -} -return s; -}); -} -_d3b=_d3b||{}; -var _d50=dojo.hostenv.normalizeLocale(_d3b.locale); -var _d51=_d3b.formatLength||"full"; -var info=dojo.date._getGregorianBundle(_d50); -var str=[]; -var _d53=dojo.lang.curry(this,formatPattern,_d3a); -if(_d3b.selector!="timeOnly"){ -var _d54=_d3b.datePattern||info["dateFormat-"+_d51]; -if(_d54){ -str.push(_processPattern(_d54,_d53)); -} -} -if(_d3b.selector!="dateOnly"){ -var _d55=_d3b.timePattern||info["timeFormat-"+_d51]; -if(_d55){ -str.push(_processPattern(_d55,_d53)); -} -} -var _d56=str.join(" "); -return _d56; -}; -dojo.date.parse=function(_d57,_d58){ -_d58=_d58||{}; -var _d59=dojo.hostenv.normalizeLocale(_d58.locale); -var info=dojo.date._getGregorianBundle(_d59); -var _d5b=_d58.formatLength||"full"; -if(!_d58.selector){ -_d58.selector="dateOnly"; -} -var _d5c=_d58.datePattern||info["dateFormat-"+_d5b]; -var _d5d=_d58.timePattern||info["timeFormat-"+_d5b]; -var _d5e; -if(_d58.selector=="dateOnly"){ -_d5e=_d5c; -}else{ -if(_d58.selector=="timeOnly"){ -_d5e=_d5d; -}else{ -if(_d58.selector=="dateTime"){ -_d5e=_d5c+" "+_d5d; -}else{ -var msg="dojo.date.parse: Unknown selector param passed: '"+_d58.selector+"'."; -msg+=" Defaulting to date pattern."; -dojo.debug(msg); -_d5e=_d5c; -} -} -} -var _d60=[]; -var _d61=_processPattern(_d5e,dojo.lang.curry(this,_buildDateTimeRE,_d60,info,_d58)); -var _d62=new RegExp("^"+_d61+"$"); -var _d63=_d62.exec(_d57); -if(!_d63){ -return null; -} -var _d64=["abbr","wide","narrow"]; -var _d65=new Date(1972,0); -var _d66={}; -for(var i=1;i<_d63.length;i++){ -var grp=_d60[i-1]; -var l=grp.length; -var v=_d63[i]; -switch(grp.charAt(0)){ -case "y": -if(l!=2){ -_d65.setFullYear(v); -_d66.year=v; -}else{ -if(v<100){ -v=Number(v); -var year=""+new Date().getFullYear(); -var _d6c=year.substring(0,2)*100; -var _d6d=Number(year.substring(2,4)); -var _d6e=Math.min(_d6d+20,99); -var num=(v<_d6e)?_d6c+v:_d6c-100+v; -_d65.setFullYear(num); -_d66.year=num; -}else{ -if(_d58.strict){ -return null; -} -_d65.setFullYear(v); -_d66.year=v; -} -} -break; -case "M": -if(l>2){ -if(!_d58.strict){ -v=v.replace(/\./g,""); -v=v.toLowerCase(); -} -var _d70=info["months-format-"+_d64[l-3]].concat(); -for(var j=0;j<_d70.length;j++){ -if(!_d58.strict){ -_d70[j]=_d70[j].toLowerCase(); -} -if(v==_d70[j]){ -_d65.setMonth(j); -_d66.month=j; -break; -} -} -if(j==_d70.length){ -dojo.debug("dojo.date.parse: Could not parse month name: '"+v+"'."); -return null; -} -}else{ -_d65.setMonth(v-1); -_d66.month=v-1; -} -break; -case "E": -case "e": -if(!_d58.strict){ -v=v.toLowerCase(); -} -var days=info["days-format-"+_d64[l-3]].concat(); -for(var j=0;j23){ -dojo.debug("dojo.date.parse: Illegal hours value"); -return null; -} -_d65.setHours(v); -break; -case "m": -_d65.setMinutes(v); -break; -case "s": -_d65.setSeconds(v); -break; -case "S": -_d65.setMilliseconds(v); -break; -default: -dojo.unimplemented("dojo.date.parse: unsupported pattern char="+grp.charAt(0)); -} -} -if(_d66.year&&_d65.getFullYear()!=_d66.year){ -dojo.debug("Parsed year: '"+_d65.getFullYear()+"' did not match input year: '"+_d66.year+"'."); -return null; -} -if(_d66.month&&_d65.getMonth()!=_d66.month){ -dojo.debug("Parsed month: '"+_d65.getMonth()+"' did not match input month: '"+_d66.month+"'."); -return null; -} -if(_d66.date&&_d65.getDate()!=_d66.date){ -dojo.debug("Parsed day of month: '"+_d65.getDate()+"' did not match input day of month: '"+_d66.date+"'."); -return null; -} -return _d65; -}; -function _processPattern(_d76,_d77,_d78,_d79){ -var _d7a=function(x){ -return x; -}; -_d77=_d77||_d7a; -_d78=_d78||_d7a; -_d79=_d79||_d7a; -var _d7c=_d76.match(/(''|[^'])+/g); -var _d7d=false; -for(var i=0;i<_d7c.length;i++){ -if(!_d7c[i]){ -_d7c[i]=""; -}else{ -_d7c[i]=(_d7d?_d78:_d77)(_d7c[i]); -_d7d=!_d7d; -} -} -return _d79(_d7c.join("")); -} -function _buildDateTimeRE(_d7f,info,_d81,_d82){ -return _d82.replace(/([a-z])\1*/ig,function(_d83){ -var s; -var c=_d83.charAt(0); -var l=_d83.length; -switch(c){ -case "y": -s="\\d"+((l==2)?"{2,4}":"+"); -break; -case "M": -s=(l>2)?"\\S+":"\\d{1,2}"; -break; -case "d": -s="\\d{1,2}"; -break; -case "E": -s="\\S+"; -break; -case "h": -case "H": -case "K": -case "k": -s="\\d{1,2}"; -break; -case "m": -case "s": -s="[0-5]\\d"; -break; -case "S": -s="\\d{1,3}"; -break; -case "a": -var am=_d81.am||info.am||"AM"; -var pm=_d81.pm||info.pm||"PM"; -if(_d81.strict){ -s=am+"|"+pm; -}else{ -s=am; -s+=(am!=am.toLowerCase())?"|"+am.toLowerCase():""; -s+="|"; -s+=(pm!=pm.toLowerCase())?pm+"|"+pm.toLowerCase():pm; -} -break; -default: -dojo.unimplemented("parse of date format, pattern="+_d82); -} -if(_d7f){ -_d7f.push(_d83); -} -return "\\s*("+s+")\\s*"; -}); -} -})(); -dojo.date.strftime=function(_d89,_d8a,_d8b){ -var _d8c=null; -function _(s,n){ -return dojo.string.pad(s,n||2,_d8c||"0"); -} -var info=dojo.date._getGregorianBundle(_d8b); -function $(_d90){ -switch(_d90){ -case "a": -return dojo.date.getDayShortName(_d89,_d8b); -case "A": -return dojo.date.getDayName(_d89,_d8b); -case "b": -case "h": -return dojo.date.getMonthShortName(_d89,_d8b); -case "B": -return dojo.date.getMonthName(_d89,_d8b); -case "c": -return dojo.date.format(_d89,{locale:_d8b}); -case "C": -return _(Math.floor(_d89.getFullYear()/100)); -case "d": -return _(_d89.getDate()); -case "D": -return $("m")+"/"+$("d")+"/"+$("y"); -case "e": -if(_d8c==null){ -_d8c=" "; -} -return _(_d89.getDate()); -case "f": -if(_d8c==null){ -_d8c=" "; -} -return _(_d89.getMonth()+1); -case "g": -break; -case "G": -dojo.unimplemented("unimplemented modifier 'G'"); -break; -case "F": -return $("Y")+"-"+$("m")+"-"+$("d"); -case "H": -return _(_d89.getHours()); -case "I": -return _(_d89.getHours()%12||12); -case "j": -return _(dojo.date.getDayOfYear(_d89),3); -case "k": -if(_d8c==null){ -_d8c=" "; -} -return _(_d89.getHours()); -case "l": -if(_d8c==null){ -_d8c=" "; -} -return _(_d89.getHours()%12||12); -case "m": -return _(_d89.getMonth()+1); -case "M": -return _(_d89.getMinutes()); -case "n": -return "\n"; -case "p": -return info[_d89.getHours()<12?"am":"pm"]; -case "r": -return $("I")+":"+$("M")+":"+$("S")+" "+$("p"); -case "R": -return $("H")+":"+$("M"); -case "S": -return _(_d89.getSeconds()); -case "t": -return "\t"; -case "T": -return $("H")+":"+$("M")+":"+$("S"); -case "u": -return String(_d89.getDay()||7); -case "U": -return _(dojo.date.getWeekOfYear(_d89)); -case "V": -return _(dojo.date.getIsoWeekOfYear(_d89)); -case "W": -return _(dojo.date.getWeekOfYear(_d89,1)); -case "w": -return String(_d89.getDay()); -case "x": -return dojo.date.format(_d89,{selector:"dateOnly",locale:_d8b}); -case "X": -return dojo.date.format(_d89,{selector:"timeOnly",locale:_d8b}); -case "y": -return _(_d89.getFullYear()%100); -case "Y": -return String(_d89.getFullYear()); -case "z": -var _d91=_d89.getTimezoneOffset(); -return (_d91>0?"-":"+")+_(Math.floor(Math.abs(_d91)/60))+":"+_(Math.abs(_d91)%60); -case "Z": -return dojo.date.getTimezoneName(_d89); -case "%": -return "%"; -} -} -var _d92=""; -var i=0; -var _d94=0; -var _d95=null; -while((_d94=_d8a.indexOf("%",i))!=-1){ -_d92+=_d8a.substring(i,_d94++); -switch(_d8a.charAt(_d94++)){ -case "_": -_d8c=" "; -break; -case "-": -_d8c=""; -break; -case "0": -_d8c="0"; -break; -case "^": -_d95="upper"; -break; -case "*": -_d95="lower"; -break; -case "#": -_d95="swap"; -break; -default: -_d8c=null; -_d94--; -break; -} -var _d96=$(_d8a.charAt(_d94++)); -switch(_d95){ -case "upper": -_d96=_d96.toUpperCase(); -break; -case "lower": -_d96=_d96.toLowerCase(); -break; -case "swap": -var _d97=_d96.toLowerCase(); -var _d98=""; -var j=0; -var ch=""; -while(j<_d96.length){ -ch=_d96.charAt(j); -_d98+=(ch==_d97.charAt(j))?ch.toUpperCase():ch.toLowerCase(); -j++; -} -_d96=_d98; -break; -default: -break; -} -_d95=null; -_d92+=_d96; -i=_d94; -} -_d92+=_d8a.substring(i); -return _d92; -}; -(function(){ -var _d9b=[]; -dojo.date.addCustomFormats=function(_d9c,_d9d){ -_d9b.push({pkg:_d9c,name:_d9d}); -}; -dojo.date._getGregorianBundle=function(_d9e){ -var _d9f={}; -dojo.lang.forEach(_d9b,function(desc){ -var _da1=dojo.i18n.getLocalization(desc.pkg,desc.name,_d9e); -_d9f=dojo.lang.mixin(_d9f,_da1); -},this); -return _d9f; -}; -})(); -dojo.date.addCustomFormats("dojo.i18n.calendar","gregorian"); -dojo.date.addCustomFormats("dojo.i18n.calendar","gregorianExtras"); -dojo.date.getNames=function(item,type,use,_da5){ -var _da6; -var _da7=dojo.date._getGregorianBundle(_da5); -var _da8=[item,use,type]; -if(use=="standAlone"){ -_da6=_da7[_da8.join("-")]; -} -_da8[1]="format"; -return (_da6||_da7[_da8.join("-")]).concat(); -}; -dojo.date.getDayName=function(_da9,_daa){ -return dojo.date.getNames("days","wide","format",_daa)[_da9.getDay()]; -}; -dojo.date.getDayShortName=function(_dab,_dac){ -return dojo.date.getNames("days","abbr","format",_dac)[_dab.getDay()]; -}; -dojo.date.getMonthName=function(_dad,_dae){ -return dojo.date.getNames("months","wide","format",_dae)[_dad.getMonth()]; -}; -dojo.date.getMonthShortName=function(_daf,_db0){ -return dojo.date.getNames("months","abbr","format",_db0)[_daf.getMonth()]; -}; -dojo.date.toRelativeString=function(_db1){ -var now=new Date(); -var diff=(now-_db1)/1000; -var end=" ago"; -var _db5=false; -if(diff<0){ -_db5=true; -end=" from now"; -diff=-diff; -} -if(diff<60){ -diff=Math.round(diff); -return diff+" second"+(diff==1?"":"s")+end; -} -if(diff<60*60){ -diff=Math.round(diff/60); -return diff+" minute"+(diff==1?"":"s")+end; -} -if(diff<60*60*24){ -diff=Math.round(diff/3600); -return diff+" hour"+(diff==1?"":"s")+end; -} -if(diff<60*60*24*7){ -diff=Math.round(diff/(3600*24)); -if(diff==1){ -return _db5?"Tomorrow":"Yesterday"; -}else{ -return diff+" days"+end; -} -} -return dojo.date.format(_db1); -}; -dojo.date.toSql=function(_db6,_db7){ -return dojo.date.strftime(_db6,"%F"+!_db7?" %T":""); -}; -dojo.date.fromSql=function(_db8){ -var _db9=_db8.split(/[\- :]/g); -while(_db9.length<6){ -_db9.push(0); -} -return new Date(_db9[0],(parseInt(_db9[1],10)-1),_db9[2],_db9[3],_db9[4],_db9[5]); -}; -dojo.provide("dojo.widget.TimePicker"); -dojo.widget.defineWidget("dojo.widget.TimePicker",dojo.widget.HtmlWidget,function(){ -this.time=""; -this.useDefaultTime=false; -this.useDefaultMinutes=false; -this.storedTime=""; -this.currentTime={}; -this.classNames={selectedTime:"selectedItem"}; -this.any="any"; -this.selectedTime={hour:"",minute:"",amPm:"",anyTime:false}; -this.hourIndexMap=["",2,4,6,8,10,1,3,5,7,9,11,0]; -this.minuteIndexMap=[0,2,4,6,8,10,1,3,5,7,9,11]; -},{isContainer:false,templateString:"
\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t
 ${this.calendar.field-hour}${this.calendar.field-minute} 
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
126
17
28
39
410
511
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
0030
0535
1040
1545
2050
2555
\r\n\t\t\t\t
 \r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
${this.calendar.am}${this.calendar.pm}
\r\n\t\t\t\t
\r\n\t\t\t\t\t
${this.widgetStrings.any}
\r\n\t\t\t\t
 
\r\n
\r\n",templateCssString:"/*Time Picker */\r\n.timePickerContainer {\r\n\twidth:122px;\r\n\tfont-family:Tahoma, Myriad, Helvetica, Arial, Verdana, sans-serif;\r\n\tfont-size:16px;\r\n}\r\n\r\n.timeContainer {\r\n\tborder-collapse:collapse;\r\n\tborder-spacing:0;\r\n}\r\n\r\n.timeContainer thead {\r\n\tcolor:#293a4b;\r\n\tfont-size:0.9em;\r\n\tfont-weight:700;\r\n}\r\n\r\n.timeContainer thead td {\r\n\tpadding:0.25em;\r\n\tfont-size:0.80em;\r\n\tborder-bottom:1px solid #6782A8;\r\n}\r\n\r\n.timeCorner {\r\n\twidth:10px;\r\n}\r\n\r\n.cornerTopLeft {\r\n\tbackground: url(\"images/dpCurveTL.png\") top left no-repeat;\r\n}\r\n\r\n.cornerTopRight {\r\n\tbackground: url(\"images/dpCurveTR.png\") top right no-repeat;\r\n}\r\n\r\n.timeLabelContainer {\r\n\tbackground: url(\"images/dpMonthBg.png\") top left repeat-x;\r\n}\r\n\r\n.hours, .minutes, .timeBorder {\r\n\tbackground: #7591bc url(\"images/dpBg.gif\") top left repeat-x;\r\n\r\n}\r\n\r\n.hours td, .minutes td {\r\n\tpadding:0.2em;\r\n\ttext-align:center;\r\n\tfont-size:0.7em;\r\n\tfont-weight:bold;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n\tcolor:#fff;\r\n}\r\n\r\n.minutes {\r\n\tborder-left:1px solid #f5d1db;\r\n}\r\n\r\n.hours {\r\n\tborder-right:1px solid #6782A8;\r\n}\r\n\r\n.hourSelector {\r\n\tborder-right:1px solid #6782A8;\r\n\tpadding:5px;\r\n\tpadding-right:10px;\r\n}\r\n\r\n.minutesSelector {\r\n\tpadding:5px;\r\n\tborder-left:1px solid #f5c7d4;\r\n\ttext-align:center;\r\n}\r\n\r\n.minutesHeading {\r\n\tpadding-left:9px !important;\r\n}\r\n\r\n.timeOptions {\r\n\tbackground-color:#F9C9D7;\r\n}\r\n\r\n.timeContainer .cornerBottomLeft, .timeContainer .cornerBottomRight, .timeContainer .timeOptions {\r\n\tborder-top:1px solid #6782A8;\r\n}\r\n\r\n.timeContainer .cornerBottomLeft {\r\n\tbackground: url(\"images/dpCurveBL.png\") bottom left no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n.timeContainer .cornerBottomRight {\r\n\tbackground: url(\"images/dpCurveBR.png\") bottom right no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n.timeOptions {\r\n\tcolor:#fff;\r\n\tbackground:url(\"images/dpYearBg.png\") top left repeat-x;\r\n\r\n}\r\n\r\n.selectedItem {\r\n\tbackground-color:#fff;\r\n\tcolor:#6782a8 !important;\r\n}\r\n\r\n.timeOptions .selectedItem {\r\n\tcolor:#fff !important;\r\n\tbackground-color:#9ec3fb !important;\r\n}\r\n\r\n.anyTimeContainer {\r\n\ttext-align:center;\r\n\tfont-weight:bold;\r\n\tfont-size:0.7em;\r\n\tpadding:0.1em;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n\tcolor:#fff !important;\r\n}\r\n\r\n.amPmContainer {\r\n\twidth:100%;\r\n}\r\n\r\n.amPmContainer td {\r\n\ttext-align:center;\r\n\tfont-size:0.7em;\r\n\tfont-weight:bold;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n\tcolor:#fff;\r\n}\r\n\r\n\r\n\r\n/*.timePickerContainer {\r\n\tmargin:1.75em 0 0.5em 0;\r\n\twidth:10em;\r\n\tfloat:left;\r\n}\r\n\r\n.timeContainer {\r\n\tborder-collapse:collapse;\r\n\tborder-spacing:0;\r\n}\r\n\r\n.timeContainer thead td{\r\n\tborder-bottom:1px solid #e6e6e6;\r\n\tpadding:0 0.4em 0.2em 0.4em;\r\n}\r\n\r\n.timeContainer td {\r\n\tfont-size:0.9em;\r\n\tpadding:0 0.25em 0 0.25em;\r\n\ttext-align:left;\r\n\tcursor:pointer;cursor:hand;\r\n}\r\n\r\n.timeContainer td.minutesHeading {\r\n\tborder-left:1px solid #e6e6e6;\r\n\tborder-right:1px solid #e6e6e6;\t\r\n}\r\n\r\n.timeContainer .minutes {\r\n\tborder-left:1px solid #e6e6e6;\r\n\tborder-right:1px solid #e6e6e6;\r\n}\r\n\r\n.selectedItem {\r\n\tbackground-color:#3a3a3a;\r\n\tcolor:#ffffff;\r\n}*/\r\n",templateCssPath:dojo.uri.moduleUri("dojo.widget","templates/TimePicker.css"),postMixInProperties:function(_dba,frag){ -dojo.widget.TimePicker.superclass.postMixInProperties.apply(this,arguments); -this.calendar=dojo.i18n.getLocalization("dojo.i18n.calendar","gregorian",this.lang); -this.widgetStrings=dojo.i18n.getLocalization("dojo.widget","TimePicker",this.lang); -},fillInTemplate:function(args,frag){ -var _dbe=this.getFragNodeRef(frag); -dojo.html.copyStyle(this.domNode,_dbe); -if(args.value){ -if(args.value instanceof Date){ -this.storedTime=dojo.date.toRfc3339(args.value); -}else{ -this.storedTime=args.value; -} -} -this.initData(); -this.initUI(); -},initData:function(){ -if(this.storedTime.indexOf("T")!=-1&&this.storedTime.split("T")[1]&&this.storedTime!=" "&&this.storedTime.split("T")[1]!="any"){ -this.time=dojo.widget.TimePicker.util.fromRfcDateTime(this.storedTime,this.useDefaultMinutes,this.selectedTime.anyTime); -}else{ -if(this.useDefaultTime){ -this.time=dojo.widget.TimePicker.util.fromRfcDateTime("",this.useDefaultMinutes,this.selectedTime.anyTime); -}else{ -this.selectedTime.anyTime=true; -this.time=dojo.widget.TimePicker.util.fromRfcDateTime("",0,1); -} -} -},initUI:function(){ -if(!this.selectedTime.anyTime&&this.time){ -var _dbf=dojo.widget.TimePicker.util.toAmPmHour(this.time.getHours()); -var hour=_dbf[0]; -var isAm=_dbf[1]; -var _dc2=this.time.getMinutes(); -var _dc3=parseInt(_dc2/5); -this.onSetSelectedHour(this.hourIndexMap[hour]); -this.onSetSelectedMinute(this.minuteIndexMap[_dc3]); -this.onSetSelectedAmPm(isAm); -}else{ -this.onSetSelectedAnyTime(); -} -},setTime:function(date){ -if(date){ -this.selectedTime.anyTime=false; -this.setDateTime(dojo.date.toRfc3339(date)); -}else{ -this.selectedTime.anyTime=true; -} -this.initData(); -this.initUI(); -},setDateTime:function(_dc5){ -this.storedTime=_dc5; -},onClearSelectedHour:function(evt){ -this.clearSelectedHour(); -},onClearSelectedMinute:function(evt){ -this.clearSelectedMinute(); -},onClearSelectedAmPm:function(evt){ -this.clearSelectedAmPm(); -},onClearSelectedAnyTime:function(evt){ -this.clearSelectedAnyTime(); -if(this.selectedTime.anyTime){ -this.selectedTime.anyTime=false; -this.time=dojo.widget.TimePicker.util.fromRfcDateTime("",this.useDefaultMinutes); -this.initUI(); -} -},clearSelectedHour:function(){ -var _dca=this.hourContainerNode.getElementsByTagName("td"); -for(var i=0;i<_dca.length;i++){ -dojo.html.setClass(_dca.item(i),""); -} -},clearSelectedMinute:function(){ -var _dcc=this.minuteContainerNode.getElementsByTagName("td"); -for(var i=0;i<_dcc.length;i++){ -dojo.html.setClass(_dcc.item(i),""); -} -},clearSelectedAmPm:function(){ -var _dce=this.amPmContainerNode.getElementsByTagName("td"); -for(var i=0;i<_dce.length;i++){ -dojo.html.setClass(_dce.item(i),""); -} -},clearSelectedAnyTime:function(){ -dojo.html.setClass(this.anyTimeContainerNode,"anyTimeContainer"); -},onSetSelectedHour:function(evt){ -this.onClearSelectedAnyTime(); -this.onClearSelectedHour(); -this.setSelectedHour(evt); -this.onSetTime(); -},setSelectedHour:function(evt){ -if(evt&&evt.target){ -if(evt.target.nodeType==dojo.dom.ELEMENT_NODE){ -var _dd2=evt.target; -}else{ -var _dd2=evt.target.parentNode; -} -dojo.event.browser.stopEvent(evt); -dojo.html.setClass(_dd2,this.classNames.selectedTime); -this.selectedTime["hour"]=_dd2.innerHTML; -}else{ -if(!isNaN(evt)){ -var _dd3=this.hourContainerNode.getElementsByTagName("td"); -if(_dd3.item(evt)){ -dojo.html.setClass(_dd3.item(evt),this.classNames.selectedTime); -this.selectedTime["hour"]=_dd3.item(evt).innerHTML; -} -} -} -this.selectedTime.anyTime=false; -},onSetSelectedMinute:function(evt){ -this.onClearSelectedAnyTime(); -this.onClearSelectedMinute(); -this.setSelectedMinute(evt); -this.selectedTime.anyTime=false; -this.onSetTime(); -},setSelectedMinute:function(evt){ -if(evt&&evt.target){ -if(evt.target.nodeType==dojo.dom.ELEMENT_NODE){ -var _dd6=evt.target; -}else{ -var _dd6=evt.target.parentNode; -} -dojo.event.browser.stopEvent(evt); -dojo.html.setClass(_dd6,this.classNames.selectedTime); -this.selectedTime["minute"]=_dd6.innerHTML; -}else{ -if(!isNaN(evt)){ -var _dd7=this.minuteContainerNode.getElementsByTagName("td"); -if(_dd7.item(evt)){ -dojo.html.setClass(_dd7.item(evt),this.classNames.selectedTime); -this.selectedTime["minute"]=_dd7.item(evt).innerHTML; -} -} -} -},onSetSelectedAmPm:function(evt){ -this.onClearSelectedAnyTime(); -this.onClearSelectedAmPm(); -this.setSelectedAmPm(evt); -this.selectedTime.anyTime=false; -this.onSetTime(); -},setSelectedAmPm:function(evt){ -var _dda=evt.target; -if(evt&&_dda){ -if(_dda.nodeType!=dojo.dom.ELEMENT_NODE){ -_dda=_dda.parentNode; -} -dojo.event.browser.stopEvent(evt); -this.selectedTime.amPm=_dda.id; -dojo.html.setClass(_dda,this.classNames.selectedTime); -}else{ -evt=evt?0:1; -var _ddb=this.amPmContainerNode.getElementsByTagName("td"); -if(_ddb.item(evt)){ -this.selectedTime.amPm=_ddb.item(evt).id; -dojo.html.setClass(_ddb.item(evt),this.classNames.selectedTime); -} -} -},onSetSelectedAnyTime:function(evt){ -this.onClearSelectedHour(); -this.onClearSelectedMinute(); -this.onClearSelectedAmPm(); -this.setSelectedAnyTime(); -this.onSetTime(); -},setSelectedAnyTime:function(evt){ -this.selectedTime.anyTime=true; -dojo.html.setClass(this.anyTimeContainerNode,this.classNames.selectedTime+" "+"anyTimeContainer"); -},onClick:function(evt){ -dojo.event.browser.stopEvent(evt); -},onSetTime:function(){ -if(this.selectedTime.anyTime){ -this.time=new Date(); -var _ddf=dojo.widget.TimePicker.util.toRfcDateTime(this.time); -this.setDateTime(_ddf.split("T")[0]); -}else{ -var hour=12; -var _de1=0; -var isAm=false; -if(this.selectedTime["hour"]){ -hour=parseInt(this.selectedTime["hour"],10); -} -if(this.selectedTime["minute"]){ -_de1=parseInt(this.selectedTime["minute"],10); -} -if(this.selectedTime["amPm"]){ -isAm=(this.selectedTime["amPm"].toLowerCase()=="am"); -} -this.time=new Date(); -this.time.setHours(dojo.widget.TimePicker.util.fromAmPmHour(hour,isAm)); -this.time.setMinutes(_de1); -this.setDateTime(dojo.widget.TimePicker.util.toRfcDateTime(this.time)); -} -this.onValueChanged(this.time); -},onValueChanged:function(date){ -}}); -dojo.widget.TimePicker.util=new function(){ -this.toRfcDateTime=function(_de4){ -if(!_de4){ -_de4=new Date(); -} -_de4.setSeconds(0); -return dojo.date.strftime(_de4,"%Y-%m-%dT%H:%M:00%z"); -}; -this.fromRfcDateTime=function(_de5,_de6,_de7){ -var _de8=new Date(); -if(!_de5||_de5.indexOf("T")==-1){ -if(_de6){ -_de8.setMinutes(Math.floor(_de8.getMinutes()/5)*5); -}else{ -_de8.setMinutes(0); -} -}else{ -var _de9=_de5.split("T")[1].split(":"); -var _de8=new Date(); -_de8.setHours(_de9[0]); -_de8.setMinutes(_de9[1]); -} -return _de8; -}; -this.toAmPmHour=function(hour){ -var _deb=hour; -var isAm=true; -if(_deb==0){ -_deb=12; -}else{ -if(_deb>12){ -_deb=_deb-12; -isAm=false; -}else{ -if(_deb==12){ -isAm=false; -} -} -} -return [_deb,isAm]; -}; -this.fromAmPmHour=function(_ded,isAm){ -var hour=parseInt(_ded,10); -if(isAm&&hour==12){ -hour=0; -}else{ -if(!isAm&&hour<12){ -hour=hour+12; -} -} -return hour; -}; -}; -dojo.provide("dojo.widget.DropdownTimePicker"); -dojo.widget.defineWidget("dojo.widget.DropdownTimePicker",dojo.widget.DropdownContainer,{iconURL:dojo.uri.moduleUri("dojo.widget","templates/images/timeIcon.gif"),formatLength:"short",displayFormat:"",timeFormat:"",saveFormat:"",value:"",name:"",postMixInProperties:function(){ -dojo.widget.DropdownTimePicker.superclass.postMixInProperties.apply(this,arguments); -var _df0=dojo.i18n.getLocalization("dojo.widget","DropdownTimePicker",this.lang); -this.iconAlt=_df0.selectTime; -if(typeof (this.value)=="string"&&this.value.toLowerCase()=="today"){ -this.value=new Date(); -} -if(this.value&&isNaN(this.value)){ -var orig=this.value; -this.value=dojo.date.fromRfc3339(this.value); -if(!this.value){ -var d=dojo.date.format(new Date(),{selector:"dateOnly",datePattern:"yyyy-MM-dd"}); -var c=orig.split(":"); -for(var i=0;i\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\"↑\"\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t

\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t

\r\n\t\t\t\t\t\t\t
\r\n\t\t\t\t
\r\n\r\n",templateCssString:".datePickerContainer {\r\n\twidth:164px; /* needed for proper user styling */\r\n}\r\n\r\n.calendarContainer {\r\n/*\tborder:1px solid #566f8f;*/\r\n}\r\n\r\n.calendarBodyContainer {\r\n\twidth:100%; /* needed for the explode effect (explain?) */\r\n\tbackground: #7591bc url(\"images/dpBg.gif\") top left repeat-x;\r\n}\r\n\r\n.calendarBodyContainer thead tr td {\r\n\tcolor:#293a4b;\r\n\tfont:bold 0.75em Helvetica, Arial, Verdana, sans-serif;\r\n\ttext-align:center;\r\n\tpadding:0.25em;\r\n\tbackground: url(\"images/dpHorizLine.gif\") bottom left repeat-x;\r\n}\r\n\r\n.calendarBodyContainer tbody tr td {\r\n\tcolor:#fff;\r\n\tfont:bold 0.7em Helvetica, Arial, Verdana, sans-serif;\r\n\ttext-align:center;\r\n\tpadding:0.4em;\r\n\tbackground: url(\"images/dpVertLine.gif\") top right repeat-y;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n}\r\n\r\n\r\n.monthWrapper {\r\n\tpadding-bottom:2px;\r\n\tbackground: url(\"images/dpHorizLine.gif\") bottom left repeat-x;\r\n}\r\n\r\n.monthContainer {\r\n\twidth:100%;\r\n}\r\n\r\n.monthLabelContainer {\r\n\ttext-align:center;\r\n\tfont:bold 0.75em Helvetica, Arial, Verdana, sans-serif;\r\n\tbackground: url(\"images/dpMonthBg.png\") repeat-x top left !important;\r\n\tcolor:#293a4b;\r\n\tpadding:0.25em;\r\n}\r\n\r\n.monthCurve {\r\n\twidth:12px;\r\n}\r\n\r\n.monthCurveTL {\r\n\tbackground: url(\"images/dpCurveTL.png\") no-repeat top left !important;\r\n}\r\n\r\n.monthCurveTR {\r\n\t\tbackground: url(\"images/dpCurveTR.png\") no-repeat top right !important;\r\n}\r\n\r\n\r\n.yearWrapper {\r\n\tbackground: url(\"images/dpHorizLineFoot.gif\") top left repeat-x;\r\n\tpadding-top:2px;\r\n}\r\n\r\n.yearContainer {\r\n\twidth:100%;\r\n}\r\n\r\n.yearContainer td {\r\n\tbackground:url(\"images/dpYearBg.png\") top left repeat-x;\r\n}\r\n\r\n.yearContainer .yearLabel {\r\n\tmargin:0;\r\n\tpadding:0.45em 0 0.45em 0;\r\n\tcolor:#fff;\r\n\tfont:bold 0.75em Helvetica, Arial, Verdana, sans-serif;\r\n\ttext-align:center;\r\n}\r\n\r\n.curveBL {\r\n\tbackground: url(\"images/dpCurveBL.png\") bottom left no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n.curveBR {\r\n\tbackground: url(\"images/dpCurveBR.png\") bottom right no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n\r\n.previousMonth {\r\n\tbackground-color:#6782a8 !important;\r\n}\r\n\r\n.previousMonthDisabled {\r\n\tbackground-color:#a4a5a6 !important;\r\n\tcursor:default !important\r\n}\r\n.currentMonth {\r\n}\r\n\r\n.currentMonthDisabled {\r\n\tbackground-color:#bbbbbc !important;\r\n\tcursor:default !important\r\n}\r\n.nextMonth {\r\n\tbackground-color:#6782a8 !important;\r\n}\r\n.nextMonthDisabled {\r\n\tbackground-color:#a4a5a6 !important;\r\n\tcursor:default !important;\r\n}\r\n\r\n.currentDate {\r\n\ttext-decoration:underline;\r\n\tfont-style:italic;\r\n}\r\n\r\n.selectedDate {\r\n\tbackground-color:#fff !important;\r\n\tcolor:#6782a8 !important;\r\n}\r\n\r\n.yearLabel .selectedYear {\r\n\tpadding:0.2em;\r\n\tbackground-color:#9ec3fb !important;\r\n}\r\n\r\n.nextYear, .previousYear {\r\n\tcursor:pointer;cursor:hand;\r\n\tpadding:0;\r\n}\r\n\r\n.nextYear {\r\n\tmargin:0 0 0 0.55em;\r\n}\r\n\r\n.previousYear {\r\n\tmargin:0 0.55em 0 0;\r\n}\r\n\r\n.incrementControl {\r\n\tcursor:pointer;cursor:hand;\r\n\twidth:1em;\r\n}\r\n\r\n.increase {\r\n\tfloat:right;\r\n}\r\n\r\n.decrease {\r\n\tfloat:left;\r\n}\r\n\r\n.lastColumn {\r\n\tbackground-image:none !important;\r\n}\r\n\r\n\r\n",templateCssPath:dojo.uri.moduleUri("dojo.widget","templates/DatePicker.css"),postMixInProperties:function(){ -dojo.widget.DatePicker.superclass.postMixInProperties.apply(this,arguments); -if(!this.weekStartsOn){ -this.weekStartsOn=dojo.date.getFirstDayOfWeek(this.lang); -} -this.today=new Date(); -this.today.setHours(0,0,0,0); -if(typeof (this.value)=="string"&&this.value.toLowerCase()=="today"){ -this.value=new Date(); -}else{ -if(this.value&&(typeof this.value=="string")&&(this.value.split("-").length>2)){ -this.value=dojo.date.fromRfc3339(this.value); -this.value.setHours(0,0,0,0); -} -} -},fillInTemplate:function(args,frag){ -dojo.widget.DatePicker.superclass.fillInTemplate.apply(this,arguments); -var _e0e=this.getFragNodeRef(frag); -dojo.html.copyStyle(this.domNode,_e0e); -this.weekTemplate=dojo.dom.removeNode(this.calendarWeekTemplate); -this._preInitUI(this.value?this.value:this.today,false,true); -var _e0f=dojo.lang.unnest(dojo.date.getNames("days",this.dayWidth,"standAlone",this.lang)); -if(this.weekStartsOn>0){ -for(var i=0;ithis.endDate){ -_e14=new Date((_e14days){ -this._preInitUI(this.startDate,true,false); -_e17=new Date(this.firstDay); -} -this.curMonth=new Date(_e17); -this.curMonth.setDate(_e17.getDate()+6); -this.curMonth.setDate(1); -var _e1a=(_e17.getMonth()==this.curMonth.getMonth())?"current":"previous"; -} -if(_e16){ -this._initUI(days); -} -},_initUI:function(days){ -dojo.dom.removeChildren(this.calendarDatesContainerNode); -for(var i=0;ithis.endDate){ -_e27=_e29=_e2b=false; -} -if(_e28&&add(d,DAY,-1)this.endDate){ -_e29=_e2b=false; -} -if(_e2a&&add(d2,YEAR,-1)this.endDate){ -_e2b=false; -} -} -function enableControl(node,_e2e){ -dojo.html.setVisibility(node,_e2e?"":"hidden"); -} -enableControl(this.decreaseWeekNode,_e26); -enableControl(this.increaseWeekNode,_e27); -enableControl(this.decreaseMonthNode,_e28); -enableControl(this.increaseMonthNode,_e29); -enableControl(this.previousYearLabelNode,_e2a); -enableControl(this.nextYearLabelNode,_e2b); -},_incrementWeek:function(evt){ -var d=new Date(this.firstDay); -switch(evt.target){ -case this.increaseWeekNode.getElementsByTagName("img").item(0): -case this.increaseWeekNode: -var _e31=dojo.date.add(d,dojo.date.dateParts.WEEK,1); -if(_e31=this.startDate){ -d=dojo.date.add(d,dojo.date.dateParts.WEEK,-1); -} -break; -} -this._preInitUI(d,true,true); -},_incrementMonth:function(evt){ -var d=new Date(this.curMonth); -var _e34=new Date(this.firstDay); -switch(evt.currentTarget){ -case this.increaseMonthNode.getElementsByTagName("img").item(0): -case this.increaseMonthNode: -_e34=dojo.date.add(_e34,dojo.date.dateParts.DAY,this.displayWeeks*7); -if(_e34this.startDate){ -d=dojo.date.add(d,dojo.date.dateParts.MONTH,-1); -}else{ -var _e36=true; -} -break; -} -if(_e36){ -d=new Date(this.startDate); -}else{ -if(_e35){ -d=new Date(this.endDate); -} -} -this._preInitUI(d,false,true); -},_incrementYear:function(evt){ -var year=this.curMonth.getFullYear(); -var _e39=new Date(this.firstDay); -switch(evt.target){ -case this.nextYearLabelNode: -_e39=dojo.date.add(_e39,dojo.date.dateParts.YEAR,1); -if(_e39this.startDate){ -year--; -}else{ -var _e3b=true; -} -break; -} -var d; -if(_e3b){ -d=new Date(this.startDate); -}else{ -if(_e3a){ -d=new Date(this.endDate); -}else{ -d=new Date(year,this.curMonth.getMonth(),1); -} -} -this._preInitUI(d,false,true); -},onIncrementWeek:function(evt){ -evt.stopPropagation(); -if(!this.staticDisplay){ -this._incrementWeek(evt); -} -},onIncrementMonth:function(evt){ -evt.stopPropagation(); -if(!this.staticDisplay){ -this._incrementMonth(evt); -} -},onIncrementYear:function(evt){ -evt.stopPropagation(); -if(!this.staticDisplay){ -this._incrementYear(evt); -} -},_setMonthLabel:function(_e40){ -this.monthLabelNode.innerHTML=dojo.date.getNames("months","wide","standAlone",this.lang)[_e40]; -},_setYearLabels:function(year){ -var y=year-1; -var that=this; -function f(n){ -that[n+"YearLabelNode"].innerHTML=dojo.date.format(new Date(y++,0),{formatLength:"yearOnly",locale:that.lang}); -} -f("previous"); -f("current"); -f("next"); -},_getDateClassName:function(date,_e46){ -var _e47=this.classNames[_e46]; -if((!this.selectedIsUsed&&this.value)&&(Number(date)==Number(this.value))){ -_e47=this.classNames.selectedDate+" "+_e47; -this.selectedIsUsed=true; -} -if((!this.currentIsUsed)&&(Number(date)==Number(this.today))){ -_e47=_e47+" "+this.classNames.currentDate; -this.currentIsUsed=true; -} -return _e47; -},onClick:function(evt){ -dojo.event.browser.stopEvent(evt); -},_handleUiClick:function(evt){ -var _e4a=evt.target; -if(_e4a.nodeType!=dojo.dom.ELEMENT_NODE){ -_e4a=_e4a.parentNode; -} -dojo.event.browser.stopEvent(evt); -this.selectedIsUsed=this.todayIsUsed=false; -if(dojo.html.hasClass(_e4a,this.classNames["disabledPrevious"])||dojo.html.hasClass(_e4a,this.classNames["disabledCurrent"])||dojo.html.hasClass(_e4a,this.classNames["disabledNext"])){ -return; -} -this.clickedNode=_e4a; -this.setDate(new Date(Number(dojo.html.getAttribute(_e4a,"djDateValue")))); -},onValueChanged:function(date){ -},_isDisabledDate:function(_e4c){ -if(_e4cthis.endDate){ -return true; -} -return this.isDisabledDate(_e4c,this.lang); -},isDisabledDate:function(_e4d,_e4e){ -return false; -},_initFirstDay:function(_e4f,adj){ -var d=new Date(_e4f); -if(!adj){ -d.setDate(1); -} -d.setDate(d.getDate()-this._getAdjustedDay(d,this.weekStartsOn)); -d.setHours(0,0,0,0); -return d; -},_getAdjustedDay:function(_e52){ -var days=[0,1,2,3,4,5,6]; -if(this.weekStartsOn>0){ -for(var i=0;ithis.datePicker.endDate){ -this.inputNode.value=""; -} -this._syncValueNode(); -this.onValueChanged(this.getDate()); -this.hideContainer(); -},onValueChanged:function(_e5e){ -},onInputChange:function(){ -var _e5f=dojo.string.trim(this.inputNode.value); -if(_e5f){ -var _e60=dojo.date.parse(_e5f,{formatLength:this.formatLength,datePattern:this.displayFormat,selector:"dateOnly",locale:this.lang}); -if(!this.datePicker._isDisabledDate(_e60)){ -this.setDate(_e60); -} -}else{ -if(_e5f==""){ -this.datePicker.setDate(""); -} -this.valueNode.value=_e5f; -} -if(_e5f){ -this._updateText(); -} -},_syncValueNode:function(){ -var date=this.datePicker.value; -var _e62=""; -switch(this.saveFormat.toLowerCase()){ -case "rfc": -case "iso": -case "": -_e62=dojo.date.toRfc3339(date,"dateOnly"); -break; -case "posix": -case "unix": -_e62=Number(date); -break; -default: -if(date){ -_e62=dojo.date.format(date,{datePattern:this.saveFormat,selector:"dateOnly",locale:this.lang}); -} -} -this.valueNode.value=_e62; -},destroy:function(_e63){ -this.datePicker.destroy(_e63); -dojo.widget.DropdownDatePicker.superclass.destroy.apply(this,arguments); -}}); -dojo.provide("struts.widget.StrutsDatePicker"); -dojo.widget.defineWidget("struts.widget.StrutsDatePicker",dojo.widget.DropdownDatePicker,{widgetType:"StrutsDatePicker",valueNotifyTopics:"",valueNotifyTopicsArray:null,postCreate:function(){ -struts.widget.StrutsDatePicker.superclass.postCreate.apply(this,arguments); -if(this.extraArgs["class"]){ -dojo.html.setClass(this.inputNode,this.extraArgs["class"]); -} -if(this.extraArgs.style){ -dojo.html.setStyleText(this.inputNode,this.extraArgs.style); -} -if(!dojo.string.isBlank(this.valueNotifyTopics)){ -this.valueNotifyTopicsArray=this.valueNotifyTopics.split(","); -} -},_syncValueNode:function(){ -var date=this.datePicker.value; -var _e65=""; -switch(this.saveFormat.toLowerCase()){ -case "rfc": -case "iso": -case "": -_e65=dojo.date.toRfc3339(date); -break; -case "posix": -case "unix": -_e65=Number(date); -break; -default: -if(date){ -_e65=dojo.date.format(date,{datePattern:this.saveFormat,selector:"dateOnly",locale:this.lang}); -} -} -this.valueNode.value=_e65; -},_updateText:function(){ -struts.widget.StrutsDatePicker.superclass._updateText.apply(this,arguments); -if(this.valueNotifyTopicsArray!=null){ -for(var i=0;i",selectedChild:"",fillInTemplate:function(args,frag){ -var _e8d=this.getFragNodeRef(frag); -dojo.html.copyStyle(this.domNode,_e8d); -dojo.widget.PageContainer.superclass.fillInTemplate.apply(this,arguments); -},postCreate:function(args,frag){ -if(this.children.length){ -dojo.lang.forEach(this.children,this._setupChild,this); -var _e90; -if(this.selectedChild){ -this.selectChild(this.selectedChild); -}else{ -for(var i=0;i0){ -this.selectChild(this.children[0],true); -} -} -},selectChild:function(page,_e96){ -page=dojo.widget.byId(page); -this.correspondingPageButton=_e96; -if(this.selectedChildWidget){ -this._hideChild(this.selectedChildWidget); -} -this.selectedChildWidget=page; -this.selectedChild=page.widgetId; -this._showChild(page); -page.isFirstChild=(page==this.children[0]); -page.isLastChild=(page==this.children[this.children.length-1]); -dojo.event.topic.publish(this.widgetId+"-selectChild",page); -},forward:function(){ -var _e97=dojo.lang.find(this.children,this.selectedChildWidget); -this.selectChild(this.children[_e97+1]); -},back:function(){ -var _e98=dojo.lang.find(this.children,this.selectedChildWidget); -this.selectChild(this.children[_e98-1]); -},onResized:function(){ -if(this.doLayout&&this.selectedChildWidget){ -with(this.selectedChildWidget.domNode.style){ -top=dojo.html.getPixelValue(this.containerNode,"padding-top",true); -left=dojo.html.getPixelValue(this.containerNode,"padding-left",true); -} -var _e99=dojo.html.getContentBox(this.containerNode); -this.selectedChildWidget.resizeTo(_e99.width,_e99.height); -} -},_showChild:function(page){ -if(this.doLayout){ -var _e9b=dojo.html.getContentBox(this.containerNode); -page.resizeTo(_e9b.width,_e9b.height); -} -page.selected=true; -page.show(); -},_hideChild:function(page){ -page.selected=false; -page.hide(); -},closeChild:function(page){ -var _e9e=page.onClose(this,page); -if(_e9e){ -this.removeChild(page); -page.destroy(); -} -},destroy:function(){ -this._beingDestroyed=true; -dojo.event.topic.destroy(this.widgetId+"-addChild"); -dojo.event.topic.destroy(this.widgetId+"-removeChild"); -dojo.event.topic.destroy(this.widgetId+"-selectChild"); -dojo.widget.PageContainer.superclass.destroy.apply(this,arguments); -}}); -dojo.widget.defineWidget("dojo.widget.PageController",dojo.widget.HtmlWidget,{templateString:"",isContainer:true,containerId:"",buttonWidget:"PageButton","class":"dojoPageController",fillInTemplate:function(){ -dojo.html.addClass(this.domNode,this["class"]); -dojo.widget.wai.setAttr(this.domNode,"waiRole","role","tablist"); -},postCreate:function(){ -this.pane2button={}; -var _e9f=dojo.widget.byId(this.containerId); -if(_e9f){ -dojo.lang.forEach(_e9f.children,this.onAddChild,this); -} -dojo.event.topic.subscribe(this.containerId+"-addChild",this,"onAddChild"); -dojo.event.topic.subscribe(this.containerId+"-removeChild",this,"onRemoveChild"); -dojo.event.topic.subscribe(this.containerId+"-selectChild",this,"onSelectChild"); -},destroy:function(){ -dojo.event.topic.unsubscribe(this.containerId+"-addChild",this,"onAddChild"); -dojo.event.topic.unsubscribe(this.containerId+"-removeChild",this,"onRemoveChild"); -dojo.event.topic.unsubscribe(this.containerId+"-selectChild",this,"onSelectChild"); -dojo.widget.PageController.superclass.destroy.apply(this,arguments); -},onAddChild:function(page){ -var _ea1=dojo.widget.createWidget(this.buttonWidget,{label:page.label,closeButton:page.closable}); -this.addChild(_ea1); -this.domNode.appendChild(_ea1.domNode); -this.pane2button[page]=_ea1; -page.controlButton=_ea1; -var _ea2=this; -dojo.event.connect(_ea1,"onClick",function(){ -_ea2.onButtonClick(page); -}); -dojo.event.connect(_ea1,"onCloseButtonClick",function(){ -_ea2.onCloseButtonClick(page); -}); -},onRemoveChild:function(page){ -if(this._currentChild==page){ -this._currentChild=null; -} -var _ea4=this.pane2button[page]; -if(_ea4){ -_ea4.destroy(); -} -this.pane2button[page]=null; -},onSelectChild:function(page){ -if(this._currentChild){ -var _ea6=this.pane2button[this._currentChild]; -_ea6.clearSelected(); -} -var _ea7=this.pane2button[page]; -_ea7.setSelected(); -this._currentChild=page; -},onButtonClick:function(page){ -var _ea9=dojo.widget.byId(this.containerId); -_ea9.selectChild(page,false,this); -},onCloseButtonClick:function(page){ -var _eab=dojo.widget.byId(this.containerId); -_eab.closeChild(page); -},onKey:function(evt){ -if((evt.keyCode==evt.KEY_RIGHT_ARROW)||(evt.keyCode==evt.KEY_LEFT_ARROW)){ -var _ead=0; -var next=null; -var _ead=dojo.lang.find(this.children,this.pane2button[this._currentChild]); -if(evt.keyCode==evt.KEY_RIGHT_ARROW){ -next=this.children[(_ead+1)%this.children.length]; -}else{ -next=this.children[(_ead+(this.children.length-1))%this.children.length]; -} -dojo.event.browser.stopEvent(evt); -next.onClick(); -} -}}); -dojo.widget.defineWidget("dojo.widget.PageButton",dojo.widget.HtmlWidget,{templateString:""+"${this.label}"+"[X]"+"",label:"foo",closeButton:false,onClick:function(){ -this.focus(); -},onCloseButtonMouseOver:function(){ -dojo.html.addClass(this.closeButtonNode,"closeHover"); -},onCloseButtonMouseOut:function(){ -dojo.html.removeClass(this.closeButtonNode,"closeHover"); -},onCloseButtonClick:function(evt){ -},setSelected:function(){ -dojo.html.addClass(this.domNode,"current"); -this.titleNode.setAttribute("tabIndex","0"); -},clearSelected:function(){ -dojo.html.removeClass(this.domNode,"current"); -this.titleNode.setAttribute("tabIndex","-1"); -},focus:function(){ -if(this.titleNode.focus){ -this.titleNode.focus(); -} -}}); -dojo.lang.extend(dojo.widget.Widget,{label:"",selected:false,closable:false,onClose:function(){ -return true; -}}); -dojo.provide("dojo.widget.TabContainer"); -dojo.widget.defineWidget("dojo.widget.TabContainer",dojo.widget.PageContainer,{labelPosition:"top",closeButton:"none",templateString:null,templateString:"
\r\n\t
\r\n\t
\r\n
\r\n",templateCssString:".dojoTabContainer {\r\n\tposition : relative;\r\n}\r\n\r\n.dojoTabPaneWrapper {\r\n\tborder : 1px solid #6290d2;\r\n\t_zoom: 1; /* force IE6 layout mode so top border doesnt disappear */\r\n\tdisplay: block;\r\n\tclear: both;\r\n\toverflow: hidden;\r\n}\r\n\r\n.dojoTabLabels-top {\r\n\tposition : relative;\r\n\ttop : 0px;\r\n\tleft : 0px;\r\n\toverflow : visible;\r\n\tmargin-bottom : -1px;\r\n\twidth : 100%;\r\n\tz-index: 2;\t/* so the bottom of the tab label will cover up the border of dojoTabPaneWrapper */\r\n}\r\n\r\n.dojoTabNoLayout.dojoTabLabels-top .dojoTab {\r\n\tmargin-bottom: -1px;\r\n\t_margin-bottom: 0px; /* IE filter so top border lines up correctly */\r\n}\r\n\r\n.dojoTab {\r\n\tposition : relative;\r\n\tfloat : left;\r\n\tpadding-left : 9px;\r\n\tborder-bottom : 1px solid #6290d2;\r\n\tbackground : url(images/tab_left.gif) no-repeat left top;\r\n\tcursor: pointer;\r\n\twhite-space: nowrap;\r\n\tz-index: 3;\r\n}\r\n\r\n.dojoTab div {\r\n\tdisplay : block;\r\n\tpadding : 4px 15px 4px 6px;\r\n\tbackground : url(images/tab_top_right.gif) no-repeat right top;\r\n\tcolor : #333;\r\n\tfont-size : 90%;\r\n}\r\n\r\n.dojoTab .close {\r\n\tdisplay : inline-block;\r\n\theight : 12px;\r\n\twidth : 12px;\r\n\tpadding : 0 12px 0 0;\r\n\tmargin : 0 -10px 0 10px;\r\n\tcursor : default;\r\n\tfont-size: small;\r\n}\r\n\r\n.dojoTab .closeImage {\r\n\tbackground : url(images/tab_close.gif) no-repeat right top;\r\n}\r\n\r\n.dojoTab .closeHover {\r\n\tbackground-image : url(images/tab_close_h.gif);\r\n}\r\n\r\n.dojoTab.current {\r\n\tpadding-bottom : 1px;\r\n\tborder-bottom : 0;\r\n\tbackground-position : 0 -150px;\r\n}\r\n\r\n.dojoTab.current div {\r\n\tpadding-bottom : 5px;\r\n\tmargin-bottom : -1px;\r\n\tbackground-position : 100% -150px;\r\n}\r\n\r\n/* bottom tabs */\r\n\r\n.dojoTabLabels-bottom {\r\n\tposition : relative;\r\n\tbottom : 0px;\r\n\tleft : 0px;\r\n\toverflow : visible;\r\n\tmargin-top : -1px;\r\n\twidth : 100%;\r\n\tz-index: 2;\r\n}\r\n\r\n.dojoTabNoLayout.dojoTabLabels-bottom {\r\n\tposition : relative;\r\n}\r\n\r\n.dojoTabLabels-bottom .dojoTab {\r\n\tborder-top : 1px solid #6290d2;\r\n\tborder-bottom : 0;\r\n\tbackground : url(images/tab_bot_left.gif) no-repeat left bottom;\r\n}\r\n\r\n.dojoTabLabels-bottom .dojoTab div {\r\n\tbackground : url(images/tab_bot_right.gif) no-repeat right bottom;\r\n}\r\n\r\n.dojoTabLabels-bottom .dojoTab.current {\r\n\tborder-top : 0;\r\n\tbackground : url(images/tab_bot_left_curr.gif) no-repeat left bottom;\r\n}\r\n\r\n.dojoTabLabels-bottom .dojoTab.current div {\r\n\tpadding-top : 4px;\r\n\tbackground : url(images/tab_bot_right_curr.gif) no-repeat right bottom;\r\n}\r\n\r\n/* right-h tabs */\r\n\r\n.dojoTabLabels-right-h {\r\n\toverflow : visible;\r\n\tmargin-left : -1px;\r\n\tz-index: 2;\r\n}\r\n\r\n.dojoTabLabels-right-h .dojoTab {\r\n\tpadding-left : 0;\r\n\tborder-left : 1px solid #6290d2;\r\n\tborder-bottom : 0;\r\n\tbackground : url(images/tab_bot_right.gif) no-repeat right bottom;\r\n\tfloat : none;\r\n}\r\n\r\n.dojoTabLabels-right-h .dojoTab div {\r\n\tpadding : 4px 15px 4px 15px;\r\n}\r\n\r\n.dojoTabLabels-right-h .dojoTab.current {\r\n\tborder-left : 0;\r\n\tborder-bottom : 1px solid #6290d2;\r\n}\r\n\r\n/* left-h tabs */\r\n\r\n.dojoTabLabels-left-h {\r\n\toverflow : visible;\r\n\tmargin-right : -1px;\r\n\tz-index: 2;\r\n}\r\n\r\n.dojoTabLabels-left-h .dojoTab {\r\n\tborder-right : 1px solid #6290d2;\r\n\tborder-bottom : 0;\r\n\tfloat : none;\r\n\tbackground : url(images/tab_top_left.gif) no-repeat left top;\r\n}\r\n\r\n.dojoTabLabels-left-h .dojoTab.current {\r\n\tborder-right : 0;\r\n\tborder-bottom : 1px solid #6290d2;\r\n\tpadding-bottom : 0;\r\n\tbackground : url(images/tab_top_left.gif) no-repeat 0 -150px;\r\n}\r\n\r\n.dojoTabLabels-left-h .dojoTab div {\r\n\tbackground : 0;\r\n\tborder-bottom : 1px solid #6290d2;\r\n}\r\n",templateCssPath:dojo.uri.moduleUri("dojo.widget","templates/TabContainer.css"),selectedTab:"",postMixInProperties:function(){ -if(this.selectedTab){ -dojo.deprecated("selectedTab deprecated, use selectedChild instead, will be removed in","0.5"); -this.selectedChild=this.selectedTab; -} -if(this.closeButton!="none"){ -dojo.deprecated("closeButton deprecated, use closable='true' on each child instead, will be removed in","0.5"); -} -dojo.widget.TabContainer.superclass.postMixInProperties.apply(this,arguments); -},fillInTemplate:function(){ -this.tablist=dojo.widget.createWidget("TabController",{id:this.widgetId+"_tablist",labelPosition:this.labelPosition,doLayout:this.doLayout,containerId:this.widgetId},this.tablistNode); -dojo.widget.TabContainer.superclass.fillInTemplate.apply(this,arguments); -},postCreate:function(args,frag){ -dojo.widget.TabContainer.superclass.postCreate.apply(this,arguments); -this.onResized(); -},_setupChild:function(tab){ -if(this.closeButton=="tab"||this.closeButton=="pane"){ -tab.closable=true; -} -dojo.html.addClass(tab.domNode,"dojoTabPane"); -dojo.widget.TabContainer.superclass._setupChild.apply(this,arguments); -},onResized:function(){ -if(!this.doLayout){ -return; -} -var _eb3=this.labelPosition.replace(/-h/,""); -var _eb4=[{domNode:this.tablist.domNode,layoutAlign:_eb3},{domNode:this.containerNode,layoutAlign:"client"}]; -dojo.widget.html.layout(this.domNode,_eb4); -if(this.selectedChildWidget){ -var _eb5=dojo.html.getContentBox(this.containerNode); -this.selectedChildWidget.resizeTo(_eb5.width,_eb5.height); -} -},selectTab:function(tab,_eb7){ -dojo.deprecated("use selectChild() rather than selectTab(), selectTab() will be removed in","0.5"); -this.selectChild(tab,_eb7); -},onKey:function(e){ -if(e.keyCode==e.KEY_UP_ARROW&&e.ctrlKey){ -var _eb9=this.correspondingTabButton||this.selectedTabWidget.tabButton; -_eb9.focus(); -dojo.event.browser.stopEvent(e); -}else{ -if(e.keyCode==e.KEY_DELETE&&e.altKey){ -if(this.selectedChildWidget.closable){ -this.closeChild(this.selectedChildWidget); -dojo.event.browser.stopEvent(e); -} -} -} -},destroy:function(){ -this.tablist.destroy(); -dojo.widget.TabContainer.superclass.destroy.apply(this,arguments); -}}); -dojo.widget.defineWidget("dojo.widget.TabController",dojo.widget.PageController,{templateString:"
",labelPosition:"top",doLayout:true,"class":"",buttonWidget:"TabButton",postMixInProperties:function(){ -if(!this["class"]){ -this["class"]="dojoTabLabels-"+this.labelPosition+(this.doLayout?"":" dojoTabNoLayout"); -} -dojo.widget.TabController.superclass.postMixInProperties.apply(this,arguments); -}}); -dojo.widget.defineWidget("dojo.widget.TabButton",dojo.widget.PageButton,{templateString:"
"+"
"+"${this.label}"+""+"
"+"
",postMixInProperties:function(){ -this.closeButtonStyle=this.closeButton?"":"display: none"; -dojo.widget.TabButton.superclass.postMixInProperties.apply(this,arguments); -},fillInTemplate:function(){ -dojo.html.disableSelection(this.titleNode); -dojo.widget.TabButton.superclass.fillInTemplate.apply(this,arguments); -},onCloseButtonClick:function(evt){ -evt.stopPropagation(); -dojo.widget.TabButton.superclass.onCloseButtonClick.apply(this,arguments); -}}); -dojo.widget.defineWidget("dojo.widget.a11y.TabButton",dojo.widget.TabButton,{imgPath:dojo.uri.moduleUri("dojo.widget","templates/images/tab_close.gif"),templateString:"
"+"
"+"${this.label}"+"[x]"+"
"+"
"}); -dojo.provide("struts.widget.StrutsTabContainer"); -dojo.widget.defineWidget("struts.widget.StrutsTabContainer",dojo.widget.TabContainer,{widgetType:"StrutsTabContainer",afterSelectTabNotifyTopics:"",afterSelectTabNotifyTopicsArray:null,beforeSelectTabNotifyTopics:"",beforeSelectTabNotifyTopicsArray:null,disabledTabCssClass:"strutsDisabledTab",postCreate:function(){ -struts.widget.StrutsTabContainer.superclass.postCreate.apply(this); -if(!dojo.string.isBlank(this.beforeSelectTabNotifyTopics)){ -this.beforeSelectTabNotifyTopicsArray=this.beforeSelectTabNotifyTopics.split(","); -} -if(!dojo.string.isBlank(this.afterSelectTabNotifyTopics)){ -this.afterSelectTabNotifyTopicsArray=this.afterSelectTabNotifyTopics.split(","); -} -if(this.disabledTabCssClass){ -dojo.lang.forEach(this.children,function(div){ -if(div.disabled){ -this.disableTab(div); -} -}); -} -},selectChild:function(tab,_ebd){ -if(!tab.disabled){ -var _ebe={"cancel":false}; -if(this.beforeSelectTabNotifyTopicsArray){ -var self=this; -dojo.lang.forEach(this.beforeSelectTabNotifyTopicsArray,function(_ec0){ -try{ -dojo.event.topic.publish(_ec0,_ebe,tab,self); -} -catch(ex){ -dojo.debug(ex); -} -}); -} -if(!_ebe.cancel){ -struts.widget.StrutsTabContainer.superclass.selectChild.apply(this,[tab,_ebd]); -if(this.afterSelectTabNotifyTopicsArray){ -var self=this; -dojo.lang.forEach(this.afterSelectTabNotifyTopicsArray,function(_ec1){ -try{ -dojo.event.topic.publish(_ec1,tab,self); -} -catch(ex){ -dojo.debug(ex); -} -}); -} -} -} -},disableTab:function(t){ -var _ec3=this.getTabWidget(t); -_ec3.disabled=true; -dojo.html.addClass(_ec3.controlButton.domNode,this.disabledTabCssClass); -},enableTab:function(t){ -var _ec5=this.getTabWidget(t); -_ec5.disabled=false; -dojo.html.removeClass(_ec5.controlButton.domNode,this.disabledTabCssClass); -},getTabWidget:function(t){ -if(dojo.lang.isNumber(t)){ -return this.children[t]; -}else{ -if(dojo.lang.isString(t)){ -return dojo.widget.byId(t); -}else{ -return t; -} -} -}}); -dojo.provide("dojo.widget.TreeNode"); -dojo.widget.defineWidget("dojo.widget.TreeNode",dojo.widget.HtmlWidget,function(){ -this.actionsDisabled=[]; -},{widgetType:"TreeNode",loadStates:{UNCHECKED:"UNCHECKED",LOADING:"LOADING",LOADED:"LOADED"},actions:{MOVE:"MOVE",REMOVE:"REMOVE",EDIT:"EDIT",ADDCHILD:"ADDCHILD"},isContainer:true,lockLevel:0,templateString:("
"+" "+"\t\t${this.title} "+" "+"${this.afterLabel} "+"
"+"
").replace(/(>|<)\s+/g,"$1"),childIconSrc:"",childIconFolderSrc:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/closed.gif"),childIconDocumentSrc:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/document.gif"),childIcon:null,isTreeNode:true,objectId:"",afterLabel:"",afterLabelNode:null,expandIcon:null,title:"",object:"",isFolder:false,labelNode:null,titleNode:null,imgs:null,expandLevel:"",tree:null,depth:0,isExpanded:false,state:null,domNodeInitialized:false,isFirstChild:function(){ -return this.getParentIndex()==0?true:false; -},isLastChild:function(){ -return this.getParentIndex()==this.parent.children.length-1?true:false; -},lock:function(){ -return this.tree.lock.apply(this,arguments); -},unlock:function(){ -return this.tree.unlock.apply(this,arguments); -},isLocked:function(){ -return this.tree.isLocked.apply(this,arguments); -},cleanLock:function(){ -return this.tree.cleanLock.apply(this,arguments); -},actionIsDisabled:function(_ec7){ -var _ec8=this; -var _ec9=false; -if(this.tree.strictFolders&&_ec7==this.actions.ADDCHILD&&!this.isFolder){ -_ec9=true; -} -if(dojo.lang.inArray(_ec8.actionsDisabled,_ec7)){ -_ec9=true; -} -if(this.isLocked()){ -_ec9=true; -} -return _ec9; -},getInfo:function(){ -var info={widgetId:this.widgetId,objectId:this.objectId,index:this.getParentIndex(),isFolder:this.isFolder}; -return info; -},initialize:function(args,frag){ -this.state=this.loadStates.UNCHECKED; -for(var i=0;i0){ -for(var i=0;i<_ece;i++){ -var img=this.tree.makeBlankImg(); -this.imgs.unshift(img); -dojo.html.insertBefore(this.imgs[0],this.domNode.firstChild); -} -} -if(_ece<0){ -for(var i=0;i<-_ece;i++){ -this.imgs.shift(); -dojo.html.removeNode(this.domNode.firstChild); -} -} -},markLoading:function(){ -this._markLoadingSavedIcon=this.expandIcon.src; -this.expandIcon.src=this.tree.expandIconSrcLoading; -},unMarkLoading:function(){ -if(!this._markLoadingSavedIcon){ -return; -} -var im=new Image(); -im.src=this.tree.expandIconSrcLoading; -if(this.expandIcon.src==im.src){ -this.expandIcon.src=this._markLoadingSavedIcon; -} -this._markLoadingSavedIcon=null; -},setFolder:function(){ -dojo.event.connect(this.expandIcon,"onclick",this,"onTreeClick"); -this.expandIcon.src=this.isExpanded?this.tree.expandIconSrcMinus:this.tree.expandIconSrcPlus; -this.isFolder=true; -},createDOMNode:function(tree,_ed3){ -this.tree=tree; -this.depth=_ed3; -this.imgs=[]; -for(var i=0;i-1?"&":"?")+"nodeId="+this.widgetId; -var self=this; -this.markLoading(); -dojo.io.bind({url:_ee8,useCache:false,preventCache:true,handler:function(type,data,e){ -if(type=="load"){ -if(data){ -dojo.lang.forEach(data,function(_eed){ -var _eee=dojo.widget.createWidget("struts:StrutsTreeNode",{title:_eed.label,isFolder:_eed.hasChildren,widgetId:_eed.id}); -self.addChild(_eee); -}); -} -} -self.unMarkLoading(); -},mimetype:"text/json"}); -} -}}); -dojo.provide("dojo.json"); -dojo.json={jsonRegistry:new dojo.AdapterRegistry(),register:function(name,_ef0,wrap,_ef2){ -dojo.json.jsonRegistry.register(name,_ef0,wrap,_ef2); -},evalJson:function(json){ -try{ -return eval("("+json+")"); -} -catch(e){ -dojo.debug(e); -return json; -} -},serialize:function(o){ -var _ef5=typeof (o); -if(_ef5=="undefined"){ -return "undefined"; -}else{ -if((_ef5=="number")||(_ef5=="boolean")){ -return o+""; -}else{ -if(o===null){ -return "null"; -} -} -} -if(_ef5=="string"){ -return dojo.string.escapeString(o); -} -var me=arguments.callee; -var _ef7; -if(typeof (o.__json__)=="function"){ -_ef7=o.__json__(); -if(o!==_ef7){ -return me(_ef7); -} -} -if(typeof (o.json)=="function"){ -_ef7=o.json(); -if(o!==_ef7){ -return me(_ef7); -} -} -if(_ef5!="function"&&typeof (o.length)=="number"){ -var res=[]; -for(var i=0;i_f29.getParentIndex()){ -_f2b--; -} -return _f2b; -},onDrop:function(e){ -var _f2d=this.position; -this.onDragOut(e); -var _f2e=e.dragObject.treeNode; -if(!dojo.lang.isObject(_f2e)){ -dojo.raise("TreeNode not found in dragObject"); -} -if(_f2d=="onto"){ -return this.controller.move(_f2e,this.treeNode,0); -}else{ -var _f2f=this.getTargetParentIndex(_f2e,_f2d); -return this.controller.move(_f2e,this.treeNode.parent,_f2f); -} -}}); -dojo.dnd.TreeDNDController=function(_f30){ -this.treeController=_f30; -this.dragSources={}; -this.dropTargets={}; -}; -dojo.lang.extend(dojo.dnd.TreeDNDController,{listenTree:function(tree){ -dojo.event.topic.subscribe(tree.eventNames.createDOMNode,this,"onCreateDOMNode"); -dojo.event.topic.subscribe(tree.eventNames.moveFrom,this,"onMoveFrom"); -dojo.event.topic.subscribe(tree.eventNames.moveTo,this,"onMoveTo"); -dojo.event.topic.subscribe(tree.eventNames.addChild,this,"onAddChild"); -dojo.event.topic.subscribe(tree.eventNames.removeNode,this,"onRemoveNode"); -dojo.event.topic.subscribe(tree.eventNames.treeDestroy,this,"onTreeDestroy"); -},unlistenTree:function(tree){ -dojo.event.topic.unsubscribe(tree.eventNames.createDOMNode,this,"onCreateDOMNode"); -dojo.event.topic.unsubscribe(tree.eventNames.moveFrom,this,"onMoveFrom"); -dojo.event.topic.unsubscribe(tree.eventNames.moveTo,this,"onMoveTo"); -dojo.event.topic.unsubscribe(tree.eventNames.addChild,this,"onAddChild"); -dojo.event.topic.unsubscribe(tree.eventNames.removeNode,this,"onRemoveNode"); -dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy,this,"onTreeDestroy"); -},onTreeDestroy:function(_f33){ -this.unlistenTree(_f33.source); -},onCreateDOMNode:function(_f34){ -this.registerDNDNode(_f34.source); -},onAddChild:function(_f35){ -this.registerDNDNode(_f35.child); -},onMoveFrom:function(_f36){ -var _f37=this; -dojo.lang.forEach(_f36.child.getDescendants(),function(node){ -_f37.unregisterDNDNode(node); -}); -},onMoveTo:function(_f39){ -var _f3a=this; -dojo.lang.forEach(_f39.child.getDescendants(),function(node){ -_f3a.registerDNDNode(node); -}); -},registerDNDNode:function(node){ -if(!node.tree.DNDMode){ -return; -} -var _f3d=null; -var _f3e=null; -if(!node.actionIsDisabled(node.actions.MOVE)){ -var _f3d=new dojo.dnd.TreeDragSource(node.labelNode,this,node.tree.widgetId,node); -this.dragSources[node.widgetId]=_f3d; -} -var _f3e=new dojo.dnd.TreeDropTarget(node.labelNode,this.treeController,node.tree.DNDAcceptTypes,node); -this.dropTargets[node.widgetId]=_f3e; -},unregisterDNDNode:function(node){ -if(this.dragSources[node.widgetId]){ -dojo.dnd.dragManager.unregisterDragSource(this.dragSources[node.widgetId]); -delete this.dragSources[node.widgetId]; -} -if(this.dropTargets[node.widgetId]){ -dojo.dnd.dragManager.unregisterDropTarget(this.dropTargets[node.widgetId]); -delete this.dropTargets[node.widgetId]; -} -}}); -dojo.provide("dojo.widget.TreeBasicController"); -dojo.widget.defineWidget("dojo.widget.TreeBasicController",dojo.widget.HtmlWidget,{widgetType:"TreeBasicController",DNDController:"",dieWithTree:false,initialize:function(args,frag){ -if(this.DNDController=="create"){ -this.DNDController=new dojo.dnd.TreeDNDController(this); -} -},listenTree:function(tree){ -dojo.event.topic.subscribe(tree.eventNames.createDOMNode,this,"onCreateDOMNode"); -dojo.event.topic.subscribe(tree.eventNames.treeClick,this,"onTreeClick"); -dojo.event.topic.subscribe(tree.eventNames.treeCreate,this,"onTreeCreate"); -dojo.event.topic.subscribe(tree.eventNames.treeDestroy,this,"onTreeDestroy"); -if(this.DNDController){ -this.DNDController.listenTree(tree); -} -},unlistenTree:function(tree){ -dojo.event.topic.unsubscribe(tree.eventNames.createDOMNode,this,"onCreateDOMNode"); -dojo.event.topic.unsubscribe(tree.eventNames.treeClick,this,"onTreeClick"); -dojo.event.topic.unsubscribe(tree.eventNames.treeCreate,this,"onTreeCreate"); -dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy,this,"onTreeDestroy"); -},onTreeDestroy:function(_f44){ -var tree=_f44.source; -this.unlistenTree(tree); -if(this.dieWithTree){ -this.destroy(); -} -},onCreateDOMNode:function(_f46){ -var node=_f46.source; -if(node.expandLevel>0){ -this.expandToLevel(node,node.expandLevel); -} -},onTreeCreate:function(_f48){ -var tree=_f48.source; -var _f4a=this; -if(tree.expandLevel){ -dojo.lang.forEach(tree.children,function(_f4b){ -_f4a.expandToLevel(_f4b,tree.expandLevel-1); -}); -} -},expandToLevel:function(node,_f4d){ -if(_f4d==0){ -return; -} -var _f4e=node.children; -var _f4f=this; -var _f50=function(node,_f52){ -this.node=node; -this.expandLevel=_f52; -this.process=function(){ -for(var i=0;i",isExpanded:true,isTree:true,objectId:"",controller:"",selector:"",menu:"",expandLevel:"",blankIconSrc:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_blank.gif"),gridIconSrcT:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_t.gif"),gridIconSrcL:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_l.gif"),gridIconSrcV:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_v.gif"),gridIconSrcP:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_p.gif"),gridIconSrcC:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_c.gif"),gridIconSrcX:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_x.gif"),gridIconSrcY:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_y.gif"),gridIconSrcZ:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_z.gif"),expandIconSrcPlus:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_expand_plus.gif"),expandIconSrcMinus:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_expand_minus.gif"),expandIconSrcLoading:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_loading.gif"),iconWidth:18,iconHeight:18,showGrid:true,showRootGrid:true,actionIsDisabled:function(_f7d){ -var _f7e=this; -return dojo.lang.inArray(_f7e.actionsDisabled,_f7d); -},actions:{ADDCHILD:"ADDCHILD"},getInfo:function(){ -var info={widgetId:this.widgetId,objectId:this.objectId}; -return info; -},initializeController:function(){ -if(this.controller!="off"){ -if(this.controller){ -this.controller=dojo.widget.byId(this.controller); -}else{ -this.controller=dojo.widget.createWidget("TreeBasicController",{DNDController:(this.DNDMode?"create":""),dieWithTree:true}); -} -this.controller.listenTree(this); -}else{ -this.controller=null; -} -},initializeSelector:function(){ -if(this.selector!="off"){ -if(this.selector){ -this.selector=dojo.widget.byId(this.selector); -}else{ -this.selector=dojo.widget.createWidget("TreeSelector",{dieWithTree:true}); -} -this.selector.listenTree(this); -}else{ -this.selector=null; -} -},initialize:function(args,frag){ -var _f82=this; -for(name in this.eventNamesDefault){ -if(dojo.lang.isUndefined(this.eventNames[name])){ -this.eventNames[name]=this.widgetId+"/"+this.eventNamesDefault[name]; -} -} -for(var i=0;i0){ -_fa1[_fa2-1].updateExpandGridColumn(); -} -if(_fa0 instanceof dojo.widget.Tree&&_fa2==0&&_fa1.length>0){ -_fa1[0].updateExpandGrid(); -} -_f9f.parent=_f9f.tree=null; -return _f9f; -},markLoading:function(){ -},unMarkLoading:function(){ -},lock:function(){ -!this.lockLevel&&this.markLoading(); -this.lockLevel++; -},unlock:function(){ -if(!this.lockLevel){ -dojo.raise("unlock: not locked"); -} -this.lockLevel--; -!this.lockLevel&&this.unMarkLoading(); -},isLocked:function(){ -var node=this; -while(true){ -if(node.lockLevel){ -return true; -} -if(node instanceof dojo.widget.Tree){ -break; -} -node=node.parent; -} -return false; -},flushLock:function(){ -this.lockLevel=0; -this.unMarkLoading(); -}}); -dojo.provide("struts.widget.StrutsTree"); -dojo.widget.defineWidget("struts.widget.StrutsTree",dojo.widget.Tree,{widgetType:"StrutsTree",href:"",errorNotifyTopics:"",errorNotifyTopicsArray:null,postCreate:function(){ -struts.widget.StrutsTree.superclass.postCreate.apply(this); -if(!dojo.string.isBlank(this.errorNotifyTopics)){ -this.errorNotifyTopicsArray=this.errorNotifyTopics.split(","); -} -var self=this; -if(!dojo.string.isBlank(this.href)){ -dojo.io.bind({url:this.href,useCache:false,preventCache:true,handler:function(type,data,e){ -if(type=="load"){ -if(data){ -dojo.lang.forEach(data,function(_fa8){ -var _fa9=dojo.widget.createWidget("struts:StrutsTreeNode",{title:_fa8.label,isFolder:_fa8.hasChildren,widgetId:_fa8.id}); -self.addChild(_fa9); -}); -} -}else{ -if(self.errorNotifyTopicsArray){ -dojo.lang.forEach(self.errorNotifyTopicsArray,function(_faa){ -try{ -dojo.event.topic.publish(_faa,data,e,self); -} -catch(ex){ -dojo.debug(ex); -} -}); -} -} -},mimetype:"text/json"}); -} -}}); -dojo.kwCompoundRequire({common:["struts.widget.Bind","struts.widget.BindDiv","struts.widget.BindAnchor","struts.widget.ComboBox","struts.widget.StrutsTimePicker","struts.widget.StrutsDatePicker","struts.widget.BindEvent","struts.widget.StrutsTreeSelector","struts.widget.StrutsTabContainer","struts.widget.StrutsTreeNode","struts.widget.StrutsTree"]}); -dojo.provide("struts.widget.*"); diff --git a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js index 8463720a3..41293de74 100644 --- a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js +++ b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js @@ -1,30 +1,40 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + if(typeof dojo == "undefined"){ // TODOC: HOW TO DOC THE BELOW? // @global: djConfig // summary: -// Application code can set the global 'djConfig' prior to loading -// the library to override certain global settings for how dojo works. +// Application code can set the global 'djConfig' prior to loading +// the library to override certain global settings for how dojo works. // description: The variables that can be set are as follows: -// - isDebug: false -// - allowQueryConfig: false -// - baseScriptUri: "" -// - baseRelativePath: "" -// - libraryScriptUri: "" -// - iePreventClobber: false -// - ieClobberMinimal: true -// - locale: undefined -// - extraLocale: undefined -// - preventBackButtonFix: true -// - searchIds: [] -// - parseWidgets: true +// - isDebug: false +// - allowQueryConfig: false +// - baseScriptUri: "" +// - baseRelativePath: "" +// - libraryScriptUri: "" +// - iePreventClobber: false +// - ieClobberMinimal: true +// - locale: undefined +// - extraLocale: undefined +// - preventBackButtonFix: true +// - searchIds: [] +// - parseWidgets: true // TODOC: HOW TO DOC THESE VARIABLES? // TODOC: IS THIS A COMPLETE LIST? // note: -// 'djConfig' does not exist under 'dojo.*' so that it can be set before the -// 'dojo' variable exists. +// 'djConfig' does not exist under 'dojo.*' so that it can be set before the +// 'dojo' variable exists. // note: -// Setting any of these variables *after* the library has loaded does nothing at all. +// Setting any of these variables *after* the library has loaded does nothing at all. // TODOC: is this still true? Release notes for 0.3 indicated they could be set after load. // @@ -32,22 +42,22 @@ if(typeof dojo == "undefined"){ //TODOC: HOW TO DOC THIS? // @global: dj_global // summary: -// an alias for the top-level global object in the host environment -// (e.g., the window object in a browser). +// an alias for the top-level global object in the host environment +// (e.g., the window object in a browser). // description: -// Refer to 'dj_global' rather than referring to window to ensure your -// code runs correctly in contexts other than web browsers (eg: Rhino on a server). +// Refer to 'dj_global' rather than referring to window to ensure your +// code runs correctly in contexts other than web browsers (eg: Rhino on a server). var dj_global = this; //TODOC: HOW TO DOC THIS? // @global: dj_currentContext // summary: -// Private global context object. Where 'dj_global' always refers to the boot-time +// Private global context object. Where 'dj_global' always refers to the boot-time // global context, 'dj_currentContext' can be modified for temporary context shifting. // dojo.global() returns dj_currentContext. // description: -// Refer to dojo.global() rather than referring to dj_global to ensure your -// code runs correctly in managed contexts. +// Refer to dojo.global() rather than referring to dj_global to ensure your +// code runs correctly in managed contexts. var dj_currentContext = this; @@ -57,30 +67,30 @@ var dj_currentContext = this; // **************************************************************** function dj_undef(/*String*/ name, /*Object?*/ object){ - //summary: Returns true if 'name' is defined on 'object' (or globally if 'object' is null). - //description: Note that 'defined' and 'exists' are not the same concept. - return (typeof (object || dj_currentContext)[name] == "undefined"); // Boolean + //summary: Returns true if 'name' is defined on 'object' (or globally if 'object' is null). + //description: Note that 'defined' and 'exists' are not the same concept. + return (typeof (object || dj_currentContext)[name] == "undefined"); // Boolean } // make sure djConfig is defined if(dj_undef("djConfig", this)){ - var djConfig = {}; + var djConfig = {}; } //TODOC: HOW TO DOC THIS? // dojo is the root variable of (almost all) our public symbols -- make sure it is defined. if(dj_undef("dojo", this)){ - var dojo = {}; + var dojo = {}; } dojo.global = function(){ - // summary: - // return the current global context object - // (e.g., the window object in a browser). - // description: - // Refer to 'dojo.global()' rather than referring to window to ensure your - // code runs correctly in contexts other than web browsers (eg: Rhino on a server). - return dj_currentContext; + // summary: + // return the current global context object + // (e.g., the window object in a browser). + // description: + // Refer to 'dojo.global()' rather than referring to window to ensure your + // code runs correctly in contexts other than web browsers (eg: Rhino on a server). + return dj_currentContext; } // Override locale setting, if specified @@ -88,92 +98,92 @@ dojo.locale = djConfig.locale; //TODOC: HOW TO DOC THIS? dojo.version = { - // summary: version number of this instance of dojo. - major: 0, minor: 4, patch: 3, flag: "", - revision: Number("$Rev$".match(/[0-9]+/)[0]), - toString: function(){ - with(dojo.version){ - return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String - } - } + // summary: version number of this instance of dojo. + major: 0, minor: 4, patch: 3, flag: "", + revision: Number("$Rev$".match(/[0-9]+/)[0]), + toString: function(){ + with(dojo.version){ + return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String + } + } } dojo.evalProp = function(/*String*/ name, /*Object*/ object, /*Boolean?*/ create){ - // summary: Returns 'object[name]'. If not defined and 'create' is true, will return a new Object. - // description: - // Returns null if 'object[name]' is not defined and 'create' is not true. - // Note: 'defined' and 'exists' are not the same concept. - if((!object)||(!name)) return undefined; // undefined - if(!dj_undef(name, object)) return object[name]; // mixed - return (create ? (object[name]={}) : undefined); // mixed + // summary: Returns 'object[name]'. If not defined and 'create' is true, will return a new Object. + // description: + // Returns null if 'object[name]' is not defined and 'create' is not true. + // Note: 'defined' and 'exists' are not the same concept. + if((!object)||(!name)) return undefined; // undefined + if(!dj_undef(name, object)) return object[name]; // mixed + return (create ? (object[name]={}) : undefined); // mixed } dojo.parseObjPath = function(/*String*/ path, /*Object?*/ context, /*Boolean?*/ create){ - // summary: Parse string path to an object, and return corresponding object reference and property name. - // description: - // Returns an object with two properties, 'obj' and 'prop'. - // 'obj[prop]' is the reference indicated by 'path'. - // path: Path to an object, in the form "A.B.C". - // context: Object to use as root of path. Defaults to 'dojo.global()'. - // create: If true, Objects will be created at any point along the 'path' that is undefined. - var object = (context || dojo.global()); - var names = path.split('.'); - var prop = names.pop(); - for (var i=0,l=names.length;i 1) { - dh.modulesLoadedListeners.push(function() { - obj[functionName](); - }); - } + var dh = dojo.hostenv; + if(arguments.length == 1) { + dh.modulesLoadedListeners.push(obj); + } else if(arguments.length > 1) { + dh.modulesLoadedListeners.push(function() { + obj[functionName](); + }); + } - //Added for xdomain loading. dojo.addOnLoad is used to - //indicate callbacks after doing some dojo.require() statements. - //In the xdomain case, if all the requires are loaded (after initial - //page load), then immediately call any listeners. - if(dh.post_load_ && dh.inFlightCount == 0 && !dh.loadNotifying){ - dh.callLoaded(); - } + //Added for xdomain loading. dojo.addOnLoad is used to + //indicate callbacks after doing some dojo.require() statements. + //In the xdomain case, if all the requires are loaded (after initial + //page load), then immediately call any listeners. + if(dh.post_load_ && dh.inFlightCount == 0 && !dh.loadNotifying){ + dh.callLoaded(); + } } dojo.addOnUnload = function(/*Object?*/obj, /*String|Function?*/functionName){ // summary: registers a function to be triggered when the page unloads // // usage: -// dojo.addOnLoad(functionPointer) -// dojo.addOnLoad(object, "functionName") - var dh = dojo.hostenv; - if(arguments.length == 1){ - dh.unloadListeners.push(obj); - } else if(arguments.length > 1) { - dh.unloadListeners.push(function() { - obj[functionName](); - }); - } +// dojo.addOnLoad(functionPointer) +// dojo.addOnLoad(object, "functionName") + var dh = dojo.hostenv; + if(arguments.length == 1){ + dh.unloadListeners.push(obj); + } else if(arguments.length > 1) { + dh.unloadListeners.push(function() { + obj[functionName](); + }); + } } dojo.hostenv.modulesLoaded = function(){ - if(this.post_load_){ return; } - if(this.loadUriStack.length==0 && this.getTextStack.length==0){ - if(this.inFlightCount > 0){ - dojo.debug("files still in flight!"); - return; - } - dojo.hostenv.callLoaded(); - } + if(this.post_load_){ return; } + if(this.loadUriStack.length==0 && this.getTextStack.length==0){ + if(this.inFlightCount > 0){ + dojo.debug("files still in flight!"); + return; + } + dojo.hostenv.callLoaded(); + } } dojo.hostenv.callLoaded = function(){ - //The "object" check is for IE, and the other opera check fixes an issue - //in Opera where it could not find the body element in some widget test cases. - //For 0.9, maybe route all browsers through the setTimeout (need protection - //still for non-browser environments though). This might also help the issue with - //FF 2.0 and freezing issues where we try to do sync xhr while background css images - //are being loaded (trac #2572)? Consider for 0.9. - if(typeof setTimeout == "object" || (djConfig["useXDomain"] && dojo.render.html.opera)){ - setTimeout("dojo.hostenv.loaded();", 0); - }else{ - dojo.hostenv.loaded(); - } + //The "object" check is for IE, and the other opera check fixes an issue + //in Opera where it could not find the body element in some widget test cases. + //For 0.9, maybe route all browsers through the setTimeout (need protection + //still for non-browser environments though). This might also help the issue with + //FF 2.0 and freezing issues where we try to do sync xhr while background css images + //are being loaded (trac #2572)? Consider for 0.9. + if(typeof setTimeout == "object" || (djConfig["useXDomain"] && dojo.render.html.opera)){ + setTimeout("dojo.hostenv.loaded();", 0); + }else{ + dojo.hostenv.loaded(); + } } dojo.hostenv.getModuleSymbols = function(/*String*/modulename){ // summary: -// Converts a module name in dotted JS notation to an array representing the path in the source tree - var syms = modulename.split("."); - for(var i = syms.length; i>0; i--){ - var parentModule = syms.slice(0, i).join("."); - if((i==1) && !this.moduleHasPrefix(parentModule)){ - // Support default module directory (sibling of dojo) for top-level modules - syms[0] = "../" + syms[0]; - }else{ - var parentModulePath = this.getModulePrefix(parentModule); - if(parentModulePath != parentModule){ - syms.splice(0, i, parentModulePath); - break; - } - } - } - return syms; // Array +// Converts a module name in dotted JS notation to an array representing the path in the source tree + var syms = modulename.split("."); + for(var i = syms.length; i>0; i--){ + var parentModule = syms.slice(0, i).join("."); + if((i==1) && !this.moduleHasPrefix(parentModule)){ + // Support default module directory (sibling of dojo) for top-level modules + syms[0] = "../" + syms[0]; + }else{ + var parentModulePath = this.getModulePrefix(parentModule); + if(parentModulePath != parentModule){ + syms.splice(0, i, parentModulePath); + break; + } + } + } + return syms; // Array } dojo.hostenv._global_omit_module_check = false; dojo.hostenv.loadModule = function(/*String*/moduleName, /*Boolean?*/exactOnly, /*Boolean?*/omitModuleCheck){ // summary: -// loads a Javascript module from the appropriate URI +// loads a Javascript module from the appropriate URI // // description: -// loadModule("A.B") first checks to see if symbol A.B is defined. -// If it is, it is simply returned (nothing to do). -// -// If it is not defined, it will look for "A/B.js" in the script root directory, -// followed by "A.js". -// -// It throws if it cannot find a file to load, or if the symbol A.B is not -// defined after loading. -// -// It returns the object A.B. -// -// This does nothing about importing symbols into the current package. -// It is presumed that the caller will take care of that. For example, to import -// all symbols: -// -// with (dojo.hostenv.loadModule("A.B")) { -// ... -// } -// -// And to import just the leaf symbol: -// -// var B = dojo.hostenv.loadModule("A.B"); -// ... -// -// dj_load is an alias for dojo.hostenv.loadModule +// loadModule("A.B") first checks to see if symbol A.B is defined. +// If it is, it is simply returned (nothing to do). +// +// If it is not defined, it will look for "A/B.js" in the script root directory, +// followed by "A.js". +// +// It throws if it cannot find a file to load, or if the symbol A.B is not +// defined after loading. +// +// It returns the object A.B. +// +// This does nothing about importing symbols into the current package. +// It is presumed that the caller will take care of that. For example, to import +// all symbols: +// +// with (dojo.hostenv.loadModule("A.B")) { +// ... +// } +// +// And to import just the leaf symbol: +// +// var B = dojo.hostenv.loadModule("A.B"); +// ... +// +// dj_load is an alias for dojo.hostenv.loadModule - if(!moduleName){ return; } - omitModuleCheck = this._global_omit_module_check || omitModuleCheck; - var module = this.findModule(moduleName, false); - if(module){ - return module; - } + if(!moduleName){ return; } + omitModuleCheck = this._global_omit_module_check || omitModuleCheck; + var module = this.findModule(moduleName, false); + if(module){ + return module; + } - // protect against infinite recursion from mutual dependencies - if(dj_undef(moduleName, this.loading_modules_)){ - this.addedToLoadingCount.push(moduleName); - } - this.loading_modules_[moduleName] = 1; + // protect against infinite recursion from mutual dependencies + if(dj_undef(moduleName, this.loading_modules_)){ + this.addedToLoadingCount.push(moduleName); + } + this.loading_modules_[moduleName] = 1; - // convert periods to slashes - var relpath = moduleName.replace(/\./g, '/') + '.js'; + // convert periods to slashes + var relpath = moduleName.replace(/\./g, '/') + '.js'; - var nsyms = moduleName.split("."); + var nsyms = moduleName.split("."); + + // this line allowed loading of a module manifest as if it were a namespace + // it's an interesting idea, but shouldn't be combined with 'namespaces' proper + // and leads to unwanted dependencies + // the effect can be achieved in other (albeit less-flexible) ways now, so I am + // removing this pending further design work + // perhaps we can explicitly define this idea of a 'module manifest', and subclass + // 'namespace manifest' from that + //dojo.getNamespace(nsyms[0]); - // this line allowed loading of a module manifest as if it were a namespace - // it's an interesting idea, but shouldn't be combined with 'namespaces' proper - // and leads to unwanted dependencies - // the effect can be achieved in other (albeit less-flexible) ways now, so I am - // removing this pending further design work - // perhaps we can explicitly define this idea of a 'module manifest', and subclass - // 'namespace manifest' from that - //dojo.getNamespace(nsyms[0]); + var syms = this.getModuleSymbols(moduleName); + var startedRelative = ((syms[0].charAt(0) != '/') && !syms[0].match(/^\w+:/)); + var last = syms[syms.length - 1]; + var ok; + // figure out if we're looking for a full package, if so, we want to do + // things slightly diffrently + if(last=="*"){ + moduleName = nsyms.slice(0, -1).join('.'); + while(syms.length){ + syms.pop(); + syms.push(this.pkgFileName); + relpath = syms.join("/") + '.js'; + if(startedRelative && relpath.charAt(0)=="/"){ + relpath = relpath.slice(1); + } + ok = this.loadPath(relpath, !omitModuleCheck ? moduleName : null); + if(ok){ break; } + syms.pop(); + } + }else{ + relpath = syms.join("/") + '.js'; + moduleName = nsyms.join('.'); + var modArg = !omitModuleCheck ? moduleName : null; + ok = this.loadPath(relpath, modArg); + if(!ok && !exactOnly){ + syms.pop(); + while(syms.length){ + relpath = syms.join('/') + '.js'; + ok = this.loadPath(relpath, modArg); + if(ok){ break; } + syms.pop(); + relpath = syms.join('/') + '/'+this.pkgFileName+'.js'; + if(startedRelative && relpath.charAt(0)=="/"){ + relpath = relpath.slice(1); + } + ok = this.loadPath(relpath, modArg); + if(ok){ break; } + } + } - var syms = this.getModuleSymbols(moduleName); - var startedRelative = ((syms[0].charAt(0) != '/') && !syms[0].match(/^\w+:/)); - var last = syms[syms.length - 1]; - var ok; - // figure out if we're looking for a full package, if so, we want to do - // things slightly diffrently - if(last=="*"){ - moduleName = nsyms.slice(0, -1).join('.'); - while(syms.length){ - syms.pop(); - syms.push(this.pkgFileName); - relpath = syms.join("/") + '.js'; - if(startedRelative && relpath.charAt(0)=="/"){ - relpath = relpath.slice(1); - } - ok = this.loadPath(relpath, !omitModuleCheck ? moduleName : null); - if(ok){ break; } - syms.pop(); - } - }else{ - relpath = syms.join("/") + '.js'; - moduleName = nsyms.join('.'); - var modArg = !omitModuleCheck ? moduleName : null; - ok = this.loadPath(relpath, modArg); - if(!ok && !exactOnly){ - syms.pop(); - while(syms.length){ - relpath = syms.join('/') + '.js'; - ok = this.loadPath(relpath, modArg); - if(ok){ break; } - syms.pop(); - relpath = syms.join('/') + '/'+this.pkgFileName+'.js'; - if(startedRelative && relpath.charAt(0)=="/"){ - relpath = relpath.slice(1); - } - ok = this.loadPath(relpath, modArg); - if(ok){ break; } - } - } + if(!ok && !omitModuleCheck){ + dojo.raise("Could not load '" + moduleName + "'; last tried '" + relpath + "'"); + } + } - if(!ok && !omitModuleCheck){ - dojo.raise("Could not load '" + moduleName + "'; last tried '" + relpath + "'"); - } - } + // check that the symbol was defined + //Don't bother if we're doing xdomain (asynchronous) loading. + if(!omitModuleCheck && !this["isXDomain"]){ + // pass in false so we can give better error + module = this.findModule(moduleName, false); + if(!module){ + dojo.raise("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'"); + } + } - // check that the symbol was defined - //Don't bother if we're doing xdomain (asynchronous) loading. - if(!omitModuleCheck && !this["isXDomain"]){ - // pass in false so we can give better error - module = this.findModule(moduleName, false); - if(!module){ - dojo.raise("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'"); - } - } - - return module; + return module; } dojo.hostenv.startPackage = function(/*String*/packageName){ // summary: -// Creates a JavaScript package +// Creates a JavaScript package // // description: -// startPackage("A.B") follows the path, and at each level creates a new empty -// object or uses what already exists. It returns the result. +// startPackage("A.B") follows the path, and at each level creates a new empty +// object or uses what already exists. It returns the result. // // packageName: the package to be created as a String in dot notation - //Make sure we have a string. - var fullPkgName = String(packageName); - var strippedPkgName = fullPkgName; + //Make sure we have a string. + var fullPkgName = String(packageName); + var strippedPkgName = fullPkgName; - var syms = packageName.split(/\./); - if(syms[syms.length-1]=="*"){ - syms.pop(); - strippedPkgName = syms.join("."); - } - var evaledPkg = dojo.evalObjPath(strippedPkgName, true); - this.loaded_modules_[fullPkgName] = evaledPkg; - this.loaded_modules_[strippedPkgName] = evaledPkg; - - return evaledPkg; // Object + var syms = packageName.split(/\./); + if(syms[syms.length-1]=="*"){ + syms.pop(); + strippedPkgName = syms.join("."); + } + var evaledPkg = dojo.evalObjPath(strippedPkgName, true); + this.loaded_modules_[fullPkgName] = evaledPkg; + this.loaded_modules_[strippedPkgName] = evaledPkg; + + return evaledPkg; // Object } dojo.hostenv.findModule = function(/*String*/moduleName, /*Boolean?*/mustExist){ // summary: -// Returns the Object representing the module, if it exists, otherwise null. +// Returns the Object representing the module, if it exists, otherwise null. // // moduleName A fully qualified module including package name, like 'A.B'. // mustExist Optional, default false. throw instead of returning null -// if the module does not currently exist. +// if the module does not currently exist. - var lmn = String(moduleName); + var lmn = String(moduleName); - if(this.loaded_modules_[lmn]){ - return this.loaded_modules_[lmn]; // Object - } + if(this.loaded_modules_[lmn]){ + return this.loaded_modules_[lmn]; // Object + } - if(mustExist){ - dojo.raise("no loaded module named '" + moduleName + "'"); - } - return null; // null + if(mustExist){ + dojo.raise("no loaded module named '" + moduleName + "'"); + } + return null; // null } //Start of old bootstrap2: dojo.kwCompoundRequire = function(/*Object containing Arrays*/modMap){ // description: -// This method taks a "map" of arrays which one can use to optionally load dojo -// modules. The map is indexed by the possible dojo.hostenv.name_ values, with -// two additional values: "default" and "common". The items in the "default" -// array will be loaded if none of the other items have been choosen based on -// the hostenv.name_ item. The items in the "common" array will _always_ be -// loaded, regardless of which list is chosen. Here's how it's normally -// called: -// -// dojo.kwCompoundRequire({ -// browser: [ -// ["foo.bar.baz", true, true], // an example that passes multiple args to loadModule() -// "foo.sample.*", -// "foo.test, -// ], -// default: [ "foo.sample.*" ], -// common: [ "really.important.module.*" ] -// }); +// This method taks a "map" of arrays which one can use to optionally load dojo +// modules. The map is indexed by the possible dojo.hostenv.name_ values, with +// two additional values: "default" and "common". The items in the "default" +// array will be loaded if none of the other items have been choosen based on +// the hostenv.name_ item. The items in the "common" array will _always_ be +// loaded, regardless of which list is chosen. Here's how it's normally +// called: +// +// dojo.kwCompoundRequire({ +// browser: [ +// ["foo.bar.baz", true, true], // an example that passes multiple args to loadModule() +// "foo.sample.*", +// "foo.test, +// ], +// default: [ "foo.sample.*" ], +// common: [ "really.important.module.*" ] +// }); - var common = modMap["common"]||[]; - var result = modMap[dojo.hostenv.name_] ? common.concat(modMap[dojo.hostenv.name_]||[]) : common.concat(modMap["default"]||[]); + var common = modMap["common"]||[]; + var result = modMap[dojo.hostenv.name_] ? common.concat(modMap[dojo.hostenv.name_]||[]) : common.concat(modMap["default"]||[]); - for(var x=0; x, - // relative to Dojo root. For example, module acme is mapped to ../acme. - // If you want to use a different module name, use dojo.registerModulePath. - return dojo.hostenv.setModulePrefix(module, prefix); + // summary: maps a module name to a path + // description: An unregistered module is given the default path of ../, + // relative to Dojo root. For example, module acme is mapped to ../acme. + // If you want to use a different module name, use dojo.registerModulePath. + return dojo.hostenv.setModulePrefix(module, prefix); } if(djConfig["modulePaths"]){ - for(var param in djConfig["modulePaths"]){ - dojo.registerModulePath(param, djConfig["modulePaths"][param]); - } + for(var param in djConfig["modulePaths"]){ + dojo.registerModulePath(param, djConfig["modulePaths"][param]); + } } dojo.setModulePrefix = function(/*String*/module, /*String*/prefix){ - // summary: maps a module name to a path - dojo.deprecated('dojo.setModulePrefix("' + module + '", "' + prefix + '")', "replaced by dojo.registerModulePath", "0.5"); - return dojo.registerModulePath(module, prefix); + // summary: maps a module name to a path + dojo.deprecated('dojo.setModulePrefix("' + module + '", "' + prefix + '")', "replaced by dojo.registerModulePath", "0.5"); + return dojo.registerModulePath(module, prefix); } dojo.exists = function(/*Object*/obj, /*String*/name){ - // summary: determine if an object supports a given method - // description: useful for longer api chains where you have to test each object in the chain - var p = name.split("."); - for(var i = 0; i < p.length; i++){ - if(!obj[p[i]]){ return false; } // Boolean - obj = obj[p[i]]; - } - return true; // Boolean + // summary: determine if an object supports a given method + // description: useful for longer api chains where you have to test each object in the chain + var p = name.split("."); + for(var i = 0; i < p.length; i++){ + if(!obj[p[i]]){ return false; } // Boolean + obj = obj[p[i]]; + } + return true; // Boolean } // Localization routines dojo.hostenv.normalizeLocale = function(/*String?*/locale){ -// summary: -// Returns canonical form of locale, as used by Dojo. All variants are case-insensitive and are separated by '-' -// as specified in RFC 3066. If no locale is specified, the user agent's default is returned. +// summary: +// Returns canonical form of locale, as used by Dojo. All variants are case-insensitive and are separated by '-' +// as specified in RFC 3066. If no locale is specified, the user agent's default is returned. - var result = locale ? locale.toLowerCase() : dojo.locale; - if(result == "root"){ - result = "ROOT"; - } - return result;// String + var result = locale ? locale.toLowerCase() : dojo.locale; + if(result == "root"){ + result = "ROOT"; + } + return result;// String }; dojo.hostenv.searchLocalePath = function(/*String*/locale, /*Boolean*/down, /*Function*/searchFunc){ -// summary: -// A helper method to assist in searching for locale-based resources. Will iterate through -// the variants of a particular locale, either up or down, executing a callback function. -// For example, "en-us" and true will try "en-us" followed by "en" and finally "ROOT". +// summary: +// A helper method to assist in searching for locale-based resources. Will iterate through +// the variants of a particular locale, either up or down, executing a callback function. +// For example, "en-us" and true will try "en-us" followed by "en" and finally "ROOT". - locale = dojo.hostenv.normalizeLocale(locale); + locale = dojo.hostenv.normalizeLocale(locale); - var elements = locale.split('-'); - var searchlist = []; - for(var i = elements.length; i > 0; i--){ - searchlist.push(elements.slice(0, i).join('-')); - } - searchlist.push(false); - if(down){searchlist.reverse();} + var elements = locale.split('-'); + var searchlist = []; + for(var i = elements.length; i > 0; i--){ + searchlist.push(elements.slice(0, i).join('-')); + } + searchlist.push(false); + if(down){searchlist.reverse();} - for(var j = searchlist.length - 1; j >= 0; j--){ - var loc = searchlist[j] || "ROOT"; - var stop = searchFunc(loc); - if(stop){ break; } - } + for(var j = searchlist.length - 1; j >= 0; j--){ + var loc = searchlist[j] || "ROOT"; + var stop = searchFunc(loc); + if(stop){ break; } + } } //These two functions are placed outside of preloadLocalizations //So that the xd loading can use/override them. -dojo.hostenv.localesGenerated =["ROOT","es-es","es","it-it","pt-br","de","fr-fr","zh-cn","pt","en-us","zh","fr","zh-tw","it","en-gb","xx","de-de","ko-kr","ja-jp","ko","en","ja"]; // value will be inserted here at build time, if necessary +dojo.hostenv.localesGenerated /***BUILD:localesGenerated***/; // value will be inserted here at build time, if necessary dojo.hostenv.registerNlsPrefix = function(){ // summary: -// Register module "nls" to point where Dojo can find pre-built localization files - dojo.registerModulePath("nls","nls"); +// Register module "nls" to point where Dojo can find pre-built localization files + dojo.registerModulePath("nls","nls"); } dojo.hostenv.preloadLocalizations = function(){ // summary: -// Load built, flattened resource bundles, if available for all locales used in the page. -// Execute only once. Note that this is a no-op unless there is a build. +// Load built, flattened resource bundles, if available for all locales used in the page. +// Execute only once. Note that this is a no-op unless there is a build. - if(dojo.hostenv.localesGenerated){ - dojo.hostenv.registerNlsPrefix(); + if(dojo.hostenv.localesGenerated){ + dojo.hostenv.registerNlsPrefix(); - function preload(locale){ - locale = dojo.hostenv.normalizeLocale(locale); - dojo.hostenv.searchLocalePath(locale, true, function(loc){ - for(var i=0; i bestLocale.length){ + bestLocale = flatLocales[i]; + } + } + } + if(!bestLocale){ + bestLocale = "ROOT"; + } + } - //Find the best-match locale to load if we have available flat locales. - var bestLocale = ""; - if(availableFlatLocales){ - var flatLocales = availableFlatLocales.split(","); - for(var i = 0; i < flatLocales.length; i++){ - //Locale must match from start of string. - if(targetLocale.indexOf(flatLocales[i]) == 0){ - if(flatLocales[i].length > bestLocale.length){ - bestLocale = flatLocales[i]; - } - } - } - if(!bestLocale){ - bestLocale = "ROOT"; - } - } + //See if the desired locale is already loaded. + var tempLocale = availableFlatLocales ? bestLocale : targetLocale; + var bundle = dojo.hostenv.findModule(bundlePackage); + var localizedBundle = null; + if(bundle){ + if(djConfig.localizationComplete && bundle._built){return;} + var jsLoc = tempLocale.replace('-', '_'); + var translationPackage = bundlePackage+"."+jsLoc; + localizedBundle = dojo.hostenv.findModule(translationPackage); + } - //See if the desired locale is already loaded. - var tempLocale = availableFlatLocales ? bestLocale : targetLocale; - var bundle = dojo.hostenv.findModule(bundlePackage); - var localizedBundle = null; - if(bundle){ - if(djConfig.localizationComplete && bundle._built){return;} - var jsLoc = tempLocale.replace('-', '_'); - var translationPackage = bundlePackage+"."+jsLoc; - localizedBundle = dojo.hostenv.findModule(translationPackage); - } + if(!localizedBundle){ + bundle = dojo.hostenv.startPackage(bundlePackage); + var syms = dojo.hostenv.getModuleSymbols(moduleName); + var modpath = syms.concat("nls").join("/"); + var parent; - if(!localizedBundle){ - bundle = dojo.hostenv.startPackage(bundlePackage); - var syms = dojo.hostenv.getModuleSymbols(moduleName); - var modpath = syms.concat("nls").join("/"); - var parent; + dojo.hostenv.searchLocalePath(tempLocale, availableFlatLocales, function(loc){ + var jsLoc = loc.replace('-', '_'); + var translationPackage = bundlePackage + "." + jsLoc; + var loaded = false; + if(!dojo.hostenv.findModule(translationPackage)){ + // Mark loaded whether it's found or not, so that further load attempts will not be made + dojo.hostenv.startPackage(translationPackage); + var module = [modpath]; + if(loc != "ROOT"){module.push(loc);} + module.push(bundleName); + var filespec = module.join("/") + '.js'; + loaded = dojo.hostenv.loadPath(filespec, null, function(hash){ + // Use singleton with prototype to point to parent bundle, then mix-in result from loadPath + var clazz = function(){}; + clazz.prototype = parent; + bundle[jsLoc] = new clazz(); + for(var j in hash){ bundle[jsLoc][j] = hash[j]; } + }); + }else{ + loaded = true; + } + if(loaded && bundle[jsLoc]){ + parent = bundle[jsLoc]; + }else{ + bundle[jsLoc] = parent; + } + + if(availableFlatLocales){ + //Stop the locale path searching if we know the availableFlatLocales, since + //the first call to this function will load the only bundle that is needed. + return true; + } + }); + } - dojo.hostenv.searchLocalePath(tempLocale, availableFlatLocales, function(loc){ - var jsLoc = loc.replace('-', '_'); - var translationPackage = bundlePackage + "." + jsLoc; - var loaded = false; - if(!dojo.hostenv.findModule(translationPackage)){ - // Mark loaded whether it's found or not, so that further load attempts will not be made - dojo.hostenv.startPackage(translationPackage); - var module = [modpath]; - if(loc != "ROOT"){module.push(loc);} - module.push(bundleName); - var filespec = module.join("/") + '.js'; - loaded = dojo.hostenv.loadPath(filespec, null, function(hash){ - // Use singleton with prototype to point to parent bundle, then mix-in result from loadPath - var clazz = function(){}; - clazz.prototype = parent; - bundle[jsLoc] = new clazz(); - for(var j in hash){ bundle[jsLoc][j] = hash[j]; } - }); - }else{ - loaded = true; - } - if(loaded && bundle[jsLoc]){ - parent = bundle[jsLoc]; - }else{ - bundle[jsLoc] = parent; - } - - if(availableFlatLocales){ - //Stop the locale path searching if we know the availableFlatLocales, since - //the first call to this function will load the only bundle that is needed. - return true; - } - }); - } - - //Save the best locale bundle as the target locale bundle when we know the - //the available bundles. - if(availableFlatLocales && targetLocale != bestLocale){ - bundle[targetLocale.replace('-', '_')] = bundle[bestLocale.replace('-', '_')]; - } + //Save the best locale bundle as the target locale bundle when we know the + //the available bundles. + if(availableFlatLocales && targetLocale != bestLocale){ + bundle[targetLocale.replace('-', '_')] = bundle[bestLocale.replace('-', '_')]; + } }; (function(){ - // If other locales are used, dojo.requireLocalization should load them as well, by default. - // Override dojo.requireLocalization to do load the default bundle, then iterate through the - // extraLocale list and load those translations as well, unless a particular locale was requested. + // If other locales are used, dojo.requireLocalization should load them as well, by default. + // Override dojo.requireLocalization to do load the default bundle, then iterate through the + // extraLocale list and load those translations as well, unless a particular locale was requested. - var extra = djConfig.extraLocale; - if(extra){ - if(!extra instanceof Array){ - extra = [extra]; - } + var extra = djConfig.extraLocale; + if(extra){ + if(!extra instanceof Array){ + extra = [extra]; + } - var req = dojo.requireLocalization; - dojo.requireLocalization = function(m, b, locale, availableFlatLocales){ - req(m,b,locale, availableFlatLocales); - if(locale){return;} - for(var i=0; i 1){ - var paramStr = params[1]; - var pairs = paramStr.split("&"); - for(var x in pairs){ - var sp = pairs[x].split("="); - // FIXME: is this eval dangerous? - if((sp[0].length > 9)&&(sp[0].substr(0, 9) == "djConfig.")){ - var opt = sp[0].substr(9); - try{ - djConfig[opt]=eval(sp[1]); - }catch(e){ - djConfig[opt]=sp[1]; - } - } - } - } - } + // attempt to figure out the path to dojo if it isn't set in the config + (function(){ + // before we get any further with the config options, try to pick them out + // of the URL. Most of this code is from NW + if(djConfig.allowQueryConfig){ + var baseUrl = document.location.toString(); // FIXME: use location.query instead? + var params = baseUrl.split("?", 2); + if(params.length > 1){ + var paramStr = params[1]; + var pairs = paramStr.split("&"); + for(var x in pairs){ + var sp = pairs[x].split("="); + // FIXME: is this eval dangerous? + if((sp[0].length > 9)&&(sp[0].substr(0, 9) == "djConfig.")){ + var opt = sp[0].substr(9); + try{ + djConfig[opt]=eval(sp[1]); + }catch(e){ + djConfig[opt]=sp[1]; + } + } + } + } + } - if( - ((djConfig["baseScriptUri"] == "")||(djConfig["baseRelativePath"] == "")) && - (document && document.getElementsByTagName) - ){ - var scripts = document.getElementsByTagName("script"); - var rePkg = /(__package__|dojo|bootstrap1)\.js([\?\.]|$)/i; - for(var i = 0; i < scripts.length; i++) { - var src = scripts[i].getAttribute("src"); - if(!src) { continue; } - var m = src.match(rePkg); - if(m) { - var root = src.substring(0, m.index); - if(src.indexOf("bootstrap1") > -1) { root += "../"; } - if(!this["djConfig"]) { djConfig = {}; } - if(djConfig["baseScriptUri"] == "") { djConfig["baseScriptUri"] = root; } - if(djConfig["baseRelativePath"] == "") { djConfig["baseRelativePath"] = root; } - break; - } - } - } + if( + ((djConfig["baseScriptUri"] == "")||(djConfig["baseRelativePath"] == "")) && + (document && document.getElementsByTagName) + ){ + var scripts = document.getElementsByTagName("script"); + var rePkg = /(__package__|dojo|bootstrap1)\.js([\?\.]|$)/i; + for(var i = 0; i < scripts.length; i++) { + var src = scripts[i].getAttribute("src"); + if(!src) { continue; } + var m = src.match(rePkg); + if(m) { + var root = src.substring(0, m.index); + if(src.indexOf("bootstrap1") > -1) { root += "../"; } + if(!this["djConfig"]) { djConfig = {}; } + if(djConfig["baseScriptUri"] == "") { djConfig["baseScriptUri"] = root; } + if(djConfig["baseRelativePath"] == "") { djConfig["baseRelativePath"] = root; } + break; + } + } + } - // fill in the rendering support information in dojo.render.* - var dr = dojo.render; - var drh = dojo.render.html; - var drs = dojo.render.svg; - var dua = (drh.UA = navigator.userAgent); - var dav = (drh.AV = navigator.appVersion); - var t = true; - var f = false; - drh.capable = t; - drh.support.builtin = t; + // fill in the rendering support information in dojo.render.* + var dr = dojo.render; + var drh = dojo.render.html; + var drs = dojo.render.svg; + var dua = (drh.UA = navigator.userAgent); + var dav = (drh.AV = navigator.appVersion); + var t = true; + var f = false; + drh.capable = t; + drh.support.builtin = t; - dr.ver = parseFloat(drh.AV); - dr.os.mac = dav.indexOf("Macintosh") >= 0; - dr.os.win = dav.indexOf("Windows") >= 0; - // could also be Solaris or something, but it's the same browser - dr.os.linux = dav.indexOf("X11") >= 0; + dr.ver = parseFloat(drh.AV); + dr.os.mac = dav.indexOf("Macintosh") >= 0; + dr.os.win = dav.indexOf("Windows") >= 0; + // could also be Solaris or something, but it's the same browser + dr.os.linux = dav.indexOf("X11") >= 0; - drh.opera = dua.indexOf("Opera") >= 0; - drh.khtml = (dav.indexOf("Konqueror") >= 0)||(dav.indexOf("Safari") >= 0); - drh.safari = dav.indexOf("Safari") >= 0; - var geckoPos = dua.indexOf("Gecko"); - drh.mozilla = drh.moz = (geckoPos >= 0)&&(!drh.khtml); - if (drh.mozilla) { - // gecko version is YYYYMMDD - drh.geckoVersion = dua.substring(geckoPos + 6, geckoPos + 14); - } - drh.ie = (document.all)&&(!drh.opera); - drh.ie50 = drh.ie && dav.indexOf("MSIE 5.0")>=0; - drh.ie55 = drh.ie && dav.indexOf("MSIE 5.5")>=0; - drh.ie60 = drh.ie && dav.indexOf("MSIE 6.0")>=0; - drh.ie70 = drh.ie && dav.indexOf("MSIE 7.0")>=0; + drh.opera = dua.indexOf("Opera") >= 0; + drh.khtml = (dav.indexOf("Konqueror") >= 0)||(dav.indexOf("Safari") >= 0); + drh.safari = dav.indexOf("Safari") >= 0; + var geckoPos = dua.indexOf("Gecko"); + drh.mozilla = drh.moz = (geckoPos >= 0)&&(!drh.khtml); + if (drh.mozilla) { + // gecko version is YYYYMMDD + drh.geckoVersion = dua.substring(geckoPos + 6, geckoPos + 14); + } + drh.ie = (document.all)&&(!drh.opera); + drh.ie50 = drh.ie && dav.indexOf("MSIE 5.0")>=0; + drh.ie55 = drh.ie && dav.indexOf("MSIE 5.5")>=0; + drh.ie60 = drh.ie && dav.indexOf("MSIE 6.0")>=0; + drh.ie70 = drh.ie && dav.indexOf("MSIE 7.0")>=0; - var cm = document["compatMode"]; - drh.quirks = (cm == "BackCompat")||(cm == "QuirksMode")||drh.ie55||drh.ie50; + var cm = document["compatMode"]; + drh.quirks = (cm == "BackCompat")||(cm == "QuirksMode")||drh.ie55||drh.ie50; - // TODO: is the HTML LANG attribute relevant? - dojo.locale = dojo.locale || (drh.ie ? navigator.userLanguage : navigator.language).toLowerCase(); + // TODO: is the HTML LANG attribute relevant? + dojo.locale = dojo.locale || (drh.ie ? navigator.userLanguage : navigator.language).toLowerCase(); - dr.vml.capable=drh.ie; - drs.capable = f; - drs.support.plugin = f; - drs.support.builtin = f; - var tdoc = window["document"]; - var tdi = tdoc["implementation"]; + dr.vml.capable=drh.ie; + drs.capable = f; + drs.support.plugin = f; + drs.support.builtin = f; + var tdoc = window["document"]; + var tdi = tdoc["implementation"]; - if((tdi)&&(tdi["hasFeature"])&&(tdi.hasFeature("org.w3c.dom.svg", "1.0"))){ - drs.capable = t; - drs.support.builtin = t; - drs.support.plugin = f; - } - // webkits after 420 support SVG natively. The test string is "AppleWebKit/420+" - if(drh.safari){ - var tmp = dua.split("AppleWebKit/")[1]; - var ver = parseFloat(tmp.split(" ")[0]); - if(ver >= 420){ - drs.capable = t; - drs.support.builtin = t; - drs.support.plugin = f; - } - }else{ - } - })(); + if((tdi)&&(tdi["hasFeature"])&&(tdi.hasFeature("org.w3c.dom.svg", "1.0"))){ + drs.capable = t; + drs.support.builtin = t; + drs.support.plugin = f; + } + // webkits after 420 support SVG natively. The test string is "AppleWebKit/420+" + if(drh.safari){ + var tmp = dua.split("AppleWebKit/")[1]; + var ver = parseFloat(tmp.split(" ")[0]); + if(ver >= 420){ + drs.capable = t; + drs.support.builtin = t; + drs.support.plugin = f; + } + }else{ + } + })(); - dojo.hostenv.startPackage("dojo.hostenv"); + dojo.hostenv.startPackage("dojo.hostenv"); - dojo.render.name = dojo.hostenv.name_ = 'browser'; - dojo.hostenv.searchIds = []; + dojo.render.name = dojo.hostenv.name_ = 'browser'; + dojo.hostenv.searchIds = []; - // These are in order of decreasing likelihood; this will change in time. - dojo.hostenv._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0']; + // These are in order of decreasing likelihood; this will change in time. + dojo.hostenv._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0']; - dojo.hostenv.getXmlhttpObject = function(){ - // summary: does the work of portably generating a new XMLHTTPRequest object. - var http = null; - var last_e = null; - try{ http = new XMLHttpRequest(); }catch(e){} - if(!http){ - for(var i=0; i<3; ++i){ - var progid = dojo.hostenv._XMLHTTP_PROGIDS[i]; - try{ - http = new ActiveXObject(progid); - }catch(e){ - last_e = e; - } + dojo.hostenv.getXmlhttpObject = function(){ + // summary: does the work of portably generating a new XMLHTTPRequest object. + var http = null; + var last_e = null; + try{ http = new XMLHttpRequest(); }catch(e){} + if(!http){ + for(var i=0; i<3; ++i){ + var progid = dojo.hostenv._XMLHTTP_PROGIDS[i]; + try{ + http = new ActiveXObject(progid); + }catch(e){ + last_e = e; + } - if(http){ - dojo.hostenv._XMLHTTP_PROGIDS = [progid]; // so faster next time - break; - } - } + if(http){ + dojo.hostenv._XMLHTTP_PROGIDS = [progid]; // so faster next time + break; + } + } - /*if(http && !http.toString) { - http.toString = function() { "[object XMLHttpRequest]"; } - }*/ - } + /*if(http && !http.toString) { + http.toString = function() { "[object XMLHttpRequest]"; } + }*/ + } - if(!http){ - return dojo.raise("XMLHTTP not available", last_e); - } + if(!http){ + return dojo.raise("XMLHTTP not available", last_e); + } - return http; // XMLHTTPRequest instance - } + return http; // XMLHTTPRequest instance + } - dojo.hostenv._blockAsync = false; - dojo.hostenv.getText = function(uri, async_cb, fail_ok){ - // summary: Read the contents of the specified uri and return those contents. - // uri: - // A relative or absolute uri. If absolute, it still must be in - // the same "domain" as we are. - // async_cb: - // If not specified, load synchronously. If specified, load - // asynchronously, and use async_cb as the progress handler which - // takes the xmlhttp object as its argument. If async_cb, this - // function returns null. - // fail_ok: - // Default false. If fail_ok and !async_cb and loading fails, - // return null instead of throwing. + dojo.hostenv._blockAsync = false; + dojo.hostenv.getText = function(uri, async_cb, fail_ok){ + // summary: Read the contents of the specified uri and return those contents. + // uri: + // A relative or absolute uri. If absolute, it still must be in + // the same "domain" as we are. + // async_cb: + // If not specified, load synchronously. If specified, load + // asynchronously, and use async_cb as the progress handler which + // takes the xmlhttp object as its argument. If async_cb, this + // function returns null. + // fail_ok: + // Default false. If fail_ok and !async_cb and loading fails, + // return null instead of throwing. - // need to block async callbacks from snatching this thread as the result - // of an async callback might call another sync XHR, this hangs khtml forever - // hostenv._blockAsync must also be checked in BrowserIO's watchInFlight() - // NOTE: must be declared before scope switches ie. this.getXmlhttpObject() - if(!async_cb){ this._blockAsync = true; } + // need to block async callbacks from snatching this thread as the result + // of an async callback might call another sync XHR, this hangs khtml forever + // hostenv._blockAsync must also be checked in BrowserIO's watchInFlight() + // NOTE: must be declared before scope switches ie. this.getXmlhttpObject() + if(!async_cb){ this._blockAsync = true; } - var http = this.getXmlhttpObject(); + var http = this.getXmlhttpObject(); - function isDocumentOk(http){ - var stat = http["status"]; - // allow a 304 use cache, needed in konq (is this compliant with the http spec?) - return Boolean((!stat)||((200 <= stat)&&(300 > stat))||(stat==304)); - } + function isDocumentOk(http){ + var stat = http["status"]; + // allow a 304 use cache, needed in konq (is this compliant with the http spec?) + return Boolean((!stat)||((200 <= stat)&&(300 > stat))||(stat==304)); + } - if(async_cb){ - var _this = this, timer = null, gbl = dojo.global(); - var xhr = dojo.evalObjPath("dojo.io.XMLHTTPTransport"); - http.onreadystatechange = function(){ - if(timer){ gbl.clearTimeout(timer); timer = null; } - if(_this._blockAsync || (xhr && xhr._blockAsync)){ - timer = gbl.setTimeout(function () { http.onreadystatechange.apply(this); }, 10); - }else{ - if(4==http.readyState){ - if(isDocumentOk(http)){ - // dojo.debug("LOADED URI: "+uri); - async_cb(http.responseText); - } - } - } - } - } + if(async_cb){ + var _this = this, timer = null, gbl = dojo.global(); + var xhr = dojo.evalObjPath("dojo.io.XMLHTTPTransport"); + http.onreadystatechange = function(){ + if(timer){ gbl.clearTimeout(timer); timer = null; } + if(_this._blockAsync || (xhr && xhr._blockAsync)){ + timer = gbl.setTimeout(function () { http.onreadystatechange.apply(this); }, 10); + }else{ + if(4==http.readyState){ + if(isDocumentOk(http)){ + // dojo.debug("LOADED URI: "+uri); + async_cb(http.responseText); + } + } + } + } + } - http.open('GET', uri, async_cb ? true : false); - try{ - http.send(null); - if(async_cb){ - return null; - } - if(!isDocumentOk(http)){ - var err = Error("Unable to load "+uri+" status:"+ http.status); - err.status = http.status; - err.responseText = http.responseText; - throw err; - } - }catch(e){ - this._blockAsync = false; - if((fail_ok)&&(!async_cb)){ - return null; - }else{ - throw e; - } - } + http.open('GET', uri, async_cb ? true : false); + try{ + http.send(null); + if(async_cb){ + return null; + } + if(!isDocumentOk(http)){ + var err = Error("Unable to load "+uri+" status:"+ http.status); + err.status = http.status; + err.responseText = http.responseText; + throw err; + } + }catch(e){ + this._blockAsync = false; + if((fail_ok)&&(!async_cb)){ + return null; + }else{ + throw e; + } + } - this._blockAsync = false; - return http.responseText; // String - } + this._blockAsync = false; + return http.responseText; // String + } - dojo.hostenv.defaultDebugContainerId = 'dojoDebug'; - dojo.hostenv._println_buffer = []; - dojo.hostenv._println_safe = false; - dojo.hostenv.println = function(/*String*/line){ - // summary: - // prints the provided line to whatever logging container is - // available. If the page isn't loaded yet, the line may be added - // to a buffer for printing later. - if(!dojo.hostenv._println_safe){ - dojo.hostenv._println_buffer.push(line); - }else{ - try { - var console = document.getElementById(djConfig.debugContainerId ? - djConfig.debugContainerId : dojo.hostenv.defaultDebugContainerId); - if(!console) { console = dojo.body(); } + dojo.hostenv.defaultDebugContainerId = 'dojoDebug'; + dojo.hostenv._println_buffer = []; + dojo.hostenv._println_safe = false; + dojo.hostenv.println = function(/*String*/line){ + // summary: + // prints the provided line to whatever logging container is + // available. If the page isn't loaded yet, the line may be added + // to a buffer for printing later. + if(!dojo.hostenv._println_safe){ + dojo.hostenv._println_buffer.push(line); + }else{ + try { + var console = document.getElementById(djConfig.debugContainerId ? + djConfig.debugContainerId : dojo.hostenv.defaultDebugContainerId); + if(!console) { console = dojo.body(); } - var div = document.createElement("div"); - div.appendChild(document.createTextNode(line)); - console.appendChild(div); - } catch (e) { - try{ - // safari needs the output wrapped in an element for some reason - document.write("
" + line + "
"); - }catch(e2){ - window.status = line; - } - } - } - } + var div = document.createElement("div"); + div.appendChild(document.createTextNode(line)); + console.appendChild(div); + } catch (e) { + try{ + // safari needs the output wrapped in an element for some reason + document.write("
" + line + "
"); + }catch(e2){ + window.status = line; + } + } + } + } - dojo.addOnLoad(function(){ - dojo.hostenv._println_safe = true; - while(dojo.hostenv._println_buffer.length > 0){ - dojo.hostenv.println(dojo.hostenv._println_buffer.shift()); - } - }); + dojo.addOnLoad(function(){ + dojo.hostenv._println_safe = true; + while(dojo.hostenv._println_buffer.length > 0){ + dojo.hostenv.println(dojo.hostenv._println_buffer.shift()); + } + }); - function dj_addNodeEvtHdlr(/*DomNode*/node, /*String*/evtName, /*Function*/fp){ - // summary: - // non-destructively adds the specified function to the node's - // evtName handler. - // node: the DomNode to add the handler to - // evtName: should be in the form "click" for "onclick" handlers - var oldHandler = node["on"+evtName] || function(){}; - node["on"+evtName] = function(){ - fp.apply(node, arguments); - oldHandler.apply(node, arguments); - } - return true; - } + function dj_addNodeEvtHdlr(/*DomNode*/node, /*String*/evtName, /*Function*/fp){ + // summary: + // non-destructively adds the specified function to the node's + // evtName handler. + // node: the DomNode to add the handler to + // evtName: should be in the form "click" for "onclick" handlers + var oldHandler = node["on"+evtName] || function(){}; + node["on"+evtName] = function(){ + fp.apply(node, arguments); + oldHandler.apply(node, arguments); + } + return true; + } - dojo.hostenv._djInitFired = false; - // BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/) - function dj_load_init(e){ - dojo.hostenv._djInitFired = true; - // allow multiple calls, only first one will take effect - // A bug in khtml calls events callbacks for document for event which isnt supported - // for example a created contextmenu event calls DOMContentLoaded, workaround - var type = (e && e.type) ? e.type.toLowerCase() : "load"; - if(arguments.callee.initialized || (type!="domcontentloaded" && type!="load")){ return; } - arguments.callee.initialized = true; - if(typeof(_timer) != 'undefined'){ - clearInterval(_timer); - delete _timer; - } + dojo.hostenv._djInitFired = false; + // BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/) + function dj_load_init(e){ + dojo.hostenv._djInitFired = true; + // allow multiple calls, only first one will take effect + // A bug in khtml calls events callbacks for document for event which isnt supported + // for example a created contextmenu event calls DOMContentLoaded, workaround + var type = (e && e.type) ? e.type.toLowerCase() : "load"; + if(arguments.callee.initialized || (type!="domcontentloaded" && type!="load")){ return; } + arguments.callee.initialized = true; + if(typeof(_timer) != 'undefined'){ + clearInterval(_timer); + delete _timer; + } - var initFunc = function(){ - //perform initialization - if(dojo.render.html.ie){ - dojo.hostenv.makeWidgets(); - } - }; + var initFunc = function(){ + //perform initialization + if(dojo.render.html.ie){ + dojo.hostenv.makeWidgets(); + } + }; - if(dojo.hostenv.inFlightCount == 0){ - initFunc(); - dojo.hostenv.modulesLoaded(); - }else{ - //This else case should be xdomain loading. - //Make sure this is the first thing in the load listener array. - //Part of the dojo.addOnLoad guarantee is that when the listeners are notified, - //It means the DOM (or page) has loaded and that widgets have been parsed. - dojo.hostenv.modulesLoadedListeners.unshift(initFunc); - } - } + if(dojo.hostenv.inFlightCount == 0){ + initFunc(); + dojo.hostenv.modulesLoaded(); + }else{ + //This else case should be xdomain loading. + //Make sure this is the first thing in the load listener array. + //Part of the dojo.addOnLoad guarantee is that when the listeners are notified, + //It means the DOM (or page) has loaded and that widgets have been parsed. + dojo.hostenv.modulesLoadedListeners.unshift(initFunc); + } + } - // START DOMContentLoaded - // Mozilla and Opera 9 expose the event we could use - if(document.addEventListener){ - // NOTE: - // due to a threading issue in Firefox 2.0, we can't enable - // DOMContentLoaded on that platform. For more information, see: - // http://trac.dojotoolkit.org/ticket/1704 - if(dojo.render.html.opera || (dojo.render.html.moz && (djConfig["enableMozDomContentLoaded"] === true))){ - document.addEventListener("DOMContentLoaded", dj_load_init, null); - } + // START DOMContentLoaded + // Mozilla and Opera 9 expose the event we could use + if(document.addEventListener){ + // NOTE: + // due to a threading issue in Firefox 2.0, we can't enable + // DOMContentLoaded on that platform. For more information, see: + // http://trac.dojotoolkit.org/ticket/1704 + if(dojo.render.html.opera || (dojo.render.html.moz && (djConfig["enableMozDomContentLoaded"] === true))){ + document.addEventListener("DOMContentLoaded", dj_load_init, null); + } - // mainly for Opera 8.5, won't be fired if DOMContentLoaded fired already. - // also used for Mozilla because of trac #1640 - window.addEventListener("load", dj_load_init, null); - } + // mainly for Opera 8.5, won't be fired if DOMContentLoaded fired already. + // also used for Mozilla because of trac #1640 + window.addEventListener("load", dj_load_init, null); + } - // for Internet Explorer. readyState will not be achieved on init call, but dojo doesn't need it - // however, we'll include it because we don't know if there are other functions added that might. - // Note that this has changed because the build process strips all comments--including conditional - // ones. - if(dojo.render.html.ie && dojo.render.os.win){ - document.attachEvent("onreadystatechange", function(e){ - if(document.readyState == "complete"){ - dj_load_init(); - } - }); - } + // for Internet Explorer. readyState will not be achieved on init call, but dojo doesn't need it + // however, we'll include it because we don't know if there are other functions added that might. + // Note that this has changed because the build process strips all comments--including conditional + // ones. + if(dojo.render.html.ie && dojo.render.os.win){ + document.attachEvent("onreadystatechange", function(e){ + if(document.readyState == "complete"){ + dj_load_init(); + } + }); + } - if (/(WebKit|khtml)/i.test(navigator.userAgent)) { // sniff - var _timer = setInterval(function() { - if (/loaded|complete/.test(document.readyState)) { - dj_load_init(); // call the onload handler - } - }, 10); - } - // END DOMContentLoaded + if (/(WebKit|khtml)/i.test(navigator.userAgent)) { // sniff + var _timer = setInterval(function() { + if (/loaded|complete/.test(document.readyState)) { + dj_load_init(); // call the onload handler + } + }, 10); + } + // END DOMContentLoaded - // IE WebControl hosted in an application can fire "beforeunload" and "unload" - // events when control visibility changes, causing Dojo to unload too soon. The - // following code fixes the problem - // Reference: http://support.microsoft.com/default.aspx?scid=kb;en-us;199155 - if(dojo.render.html.ie){ - dj_addNodeEvtHdlr(window, "beforeunload", function(){ - dojo.hostenv._unloading = true; - window.setTimeout(function() { - dojo.hostenv._unloading = false; - }, 0); - }); - } + // IE WebControl hosted in an application can fire "beforeunload" and "unload" + // events when control visibility changes, causing Dojo to unload too soon. The + // following code fixes the problem + // Reference: http://support.microsoft.com/default.aspx?scid=kb;en-us;199155 + if(dojo.render.html.ie){ + dj_addNodeEvtHdlr(window, "beforeunload", function(){ + dojo.hostenv._unloading = true; + window.setTimeout(function() { + dojo.hostenv._unloading = false; + }, 0); + }); + } - dj_addNodeEvtHdlr(window, "unload", function(){ - dojo.hostenv.unloaded(); - if((!dojo.render.html.ie)||(dojo.render.html.ie && dojo.hostenv._unloading)){ - dojo.hostenv.unloaded(); - } - }); + dj_addNodeEvtHdlr(window, "unload", function(){ + dojo.hostenv.unloaded(); + if((!dojo.render.html.ie)||(dojo.render.html.ie && dojo.hostenv._unloading)){ + dojo.hostenv.unloaded(); + } + }); - dojo.hostenv.makeWidgets = function(){ - // you can put searchIds in djConfig and dojo.hostenv at the moment - // we should probably eventually move to one or the other - var sids = []; - if(djConfig.searchIds && djConfig.searchIds.length > 0) { - sids = sids.concat(djConfig.searchIds); - } - if(dojo.hostenv.searchIds && dojo.hostenv.searchIds.length > 0) { - sids = sids.concat(dojo.hostenv.searchIds); - } + dojo.hostenv.makeWidgets = function(){ + // you can put searchIds in djConfig and dojo.hostenv at the moment + // we should probably eventually move to one or the other + var sids = []; + if(djConfig.searchIds && djConfig.searchIds.length > 0) { + sids = sids.concat(djConfig.searchIds); + } + if(dojo.hostenv.searchIds && dojo.hostenv.searchIds.length > 0) { + sids = sids.concat(dojo.hostenv.searchIds); + } - if((djConfig.parseWidgets)||(sids.length > 0)){ - if(dojo.evalObjPath("dojo.widget.Parse")){ - // we must do this on a delay to avoid: - // http://www.shaftek.org/blog/archives/000212.html - // (IE bug) - var parser = new dojo.xml.Parse(); - if(sids.length > 0){ - for(var x=0; x 0)){ + if(dojo.evalObjPath("dojo.widget.Parse")){ + // we must do this on a delay to avoid: + // http://www.shaftek.org/blog/archives/000212.html + // (IE bug) + var parser = new dojo.xml.Parse(); + if(sids.length > 0){ + for(var x=0; x 0, trim from start, if wh < 0, trim from end, else both - if(!str.replace){ return str; } - if(!str.length){ return str; } - var re = (wh > 0) ? (/^\s+/) : (wh < 0) ? (/\s+$/) : (/^\s+|\s+$/g); - return str.replace(re, ""); // string + // summary + // Trim whitespace from str. If wh > 0, trim from start, if wh < 0, trim from end, else both + if(!str.replace){ return str; } + if(!str.length){ return str; } + var re = (wh > 0) ? (/^\s+/) : (wh < 0) ? (/\s+$/) : (/^\s+|\s+$/g); + return str.replace(re, ""); // string } dojo.string.trimStart = function(/* string */str) { - // summary - // Trim whitespace at the beginning of 'str' - return dojo.string.trim(str, 1); // string + // summary + // Trim whitespace at the beginning of 'str' + return dojo.string.trim(str, 1); // string } dojo.string.trimEnd = function(/* string */str) { - // summary - // Trim whitespace at the end of 'str' - return dojo.string.trim(str, -1); + // summary + // Trim whitespace at the end of 'str' + return dojo.string.trim(str, -1); } dojo.string.repeat = function(/* string */str, /* integer */count, /* string? */separator) { - // summary - // Return 'str' repeated 'count' times, optionally placing 'separator' between each rep - var out = ""; - for(var i = 0; i < count; i++) { - out += str; - if(separator && i < count - 1) { - out += separator; - } - } - return out; // string + // summary + // Return 'str' repeated 'count' times, optionally placing 'separator' between each rep + var out = ""; + for(var i = 0; i < count; i++) { + out += str; + if(separator && i < count - 1) { + out += separator; + } + } + return out; // string } dojo.string.pad = function(/* string */str, /* integer */len/*=2*/, /* string */ c/*='0'*/, /* integer */dir/*=1*/) { - // summary - // Pad 'str' to guarantee that it is at least 'len' length with the character 'c' at either the - // start (dir=1) or end (dir=-1) of the string - var out = String(str); - if(!c) { - c = '0'; - } - if(!dir) { - dir = 1; - } - while(out.length < len) { - if(dir > 0) { - out = c + out; - } else { - out += c; - } - } - return out; // string + // summary + // Pad 'str' to guarantee that it is at least 'len' length with the character 'c' at either the + // start (dir=1) or end (dir=-1) of the string + var out = String(str); + if(!c) { + c = '0'; + } + if(!dir) { + dir = 1; + } + while(out.length < len) { + if(dir > 0) { + out = c + out; + } else { + out += c; + } + } + return out; // string } dojo.string.padLeft = function(/* string */str, /* integer */len, /* string */c) { - // summary - // same as dojo.string.pad(str, len, c, 1) - return dojo.string.pad(str, len, c, 1); // string + // summary + // same as dojo.string.pad(str, len, c, 1) + return dojo.string.pad(str, len, c, 1); // string } dojo.string.padRight = function(/* string */str, /* integer */len, /* string */c) { - // summary - // same as dojo.string.pad(str, len, c, -1) - return dojo.string.pad(str, len, c, -1); // string + // summary + // same as dojo.string.pad(str, len, c, -1) + return dojo.string.pad(str, len, c, -1); // string } dojo.provide("dojo.string"); @@ -1725,60 +1735,60 @@ dojo.provide("dojo.string"); dojo.provide("dojo.lang.common"); dojo.lang.inherits = function(/*Function*/subclass, /*Function*/superclass){ - // summary: Set up inheritance between two classes. - if(!dojo.lang.isFunction(superclass)){ - dojo.raise("dojo.inherits: superclass argument ["+superclass+"] must be a function (subclass: ["+subclass+"']"); - } - subclass.prototype = new superclass(); - subclass.prototype.constructor = subclass; - subclass.superclass = superclass.prototype; - // DEPRECATED: super is a reserved word, use 'superclass' - subclass['super'] = superclass.prototype; + // summary: Set up inheritance between two classes. + if(!dojo.lang.isFunction(superclass)){ + dojo.raise("dojo.inherits: superclass argument ["+superclass+"] must be a function (subclass: ["+subclass+"']"); + } + subclass.prototype = new superclass(); + subclass.prototype.constructor = subclass; + subclass.superclass = superclass.prototype; + // DEPRECATED: super is a reserved word, use 'superclass' + subclass['super'] = superclass.prototype; } dojo.lang._mixin = function(/*Object*/ obj, /*Object*/ props){ - // summary: - // Adds all properties and methods of props to obj. This addition is - // "prototype extension safe", so that instances of objects will not - // pass along prototype defaults. - var tobj = {}; - for(var x in props){ - // the "tobj" condition avoid copying properties in "props" - // inherited from Object.prototype. For example, if obj has a custom - // toString() method, don't overwrite it with the toString() method - // that props inherited from Object.protoype - if((typeof tobj[x] == "undefined") || (tobj[x] != props[x])){ - obj[x] = props[x]; - } - } - // IE doesn't recognize custom toStrings in for..in - if(dojo.render.html.ie - && (typeof(props["toString"]) == "function") - && (props["toString"] != obj["toString"]) - && (props["toString"] != tobj["toString"])) - { - obj.toString = props.toString; - } - return obj; // Object + // summary: + // Adds all properties and methods of props to obj. This addition is + // "prototype extension safe", so that instances of objects will not + // pass along prototype defaults. + var tobj = {}; + for(var x in props){ + // the "tobj" condition avoid copying properties in "props" + // inherited from Object.prototype. For example, if obj has a custom + // toString() method, don't overwrite it with the toString() method + // that props inherited from Object.protoype + if((typeof tobj[x] == "undefined") || (tobj[x] != props[x])){ + obj[x] = props[x]; + } + } + // IE doesn't recognize custom toStrings in for..in + if(dojo.render.html.ie + && (typeof(props["toString"]) == "function") + && (props["toString"] != obj["toString"]) + && (props["toString"] != tobj["toString"])) + { + obj.toString = props.toString; + } + return obj; // Object } dojo.lang.mixin = function(/*Object*/obj, /*Object...*/props){ - // summary: Adds all properties and methods of props to obj. - for(var i=1, l=arguments.length; i -1; // boolean + // summary: Return true if value is present in array. + return dojo.lang.find(array, value) > -1; // boolean } /** @@ -1868,59 +1878,59 @@ dojo.lang.inArray = function(array /*Array*/, value /*Object*/){ */ dojo.lang.isObject = function(/*anything*/ it){ - // summary: Return true if it is an Object, Array or Function. - if(typeof it == "undefined"){ return false; } - return (typeof it == "object" || it === null || dojo.lang.isArray(it) || dojo.lang.isFunction(it)); // Boolean + // summary: Return true if it is an Object, Array or Function. + if(typeof it == "undefined"){ return false; } + return (typeof it == "object" || it === null || dojo.lang.isArray(it) || dojo.lang.isFunction(it)); // Boolean } dojo.lang.isArray = function(/*anything*/ it){ - // summary: Return true if it is an Array. - return (it && it instanceof Array || typeof it == "array"); // Boolean + // summary: Return true if it is an Array. + return (it && it instanceof Array || typeof it == "array"); // Boolean } dojo.lang.isArrayLike = function(/*anything*/ it){ - // summary: - // Return true if it can be used as an array (i.e. is an object with - // an integer length property). - if((!it)||(dojo.lang.isUndefined(it))){ return false; } - if(dojo.lang.isString(it)){ return false; } - if(dojo.lang.isFunction(it)){ return false; } // keeps out built-in constructors (Number, String, ...) which have length properties - if(dojo.lang.isArray(it)){ return true; } - // form node itself is ArrayLike, but not always iterable. Use form.elements instead. - if((it.tagName)&&(it.tagName.toLowerCase()=='form')){ return false; } - if(dojo.lang.isNumber(it.length) && isFinite(it.length)){ return true; } - return false; // Boolean + // summary: + // Return true if it can be used as an array (i.e. is an object with + // an integer length property). + if((!it)||(dojo.lang.isUndefined(it))){ return false; } + if(dojo.lang.isString(it)){ return false; } + if(dojo.lang.isFunction(it)){ return false; } // keeps out built-in constructors (Number, String, ...) which have length properties + if(dojo.lang.isArray(it)){ return true; } + // form node itself is ArrayLike, but not always iterable. Use form.elements instead. + if((it.tagName)&&(it.tagName.toLowerCase()=='form')){ return false; } + if(dojo.lang.isNumber(it.length) && isFinite(it.length)){ return true; } + return false; // Boolean } dojo.lang.isFunction = function(/*anything*/ it){ - // summary: Return true if it is a Function. - return (it instanceof Function || typeof it == "function"); // Boolean + // summary: Return true if it is a Function. + return (it instanceof Function || typeof it == "function"); // Boolean }; (function(){ - // webkit treats NodeList as a function, which is bad - if((dojo.render.html.capable)&&(dojo.render.html["safari"])){ - dojo.lang.isFunction = function(/*anything*/ it){ - if((typeof(it) == "function") && (it == "[object NodeList]")) { return false; } - return (it instanceof Function || typeof it == "function"); // Boolean - } - } + // webkit treats NodeList as a function, which is bad + if((dojo.render.html.capable)&&(dojo.render.html["safari"])){ + dojo.lang.isFunction = function(/*anything*/ it){ + if((typeof(it) == "function") && (it == "[object NodeList]")) { return false; } + return (it instanceof Function || typeof it == "function"); // Boolean + } + } })(); dojo.lang.isString = function(/*anything*/ it){ - // summary: Return true if it is a String. - return (typeof it == "string" || it instanceof String); + // summary: Return true if it is a String. + return (typeof it == "string" || it instanceof String); } dojo.lang.isAlien = function(/*anything*/ it){ - // summary: Return true if it is not a built-in function. False if not. - if(!it){ return false; } - return !dojo.lang.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean + // summary: Return true if it is not a built-in function. False if not. + if(!it){ return false; } + return !dojo.lang.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean } dojo.lang.isBoolean = function(/*anything*/ it){ - // summary: Return true if it is a Boolean. - return (it instanceof Boolean || typeof it == "boolean"); // Boolean + // summary: Return true if it is a Boolean. + return (it instanceof Boolean || typeof it == "boolean"); // Boolean } /** @@ -1930,38 +1940,38 @@ dojo.lang.isBoolean = function(/*anything*/ it){ * */ dojo.lang.isNumber = function(/*anything*/ it){ - // summary: Return true if it is a number. - // description: - // WARNING - In most cases, isNaN(it) is sufficient to determine whether or not - // something is a number or can be used as such. For example, a number or string - // can be used interchangably when accessing array items (array["1"] is the same as - // array[1]) and isNaN will return false for both values ("1" and 1). However, - // isNumber("1") will return false, which is generally not too useful. - // Also, isNumber(NaN) returns true, again, this isn't generally useful, but there - // are corner cases (like when you want to make sure that two things are really - // the same type of thing). That is really where isNumber "shines". - // - // Recommendation - Use isNaN(it) when possible - - return (it instanceof Number || typeof it == "number"); // Boolean + // summary: Return true if it is a number. + // description: + // WARNING - In most cases, isNaN(it) is sufficient to determine whether or not + // something is a number or can be used as such. For example, a number or string + // can be used interchangably when accessing array items (array["1"] is the same as + // array[1]) and isNaN will return false for both values ("1" and 1). However, + // isNumber("1") will return false, which is generally not too useful. + // Also, isNumber(NaN) returns true, again, this isn't generally useful, but there + // are corner cases (like when you want to make sure that two things are really + // the same type of thing). That is really where isNumber "shines". + // + // Recommendation - Use isNaN(it) when possible + + return (it instanceof Number || typeof it == "number"); // Boolean } /* * FIXME: Should isUndefined go away since it is error prone? */ dojo.lang.isUndefined = function(/*anything*/ it){ - // summary: Return true if it is not defined. - // description: - // WARNING - In some cases, isUndefined will not behave as you - // might expect. If you do isUndefined(foo) and there is no earlier - // reference to foo, an error will be thrown before isUndefined is - // called. It behaves correctly if you scope yor object first, i.e. - // isUndefined(foo.bar) where foo is an object and bar isn't a - // property of the object. - // - // Recommendation - Use typeof foo == "undefined" when possible + // summary: Return true if it is not defined. + // description: + // WARNING - In some cases, isUndefined will not behave as you + // might expect. If you do isUndefined(foo) and there is no earlier + // reference to foo, an error will be thrown before isUndefined is + // called. It behaves correctly if you scope yor object first, i.e. + // isUndefined(foo.bar) where foo is an object and bar isn't a + // property of the object. + // + // Recommendation - Use typeof foo == "undefined" when possible - return ((typeof(it) == "undefined")&&(it == undefined)); // Boolean + return ((typeof(it) == "undefined")&&(it == undefined)); // Boolean } // end Crockford functions @@ -1971,133 +1981,133 @@ dojo.provide("dojo.lang.extras"); dojo.lang.setTimeout = function(/*Function*/func, /*int*/delay /*, ...*/){ - // summary: - // Sets a timeout in milliseconds to execute a function in a given - // context with optional arguments. - // usage: - // dojo.lang.setTimeout(Object context, function func, number delay[, arg1[, ...]]); - // dojo.lang.setTimeout(function func, number delay[, arg1[, ...]]); + // summary: + // Sets a timeout in milliseconds to execute a function in a given + // context with optional arguments. + // usage: + // dojo.lang.setTimeout(Object context, function func, number delay[, arg1[, ...]]); + // dojo.lang.setTimeout(function func, number delay[, arg1[, ...]]); - var context = window, argsStart = 2; - if(!dojo.lang.isFunction(func)){ - context = func; - func = delay; - delay = arguments[2]; - argsStart++; - } + var context = window, argsStart = 2; + if(!dojo.lang.isFunction(func)){ + context = func; + func = delay; + delay = arguments[2]; + argsStart++; + } - if(dojo.lang.isString(func)){ - func = context[func]; - } - - var args = []; - for (var i = argsStart; i < arguments.length; i++){ - args.push(arguments[i]); - } - return dojo.global().setTimeout(function(){ func.apply(context, args); }, delay); // int + if(dojo.lang.isString(func)){ + func = context[func]; + } + + var args = []; + for (var i = argsStart; i < arguments.length; i++){ + args.push(arguments[i]); + } + return dojo.global().setTimeout(function(){ func.apply(context, args); }, delay); // int } dojo.lang.clearTimeout = function(/*int*/timer){ - // summary: clears timer by number from the execution queue + // summary: clears timer by number from the execution queue - // FIXME: - // why do we have this function? It's not portable outside of browser - // environments and it's a stupid wrapper on something that browsers - // provide anyway. - dojo.global().clearTimeout(timer); + // FIXME: + // why do we have this function? It's not portable outside of browser + // environments and it's a stupid wrapper on something that browsers + // provide anyway. + dojo.global().clearTimeout(timer); } dojo.lang.getNameInObj = function(/*Object*/ns, /*unknown*/item){ - // summary: - // looks for a value in the object ns with a value matching item and - // returns the property name - // ns: if null, dj_global is used - // item: value to return a name for - if(!ns){ ns = dj_global; } + // summary: + // looks for a value in the object ns with a value matching item and + // returns the property name + // ns: if null, dj_global is used + // item: value to return a name for + if(!ns){ ns = dj_global; } - for(var x in ns){ - if(ns[x] === item){ - return new String(x); // String - } - } - return null; // null + for(var x in ns){ + if(ns[x] === item){ + return new String(x); // String + } + } + return null; // null } dojo.lang.shallowCopy = function(/*Object*/obj, /*Boolean?*/deep){ - // summary: - // copies object obj one level deep, or full depth if deep is true - var i, ret; + // summary: + // copies object obj one level deep, or full depth if deep is true + var i, ret; - if(obj === null){ /*obj: null*/ return null; } // null + if(obj === null){ /*obj: null*/ return null; } // null + + if(dojo.lang.isObject(obj)){ + // obj: Object + ret = new obj.constructor(); + for(i in obj){ + if(dojo.lang.isUndefined(ret[i])){ + ret[i] = deep ? dojo.lang.shallowCopy(obj[i], deep) : obj[i]; + } + } + }else if(dojo.lang.isArray(obj)){ + // obj: Array + ret = []; + for(i=0; i hacks: + * iframe document hacks allow browsers to communicate asynchronously + * with a server via HTTP POST and GET operations. With significant + * effort and server cooperation, low-latency data transit between + * client and server can be acheived via iframe mechanisms (repubsub). * - * "); - } + if((!djConfig["preventBackButtonFix"])&&(!dojo.hostenv.post_load_)){ + document.write(""); + } }catch(e){/* squelch */} if(dojo.render.html.opera){ - dojo.debug("Opera is not supported with dojo.undo.browser, so back/forward detection will not work."); + dojo.debug("Opera is not supported with dojo.undo.browser, so back/forward detection will not work."); } dojo.undo.browser = { - initialHref: (!dj_undef("window")) ? window.location.href : "", - initialHash: (!dj_undef("window")) ? window.location.hash : "", + initialHref: (!dj_undef("window")) ? window.location.href : "", + initialHash: (!dj_undef("window")) ? window.location.hash : "", - moveForward: false, - historyStack: [], - forwardStack: [], - historyIframe: null, - bookmarkAnchor: null, - locationTimer: null, + moveForward: false, + historyStack: [], + forwardStack: [], + historyIframe: null, + bookmarkAnchor: null, + locationTimer: null, - /** - * - */ - setInitialState: function(/*Object*/args){ - //summary: Sets the state object and back callback for the very first page that is loaded. - //description: It is recommended that you call this method as part of an event listener that is registered via - //dojo.addOnLoad(). - //args: Object - // See the addToHistory() function for the list of valid args properties. - this.initialState = this._createState(this.initialHref, args, this.initialHash); - }, + /** + * + */ + setInitialState: function(/*Object*/args){ + //summary: Sets the state object and back callback for the very first page that is loaded. + //description: It is recommended that you call this method as part of an event listener that is registered via + //dojo.addOnLoad(). + //args: Object + // See the addToHistory() function for the list of valid args properties. + this.initialState = this._createState(this.initialHref, args, this.initialHash); + }, - //FIXME: Would like to support arbitrary back/forward jumps. Have to rework iframeLoaded among other things. - //FIXME: is there a slight race condition in moz using change URL with the timer check and when - // the hash gets set? I think I have seen a back/forward call in quick succession, but not consistent. - addToHistory: function(args){ - //summary: adds a state object (args) to the history list. You must set - //djConfig.preventBackButtonFix = false to use dojo.undo.browser. + //FIXME: Would like to support arbitrary back/forward jumps. Have to rework iframeLoaded among other things. + //FIXME: is there a slight race condition in moz using change URL with the timer check and when + // the hash gets set? I think I have seen a back/forward call in quick succession, but not consistent. + addToHistory: function(args){ + //summary: adds a state object (args) to the history list. You must set + //djConfig.preventBackButtonFix = false to use dojo.undo.browser. - //args: Object - // args can have the following properties: - // To support getting back button notifications, the object argument should implement a - // function called either "back", "backButton", or "handle". The string "back" will be - // passed as the first and only argument to this callback. - // - To support getting forward button notifications, the object argument should implement a - // function called either "forward", "forwardButton", or "handle". The string "forward" will be - // passed as the first and only argument to this callback. - // - If you want the browser location string to change, define "changeUrl" on the object. If the - // value of "changeUrl" is true, then a unique number will be appended to the URL as a fragment - // identifier (http://some.domain.com/path#uniquenumber). If it is any other value that does - // not evaluate to false, that value will be used as the fragment identifier. For example, - // if changeUrl: 'page1', then the URL will look like: http://some.domain.com/path#page1 - // Full example: - // dojo.undo.browser.addToHistory({ - // back: function() { alert('back pressed'); }, - // forward: function() { alert('forward pressed'); }, - // changeUrl: true - // }); - // - // BROWSER NOTES: - // Safari 1.2: - // back button "works" fine, however it's not possible to actually - // DETECT that you've moved backwards by inspecting window.location. - // Unless there is some other means of locating. - // FIXME: perhaps we can poll on history.length? - // Safari 2.0.3+ (and probably 1.3.2+): - // works fine, except when changeUrl is used. When changeUrl is used, - // Safari jumps all the way back to whatever page was shown before - // the page that uses dojo.undo.browser support. - // IE 5.5 SP2: - // back button behavior is macro. It does not move back to the - // previous hash value, but to the last full page load. This suggests - // that the iframe is the correct way to capture the back button in - // these cases. - // Don't test this page using local disk for MSIE. MSIE will not create - // a history list for iframe_history.html if served from a file: URL. - // The XML served back from the XHR tests will also not be properly - // created if served from local disk. Serve the test pages from a web - // server to test in that browser. - // IE 6.0: - // same behavior as IE 5.5 SP2 - // Firefox 1.0+: - // the back button will return us to the previous hash on the same - // page, thereby not requiring an iframe hack, although we do then - // need to run a timer to detect inter-page movement. + //args: Object + // args can have the following properties: + // To support getting back button notifications, the object argument should implement a + // function called either "back", "backButton", or "handle". The string "back" will be + // passed as the first and only argument to this callback. + // - To support getting forward button notifications, the object argument should implement a + // function called either "forward", "forwardButton", or "handle". The string "forward" will be + // passed as the first and only argument to this callback. + // - If you want the browser location string to change, define "changeUrl" on the object. If the + // value of "changeUrl" is true, then a unique number will be appended to the URL as a fragment + // identifier (http://some.domain.com/path#uniquenumber). If it is any other value that does + // not evaluate to false, that value will be used as the fragment identifier. For example, + // if changeUrl: 'page1', then the URL will look like: http://some.domain.com/path#page1 + // Full example: + // dojo.undo.browser.addToHistory({ + // back: function() { alert('back pressed'); }, + // forward: function() { alert('forward pressed'); }, + // changeUrl: true + // }); + // + // BROWSER NOTES: + // Safari 1.2: + // back button "works" fine, however it's not possible to actually + // DETECT that you've moved backwards by inspecting window.location. + // Unless there is some other means of locating. + // FIXME: perhaps we can poll on history.length? + // Safari 2.0.3+ (and probably 1.3.2+): + // works fine, except when changeUrl is used. When changeUrl is used, + // Safari jumps all the way back to whatever page was shown before + // the page that uses dojo.undo.browser support. + // IE 5.5 SP2: + // back button behavior is macro. It does not move back to the + // previous hash value, but to the last full page load. This suggests + // that the iframe is the correct way to capture the back button in + // these cases. + // Don't test this page using local disk for MSIE. MSIE will not create + // a history list for iframe_history.html if served from a file: URL. + // The XML served back from the XHR tests will also not be properly + // created if served from local disk. Serve the test pages from a web + // server to test in that browser. + // IE 6.0: + // same behavior as IE 5.5 SP2 + // Firefox 1.0+: + // the back button will return us to the previous hash on the same + // page, thereby not requiring an iframe hack, although we do then + // need to run a timer to detect inter-page movement. - //If addToHistory is called, then that means we prune the - //forward stack -- the user went back, then wanted to - //start a new forward path. - this.forwardStack = []; + //If addToHistory is called, then that means we prune the + //forward stack -- the user went back, then wanted to + //start a new forward path. + this.forwardStack = []; - var hash = null; - var url = null; - if(!this.historyIframe){ - if(djConfig["useXDomain"] && !djConfig["dojoIframeHistoryUrl"]){ - dojo.debug("dojo.undo.browser: When using cross-domain Dojo builds," - + " please save iframe_history.html to your domain and set djConfig.dojoIframeHistoryUrl" - + " to the path on your domain to iframe_history.html"); - } - this.historyIframe = window.frames["djhistory"]; - } - if(!this.bookmarkAnchor){ - this.bookmarkAnchor = document.createElement("a"); - dojo.body().appendChild(this.bookmarkAnchor); - this.bookmarkAnchor.style.display = "none"; - } - if(args["changeUrl"]){ - hash = "#"+ ((args["changeUrl"]!==true) ? args["changeUrl"] : (new Date()).getTime()); + var hash = null; + var url = null; + if(!this.historyIframe){ + if(djConfig["useXDomain"] && !djConfig["dojoIframeHistoryUrl"]){ + dojo.debug("dojo.undo.browser: When using cross-domain Dojo builds," + + " please save iframe_history.html to your domain and set djConfig.dojoIframeHistoryUrl" + + " to the path on your domain to iframe_history.html"); + } + this.historyIframe = window.frames["djhistory"]; + } + if(!this.bookmarkAnchor){ + this.bookmarkAnchor = document.createElement("a"); + dojo.body().appendChild(this.bookmarkAnchor); + this.bookmarkAnchor.style.display = "none"; + } + if(args["changeUrl"]){ + hash = "#"+ ((args["changeUrl"]!==true) ? args["changeUrl"] : (new Date()).getTime()); + + //If the current hash matches the new one, just replace the history object with + //this new one. It doesn't make sense to track different state objects for the same + //logical URL. This matches the browser behavior of only putting in one history + //item no matter how many times you click on the same #hash link, at least in Firefox + //and Safari, and there is no reliable way in those browsers to know if a #hash link + //has been clicked on multiple times. So making this the standard behavior in all browsers + //so that dojo.undo.browser's behavior is the same in all browsers. + if(this.historyStack.length == 0 && this.initialState.urlHash == hash){ + this.initialState = this._createState(url, args, hash); + return; + }else if(this.historyStack.length > 0 && this.historyStack[this.historyStack.length - 1].urlHash == hash){ + this.historyStack[this.historyStack.length - 1] = this._createState(url, args, hash); + return; + } - //If the current hash matches the new one, just replace the history object with - //this new one. It doesn't make sense to track different state objects for the same - //logical URL. This matches the browser behavior of only putting in one history - //item no matter how many times you click on the same #hash link, at least in Firefox - //and Safari, and there is no reliable way in those browsers to know if a #hash link - //has been clicked on multiple times. So making this the standard behavior in all browsers - //so that dojo.undo.browser's behavior is the same in all browsers. - if(this.historyStack.length == 0 && this.initialState.urlHash == hash){ - this.initialState = this._createState(url, args, hash); - return; - }else if(this.historyStack.length > 0 && this.historyStack[this.historyStack.length - 1].urlHash == hash){ - this.historyStack[this.historyStack.length - 1] = this._createState(url, args, hash); - return; - } + this.changingUrl = true; + setTimeout("window.location.href = '"+hash+"'; dojo.undo.browser.changingUrl = false;", 1); + this.bookmarkAnchor.href = hash; + + if(dojo.render.html.ie){ + url = this._loadIframeHistory(); - this.changingUrl = true; - setTimeout("window.location.href = '"+hash+"'; dojo.undo.browser.changingUrl = false;", 1); - this.bookmarkAnchor.href = hash; + var oldCB = args["back"]||args["backButton"]||args["handle"]; - if(dojo.render.html.ie){ - url = this._loadIframeHistory(); + //The function takes handleName as a parameter, in case the + //callback we are overriding was "handle". In that case, + //we will need to pass the handle name to handle. + var tcb = function(handleName){ + if(window.location.hash != ""){ + setTimeout("window.location.href = '"+hash+"';", 1); + } + //Use apply to set "this" to args, and to try to avoid memory leaks. + oldCB.apply(this, [handleName]); + } + + //Set interceptor function in the right place. + if(args["back"]){ + args.back = tcb; + }else if(args["backButton"]){ + args.backButton = tcb; + }else if(args["handle"]){ + args.handle = tcb; + } + + var oldFW = args["forward"]||args["forwardButton"]||args["handle"]; + + //The function takes handleName as a parameter, in case the + //callback we are overriding was "handle". In that case, + //we will need to pass the handle name to handle. + var tfw = function(handleName){ + if(window.location.hash != ""){ + window.location.href = hash; + } + if(oldFW){ // we might not actually have one + //Use apply to set "this" to args, and to try to avoid memory leaks. + oldFW.apply(this, [handleName]); + } + } - var oldCB = args["back"]||args["backButton"]||args["handle"]; + //Set interceptor function in the right place. + if(args["forward"]){ + args.forward = tfw; + }else if(args["forwardButton"]){ + args.forwardButton = tfw; + }else if(args["handle"]){ + args.handle = tfw; + } - //The function takes handleName as a parameter, in case the - //callback we are overriding was "handle". In that case, - //we will need to pass the handle name to handle. - var tcb = function(handleName){ - if(window.location.hash != ""){ - setTimeout("window.location.href = '"+hash+"';", 1); - } - //Use apply to set "this" to args, and to try to avoid memory leaks. - oldCB.apply(this, [handleName]); - } + }else if(dojo.render.html.moz){ + // start the timer + if(!this.locationTimer){ + this.locationTimer = setInterval("dojo.undo.browser.checkLocation();", 200); + } + } + }else{ + url = this._loadIframeHistory(); + } - //Set interceptor function in the right place. - if(args["back"]){ - args.back = tcb; - }else if(args["backButton"]){ - args.backButton = tcb; - }else if(args["handle"]){ - args.handle = tcb; - } + this.historyStack.push(this._createState(url, args, hash)); + }, - var oldFW = args["forward"]||args["forwardButton"]||args["handle"]; + checkLocation: function(){ + //summary: private method. Do not call this directly. + if (!this.changingUrl){ + var hsl = this.historyStack.length; - //The function takes handleName as a parameter, in case the - //callback we are overriding was "handle". In that case, - //we will need to pass the handle name to handle. - var tfw = function(handleName){ - if(window.location.hash != ""){ - window.location.href = hash; - } - if(oldFW){ // we might not actually have one - //Use apply to set "this" to args, and to try to avoid memory leaks. - oldFW.apply(this, [handleName]); - } - } + if((window.location.hash == this.initialHash||window.location.href == this.initialHref)&&(hsl == 1)){ + // FIXME: could this ever be a forward button? + // we can't clear it because we still need to check for forwards. Ugg. + // clearInterval(this.locationTimer); + this.handleBackButton(); + return; + } + + // first check to see if we could have gone forward. We always halt on + // a no-hash item. + if(this.forwardStack.length > 0){ + if(this.forwardStack[this.forwardStack.length-1].urlHash == window.location.hash){ + this.handleForwardButton(); + return; + } + } + + // ok, that didn't work, try someplace back in the history stack + if((hsl >= 2)&&(this.historyStack[hsl-2])){ + if(this.historyStack[hsl-2].urlHash==window.location.hash){ + this.handleBackButton(); + return; + } + } + } + }, - //Set interceptor function in the right place. - if(args["forward"]){ - args.forward = tfw; - }else if(args["forwardButton"]){ - args.forwardButton = tfw; - }else if(args["handle"]){ - args.handle = tfw; - } + iframeLoaded: function(evt, ifrLoc){ + //summary: private method. Do not call this directly. + if(!dojo.render.html.opera){ + var query = this._getUrlQuery(ifrLoc.href); + if(query == null){ + // alert("iframeLoaded"); + // we hit the end of the history, so we should go back + if(this.historyStack.length == 1){ + this.handleBackButton(); + } + return; + } + if(this.moveForward){ + // we were expecting it, so it's not either a forward or backward movement + this.moveForward = false; + return; + } + + //Check the back stack first, since it is more likely. + //Note that only one step back or forward is supported. + if(this.historyStack.length >= 2 && query == this._getUrlQuery(this.historyStack[this.historyStack.length-2].url)){ + this.handleBackButton(); + } + else if(this.forwardStack.length > 0 && query == this._getUrlQuery(this.forwardStack[this.forwardStack.length-1].url)){ + this.handleForwardButton(); + } + } + }, - }else if(dojo.render.html.moz){ - // start the timer - if(!this.locationTimer){ - this.locationTimer = setInterval("dojo.undo.browser.checkLocation();", 200); - } - } - }else{ - url = this._loadIframeHistory(); - } + handleBackButton: function(){ + //summary: private method. Do not call this directly. - this.historyStack.push(this._createState(url, args, hash)); - }, + //The "current" page is always at the top of the history stack. + var current = this.historyStack.pop(); + if(!current){ return; } + var last = this.historyStack[this.historyStack.length-1]; + if(!last && this.historyStack.length == 0){ + last = this.initialState; + } + if (last){ + if(last.kwArgs["back"]){ + last.kwArgs["back"](); + }else if(last.kwArgs["backButton"]){ + last.kwArgs["backButton"](); + }else if(last.kwArgs["handle"]){ + last.kwArgs.handle("back"); + } + } + this.forwardStack.push(current); + }, - checkLocation: function(){ - //summary: private method. Do not call this directly. - if (!this.changingUrl){ - var hsl = this.historyStack.length; + handleForwardButton: function(){ + //summary: private method. Do not call this directly. - if((window.location.hash == this.initialHash||window.location.href == this.initialHref)&&(hsl == 1)){ - // FIXME: could this ever be a forward button? - // we can't clear it because we still need to check for forwards. Ugg. - // clearInterval(this.locationTimer); - this.handleBackButton(); - return; - } + var last = this.forwardStack.pop(); + if(!last){ return; } + if(last.kwArgs["forward"]){ + last.kwArgs.forward(); + }else if(last.kwArgs["forwardButton"]){ + last.kwArgs.forwardButton(); + }else if(last.kwArgs["handle"]){ + last.kwArgs.handle("forward"); + } + this.historyStack.push(last); + }, - // first check to see if we could have gone forward. We always halt on - // a no-hash item. - if(this.forwardStack.length > 0){ - if(this.forwardStack[this.forwardStack.length-1].urlHash == window.location.hash){ - this.handleForwardButton(); - return; - } - } + _createState: function(url, args, hash){ + //summary: private method. Do not call this directly. - // ok, that didn't work, try someplace back in the history stack - if((hsl >= 2)&&(this.historyStack[hsl-2])){ - if(this.historyStack[hsl-2].urlHash==window.location.hash){ - this.handleBackButton(); - return; - } - } - } - }, + return {"url": url, "kwArgs": args, "urlHash": hash}; //Object + }, - iframeLoaded: function(evt, ifrLoc){ - //summary: private method. Do not call this directly. - if(!dojo.render.html.opera){ - var query = this._getUrlQuery(ifrLoc.href); - if(query == null){ - // alert("iframeLoaded"); - // we hit the end of the history, so we should go back - if(this.historyStack.length == 1){ - this.handleBackButton(); - } - return; - } - if(this.moveForward){ - // we were expecting it, so it's not either a forward or backward movement - this.moveForward = false; - return; - } - - //Check the back stack first, since it is more likely. - //Note that only one step back or forward is supported. - if(this.historyStack.length >= 2 && query == this._getUrlQuery(this.historyStack[this.historyStack.length-2].url)){ - this.handleBackButton(); - } - else if(this.forwardStack.length > 0 && query == this._getUrlQuery(this.forwardStack[this.forwardStack.length-1].url)){ - this.handleForwardButton(); - } - } - }, - - handleBackButton: function(){ - //summary: private method. Do not call this directly. - - //The "current" page is always at the top of the history stack. - var current = this.historyStack.pop(); - if(!current){ return; } - var last = this.historyStack[this.historyStack.length-1]; - if(!last && this.historyStack.length == 0){ - last = this.initialState; - } - if (last){ - if(last.kwArgs["back"]){ - last.kwArgs["back"](); - }else if(last.kwArgs["backButton"]){ - last.kwArgs["backButton"](); - }else if(last.kwArgs["handle"]){ - last.kwArgs.handle("back"); - } - } - this.forwardStack.push(current); - }, - - handleForwardButton: function(){ - //summary: private method. Do not call this directly. - - var last = this.forwardStack.pop(); - if(!last){ return; } - if(last.kwArgs["forward"]){ - last.kwArgs.forward(); - }else if(last.kwArgs["forwardButton"]){ - last.kwArgs.forwardButton(); - }else if(last.kwArgs["handle"]){ - last.kwArgs.handle("forward"); - } - this.historyStack.push(last); - }, - - _createState: function(url, args, hash){ - //summary: private method. Do not call this directly. - - return {"url": url, "kwArgs": args, "urlHash": hash}; //Object - }, - - _getUrlQuery: function(url){ - //summary: private method. Do not call this directly. - var segments = url.split("?"); - if (segments.length < 2){ - return null; //null - } - else{ - return segments[1]; //String - } - }, - - _loadIframeHistory: function(){ - //summary: private method. Do not call this directly. - var url = (djConfig["dojoIframeHistoryUrl"] || dojo.hostenv.getBaseScriptUri()+'iframe_history.html') - + "?" + (new Date()).getTime(); - this.moveForward = true; - dojo.io.setIFrameSrc(this.historyIframe, url, false); - return url; //String - } + _getUrlQuery: function(url){ + //summary: private method. Do not call this directly. + var segments = url.split("?"); + if (segments.length < 2){ + return null; //null + } + else{ + return segments[1]; //String + } + }, + + _loadIframeHistory: function(){ + //summary: private method. Do not call this directly. + var url = (djConfig["dojoIframeHistoryUrl"] || dojo.hostenv.getBaseScriptUri()+'iframe_history.html') + + "?" + (new Date()).getTime(); + this.moveForward = true; + dojo.io.setIFrameSrc(this.historyIframe, url, false); + return url; //String + } } dojo.provide("dojo.io.BrowserIO"); @@ -4262,803 +4272,803 @@ dojo.provide("dojo.io.BrowserIO"); if(!dj_undef("window")) { dojo.io.checkChildrenForFile = function(/*DOMNode*/node){ - //summary: Checks any child nodes of node for an input type="file" element. - var hasFile = false; - var inputs = node.getElementsByTagName("input"); - dojo.lang.forEach(inputs, function(input){ - if(hasFile){ return; } - if(input.getAttribute("type")=="file"){ - hasFile = true; - } - }); - return hasFile; //boolean + //summary: Checks any child nodes of node for an input type="file" element. + var hasFile = false; + var inputs = node.getElementsByTagName("input"); + dojo.lang.forEach(inputs, function(input){ + if(hasFile){ return; } + if(input.getAttribute("type")=="file"){ + hasFile = true; + } + }); + return hasFile; //boolean } dojo.io.formHasFile = function(/*DOMNode*/formNode){ - //summary: Just calls dojo.io.checkChildrenForFile(). - return dojo.io.checkChildrenForFile(formNode); //boolean + //summary: Just calls dojo.io.checkChildrenForFile(). + return dojo.io.checkChildrenForFile(formNode); //boolean } dojo.io.updateNode = function(/*DOMNode*/node, /*String or Object*/urlOrArgs){ - //summary: Updates a DOMnode with the result of a dojo.io.bind() call. - //node: DOMNode - //urlOrArgs: String or Object - // Either a String that has an URL, or an object containing dojo.io.bind() - // arguments. - node = dojo.byId(node); - var args = urlOrArgs; - if(dojo.lang.isString(urlOrArgs)){ - args = { url: urlOrArgs }; - } - args.mimetype = "text/html"; - args.load = function(t, d, e){ - while(node.firstChild){ - dojo.dom.destroyNode(node.firstChild); - } - node.innerHTML = d; - }; - dojo.io.bind(args); + //summary: Updates a DOMnode with the result of a dojo.io.bind() call. + //node: DOMNode + //urlOrArgs: String or Object + // Either a String that has an URL, or an object containing dojo.io.bind() + // arguments. + node = dojo.byId(node); + var args = urlOrArgs; + if(dojo.lang.isString(urlOrArgs)){ + args = { url: urlOrArgs }; + } + args.mimetype = "text/html"; + args.load = function(t, d, e){ + while(node.firstChild){ + dojo.dom.destroyNode(node.firstChild); + } + node.innerHTML = d; + }; + dojo.io.bind(args); } dojo.io.formFilter = function(/*DOMNode*/node) { - //summary: Returns true if the node is an input element that is enabled, has - //a name, and whose type is one of the following values: ["file", "submit", "image", "reset", "button"] - var type = (node.type||"").toLowerCase(); - return !node.disabled && node.name - && !dojo.lang.inArray(["file", "submit", "image", "reset", "button"], type); //boolean + //summary: Returns true if the node is an input element that is enabled, has + //a name, and whose type is one of the following values: ["file", "submit", "image", "reset", "button"] + var type = (node.type||"").toLowerCase(); + return !node.disabled && node.name + && !dojo.lang.inArray(["file", "submit", "image", "reset", "button"], type); //boolean } // TODO: Move to htmlUtils dojo.io.encodeForm = function(/*DOMNode*/formNode, /*String?*/encoding, /*Function?*/formFilter){ - //summary: Converts the names and values of form elements into an URL-encoded - //string (name=value&name=value...). - //formNode: DOMNode - //encoding: String? - // The encoding to use for the values. Specify a string that starts with - // "utf" (for instance, "utf8"), to use encodeURIComponent() as the encoding - // function. Otherwise, dojo.string.encodeAscii will be used. - //formFilter: Function? - // A function used to filter out form elements. The element node will be passed - // to the formFilter function, and a boolean result is expected (true indicating - // indicating that the element should have its name/value included in the output). - // If no formFilter is specified, then dojo.io.formFilter() will be used. - if((!formNode)||(!formNode.tagName)||(!formNode.tagName.toLowerCase() == "form")){ - dojo.raise("Attempted to encode a non-form element."); - } - if(!formFilter) { formFilter = dojo.io.formFilter; } - var enc = /utf/i.test(encoding||"") ? encodeURIComponent : dojo.string.encodeAscii; - var values = []; + //summary: Converts the names and values of form elements into an URL-encoded + //string (name=value&name=value...). + //formNode: DOMNode + //encoding: String? + // The encoding to use for the values. Specify a string that starts with + // "utf" (for instance, "utf8"), to use encodeURIComponent() as the encoding + // function. Otherwise, dojo.string.encodeAscii will be used. + //formFilter: Function? + // A function used to filter out form elements. The element node will be passed + // to the formFilter function, and a boolean result is expected (true indicating + // indicating that the element should have its name/value included in the output). + // If no formFilter is specified, then dojo.io.formFilter() will be used. + if((!formNode)||(!formNode.tagName)||(!formNode.tagName.toLowerCase() == "form")){ + dojo.raise("Attempted to encode a non-form element."); + } + if(!formFilter) { formFilter = dojo.io.formFilter; } + var enc = /utf/i.test(encoding||"") ? encodeURIComponent : dojo.string.encodeAscii; + var values = []; - for(var i = 0; i < formNode.elements.length; i++){ - var elm = formNode.elements[i]; - if(!elm || elm.tagName.toLowerCase() == "fieldset" || !formFilter(elm)) { continue; } - var name = enc(elm.name); - var type = elm.type.toLowerCase(); + for(var i = 0; i < formNode.elements.length; i++){ + var elm = formNode.elements[i]; + if(!elm || elm.tagName.toLowerCase() == "fieldset" || !formFilter(elm)) { continue; } + var name = enc(elm.name); + var type = elm.type.toLowerCase(); - if(type == "select-multiple"){ - for(var j = 0; j < elm.options.length; j++){ - if(elm.options[j].selected) { - values.push(name + "=" + enc(elm.options[j].value)); - } - } - }else if(dojo.lang.inArray(["radio", "checkbox"], type)){ - if(elm.checked){ - values.push(name + "=" + enc(elm.value)); - } - }else{ - values.push(name + "=" + enc(elm.value)); - } - } + if(type == "select-multiple"){ + for(var j = 0; j < elm.options.length; j++){ + if(elm.options[j].selected) { + values.push(name + "=" + enc(elm.options[j].value)); + } + } + }else if(dojo.lang.inArray(["radio", "checkbox"], type)){ + if(elm.checked){ + values.push(name + "=" + enc(elm.value)); + } + }else{ + values.push(name + "=" + enc(elm.value)); + } + } - // now collect input type="image", which doesn't show up in the elements array - var inputs = formNode.getElementsByTagName("input"); - for(var i = 0; i < inputs.length; i++) { - var input = inputs[i]; - if(input.type.toLowerCase() == "image" && input.form == formNode - && formFilter(input)) { - var name = enc(input.name); - values.push(name + "=" + enc(input.value)); - values.push(name + ".x=0"); - values.push(name + ".y=0"); - } - } - return values.join("&") + "&"; //String + // now collect input type="image", which doesn't show up in the elements array + var inputs = formNode.getElementsByTagName("input"); + for(var i = 0; i < inputs.length; i++) { + var input = inputs[i]; + if(input.type.toLowerCase() == "image" && input.form == formNode + && formFilter(input)) { + var name = enc(input.name); + values.push(name + "=" + enc(input.value)); + values.push(name + ".x=0"); + values.push(name + ".y=0"); + } + } + return values.join("&") + "&"; //String } dojo.io.FormBind = function(/*DOMNode or Object*/args) { - //summary: constructor for a dojo.io.FormBind object. See the Dojo Book for - //some information on usage: http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book23 - //args: DOMNode or Object - // args can either be the DOMNode for a form element, or an object containing - // dojo.io.bind() arguments, one of which should be formNode with the value of - // a form element DOMNode. - this.bindArgs = {}; + //summary: constructor for a dojo.io.FormBind object. See the Dojo Book for + //some information on usage: http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book23 + //args: DOMNode or Object + // args can either be the DOMNode for a form element, or an object containing + // dojo.io.bind() arguments, one of which should be formNode with the value of + // a form element DOMNode. + this.bindArgs = {}; - if(args && args.formNode) { - this.init(args); - } else if(args) { - this.init({formNode: args}); - } + if(args && args.formNode) { + this.init(args); + } else if(args) { + this.init({formNode: args}); + } } dojo.lang.extend(dojo.io.FormBind, { - form: null, + form: null, - bindArgs: null, + bindArgs: null, - clickedButton: null, + clickedButton: null, - init: function(/*DOMNode or Object*/args) { - //summary: Internal function called by the dojo.io.FormBind() constructor - //do not call this method directly. - var form = dojo.byId(args.formNode); + init: function(/*DOMNode or Object*/args) { + //summary: Internal function called by the dojo.io.FormBind() constructor + //do not call this method directly. + var form = dojo.byId(args.formNode); - if(!form || !form.tagName || form.tagName.toLowerCase() != "form") { - throw new Error("FormBind: Couldn't apply, invalid form"); - } else if(this.form == form) { - return; - } else if(this.form) { - throw new Error("FormBind: Already applied to a form"); - } + if(!form || !form.tagName || form.tagName.toLowerCase() != "form") { + throw new Error("FormBind: Couldn't apply, invalid form"); + } else if(this.form == form) { + return; + } else if(this.form) { + throw new Error("FormBind: Already applied to a form"); + } - dojo.lang.mixin(this.bindArgs, args); - this.form = form; + dojo.lang.mixin(this.bindArgs, args); + this.form = form; - this.connect(form, "onsubmit", "submit"); + this.connect(form, "onsubmit", "submit"); - for(var i = 0; i < form.elements.length; i++) { - var node = form.elements[i]; - if(node && node.type && dojo.lang.inArray(["submit", "button"], node.type.toLowerCase())) { - this.connect(node, "onclick", "click"); - } - } + for(var i = 0; i < form.elements.length; i++) { + var node = form.elements[i]; + if(node && node.type && dojo.lang.inArray(["submit", "button"], node.type.toLowerCase())) { + this.connect(node, "onclick", "click"); + } + } - var inputs = form.getElementsByTagName("input"); - for(var i = 0; i < inputs.length; i++) { - var input = inputs[i]; - if(input.type.toLowerCase() == "image" && input.form == form) { - this.connect(input, "onclick", "click"); - } - } - }, + var inputs = form.getElementsByTagName("input"); + for(var i = 0; i < inputs.length; i++) { + var input = inputs[i]; + if(input.type.toLowerCase() == "image" && input.form == form) { + this.connect(input, "onclick", "click"); + } + } + }, - onSubmit: function(/*DOMNode*/form) { - //summary: Function used to verify that the form is OK to submit. - //Override this function if you want specific form validation done. - return true; //boolean - }, + onSubmit: function(/*DOMNode*/form) { + //summary: Function used to verify that the form is OK to submit. + //Override this function if you want specific form validation done. + return true; //boolean + }, - submit: function(/*Event*/e) { - //summary: internal function that is connected as a listener to the - //form's onsubmit event. - e.preventDefault(); - if(this.onSubmit(this.form)) { - dojo.io.bind(dojo.lang.mixin(this.bindArgs, { - formFilter: dojo.lang.hitch(this, "formFilter") - })); - } - }, + submit: function(/*Event*/e) { + //summary: internal function that is connected as a listener to the + //form's onsubmit event. + e.preventDefault(); + if(this.onSubmit(this.form)) { + dojo.io.bind(dojo.lang.mixin(this.bindArgs, { + formFilter: dojo.lang.hitch(this, "formFilter") + })); + } + }, - click: function(/*Event*/e) { - //summary: internal method that is connected as a listener to the - //form's elements whose click event can submit a form. - var node = e.currentTarget; - if(node.disabled) { return; } - this.clickedButton = node; - }, + click: function(/*Event*/e) { + //summary: internal method that is connected as a listener to the + //form's elements whose click event can submit a form. + var node = e.currentTarget; + if(node.disabled) { return; } + this.clickedButton = node; + }, - formFilter: function(/*DOMNode*/node) { - //summary: internal function used to know which form element values to include - // in the dojo.io.bind() request. - var type = (node.type||"").toLowerCase(); - var accept = false; - if(node.disabled || !node.name) { - accept = false; - } else if(dojo.lang.inArray(["submit", "button", "image"], type)) { - if(!this.clickedButton) { this.clickedButton = node; } - accept = node == this.clickedButton; - } else { - accept = !dojo.lang.inArray(["file", "submit", "reset", "button"], type); - } - return accept; //boolean - }, + formFilter: function(/*DOMNode*/node) { + //summary: internal function used to know which form element values to include + // in the dojo.io.bind() request. + var type = (node.type||"").toLowerCase(); + var accept = false; + if(node.disabled || !node.name) { + accept = false; + } else if(dojo.lang.inArray(["submit", "button", "image"], type)) { + if(!this.clickedButton) { this.clickedButton = node; } + accept = node == this.clickedButton; + } else { + accept = !dojo.lang.inArray(["file", "submit", "reset", "button"], type); + } + return accept; //boolean + }, - // in case you don't have dojo.event.* pulled in - connect: function(/*Object*/srcObj, /*Function*/srcFcn, /*Function*/targetFcn) { - //summary: internal function used to connect event listeners to form elements - //that trigger events. Used in case dojo.event is not loaded. - if(dojo.evalObjPath("dojo.event.connect")) { - dojo.event.connect(srcObj, srcFcn, this, targetFcn); - } else { - var fcn = dojo.lang.hitch(this, targetFcn); - srcObj[srcFcn] = function(e) { - if(!e) { e = window.event; } - if(!e.currentTarget) { e.currentTarget = e.srcElement; } - if(!e.preventDefault) { e.preventDefault = function() { window.event.returnValue = false; } } - fcn(e); - } - } - } + // in case you don't have dojo.event.* pulled in + connect: function(/*Object*/srcObj, /*Function*/srcFcn, /*Function*/targetFcn) { + //summary: internal function used to connect event listeners to form elements + //that trigger events. Used in case dojo.event is not loaded. + if(dojo.evalObjPath("dojo.event.connect")) { + dojo.event.connect(srcObj, srcFcn, this, targetFcn); + } else { + var fcn = dojo.lang.hitch(this, targetFcn); + srcObj[srcFcn] = function(e) { + if(!e) { e = window.event; } + if(!e.currentTarget) { e.currentTarget = e.srcElement; } + if(!e.preventDefault) { e.preventDefault = function() { window.event.returnValue = false; } } + fcn(e); + } + } + } }); dojo.io.XMLHTTPTransport = new function(){ - //summary: The object that implements the dojo.io.bind transport for XMLHttpRequest. - var _this = this; + //summary: The object that implements the dojo.io.bind transport for XMLHttpRequest. + var _this = this; - var _cache = {}; // FIXME: make this public? do we even need to? - this.useCache = false; // if this is true, we'll cache unless kwArgs.useCache = false - this.preventCache = false; // if this is true, we'll always force GET requests to cache + var _cache = {}; // FIXME: make this public? do we even need to? + this.useCache = false; // if this is true, we'll cache unless kwArgs.useCache = false + this.preventCache = false; // if this is true, we'll always force GET requests to cache - // FIXME: Should this even be a function? or do we just hard code it in the next 2 functions? - function getCacheKey(url, query, method) { - return url + "|" + query + "|" + method.toLowerCase(); - } + // FIXME: Should this even be a function? or do we just hard code it in the next 2 functions? + function getCacheKey(url, query, method) { + return url + "|" + query + "|" + method.toLowerCase(); + } - function addToCache(url, query, method, http) { - _cache[getCacheKey(url, query, method)] = http; - } + function addToCache(url, query, method, http) { + _cache[getCacheKey(url, query, method)] = http; + } - function getFromCache(url, query, method) { - return _cache[getCacheKey(url, query, method)]; - } + function getFromCache(url, query, method) { + return _cache[getCacheKey(url, query, method)]; + } - this.clearCache = function() { - _cache = {}; - } + this.clearCache = function() { + _cache = {}; + } - // moved successful load stuff here - function doLoad(kwArgs, http, url, query, useCache) { - if( ((http.status>=200)&&(http.status<300))|| // allow any 2XX response code - (http.status==304)|| // get it out of the cache - (http.status==1223)|| // Internet Explorer mangled the status code - (location.protocol=="file:" && (http.status==0 || http.status==undefined))|| - (location.protocol=="chrome:" && (http.status==0 || http.status==undefined)) - ){ - var ret; - if(kwArgs.method.toLowerCase() == "head"){ - var headers = http.getAllResponseHeaders(); - ret = {}; - ret.toString = function(){ return headers; } - var values = headers.split(/[\r\n]+/g); - for(var i = 0; i < values.length; i++) { - var pair = values[i].match(/^([^:]+)\s*:\s*(.+)$/i); - if(pair) { - ret[pair[1]] = pair[2]; - } - } - }else if(kwArgs.mimetype == "text/javascript"){ - try{ - ret = dj_eval(http.responseText); - }catch(e){ - dojo.debug(e); - dojo.debug(http.responseText); - ret = null; - } - }else if(kwArgs.mimetype.substr(0, 9) == "text/json" || kwArgs.mimetype.substr(0, 16) == "application/json"){ - try{ - ret = dj_eval("("+kwArgs.jsonFilter(http.responseText)+")"); - }catch(e){ - dojo.debug(e); - dojo.debug(http.responseText); - ret = false; - } - }else if((kwArgs.mimetype == "application/xml")|| - (kwArgs.mimetype == "text/xml")){ - ret = http.responseXML; - if(!ret || typeof ret == "string" || !http.getResponseHeader("Content-Type")) { - ret = dojo.dom.createDocumentFromText(http.responseText); - } - }else{ - ret = http.responseText; - } + // moved successful load stuff here + function doLoad(kwArgs, http, url, query, useCache) { + if( ((http.status>=200)&&(http.status<300))|| // allow any 2XX response code + (http.status==304)|| // get it out of the cache + (http.status==1223)|| // Internet Explorer mangled the status code + (location.protocol=="file:" && (http.status==0 || http.status==undefined))|| + (location.protocol=="chrome:" && (http.status==0 || http.status==undefined)) + ){ + var ret; + if(kwArgs.method.toLowerCase() == "head"){ + var headers = http.getAllResponseHeaders(); + ret = {}; + ret.toString = function(){ return headers; } + var values = headers.split(/[\r\n]+/g); + for(var i = 0; i < values.length; i++) { + var pair = values[i].match(/^([^:]+)\s*:\s*(.+)$/i); + if(pair) { + ret[pair[1]] = pair[2]; + } + } + }else if(kwArgs.mimetype == "text/javascript"){ + try{ + ret = dj_eval(http.responseText); + }catch(e){ + dojo.debug(e); + dojo.debug(http.responseText); + ret = null; + } + }else if(kwArgs.mimetype.substr(0, 9) == "text/json" || kwArgs.mimetype.substr(0, 16) == "application/json"){ + try{ + ret = dj_eval("("+kwArgs.jsonFilter(http.responseText)+")"); + }catch(e){ + dojo.debug(e); + dojo.debug(http.responseText); + ret = false; + } + }else if((kwArgs.mimetype == "application/xml")|| + (kwArgs.mimetype == "text/xml")){ + ret = http.responseXML; + if(!ret || typeof ret == "string" || !http.getResponseHeader("Content-Type")) { + ret = dojo.dom.createDocumentFromText(http.responseText); + } + }else{ + ret = http.responseText; + } - if(useCache){ // only cache successful responses - addToCache(url, query, kwArgs.method, http); - } - kwArgs[(typeof kwArgs.load == "function") ? "load" : "handle"]("load", ret, http, kwArgs); - }else{ - var errObj = new dojo.io.Error("XMLHttpTransport Error: "+http.status+" "+http.statusText); - kwArgs[(typeof kwArgs.error == "function") ? "error" : "handle"]("error", errObj, http, kwArgs); - } - } + if(useCache){ // only cache successful responses + addToCache(url, query, kwArgs.method, http); + } + kwArgs[(typeof kwArgs.load == "function") ? "load" : "handle"]("load", ret, http, kwArgs); + }else{ + var errObj = new dojo.io.Error("XMLHttpTransport Error: "+http.status+" "+http.statusText); + kwArgs[(typeof kwArgs.error == "function") ? "error" : "handle"]("error", errObj, http, kwArgs); + } + } - // set headers (note: Content-Type will get overriden if kwArgs.contentType is set) - function setHeaders(http, kwArgs){ - if(kwArgs["headers"]) { - for(var header in kwArgs["headers"]) { - if(header.toLowerCase() == "content-type" && !kwArgs["contentType"]) { - kwArgs["contentType"] = kwArgs["headers"][header]; - } else { - http.setRequestHeader(header, kwArgs["headers"][header]); - } - } - } - } + // set headers (note: Content-Type will get overriden if kwArgs.contentType is set) + function setHeaders(http, kwArgs){ + if(kwArgs["headers"]) { + for(var header in kwArgs["headers"]) { + if(header.toLowerCase() == "content-type" && !kwArgs["contentType"]) { + kwArgs["contentType"] = kwArgs["headers"][header]; + } else { + http.setRequestHeader(header, kwArgs["headers"][header]); + } + } + } + } - this.inFlight = []; - this.inFlightTimer = null; + this.inFlight = []; + this.inFlightTimer = null; - this.startWatchingInFlight = function(){ - //summary: internal method used to trigger a timer to watch all inflight - //XMLHttpRequests. - if(!this.inFlightTimer){ - // setInterval broken in mozilla x86_64 in some circumstances, see - // https://bugzilla.mozilla.org/show_bug.cgi?id=344439 - // using setTimeout instead - this.inFlightTimer = setTimeout("dojo.io.XMLHTTPTransport.watchInFlight();", 10); - } - } + this.startWatchingInFlight = function(){ + //summary: internal method used to trigger a timer to watch all inflight + //XMLHttpRequests. + if(!this.inFlightTimer){ + // setInterval broken in mozilla x86_64 in some circumstances, see + // https://bugzilla.mozilla.org/show_bug.cgi?id=344439 + // using setTimeout instead + this.inFlightTimer = setTimeout("dojo.io.XMLHTTPTransport.watchInFlight();", 10); + } + } - this.watchInFlight = function(){ - //summary: internal method that checks each inflight XMLHttpRequest to see - //if it has completed or if the timeout situation applies. - var now = null; - // make sure sync calls stay thread safe, if this callback is called during a sync call - // and this results in another sync call before the first sync call ends the browser hangs - if(!dojo.hostenv._blockAsync && !_this._blockAsync){ - for(var x=this.inFlight.length-1; x>=0; x--){ - try{ - var tif = this.inFlight[x]; - if(!tif || tif.http._aborted || !tif.http.readyState){ - this.inFlight.splice(x, 1); continue; - } - if(4==tif.http.readyState){ - // remove it so we can clean refs - this.inFlight.splice(x, 1); - doLoad(tif.req, tif.http, tif.url, tif.query, tif.useCache); - }else if (tif.startTime){ - //See if this is a timeout case. - if(!now){ - now = (new Date()).getTime(); - } - if(tif.startTime + (tif.req.timeoutSeconds * 1000) < now){ - //Stop the request. - if(typeof tif.http.abort == "function"){ - tif.http.abort(); - } + this.watchInFlight = function(){ + //summary: internal method that checks each inflight XMLHttpRequest to see + //if it has completed or if the timeout situation applies. + var now = null; + // make sure sync calls stay thread safe, if this callback is called during a sync call + // and this results in another sync call before the first sync call ends the browser hangs + if(!dojo.hostenv._blockAsync && !_this._blockAsync){ + for(var x=this.inFlight.length-1; x>=0; x--){ + try{ + var tif = this.inFlight[x]; + if(!tif || tif.http._aborted || !tif.http.readyState){ + this.inFlight.splice(x, 1); continue; + } + if(4==tif.http.readyState){ + // remove it so we can clean refs + this.inFlight.splice(x, 1); + doLoad(tif.req, tif.http, tif.url, tif.query, tif.useCache); + }else if (tif.startTime){ + //See if this is a timeout case. + if(!now){ + now = (new Date()).getTime(); + } + if(tif.startTime + (tif.req.timeoutSeconds * 1000) < now){ + //Stop the request. + if(typeof tif.http.abort == "function"){ + tif.http.abort(); + } + + // remove it so we can clean refs + this.inFlight.splice(x, 1); + tif.req[(typeof tif.req.timeout == "function") ? "timeout" : "handle"]("timeout", null, tif.http, tif.req); + } + } + }catch(e){ + try{ + var errObj = new dojo.io.Error("XMLHttpTransport.watchInFlight Error: " + e); + tif.req[(typeof tif.req.error == "function") ? "error" : "handle"]("error", errObj, tif.http, tif.req); + }catch(e2){ + dojo.debug("XMLHttpTransport error callback failed: " + e2); + } + } + } + } - // remove it so we can clean refs - this.inFlight.splice(x, 1); - tif.req[(typeof tif.req.timeout == "function") ? "timeout" : "handle"]("timeout", null, tif.http, tif.req); - } - } - }catch(e){ - try{ - var errObj = new dojo.io.Error("XMLHttpTransport.watchInFlight Error: " + e); - tif.req[(typeof tif.req.error == "function") ? "error" : "handle"]("error", errObj, tif.http, tif.req); - }catch(e2){ - dojo.debug("XMLHttpTransport error callback failed: " + e2); - } - } - } - } + clearTimeout(this.inFlightTimer); + if(this.inFlight.length == 0){ + this.inFlightTimer = null; + return; + } + this.inFlightTimer = setTimeout("dojo.io.XMLHTTPTransport.watchInFlight();", 10); + } - clearTimeout(this.inFlightTimer); - if(this.inFlight.length == 0){ - this.inFlightTimer = null; - return; - } - this.inFlightTimer = setTimeout("dojo.io.XMLHTTPTransport.watchInFlight();", 10); - } + var hasXmlHttp = dojo.hostenv.getXmlhttpObject() ? true : false; + this.canHandle = function(/*dojo.io.Request*/kwArgs){ + //summary: Tells dojo.io.bind() if this is a good transport to + //use for the particular type of request. This type of transport cannot + //handle forms that have an input type="file" element. - var hasXmlHttp = dojo.hostenv.getXmlhttpObject() ? true : false; - this.canHandle = function(/*dojo.io.Request*/kwArgs){ - //summary: Tells dojo.io.bind() if this is a good transport to - //use for the particular type of request. This type of transport cannot - //handle forms that have an input type="file" element. + // FIXME: we need to determine when form values need to be + // multi-part mime encoded and avoid using this transport for those + // requests. + var mlc = kwArgs["mimetype"].toLowerCase()||""; + return hasXmlHttp + && ( + ( + dojo.lang.inArray([ + "text/plain", "text/html", "application/xml", + "text/xml", "text/javascript" + ], mlc + ) + ) || ( + mlc.substr(0, 9) == "text/json" || mlc.substr(0, 16) == "application/json" + ) + ) + && !( kwArgs["formNode"] && dojo.io.formHasFile(kwArgs["formNode"]) ); //boolean + } - // FIXME: we need to determine when form values need to be - // multi-part mime encoded and avoid using this transport for those - // requests. - var mlc = kwArgs["mimetype"].toLowerCase()||""; - return hasXmlHttp - && ( - ( - dojo.lang.inArray([ - "text/plain", "text/html", "application/xml", - "text/xml", "text/javascript" - ], mlc - ) - ) || ( - mlc.substr(0, 9) == "text/json" || mlc.substr(0, 16) == "application/json" - ) - ) - && !( kwArgs["formNode"] && dojo.io.formHasFile(kwArgs["formNode"]) ); //boolean - } + this.multipartBoundary = "45309FFF-BD65-4d50-99C9-36986896A96F"; // unique guid as a boundary value for multipart posts - this.multipartBoundary = "45309FFF-BD65-4d50-99C9-36986896A96F"; // unique guid as a boundary value for multipart posts + this.bind = function(/*dojo.io.Request*/kwArgs){ + //summary: function that sends the request to the server. - this.bind = function(/*dojo.io.Request*/kwArgs){ - //summary: function that sends the request to the server. - - //This function will attach an abort() function to the kwArgs dojo.io.Request object, - //so if you need to abort the request, you can call that method on the request object. - //The following are acceptable properties in kwArgs (in addition to the - //normal dojo.io.Request object properties). - //url: String: URL the server URL to use for the request. - //method: String: the HTTP method to use (GET, POST, etc...). - //mimetype: Specifies what format the result data should be given to the load/handle callback. Valid values are: - // text/javascript, text/json, application/json, application/xml, text/xml. Any other mimetype will give back a text - // string. - //transport: String: specify "XMLHTTPTransport" to force the use of this XMLHttpRequest transport. - //headers: Object: The object property names and values will be sent as HTTP request header - // names and values. - //sendTransport: boolean: If true, then dojo.transport=xmlhttp will be added to the request. - //encoding: String: The type of encoding to use when dealing with the content kwArgs property. - //content: Object: The content object is converted into a name=value&name=value string, by - // using dojo.io.argsFromMap(). The encoding kwArgs property is passed to dojo.io.argsFromMap() - // for use in encoding the names and values. The resulting string is added to the request. - //formNode: DOMNode: a form element node. This should not normally be used. Use new dojo.io.FormBind() instead. - // If formNode is used, then the names and values of the form elements will be converted - // to a name=value&name=value string and added to the request. The encoding kwArgs property is used - // to encode the names and values. - //postContent: String: Raw name=value&name=value string to be included as part of the request. - //back or backButton: Function: A function to be called if the back button is pressed. If this kwArgs property - // is used, then back button support via dojo.undo.browser will be used. See notes for dojo.undo.browser on usage. - // You need to set djConfig.preventBackButtonFix = false to enable back button support. - //changeUrl: boolean or String: Used as part of back button support. See notes for dojo.undo.browser on usage. - //user: String: The user name. Used in conjuction with password. Passed to XMLHttpRequest.open(). - //password: String: The user's password. Used in conjuction with user. Passed to XMLHttpRequest.open(). - //file: Object or Array of Objects: an object simulating a file to be uploaded. file objects should have the following properties: - // name or fileName: the name of the file - // contentType: the MIME content type for the file. - // content: the actual content of the file. - //multipart: boolean: indicates whether this should be a multipart mime request. If kwArgs.file exists, then this - // property is set to true automatically. - //sync: boolean: if true, then a synchronous XMLHttpRequest call is done, - // if false (the default), then an asynchronous call is used. - //preventCache: boolean: If true, then a cache busting parameter is added to the request URL. - // default value is false. - //useCache: boolean: If true, then XMLHttpTransport will keep an internal cache of the server - // response and use that response if a similar request is done again. - // A similar request is one that has the same URL, query string and HTTP method value. - // default is false. - if(!kwArgs["url"]){ - // are we performing a history action? - if( !kwArgs["formNode"] - && (kwArgs["backButton"] || kwArgs["back"] || kwArgs["changeUrl"] || kwArgs["watchForURL"]) - && (!djConfig.preventBackButtonFix)) { + //This function will attach an abort() function to the kwArgs dojo.io.Request object, + //so if you need to abort the request, you can call that method on the request object. + //The following are acceptable properties in kwArgs (in addition to the + //normal dojo.io.Request object properties). + //url: String: URL the server URL to use for the request. + //method: String: the HTTP method to use (GET, POST, etc...). + //mimetype: Specifies what format the result data should be given to the load/handle callback. Valid values are: + // text/javascript, text/json, application/json, application/xml, text/xml. Any other mimetype will give back a text + // string. + //transport: String: specify "XMLHTTPTransport" to force the use of this XMLHttpRequest transport. + //headers: Object: The object property names and values will be sent as HTTP request header + // names and values. + //sendTransport: boolean: If true, then dojo.transport=xmlhttp will be added to the request. + //encoding: String: The type of encoding to use when dealing with the content kwArgs property. + //content: Object: The content object is converted into a name=value&name=value string, by + // using dojo.io.argsFromMap(). The encoding kwArgs property is passed to dojo.io.argsFromMap() + // for use in encoding the names and values. The resulting string is added to the request. + //formNode: DOMNode: a form element node. This should not normally be used. Use new dojo.io.FormBind() instead. + // If formNode is used, then the names and values of the form elements will be converted + // to a name=value&name=value string and added to the request. The encoding kwArgs property is used + // to encode the names and values. + //postContent: String: Raw name=value&name=value string to be included as part of the request. + //back or backButton: Function: A function to be called if the back button is pressed. If this kwArgs property + // is used, then back button support via dojo.undo.browser will be used. See notes for dojo.undo.browser on usage. + // You need to set djConfig.preventBackButtonFix = false to enable back button support. + //changeUrl: boolean or String: Used as part of back button support. See notes for dojo.undo.browser on usage. + //user: String: The user name. Used in conjuction with password. Passed to XMLHttpRequest.open(). + //password: String: The user's password. Used in conjuction with user. Passed to XMLHttpRequest.open(). + //file: Object or Array of Objects: an object simulating a file to be uploaded. file objects should have the following properties: + // name or fileName: the name of the file + // contentType: the MIME content type for the file. + // content: the actual content of the file. + //multipart: boolean: indicates whether this should be a multipart mime request. If kwArgs.file exists, then this + // property is set to true automatically. + //sync: boolean: if true, then a synchronous XMLHttpRequest call is done, + // if false (the default), then an asynchronous call is used. + //preventCache: boolean: If true, then a cache busting parameter is added to the request URL. + // default value is false. + //useCache: boolean: If true, then XMLHttpTransport will keep an internal cache of the server + // response and use that response if a similar request is done again. + // A similar request is one that has the same URL, query string and HTTP method value. + // default is false. + if(!kwArgs["url"]){ + // are we performing a history action? + if( !kwArgs["formNode"] + && (kwArgs["backButton"] || kwArgs["back"] || kwArgs["changeUrl"] || kwArgs["watchForURL"]) + && (!djConfig.preventBackButtonFix)) { dojo.deprecated("Using dojo.io.XMLHTTPTransport.bind() to add to browser history without doing an IO request", - "Use dojo.undo.browser.addToHistory() instead.", "0.4"); - dojo.undo.browser.addToHistory(kwArgs); - return true; - } - } + "Use dojo.undo.browser.addToHistory() instead.", "0.4"); + dojo.undo.browser.addToHistory(kwArgs); + return true; + } + } - // build this first for cache purposes - var url = kwArgs.url; - var query = ""; - if(kwArgs["formNode"]){ - var ta = kwArgs.formNode.getAttribute("action"); - if((ta)&&(!kwArgs["url"])){ url = ta; } - var tp = kwArgs.formNode.getAttribute("method"); - if((tp)&&(!kwArgs["method"])){ kwArgs.method = tp; } - query += dojo.io.encodeForm(kwArgs.formNode, kwArgs.encoding, kwArgs["formFilter"]); - } + // build this first for cache purposes + var url = kwArgs.url; + var query = ""; + if(kwArgs["formNode"]){ + var ta = kwArgs.formNode.getAttribute("action"); + if((ta)&&(!kwArgs["url"])){ url = ta; } + var tp = kwArgs.formNode.getAttribute("method"); + if((tp)&&(!kwArgs["method"])){ kwArgs.method = tp; } + query += dojo.io.encodeForm(kwArgs.formNode, kwArgs.encoding, kwArgs["formFilter"]); + } - if(url.indexOf("#") > -1) { - dojo.debug("Warning: dojo.io.bind: stripping hash values from url:", url); - url = url.split("#")[0]; - } + if(url.indexOf("#") > -1) { + dojo.debug("Warning: dojo.io.bind: stripping hash values from url:", url); + url = url.split("#")[0]; + } - if(kwArgs["file"]){ - // force post for file transfer - kwArgs.method = "post"; - } + if(kwArgs["file"]){ + // force post for file transfer + kwArgs.method = "post"; + } - if(!kwArgs["method"]){ - kwArgs.method = "get"; - } + if(!kwArgs["method"]){ + kwArgs.method = "get"; + } - // guess the multipart value - if(kwArgs.method.toLowerCase() == "get"){ - // GET cannot use multipart - kwArgs.multipart = false; - }else{ - if(kwArgs["file"]){ - // enforce multipart when sending files - kwArgs.multipart = true; - }else if(!kwArgs["multipart"]){ - // default - kwArgs.multipart = false; - } - } + // guess the multipart value + if(kwArgs.method.toLowerCase() == "get"){ + // GET cannot use multipart + kwArgs.multipart = false; + }else{ + if(kwArgs["file"]){ + // enforce multipart when sending files + kwArgs.multipart = true; + }else if(!kwArgs["multipart"]){ + // default + kwArgs.multipart = false; + } + } - if(kwArgs["backButton"] || kwArgs["back"] || kwArgs["changeUrl"]){ - dojo.undo.browser.addToHistory(kwArgs); - } + if(kwArgs["backButton"] || kwArgs["back"] || kwArgs["changeUrl"]){ + dojo.undo.browser.addToHistory(kwArgs); + } - var content = kwArgs["content"] || {}; + var content = kwArgs["content"] || {}; - if(kwArgs.sendTransport) { - content["dojo.transport"] = "xmlhttp"; - } + if(kwArgs.sendTransport) { + content["dojo.transport"] = "xmlhttp"; + } - do { // break-block - if(kwArgs.postContent){ - query = kwArgs.postContent; - break; - } + do { // break-block + if(kwArgs.postContent){ + query = kwArgs.postContent; + break; + } - if(content) { - query += dojo.io.argsFromMap(content, kwArgs.encoding); - } + if(content) { + query += dojo.io.argsFromMap(content, kwArgs.encoding); + } + + if(kwArgs.method.toLowerCase() == "get" || !kwArgs.multipart){ + break; + } - if(kwArgs.method.toLowerCase() == "get" || !kwArgs.multipart){ - break; - } + var t = []; + if(query.length){ + var q = query.split("&"); + for(var i = 0; i < q.length; ++i){ + if(q[i].length){ + var p = q[i].split("="); + t.push( "--" + this.multipartBoundary, + "Content-Disposition: form-data; name=\"" + p[0] + "\"", + "", + p[1]); + } + } + } - var t = []; - if(query.length){ - var q = query.split("&"); - for(var i = 0; i < q.length; ++i){ - if(q[i].length){ - var p = q[i].split("="); - t.push( "--" + this.multipartBoundary, - "Content-Disposition: form-data; name=\"" + p[0] + "\"", - "", - p[1]); - } - } - } + if(kwArgs.file){ + if(dojo.lang.isArray(kwArgs.file)){ + for(var i = 0; i < kwArgs.file.length; ++i){ + var o = kwArgs.file[i]; + t.push( "--" + this.multipartBoundary, + "Content-Disposition: form-data; name=\"" + o.name + "\"; filename=\"" + ("fileName" in o ? o.fileName : o.name) + "\"", + "Content-Type: " + ("contentType" in o ? o.contentType : "application/octet-stream"), + "", + o.content); + } + }else{ + var o = kwArgs.file; + t.push( "--" + this.multipartBoundary, + "Content-Disposition: form-data; name=\"" + o.name + "\"; filename=\"" + ("fileName" in o ? o.fileName : o.name) + "\"", + "Content-Type: " + ("contentType" in o ? o.contentType : "application/octet-stream"), + "", + o.content); + } + } - if(kwArgs.file){ - if(dojo.lang.isArray(kwArgs.file)){ - for(var i = 0; i < kwArgs.file.length; ++i){ - var o = kwArgs.file[i]; - t.push( "--" + this.multipartBoundary, - "Content-Disposition: form-data; name=\"" + o.name + "\"; filename=\"" + ("fileName" in o ? o.fileName : o.name) + "\"", - "Content-Type: " + ("contentType" in o ? o.contentType : "application/octet-stream"), - "", - o.content); - } - }else{ - var o = kwArgs.file; - t.push( "--" + this.multipartBoundary, - "Content-Disposition: form-data; name=\"" + o.name + "\"; filename=\"" + ("fileName" in o ? o.fileName : o.name) + "\"", - "Content-Type: " + ("contentType" in o ? o.contentType : "application/octet-stream"), - "", - o.content); - } - } + if(t.length){ + t.push("--"+this.multipartBoundary+"--", ""); + query = t.join("\r\n"); + } + }while(false); - if(t.length){ - t.push("--"+this.multipartBoundary+"--", ""); - query = t.join("\r\n"); - } - }while(false); + // kwArgs.Connection = "close"; - // kwArgs.Connection = "close"; + var async = kwArgs["sync"] ? false : true; - var async = kwArgs["sync"] ? false : true; + var preventCache = kwArgs["preventCache"] || + (this.preventCache == true && kwArgs["preventCache"] != false); + var useCache = kwArgs["useCache"] == true || + (this.useCache == true && kwArgs["useCache"] != false ); - var preventCache = kwArgs["preventCache"] || - (this.preventCache == true && kwArgs["preventCache"] != false); - var useCache = kwArgs["useCache"] == true || - (this.useCache == true && kwArgs["useCache"] != false ); + // preventCache is browser-level (add query string junk), useCache + // is for the local cache. If we say preventCache, then don't attempt + // to look in the cache, but if useCache is true, we still want to cache + // the response + if(!preventCache && useCache){ + var cachedHttp = getFromCache(url, query, kwArgs.method); + if(cachedHttp){ + doLoad(kwArgs, cachedHttp, url, query, false); + return; + } + } - // preventCache is browser-level (add query string junk), useCache - // is for the local cache. If we say preventCache, then don't attempt - // to look in the cache, but if useCache is true, we still want to cache - // the response - if(!preventCache && useCache){ - var cachedHttp = getFromCache(url, query, kwArgs.method); - if(cachedHttp){ - doLoad(kwArgs, cachedHttp, url, query, false); - return; - } - } + // much of this is from getText, but reproduced here because we need + // more flexibility + var http = dojo.hostenv.getXmlhttpObject(kwArgs); + var received = false; - // much of this is from getText, but reproduced here because we need - // more flexibility - var http = dojo.hostenv.getXmlhttpObject(kwArgs); - var received = false; + // build a handler function that calls back to the handler obj + if(async){ + var startTime = + // FIXME: setting up this callback handler leaks on IE!!! + this.inFlight.push({ + "req": kwArgs, + "http": http, + "url": url, + "query": query, + "useCache": useCache, + "startTime": kwArgs.timeoutSeconds ? (new Date()).getTime() : 0 + }); + this.startWatchingInFlight(); + }else{ + // block async callbacks until sync is in, needed in khtml, others? + _this._blockAsync = true; + } - // build a handler function that calls back to the handler obj - if(async){ - var startTime = - // FIXME: setting up this callback handler leaks on IE!!! - this.inFlight.push({ - "req": kwArgs, - "http": http, - "url": url, - "query": query, - "useCache": useCache, - "startTime": kwArgs.timeoutSeconds ? (new Date()).getTime() : 0 - }); - this.startWatchingInFlight(); - }else{ - // block async callbacks until sync is in, needed in khtml, others? - _this._blockAsync = true; - } - - if(kwArgs.method.toLowerCase() == "post"){ - // FIXME: need to hack in more flexible Content-Type setting here! - if (!kwArgs.user) { - http.open("POST", url, async); - }else{ + if(kwArgs.method.toLowerCase() == "post"){ + // FIXME: need to hack in more flexible Content-Type setting here! + if (!kwArgs.user) { + http.open("POST", url, async); + }else{ http.open("POST", url, async, kwArgs.user, kwArgs.password); - } - setHeaders(http, kwArgs); - http.setRequestHeader("Content-Type", kwArgs.multipart ? ("multipart/form-data; boundary=" + this.multipartBoundary) : - (kwArgs.contentType || "application/x-www-form-urlencoded")); - try{ - http.send(query); - }catch(e){ - if(typeof http.abort == "function"){ - http.abort(); - } - doLoad(kwArgs, {status: 404}, url, query, useCache); - } - }else{ - var tmpUrl = url; - if(query != "") { - tmpUrl += (tmpUrl.indexOf("?") > -1 ? "&" : "?") + query; - } - if(preventCache) { - tmpUrl += (dojo.string.endsWithAny(tmpUrl, "?", "&") - ? "" : (tmpUrl.indexOf("?") > -1 ? "&" : "?")) + "dojo.preventCache=" + new Date().valueOf(); - } - if (!kwArgs.user) { - http.open(kwArgs.method.toUpperCase(), tmpUrl, async); - }else{ - http.open(kwArgs.method.toUpperCase(), tmpUrl, async, kwArgs.user, kwArgs.password); - } - setHeaders(http, kwArgs); - try { - http.send(null); - }catch(e) { - if(typeof http.abort == "function"){ - http.abort(); - } - doLoad(kwArgs, {status: 404}, url, query, useCache); - } - } + } + setHeaders(http, kwArgs); + http.setRequestHeader("Content-Type", kwArgs.multipart ? ("multipart/form-data; boundary=" + this.multipartBoundary) : + (kwArgs.contentType || "application/x-www-form-urlencoded")); + try{ + http.send(query); + }catch(e){ + if(typeof http.abort == "function"){ + http.abort(); + } + doLoad(kwArgs, {status: 404}, url, query, useCache); + } + }else{ + var tmpUrl = url; + if(query != "") { + tmpUrl += (tmpUrl.indexOf("?") > -1 ? "&" : "?") + query; + } + if(preventCache) { + tmpUrl += (dojo.string.endsWithAny(tmpUrl, "?", "&") + ? "" : (tmpUrl.indexOf("?") > -1 ? "&" : "?")) + "dojo.preventCache=" + new Date().valueOf(); + } + if (!kwArgs.user) { + http.open(kwArgs.method.toUpperCase(), tmpUrl, async); + }else{ + http.open(kwArgs.method.toUpperCase(), tmpUrl, async, kwArgs.user, kwArgs.password); + } + setHeaders(http, kwArgs); + try { + http.send(null); + }catch(e) { + if(typeof http.abort == "function"){ + http.abort(); + } + doLoad(kwArgs, {status: 404}, url, query, useCache); + } + } - if( !async ) { - doLoad(kwArgs, http, url, query, useCache); - _this._blockAsync = false; - } + if( !async ) { + doLoad(kwArgs, http, url, query, useCache); + _this._blockAsync = false; + } - kwArgs.abort = function(){ - try{// khtml doesent reset readyState on abort, need this workaround - http._aborted = true; - }catch(e){/*squelsh*/} - return http.abort(); - } + kwArgs.abort = function(){ + try{// khtml doesent reset readyState on abort, need this workaround + http._aborted = true; + }catch(e){/*squelsh*/} + return http.abort(); + } - return; - } - dojo.io.transports.addTransport("XMLHTTPTransport"); + return; + } + dojo.io.transports.addTransport("XMLHTTPTransport"); } } dojo.provide("dojo.io.cookie"); -dojo.io.cookie.setCookie = function(/*String*/name, /*String*/value, - /*Number?*/days, /*String?*/path, - /*String?*/domain, /*boolean?*/secure){ - //summary: sets a cookie. - var expires = -1; - if((typeof days == "number")&&(days >= 0)){ - var d = new Date(); - d.setTime(d.getTime()+(days*24*60*60*1000)); - expires = d.toGMTString(); - } - value = escape(value); - document.cookie = name + "=" + value + ";" - + (expires != -1 ? " expires=" + expires + ";" : "") - + (path ? "path=" + path : "") - + (domain ? "; domain=" + domain : "") - + (secure ? "; secure" : ""); +dojo.io.cookie.setCookie = function(/*String*/name, /*String*/value, + /*Number?*/days, /*String?*/path, + /*String?*/domain, /*boolean?*/secure){ + //summary: sets a cookie. + var expires = -1; + if((typeof days == "number")&&(days >= 0)){ + var d = new Date(); + d.setTime(d.getTime()+(days*24*60*60*1000)); + expires = d.toGMTString(); + } + value = escape(value); + document.cookie = name + "=" + value + ";" + + (expires != -1 ? " expires=" + expires + ";" : "") + + (path ? "path=" + path : "") + + (domain ? "; domain=" + domain : "") + + (secure ? "; secure" : ""); } dojo.io.cookie.set = dojo.io.cookie.setCookie; dojo.io.cookie.getCookie = function(/*String*/name){ - //summary: Gets a cookie with the given name. + //summary: Gets a cookie with the given name. - // FIXME: Which cookie should we return? - // If there are cookies set for different sub domains in the current - // scope there could be more than one cookie with the same name. - // I think taking the last one in the list takes the one from the - // deepest subdomain, which is what we're doing here. - var idx = document.cookie.lastIndexOf(name+'='); - if(idx == -1) { return null; } - var value = document.cookie.substring(idx+name.length+1); - var end = value.indexOf(';'); - if(end == -1) { end = value.length; } - value = value.substring(0, end); - value = unescape(value); - return value; //String + // FIXME: Which cookie should we return? + // If there are cookies set for different sub domains in the current + // scope there could be more than one cookie with the same name. + // I think taking the last one in the list takes the one from the + // deepest subdomain, which is what we're doing here. + var idx = document.cookie.lastIndexOf(name+'='); + if(idx == -1) { return null; } + var value = document.cookie.substring(idx+name.length+1); + var end = value.indexOf(';'); + if(end == -1) { end = value.length; } + value = value.substring(0, end); + value = unescape(value); + return value; //String } dojo.io.cookie.get = dojo.io.cookie.getCookie; dojo.io.cookie.deleteCookie = function(/*String*/name){ - //summary: Deletes a cookie with the given name. - dojo.io.cookie.setCookie(name, "-", 0); + //summary: Deletes a cookie with the given name. + dojo.io.cookie.setCookie(name, "-", 0); } -dojo.io.cookie.setObjectCookie = function( /*String*/name, /*Object*/obj, - /*Number?*/days, /*String?*/path, - /*String?*/domain, /*boolean?*/secure, - /*boolean?*/clearCurrent){ - //summary: Takes an object, serializes it to a cookie value, and either - //sets a cookie with the serialized value. - //description: If clearCurrent is true, then any current cookie value - //for this object will be replaced with the the new serialized object value. - //If clearCurrent is false, then the existing cookie value will be modified - //with any changes from the new object value. - //Objects must be simple name/value pairs where the value is either a string - //or a number. Any other value will be ignored. - if(arguments.length == 5){ // for backwards compat - clearCurrent = domain; - domain = null; - secure = null; - } - var pairs = [], cookie, value = ""; - if(!clearCurrent){ - cookie = dojo.io.cookie.getObjectCookie(name); - } - if(days >= 0){ - if(!cookie){ cookie = {}; } - for(var prop in obj){ - if(obj[prop] == null){ - delete cookie[prop]; - }else if((typeof obj[prop] == "string")||(typeof obj[prop] == "number")){ - cookie[prop] = obj[prop]; - } - } - prop = null; - for(var prop in cookie){ - pairs.push(escape(prop) + "=" + escape(cookie[prop])); - } - value = pairs.join("&"); - } - dojo.io.cookie.setCookie(name, value, days, path, domain, secure); +dojo.io.cookie.setObjectCookie = function( /*String*/name, /*Object*/obj, + /*Number?*/days, /*String?*/path, + /*String?*/domain, /*boolean?*/secure, + /*boolean?*/clearCurrent){ + //summary: Takes an object, serializes it to a cookie value, and either + //sets a cookie with the serialized value. + //description: If clearCurrent is true, then any current cookie value + //for this object will be replaced with the the new serialized object value. + //If clearCurrent is false, then the existing cookie value will be modified + //with any changes from the new object value. + //Objects must be simple name/value pairs where the value is either a string + //or a number. Any other value will be ignored. + if(arguments.length == 5){ // for backwards compat + clearCurrent = domain; + domain = null; + secure = null; + } + var pairs = [], cookie, value = ""; + if(!clearCurrent){ + cookie = dojo.io.cookie.getObjectCookie(name); + } + if(days >= 0){ + if(!cookie){ cookie = {}; } + for(var prop in obj){ + if(obj[prop] == null){ + delete cookie[prop]; + }else if((typeof obj[prop] == "string")||(typeof obj[prop] == "number")){ + cookie[prop] = obj[prop]; + } + } + prop = null; + for(var prop in cookie){ + pairs.push(escape(prop) + "=" + escape(cookie[prop])); + } + value = pairs.join("&"); + } + dojo.io.cookie.setCookie(name, value, days, path, domain, secure); } dojo.io.cookie.getObjectCookie = function(/*String*/name){ - //summary: Gets an object value for the given cookie name. The complement of - //dojo.io.cookie.setObjectCookie(). - var values = null, cookie = dojo.io.cookie.getCookie(name); - if(cookie){ - values = {}; - var pairs = cookie.split("&"); - for(var i = 0; i < pairs.length; i++){ - var pair = pairs[i].split("="); - var value = pair[1]; - if( isNaN(value) ){ value = unescape(pair[1]); } - values[ unescape(pair[0]) ] = value; - } - } - return values; + //summary: Gets an object value for the given cookie name. The complement of + //dojo.io.cookie.setObjectCookie(). + var values = null, cookie = dojo.io.cookie.getCookie(name); + if(cookie){ + values = {}; + var pairs = cookie.split("&"); + for(var i = 0; i < pairs.length; i++){ + var pair = pairs[i].split("="); + var value = pair[1]; + if( isNaN(value) ){ value = unescape(pair[1]); } + values[ unescape(pair[0]) ] = value; + } + } + return values; } dojo.io.cookie.isSupported = function(){ - //summary: Tests the browser to see if cookies are enabled. - if(typeof navigator.cookieEnabled != "boolean"){ - dojo.io.cookie.setCookie("__TestingYourBrowserForCookieSupport__", - "CookiesAllowed", 90, null); - var cookieVal = dojo.io.cookie.getCookie("__TestingYourBrowserForCookieSupport__"); - navigator.cookieEnabled = (cookieVal == "CookiesAllowed"); - if(navigator.cookieEnabled){ - // FIXME: should we leave this around? - this.deleteCookie("__TestingYourBrowserForCookieSupport__"); - } - } - return navigator.cookieEnabled; //boolean + //summary: Tests the browser to see if cookies are enabled. + if(typeof navigator.cookieEnabled != "boolean"){ + dojo.io.cookie.setCookie("__TestingYourBrowserForCookieSupport__", + "CookiesAllowed", 90, null); + var cookieVal = dojo.io.cookie.getCookie("__TestingYourBrowserForCookieSupport__"); + navigator.cookieEnabled = (cookieVal == "CookiesAllowed"); + if(navigator.cookieEnabled){ + // FIXME: should we leave this around? + this.deleteCookie("__TestingYourBrowserForCookieSupport__"); + } + } + return navigator.cookieEnabled; //boolean } // need to leave this in for backwards-compat from 0.1 for when it gets pulled in by dojo.io.* if(!dojo.io.cookies){ dojo.io.cookies = dojo.io.cookie; } dojo.kwCompoundRequire({ - common: ["dojo.io.common"], - rhino: ["dojo.io.RhinoIO"], - browser: ["dojo.io.BrowserIO", "dojo.io.cookie"], - dashboard: ["dojo.io.BrowserIO", "dojo.io.cookie"] + common: ["dojo.io.common"], + rhino: ["dojo.io.RhinoIO"], + browser: ["dojo.io.BrowserIO", "dojo.io.cookie"], + dashboard: ["dojo.io.BrowserIO", "dojo.io.cookie"] }); dojo.provide("dojo.io.*"); @@ -5069,1103 +5079,1103 @@ dojo.provide("dojo.event.common"); // TODO: connection filter functions -// these are functions that accept a method invocation (like around -// advice) and return a boolean based on it. That value determines -// whether or not the connection proceeds. It could "feel" like around -// advice for those who know what it is (calling proceed() or not), -// but I think presenting it as a "filter" and/or calling it with the -// function args and not the MethodInvocation might make it more -// palletable to "normal" users than around-advice currently is +// these are functions that accept a method invocation (like around +// advice) and return a boolean based on it. That value determines +// whether or not the connection proceeds. It could "feel" like around +// advice for those who know what it is (calling proceed() or not), +// but I think presenting it as a "filter" and/or calling it with the +// function args and not the MethodInvocation might make it more +// palletable to "normal" users than around-advice currently is // TODO: execution scope mangling -// YUI's event facility by default executes listeners in the context -// of the source object. This is very odd, but should probably be -// supported as an option (both for the source and for the dest). It -// can be thought of as a connection-specific hitch(). +// YUI's event facility by default executes listeners in the context +// of the source object. This is very odd, but should probably be +// supported as an option (both for the source and for the dest). It +// can be thought of as a connection-specific hitch(). // TODO: more resiliency for 4+ arguments to connect() dojo.event = new function(){ - this._canTimeout = dojo.lang.isFunction(dj_global["setTimeout"])||dojo.lang.isAlien(dj_global["setTimeout"]); + this._canTimeout = dojo.lang.isFunction(dj_global["setTimeout"])||dojo.lang.isAlien(dj_global["setTimeout"]); - // FIXME: where should we put this method (not here!)? - function interpolateArgs(args, searchForNames){ - var dl = dojo.lang; - var ao = { - srcObj: dj_global, - srcFunc: null, - adviceObj: dj_global, - adviceFunc: null, - aroundObj: null, - aroundFunc: null, - adviceType: (args.length>2) ? args[0] : "after", - precedence: "last", - once: false, - delay: null, - rate: 0, - adviceMsg: false, - maxCalls: -1 - }; + // FIXME: where should we put this method (not here!)? + function interpolateArgs(args, searchForNames){ + var dl = dojo.lang; + var ao = { + srcObj: dj_global, + srcFunc: null, + adviceObj: dj_global, + adviceFunc: null, + aroundObj: null, + aroundFunc: null, + adviceType: (args.length>2) ? args[0] : "after", + precedence: "last", + once: false, + delay: null, + rate: 0, + adviceMsg: false, + maxCalls: -1 + }; - switch(args.length){ - case 0: return; - case 1: return; - case 2: - ao.srcFunc = args[0]; - ao.adviceFunc = args[1]; - break; - case 3: - if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isString(args[2]))){ - ao.adviceType = "after"; - ao.srcObj = args[0]; - ao.srcFunc = args[1]; - ao.adviceFunc = args[2]; - }else if((dl.isString(args[1]))&&(dl.isString(args[2]))){ - ao.srcFunc = args[1]; - ao.adviceFunc = args[2]; - }else if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isFunction(args[2]))){ - ao.adviceType = "after"; - ao.srcObj = args[0]; - ao.srcFunc = args[1]; - var tmpName = dl.nameAnonFunc(args[2], ao.adviceObj, searchForNames); - ao.adviceFunc = tmpName; - }else if((dl.isFunction(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))){ - ao.adviceType = "after"; - ao.srcObj = dj_global; - var tmpName = dl.nameAnonFunc(args[0], ao.srcObj, searchForNames); - ao.srcFunc = tmpName; - ao.adviceObj = args[1]; - ao.adviceFunc = args[2]; - } - break; - case 4: - if((dl.isObject(args[0]))&&(dl.isObject(args[2]))){ - // we can assume that we've got an old-style "connect" from - // the sigslot school of event attachment. We therefore - // assume after-advice. - ao.adviceType = "after"; - ao.srcObj = args[0]; - ao.srcFunc = args[1]; - ao.adviceObj = args[2]; - ao.adviceFunc = args[3]; - }else if((dl.isString(args[0]))&&(dl.isString(args[1]))&&(dl.isObject(args[2]))){ - ao.adviceType = args[0]; - ao.srcObj = dj_global; - ao.srcFunc = args[1]; - ao.adviceObj = args[2]; - ao.adviceFunc = args[3]; - }else if((dl.isString(args[0]))&&(dl.isFunction(args[1]))&&(dl.isObject(args[2]))){ - ao.adviceType = args[0]; - ao.srcObj = dj_global; - var tmpName = dl.nameAnonFunc(args[1], dj_global, searchForNames); - ao.srcFunc = tmpName; - ao.adviceObj = args[2]; - ao.adviceFunc = args[3]; - }else if((dl.isString(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))&&(dl.isFunction(args[3]))){ - ao.srcObj = args[1]; - ao.srcFunc = args[2]; - var tmpName = dl.nameAnonFunc(args[3], dj_global, searchForNames); - ao.adviceObj = dj_global; - ao.adviceFunc = tmpName; - }else if(dl.isObject(args[1])){ - ao.srcObj = args[1]; - ao.srcFunc = args[2]; - ao.adviceObj = dj_global; - ao.adviceFunc = args[3]; - }else if(dl.isObject(args[2])){ - ao.srcObj = dj_global; - ao.srcFunc = args[1]; - ao.adviceObj = args[2]; - ao.adviceFunc = args[3]; - }else{ - ao.srcObj = ao.adviceObj = ao.aroundObj = dj_global; - ao.srcFunc = args[1]; - ao.adviceFunc = args[2]; - ao.aroundFunc = args[3]; - } - break; - case 6: - ao.srcObj = args[1]; - ao.srcFunc = args[2]; - ao.adviceObj = args[3] - ao.adviceFunc = args[4]; - ao.aroundFunc = args[5]; - ao.aroundObj = dj_global; - break; - default: - ao.srcObj = args[1]; - ao.srcFunc = args[2]; - ao.adviceObj = args[3] - ao.adviceFunc = args[4]; - ao.aroundObj = args[5]; - ao.aroundFunc = args[6]; - ao.once = args[7]; - ao.delay = args[8]; - ao.rate = args[9]; - ao.adviceMsg = args[10]; - ao.maxCalls = (!isNaN(parseInt(args[11]))) ? args[11] : -1; - break; - } + switch(args.length){ + case 0: return; + case 1: return; + case 2: + ao.srcFunc = args[0]; + ao.adviceFunc = args[1]; + break; + case 3: + if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isString(args[2]))){ + ao.adviceType = "after"; + ao.srcObj = args[0]; + ao.srcFunc = args[1]; + ao.adviceFunc = args[2]; + }else if((dl.isString(args[1]))&&(dl.isString(args[2]))){ + ao.srcFunc = args[1]; + ao.adviceFunc = args[2]; + }else if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isFunction(args[2]))){ + ao.adviceType = "after"; + ao.srcObj = args[0]; + ao.srcFunc = args[1]; + var tmpName = dl.nameAnonFunc(args[2], ao.adviceObj, searchForNames); + ao.adviceFunc = tmpName; + }else if((dl.isFunction(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))){ + ao.adviceType = "after"; + ao.srcObj = dj_global; + var tmpName = dl.nameAnonFunc(args[0], ao.srcObj, searchForNames); + ao.srcFunc = tmpName; + ao.adviceObj = args[1]; + ao.adviceFunc = args[2]; + } + break; + case 4: + if((dl.isObject(args[0]))&&(dl.isObject(args[2]))){ + // we can assume that we've got an old-style "connect" from + // the sigslot school of event attachment. We therefore + // assume after-advice. + ao.adviceType = "after"; + ao.srcObj = args[0]; + ao.srcFunc = args[1]; + ao.adviceObj = args[2]; + ao.adviceFunc = args[3]; + }else if((dl.isString(args[0]))&&(dl.isString(args[1]))&&(dl.isObject(args[2]))){ + ao.adviceType = args[0]; + ao.srcObj = dj_global; + ao.srcFunc = args[1]; + ao.adviceObj = args[2]; + ao.adviceFunc = args[3]; + }else if((dl.isString(args[0]))&&(dl.isFunction(args[1]))&&(dl.isObject(args[2]))){ + ao.adviceType = args[0]; + ao.srcObj = dj_global; + var tmpName = dl.nameAnonFunc(args[1], dj_global, searchForNames); + ao.srcFunc = tmpName; + ao.adviceObj = args[2]; + ao.adviceFunc = args[3]; + }else if((dl.isString(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))&&(dl.isFunction(args[3]))){ + ao.srcObj = args[1]; + ao.srcFunc = args[2]; + var tmpName = dl.nameAnonFunc(args[3], dj_global, searchForNames); + ao.adviceObj = dj_global; + ao.adviceFunc = tmpName; + }else if(dl.isObject(args[1])){ + ao.srcObj = args[1]; + ao.srcFunc = args[2]; + ao.adviceObj = dj_global; + ao.adviceFunc = args[3]; + }else if(dl.isObject(args[2])){ + ao.srcObj = dj_global; + ao.srcFunc = args[1]; + ao.adviceObj = args[2]; + ao.adviceFunc = args[3]; + }else{ + ao.srcObj = ao.adviceObj = ao.aroundObj = dj_global; + ao.srcFunc = args[1]; + ao.adviceFunc = args[2]; + ao.aroundFunc = args[3]; + } + break; + case 6: + ao.srcObj = args[1]; + ao.srcFunc = args[2]; + ao.adviceObj = args[3] + ao.adviceFunc = args[4]; + ao.aroundFunc = args[5]; + ao.aroundObj = dj_global; + break; + default: + ao.srcObj = args[1]; + ao.srcFunc = args[2]; + ao.adviceObj = args[3] + ao.adviceFunc = args[4]; + ao.aroundObj = args[5]; + ao.aroundFunc = args[6]; + ao.once = args[7]; + ao.delay = args[8]; + ao.rate = args[9]; + ao.adviceMsg = args[10]; + ao.maxCalls = (!isNaN(parseInt(args[11]))) ? args[11] : -1; + break; + } - if(dl.isFunction(ao.aroundFunc)){ - var tmpName = dl.nameAnonFunc(ao.aroundFunc, ao.aroundObj, searchForNames); - ao.aroundFunc = tmpName; - } + if(dl.isFunction(ao.aroundFunc)){ + var tmpName = dl.nameAnonFunc(ao.aroundFunc, ao.aroundObj, searchForNames); + ao.aroundFunc = tmpName; + } - if(dl.isFunction(ao.srcFunc)){ - ao.srcFunc = dl.getNameInObj(ao.srcObj, ao.srcFunc); - } + if(dl.isFunction(ao.srcFunc)){ + ao.srcFunc = dl.getNameInObj(ao.srcObj, ao.srcFunc); + } - if(dl.isFunction(ao.adviceFunc)){ - ao.adviceFunc = dl.getNameInObj(ao.adviceObj, ao.adviceFunc); - } + if(dl.isFunction(ao.adviceFunc)){ + ao.adviceFunc = dl.getNameInObj(ao.adviceObj, ao.adviceFunc); + } - if((ao.aroundObj)&&(dl.isFunction(ao.aroundFunc))){ - ao.aroundFunc = dl.getNameInObj(ao.aroundObj, ao.aroundFunc); - } + if((ao.aroundObj)&&(dl.isFunction(ao.aroundFunc))){ + ao.aroundFunc = dl.getNameInObj(ao.aroundObj, ao.aroundFunc); + } - if(!ao.srcObj){ - dojo.raise("bad srcObj for srcFunc: "+ao.srcFunc); - } - if(!ao.adviceObj){ - dojo.raise("bad adviceObj for adviceFunc: "+ao.adviceFunc); - } + if(!ao.srcObj){ + dojo.raise("bad srcObj for srcFunc: "+ao.srcFunc); + } + if(!ao.adviceObj){ + dojo.raise("bad adviceObj for adviceFunc: "+ao.adviceFunc); + } + + if(!ao.adviceFunc){ + dojo.debug("bad adviceFunc for srcFunc: "+ao.srcFunc); + dojo.debugShallow(ao); + } + + return ao; + } - if(!ao.adviceFunc){ - dojo.debug("bad adviceFunc for srcFunc: "+ao.srcFunc); - dojo.debugShallow(ao); - } + this.connect = function(/*...*/){ + // summary: + // dojo.event.connect is the glue that holds most Dojo-based + // applications together. Most combinations of arguments are + // supported, with the connect() method attempting to disambiguate + // the implied types of positional parameters. The following will + // all work: + // dojo.event.connect("globalFunctionName1", "globalFunctionName2"); + // dojo.event.connect(functionReference1, functionReference2); + // dojo.event.connect("globalFunctionName1", functionReference2); + // dojo.event.connect(functionReference1, "globalFunctionName2"); + // dojo.event.connect(scope1, "functionName1", "globalFunctionName2"); + // dojo.event.connect("globalFunctionName1", scope2, "functionName2"); + // dojo.event.connect(scope1, "functionName1", scope2, "functionName2"); + // dojo.event.connect("after", scope1, "functionName1", scope2, "functionName2"); + // dojo.event.connect("before", scope1, "functionName1", scope2, "functionName2"); + // dojo.event.connect("around", scope1, "functionName1", + // scope2, "functionName2", + // aroundFunctionReference); + // dojo.event.connect("around", scope1, "functionName1", + // scope2, "functionName2", + // scope3, "aroundFunctionName"); + // dojo.event.connect("before-around", scope1, "functionName1", + // scope2, "functionName2", + // aroundFunctionReference); + // dojo.event.connect("after-around", scope1, "functionName1", + // scope2, "functionName2", + // aroundFunctionReference); + // dojo.event.connect("after-around", scope1, "functionName1", + // scope2, "functionName2", + // scope3, "aroundFunctionName"); + // dojo.event.connect("around", scope1, "functionName1", + // scope2, "functionName2", + // scope3, "aroundFunctionName", true, 30); + // dojo.event.connect("around", scope1, "functionName1", + // scope2, "functionName2", + // scope3, "aroundFunctionName", null, null, 10); + // adviceType: + // Optional. String. One of "before", "after", "around", + // "before-around", or "after-around". FIXME + // srcObj: + // the scope in which to locate/execute the named srcFunc. Along + // with srcFunc, this creates a way to dereference the function to + // call. So if the function in question is "foo.bar", the + // srcObj/srcFunc pair would be foo and "bar", where "bar" is a + // string and foo is an object reference. + // srcFunc: + // the name of the function to connect to. When it is executed, + // the listener being registered with this call will be called. + // The adviceType defines the call order between the source and + // the target functions. + // adviceObj: + // the scope in which to locate/execute the named adviceFunc. + // adviceFunc: + // the name of the function being conected to srcObj.srcFunc + // aroundObj: + // the scope in which to locate/execute the named aroundFunc. + // aroundFunc: + // the name of, or a reference to, the function that will be used + // to mediate the advice call. Around advice requires a special + // unary function that will be passed a "MethodInvocation" object. + // These objects have several important properties, namely: + // - args + // a mutable array of arguments to be passed into the + // wrapped function + // - proceed + // a function that "continues" the invocation. The result + // of this function is the return of the wrapped function. + // You can then manipulate this return before passing it + // back out (or take further action based on it). + // once: + // boolean that determines whether or not this connect() will + // create a new connection if an identical connect() has already + // been made. Defaults to "false". + // delay: + // an optional delay (in ms), as an integer, for dispatch of a + // listener after the source has been fired. + // rate: + // an optional rate throttling parameter (integer, in ms). When + // specified, this particular connection will not fire more than + // once in the interval specified by the rate + // adviceMsg: + // boolean. Should the listener have all the parameters passed in + // as a single argument? - return ao; - } + /* + ao.adviceType = args[0]; + ao.srcObj = args[1]; + ao.srcFunc = args[2]; + ao.adviceObj = args[3] + ao.adviceFunc = args[4]; + ao.aroundObj = args[5]; + ao.aroundFunc = args[6]; + ao.once = args[7]; + ao.delay = args[8]; + ao.rate = args[9]; + ao.adviceMsg = args[10]; + ao.maxCalls = args[11]; + */ + if(arguments.length == 1){ + var ao = arguments[0]; + }else{ + var ao = interpolateArgs(arguments, true); + } + if(dojo.lang.isString(ao.srcFunc) && (ao.srcFunc.toLowerCase() == "onkey") ){ + if(dojo.render.html.ie){ + ao.srcFunc = "onkeydown"; + this.connect(ao); + } + ao.srcFunc = "onkeypress"; + } - this.connect = function(/*...*/){ - // summary: - // dojo.event.connect is the glue that holds most Dojo-based - // applications together. Most combinations of arguments are - // supported, with the connect() method attempting to disambiguate - // the implied types of positional parameters. The following will - // all work: - // dojo.event.connect("globalFunctionName1", "globalFunctionName2"); - // dojo.event.connect(functionReference1, functionReference2); - // dojo.event.connect("globalFunctionName1", functionReference2); - // dojo.event.connect(functionReference1, "globalFunctionName2"); - // dojo.event.connect(scope1, "functionName1", "globalFunctionName2"); - // dojo.event.connect("globalFunctionName1", scope2, "functionName2"); - // dojo.event.connect(scope1, "functionName1", scope2, "functionName2"); - // dojo.event.connect("after", scope1, "functionName1", scope2, "functionName2"); - // dojo.event.connect("before", scope1, "functionName1", scope2, "functionName2"); - // dojo.event.connect("around", scope1, "functionName1", - // scope2, "functionName2", - // aroundFunctionReference); - // dojo.event.connect("around", scope1, "functionName1", - // scope2, "functionName2", - // scope3, "aroundFunctionName"); - // dojo.event.connect("before-around", scope1, "functionName1", - // scope2, "functionName2", - // aroundFunctionReference); - // dojo.event.connect("after-around", scope1, "functionName1", - // scope2, "functionName2", - // aroundFunctionReference); - // dojo.event.connect("after-around", scope1, "functionName1", - // scope2, "functionName2", - // scope3, "aroundFunctionName"); - // dojo.event.connect("around", scope1, "functionName1", - // scope2, "functionName2", - // scope3, "aroundFunctionName", true, 30); - // dojo.event.connect("around", scope1, "functionName1", - // scope2, "functionName2", - // scope3, "aroundFunctionName", null, null, 10); - // adviceType: - // Optional. String. One of "before", "after", "around", - // "before-around", or "after-around". FIXME - // srcObj: - // the scope in which to locate/execute the named srcFunc. Along - // with srcFunc, this creates a way to dereference the function to - // call. So if the function in question is "foo.bar", the - // srcObj/srcFunc pair would be foo and "bar", where "bar" is a - // string and foo is an object reference. - // srcFunc: - // the name of the function to connect to. When it is executed, - // the listener being registered with this call will be called. - // The adviceType defines the call order between the source and - // the target functions. - // adviceObj: - // the scope in which to locate/execute the named adviceFunc. - // adviceFunc: - // the name of the function being conected to srcObj.srcFunc - // aroundObj: - // the scope in which to locate/execute the named aroundFunc. - // aroundFunc: - // the name of, or a reference to, the function that will be used - // to mediate the advice call. Around advice requires a special - // unary function that will be passed a "MethodInvocation" object. - // These objects have several important properties, namely: - // - args - // a mutable array of arguments to be passed into the - // wrapped function - // - proceed - // a function that "continues" the invocation. The result - // of this function is the return of the wrapped function. - // You can then manipulate this return before passing it - // back out (or take further action based on it). - // once: - // boolean that determines whether or not this connect() will - // create a new connection if an identical connect() has already - // been made. Defaults to "false". - // delay: - // an optional delay (in ms), as an integer, for dispatch of a - // listener after the source has been fired. - // rate: - // an optional rate throttling parameter (integer, in ms). When - // specified, this particular connection will not fire more than - // once in the interval specified by the rate - // adviceMsg: - // boolean. Should the listener have all the parameters passed in - // as a single argument? + if(dojo.lang.isArray(ao.srcObj) && ao.srcObj!=""){ + var tmpAO = {}; + for(var x in ao){ + tmpAO[x] = ao[x]; + } + var mjps = []; + dojo.lang.forEach(ao.srcObj, function(src){ + if((dojo.render.html.capable)&&(dojo.lang.isString(src))){ + src = dojo.byId(src); + // dojo.debug(src); + } + tmpAO.srcObj = src; + // dojo.debug(tmpAO.srcObj, tmpAO.srcFunc); + // dojo.debug(tmpAO.adviceObj, tmpAO.adviceFunc); + mjps.push(dojo.event.connect.call(dojo.event, tmpAO)); + }); + return mjps; + } - /* - ao.adviceType = args[0]; - ao.srcObj = args[1]; - ao.srcFunc = args[2]; - ao.adviceObj = args[3] - ao.adviceFunc = args[4]; - ao.aroundObj = args[5]; - ao.aroundFunc = args[6]; - ao.once = args[7]; - ao.delay = args[8]; - ao.rate = args[9]; - ao.adviceMsg = args[10]; - ao.maxCalls = args[11]; - */ - if(arguments.length == 1){ - var ao = arguments[0]; - }else{ - var ao = interpolateArgs(arguments, true); - } - if(dojo.lang.isString(ao.srcFunc) && (ao.srcFunc.toLowerCase() == "onkey") ){ - if(dojo.render.html.ie){ - ao.srcFunc = "onkeydown"; - this.connect(ao); - } - ao.srcFunc = "onkeypress"; - } + // FIXME: just doing a "getForMethod()" seems to be enough to put this into infinite recursion!! + var mjp = dojo.event.MethodJoinPoint.getForMethod(ao.srcObj, ao.srcFunc); + if(ao.adviceFunc){ + var mjp2 = dojo.event.MethodJoinPoint.getForMethod(ao.adviceObj, ao.adviceFunc); + } - if(dojo.lang.isArray(ao.srcObj) && ao.srcObj!=""){ - var tmpAO = {}; - for(var x in ao){ - tmpAO[x] = ao[x]; - } - var mjps = []; - dojo.lang.forEach(ao.srcObj, function(src){ - if((dojo.render.html.capable)&&(dojo.lang.isString(src))){ - src = dojo.byId(src); - // dojo.debug(src); - } - tmpAO.srcObj = src; - // dojo.debug(tmpAO.srcObj, tmpAO.srcFunc); - // dojo.debug(tmpAO.adviceObj, tmpAO.adviceFunc); - mjps.push(dojo.event.connect.call(dojo.event, tmpAO)); - }); - return mjps; - } + mjp.kwAddAdvice(ao); - // FIXME: just doing a "getForMethod()" seems to be enough to put this into infinite recursion!! - var mjp = dojo.event.MethodJoinPoint.getForMethod(ao.srcObj, ao.srcFunc); - if(ao.adviceFunc){ - var mjp2 = dojo.event.MethodJoinPoint.getForMethod(ao.adviceObj, ao.adviceFunc); - } + // advanced users might want to fsck w/ the join point manually + return mjp; // a MethodJoinPoint object + } - mjp.kwAddAdvice(ao); + this.log = function(/*object or funcName*/ a1, /*funcName*/ a2){ + // summary: + // a function that will wrap and log all calls to the specified + // a1.a2() function. If only a1 is passed, it'll be used as a + // function or function name on the global context. Logging will + // be sent to dojo.debug + // a1: + // if a2 is passed, this should be an object. If not, it can be a + // function or function name. + // a2: + // a function name + var kwArgs; + if((arguments.length == 1)&&(typeof a1 == "object")){ + kwArgs = a1; + }else{ + kwArgs = { + srcObj: a1, + srcFunc: a2 + }; + } + kwArgs.adviceFunc = function(){ + var argsStr = []; + for(var x=0; x= this.jp_.around.length){ - return this.jp_.object[this.jp_.methodname].apply(this.jp_.object, this.args); - // return this.jp_.run_before_after(this.object, this.args); - }else{ - var ti = this.jp_.around[this.around_index]; - var mobj = ti[0]||dj_global; - var meth = ti[1]; - return mobj[meth].call(mobj, this); - } -} + // summary: + // proceed with the method call that's represented by this invocation + // object + this.around_index++; + if(this.around_index >= this.jp_.around.length){ + return this.jp_.object[this.jp_.methodname].apply(this.jp_.object, this.args); + // return this.jp_.run_before_after(this.object, this.args); + }else{ + var ti = this.jp_.around[this.around_index]; + var mobj = ti[0]||dj_global; + var meth = ti[1]; + return mobj[meth].call(mobj, this); + } +} dojo.event.MethodJoinPoint = function(/*Object*/obj, /*String*/funcName){ - this.object = obj||dj_global; - this.methodname = funcName; - this.methodfunc = this.object[funcName]; - this.squelch = false; - // this.before = []; - // this.after = []; - // this.around = []; + this.object = obj||dj_global; + this.methodname = funcName; + this.methodfunc = this.object[funcName]; + this.squelch = false; + // this.before = []; + // this.after = []; + // this.around = []; } dojo.event.MethodJoinPoint.getForMethod = function(/*Object*/obj, /*String*/funcName){ - // summary: - // "static" class function for returning a MethodJoinPoint from a - // scoped function. If one doesn't exist, one is created. - // obj: - // the scope to search for the function in - // funcName: - // the name of the function to return a MethodJoinPoint for - if(!obj){ obj = dj_global; } - var ofn = obj[funcName]; - if(!ofn){ - // supply a do-nothing method implementation - ofn = obj[funcName] = function(){}; - if(!obj[funcName]){ - // e.g. cannot add to inbuilt objects in IE6 - dojo.raise("Cannot set do-nothing method on that object "+funcName); - } - }else if((typeof ofn != "function")&&(!dojo.lang.isFunction(ofn))&&(!dojo.lang.isAlien(ofn))){ - // FIXME: should we throw an exception here instead? - return null; - } - // we hide our joinpoint instance in obj[funcName + '$joinpoint'] - var jpname = funcName + "$joinpoint"; - var jpfuncname = funcName + "$joinpoint$method"; - var joinpoint = obj[jpname]; - if(!joinpoint){ - var isNode = false; - if(dojo.event["browser"]){ - if( (obj["attachEvent"])|| - (obj["nodeType"])|| - (obj["addEventListener"]) ){ - isNode = true; - dojo.event.browser.addClobberNodeAttrs(obj, [jpname, jpfuncname, funcName]); - } - } - var origArity = ofn.length; - obj[jpfuncname] = ofn; - // joinpoint = obj[jpname] = new dojo.event.MethodJoinPoint(obj, funcName); - joinpoint = obj[jpname] = new dojo.event.MethodJoinPoint(obj, jpfuncname); + // summary: + // "static" class function for returning a MethodJoinPoint from a + // scoped function. If one doesn't exist, one is created. + // obj: + // the scope to search for the function in + // funcName: + // the name of the function to return a MethodJoinPoint for + if(!obj){ obj = dj_global; } + var ofn = obj[funcName]; + if(!ofn){ + // supply a do-nothing method implementation + ofn = obj[funcName] = function(){}; + if(!obj[funcName]){ + // e.g. cannot add to inbuilt objects in IE6 + dojo.raise("Cannot set do-nothing method on that object "+funcName); + } + }else if((typeof ofn != "function")&&(!dojo.lang.isFunction(ofn))&&(!dojo.lang.isAlien(ofn))){ + // FIXME: should we throw an exception here instead? + return null; + } + // we hide our joinpoint instance in obj[funcName + '$joinpoint'] + var jpname = funcName + "$joinpoint"; + var jpfuncname = funcName + "$joinpoint$method"; + var joinpoint = obj[jpname]; + if(!joinpoint){ + var isNode = false; + if(dojo.event["browser"]){ + if( (obj["attachEvent"])|| + (obj["nodeType"])|| + (obj["addEventListener"]) ){ + isNode = true; + dojo.event.browser.addClobberNodeAttrs(obj, [jpname, jpfuncname, funcName]); + } + } + var origArity = ofn.length; + obj[jpfuncname] = ofn; + // joinpoint = obj[jpname] = new dojo.event.MethodJoinPoint(obj, funcName); + joinpoint = obj[jpname] = new dojo.event.MethodJoinPoint(obj, jpfuncname); - if(!isNode){ - obj[funcName] = function(){ - // var args = []; - // for(var x=0; x -1){ + if(maxCount == 0){ + return; + } + marr[7]--; + } + var undef; - var callObj = marr[0]||dj_global; - var callFunc = marr[1]; + var to = { + args: [], + jp_: this, + object: obj, + proceed: function(){ + return callObj[callFunc].apply(callObj, to.args); + } + }; + to.args = aargs; - if(!callObj[callFunc]){ - dojo.raise("function \"" + callFunc + "\" does not exist on \"" + callObj + "\""); - } + var delay = parseInt(marr[4]); + var hasDelay = ((!isNaN(delay))&&(marr[4]!==null)&&(typeof marr[4] != "undefined")); + if(marr[5]){ + var rate = parseInt(marr[5]); + var cur = new Date(); + var timerSet = false; + if((marr["last"])&&((cur-marr.last)<=rate)){ + if(dojo.event._canTimeout){ + if(marr["delayTimer"]){ + clearTimeout(marr.delayTimer); + } + var tod = parseInt(rate*2); // is rate*2 naive? + var mcpy = dojo.lang.shallowCopy(marr); + marr.delayTimer = setTimeout(function(){ + // FIXME: on IE at least, event objects from the + // browser can go out of scope. How (or should?) we + // deal with it? + mcpy[5] = 0; + unrollAdvice(mcpy); + }, tod); + } + return; + }else{ + marr.last = cur; + } + } - var aroundObj = marr[2]||dj_global; - var aroundFunc = marr[3]; - var msg = marr[6]; - var maxCount = marr[7]; - if(maxCount > -1){ - if(maxCount == 0){ - return; - } - marr[7]--; - } - var undef; + // FIXME: need to enforce rates for a connection here! - var to = { - args: [], - jp_: this, - object: obj, - proceed: function(){ - return callObj[callFunc].apply(callObj, to.args); - } - }; - to.args = aargs; + if(aroundFunc){ + // NOTE: around advice can't delay since we might otherwise depend + // on execution order! + aroundObj[aroundFunc].call(aroundObj, to); + }else{ + // var tmjp = dojo.event.MethodJoinPoint.getForMethod(obj, methname); + if((hasDelay)&&((dojo.render.html)||(dojo.render.svg))){ // FIXME: the render checks are grotty! + dj_global["setTimeout"](function(){ + if(msg){ + callObj[callFunc].call(callObj, to); + }else{ + callObj[callFunc].apply(callObj, args); + } + }, delay); + }else{ // many environments can't support delay! + if(msg){ + callObj[callFunc].call(callObj, to); + }else{ + callObj[callFunc].apply(callObj, args); + } + } + } + }; - var delay = parseInt(marr[4]); - var hasDelay = ((!isNaN(delay))&&(marr[4]!==null)&&(typeof marr[4] != "undefined")); - if(marr[5]){ - var rate = parseInt(marr[5]); - var cur = new Date(); - var timerSet = false; - if((marr["last"])&&((cur-marr.last)<=rate)){ - if(dojo.event._canTimeout){ - if(marr["delayTimer"]){ - clearTimeout(marr.delayTimer); - } - var tod = parseInt(rate*2); // is rate*2 naive? - var mcpy = dojo.lang.shallowCopy(marr); - marr.delayTimer = setTimeout(function(){ - // FIXME: on IE at least, event objects from the - // browser can go out of scope. How (or should?) we - // deal with it? - mcpy[5] = 0; - unrollAdvice(mcpy); - }, tod); - } - return; - }else{ - marr.last = cur; - } - } + var unRollSquelch = function(){ + if(this.squelch){ + try{ + return unrollAdvice.apply(this, arguments); + }catch(e){ + dojo.debug(e); + } + }else{ + return unrollAdvice.apply(this, arguments); + } + }; - // FIXME: need to enforce rates for a connection here! + if((this["before"])&&(this.before.length>0)){ + // pass a cloned array, if this event disconnects this event forEach on this.before wont work + dojo.lang.forEach(this.before.concat(new Array()), unRollSquelch); + } - if(aroundFunc){ - // NOTE: around advice can't delay since we might otherwise depend - // on execution order! - aroundObj[aroundFunc].call(aroundObj, to); - }else{ - // var tmjp = dojo.event.MethodJoinPoint.getForMethod(obj, methname); - if((hasDelay)&&((dojo.render.html)||(dojo.render.svg))){ // FIXME: the render checks are grotty! - dj_global["setTimeout"](function(){ - if(msg){ - callObj[callFunc].call(callObj, to); - }else{ - callObj[callFunc].apply(callObj, args); - } - }, delay); - }else{ // many environments can't support delay! - if(msg){ - callObj[callFunc].call(callObj, to); - }else{ - callObj[callFunc].apply(callObj, args); - } - } - } - }; + var result; + try{ + if((this["around"])&&(this.around.length>0)){ + var mi = new dojo.event.MethodInvocation(this, obj, args); + result = mi.proceed(); + }else if(this.methodfunc){ + result = this.object[this.methodname].apply(this.object, args); + } + }catch(e){ + if(!this.squelch){ + dojo.debug(e,"when calling",this.methodname,"on",this.object,"with arguments",args); + dojo.raise(e); + } + } - var unRollSquelch = function(){ - if(this.squelch){ - try{ - return unrollAdvice.apply(this, arguments); - }catch(e){ - dojo.debug(e); - } - }else{ - return unrollAdvice.apply(this, arguments); - } - }; + if((this["after"])&&(this.after.length>0)){ + // see comment on this.before above + dojo.lang.forEach(this.after.concat(new Array()), unRollSquelch); + } - if((this["before"])&&(this.before.length>0)){ - // pass a cloned array, if this event disconnects this event forEach on this.before wont work - dojo.lang.forEach(this.before.concat(new Array()), unRollSquelch); - } + return (this.methodfunc) ? result : null; + }, - var result; - try{ - if((this["around"])&&(this.around.length>0)){ - var mi = new dojo.event.MethodInvocation(this, obj, args); - result = mi.proceed(); - }else if(this.methodfunc){ - result = this.object[this.methodname].apply(this.object, args); - } - }catch(e){ - if(!this.squelch){ - dojo.debug(e,"when calling",this.methodname,"on",this.object,"with arguments",args); - dojo.raise(e); - } - } + getArr: function(/*String*/kind){ + // summary: return a list of listeners of the past "kind" + // kind: + // can be one of: "before", "after", "around", "before-around", or + // "after-around" + var type = "after"; + // FIXME: we should be able to do this through props or Array.in() + if((typeof kind == "string")&&(kind.indexOf("before")!=-1)){ + type = "before"; + }else if(kind=="around"){ + type = "around"; + } + if(!this[type]){ this[type] = []; } + return this[type]; // Array + }, - if((this["after"])&&(this.after.length>0)){ - // see comment on this.before above - dojo.lang.forEach(this.after.concat(new Array()), unRollSquelch); - } + kwAddAdvice: function(/*Object*/args){ + // summary: + // adds advice to the joinpoint with arguments in a map + // args: + // An object that can have the following properties: + // - adviceType + // - adviceObj + // - adviceFunc + // - aroundObj + // - aroundFunc + // - once + // - delay + // - rate + // - adviceMsg + // - maxCalls + this.addAdvice( args["adviceObj"], args["adviceFunc"], + args["aroundObj"], args["aroundFunc"], + args["adviceType"], args["precedence"], + args["once"], args["delay"], args["rate"], + args["adviceMsg"], args["maxCalls"]); + }, - return (this.methodfunc) ? result : null; - }, + addAdvice: function( thisAdviceObj, thisAdvice, + thisAroundObj, thisAround, + adviceType, precedence, + once, delay, rate, asMessage, + maxCalls){ + // summary: + // add advice to this joinpoint using positional parameters + // thisAdviceObj: + // the scope in which to locate/execute the named adviceFunc. + // thisAdviceFunc: + // the name of the function being conected + // thisAroundObj: + // the scope in which to locate/execute the named aroundFunc. + // thisAroundFunc: + // the name of the function that will be used to mediate the + // advice call. + // adviceType: + // Optional. String. One of "before", "after", "around", + // "before-around", or "after-around". FIXME + // once: + // boolean that determines whether or not this advice will create + // a new connection if an identical advice set has already been + // provided. Defaults to "false". + // delay: + // an optional delay (in ms), as an integer, for dispatch of a + // listener after the source has been fired. + // rate: + // an optional rate throttling parameter (integer, in ms). When + // specified, this particular connection will not fire more than + // once in the interval specified by the rate + // adviceMsg: + // boolean. Should the listener have all the parameters passed in + // as a single argument? + // maxCalls: + // Integer. The maximum number of times this connection can be + // used before being auto-disconnected. -1 signals that the + // connection should never be disconnected. + var arr = this.getArr(adviceType); + if(!arr){ + dojo.raise("bad this: " + this); + } - getArr: function(/*String*/kind){ - // summary: return a list of listeners of the past "kind" - // kind: - // can be one of: "before", "after", "around", "before-around", or - // "after-around" - var type = "after"; - // FIXME: we should be able to do this through props or Array.in() - if((typeof kind == "string")&&(kind.indexOf("before")!=-1)){ - type = "before"; - }else if(kind=="around"){ - type = "around"; - } - if(!this[type]){ this[type] = []; } - return this[type]; // Array - }, + var ao = [thisAdviceObj, thisAdvice, thisAroundObj, thisAround, delay, rate, asMessage, maxCalls]; + + if(once){ + if(this.hasAdvice(thisAdviceObj, thisAdvice, adviceType, arr) >= 0){ + return; + } + } - kwAddAdvice: function(/*Object*/args){ - // summary: - // adds advice to the joinpoint with arguments in a map - // args: - // An object that can have the following properties: - // - adviceType - // - adviceObj - // - adviceFunc - // - aroundObj - // - aroundFunc - // - once - // - delay - // - rate - // - adviceMsg - // - maxCalls - this.addAdvice( args["adviceObj"], args["adviceFunc"], - args["aroundObj"], args["aroundFunc"], - args["adviceType"], args["precedence"], - args["once"], args["delay"], args["rate"], - args["adviceMsg"], args["maxCalls"]); - }, + if(precedence == "first"){ + arr.unshift(ao); + }else{ + arr.push(ao); + } + }, - addAdvice: function( thisAdviceObj, thisAdvice, - thisAroundObj, thisAround, - adviceType, precedence, - once, delay, rate, asMessage, - maxCalls){ - // summary: - // add advice to this joinpoint using positional parameters - // thisAdviceObj: - // the scope in which to locate/execute the named adviceFunc. - // thisAdviceFunc: - // the name of the function being conected - // thisAroundObj: - // the scope in which to locate/execute the named aroundFunc. - // thisAroundFunc: - // the name of the function that will be used to mediate the - // advice call. - // adviceType: - // Optional. String. One of "before", "after", "around", - // "before-around", or "after-around". FIXME - // once: - // boolean that determines whether or not this advice will create - // a new connection if an identical advice set has already been - // provided. Defaults to "false". - // delay: - // an optional delay (in ms), as an integer, for dispatch of a - // listener after the source has been fired. - // rate: - // an optional rate throttling parameter (integer, in ms). When - // specified, this particular connection will not fire more than - // once in the interval specified by the rate - // adviceMsg: - // boolean. Should the listener have all the parameters passed in - // as a single argument? - // maxCalls: - // Integer. The maximum number of times this connection can be - // used before being auto-disconnected. -1 signals that the - // connection should never be disconnected. - var arr = this.getArr(adviceType); - if(!arr){ - dojo.raise("bad this: " + this); - } + hasAdvice: function(thisAdviceObj, thisAdvice, adviceType, arr){ + // summary: + // returns the array index of the first existing connection + // betweened the passed advice and this joinpoint. Will be -1 if + // none exists. + // thisAdviceObj: + // the scope in which to locate/execute the named adviceFunc. + // thisAdviceFunc: + // the name of the function being conected + // adviceType: + // Optional. String. One of "before", "after", "around", + // "before-around", or "after-around". FIXME + // arr: + // Optional. The list of advices to search. Will be found via + // adviceType if not passed + if(!arr){ arr = this.getArr(adviceType); } + var ind = -1; + for(var x=0; x= 0){ - return; - } - } - - if(precedence == "first"){ - arr.unshift(ao); - }else{ - arr.push(ao); - } - }, - - hasAdvice: function(thisAdviceObj, thisAdvice, adviceType, arr){ - // summary: - // returns the array index of the first existing connection - // betweened the passed advice and this joinpoint. Will be -1 if - // none exists. - // thisAdviceObj: - // the scope in which to locate/execute the named adviceFunc. - // thisAdviceFunc: - // the name of the function being conected - // adviceType: - // Optional. String. One of "before", "after", "around", - // "before-around", or "after-around". FIXME - // arr: - // Optional. The list of advices to search. Will be found via - // adviceType if not passed - if(!arr){ arr = this.getArr(adviceType); } - var ind = -1; - for(var x=0; x=0; i=i-1){ - var el = na[i]; - try{ - if(el && el["__clobberAttrs__"]){ - for(var j=0; j=0; i=i-1){ + var el = na[i]; + try{ + if(el && el["__clobberAttrs__"]){ + for(var j=0; j= 65 && unifiedCharCode <= 90 && evt.shiftKey == false){ + unifiedCharCode += 32; + } + if(unifiedCharCode >= 1 && unifiedCharCode <= 26 && evt.ctrlKey){ + unifiedCharCode += 96; // 001-032 = ctrl+[a-z] + } + evt.key = String.fromCharCode(unifiedCharCode); + } + } + } else if(evt["type"] == "keypress"){ + if(dojo.render.html.opera){ + if(evt.which == 0){ + evt.key = evt.keyCode; + }else if(evt.which > 0){ + switch(evt.which){ + case evt.KEY_SHIFT: + case evt.KEY_CTRL: + case evt.KEY_ALT: + case evt.KEY_CAPS_LOCK: + case evt.KEY_NUM_LOCK: + case evt.KEY_SCROLL_LOCK: + break; + case evt.KEY_PAUSE: + case evt.KEY_TAB: + case evt.KEY_BACKSPACE: + case evt.KEY_ENTER: + case evt.KEY_ESCAPE: + evt.key = evt.which; + break; + default: + var unifiedCharCode = evt.which; + if((evt.ctrlKey || evt.altKey || evt.metaKey) && (evt.which >= 65 && evt.which <= 90 && evt.shiftKey == false)){ + unifiedCharCode += 32; + } + evt.key = String.fromCharCode(unifiedCharCode); + } + } + }else if(dojo.render.html.ie){ // catch some IE keys that are hard to get in keyDown + // key combinations were handled in onKeyDown + if(!evt.ctrlKey && !evt.altKey && evt.keyCode >= evt.KEY_SPACE){ + evt.key = String.fromCharCode(evt.keyCode); + } + }else if(dojo.render.html.safari){ + switch(evt.keyCode){ + case 25: evt.key = evt.KEY_TAB; evt.shift = true;break; + case 63232: evt.key = evt.KEY_UP_ARROW; break; + case 63233: evt.key = evt.KEY_DOWN_ARROW; break; + case 63234: evt.key = evt.KEY_LEFT_ARROW; break; + case 63235: evt.key = evt.KEY_RIGHT_ARROW; break; + case 63236: evt.key = evt.KEY_F1; break; + case 63237: evt.key = evt.KEY_F2; break; + case 63238: evt.key = evt.KEY_F3; break; + case 63239: evt.key = evt.KEY_F4; break; + case 63240: evt.key = evt.KEY_F5; break; + case 63241: evt.key = evt.KEY_F6; break; + case 63242: evt.key = evt.KEY_F7; break; + case 63243: evt.key = evt.KEY_F8; break; + case 63244: evt.key = evt.KEY_F9; break; + case 63245: evt.key = evt.KEY_F10; break; + case 63246: evt.key = evt.KEY_F11; break; + case 63247: evt.key = evt.KEY_F12; break; + case 63250: evt.key = evt.KEY_PAUSE; break; + case 63272: evt.key = evt.KEY_DELETE; break; + case 63273: evt.key = evt.KEY_HOME; break; + case 63275: evt.key = evt.KEY_END; break; + case 63276: evt.key = evt.KEY_PAGE_UP; break; + case 63277: evt.key = evt.KEY_PAGE_DOWN; break; + case 63302: evt.key = evt.KEY_INSERT; break; + case 63248://prtscr + case 63249://scrolllock + case 63289://numlock + break; + default: + evt.key = evt.charCode >= evt.KEY_SPACE ? String.fromCharCode(evt.charCode) : evt.keyCode; + } + }else{ + evt.key = evt.charCode > 0 ? String.fromCharCode(evt.charCode) : evt.keyCode; + } + } + } + if(dojo.render.html.ie){ + if(!evt.target){ evt.target = evt.srcElement; } + if(!evt.currentTarget){ evt.currentTarget = (sender ? sender : evt.srcElement); } + if(!evt.layerX){ evt.layerX = evt.offsetX; } + if(!evt.layerY){ evt.layerY = evt.offsetY; } + // FIXME: scroll position query is duped from dojo.html to avoid dependency on that entire module + // DONOT replace the following to use dojo.body(), in IE, document.documentElement should be used + // here rather than document.body + var doc = (evt.srcElement && evt.srcElement.ownerDocument) ? evt.srcElement.ownerDocument : document; + var docBody = ((dojo.render.html.ie55)||(doc["compatMode"] == "BackCompat")) ? doc.body : doc.documentElement; + if(!evt.pageX){ evt.pageX = evt.clientX + (docBody.scrollLeft || 0) } + if(!evt.pageY){ evt.pageY = evt.clientY + (docBody.scrollTop || 0) } + // mouseover + if(evt.type == "mouseover"){ evt.relatedTarget = evt.fromElement; } + // mouseout + if(evt.type == "mouseout"){ evt.relatedTarget = evt.toElement; } + this.currentEvent = evt; + evt.callListener = this.callListener; + evt.stopPropagation = this._stopPropagation; + evt.preventDefault = this._preventDefault; + } + return evt; // Event + } - // reverse lookup - this.revKeys = []; - for(var key in this.keys){ - this.revKeys[this.keys[key]] = key; - } - - this.fixEvent = function(/*Event*/evt, /*DOMNode*/sender){ - // summary: - // normalizes properties on the event object including event - // bubbling methods, keystroke normalization, and x/y positions - // evt: the native event object - // sender: the node to treat as "currentTarget" - if(!evt){ - if(window["event"]){ - evt = window.event; - } - } - - if((evt["type"])&&(evt["type"].indexOf("key") == 0)){ // key events - evt.keys = this.revKeys; - // FIXME: how can we eliminate this iteration? - for(var key in this.keys){ - evt[key] = this.keys[key]; - } - if(evt["type"] == "keydown" && dojo.render.html.ie){ - switch(evt.keyCode){ - case evt.KEY_SHIFT: - case evt.KEY_CTRL: - case evt.KEY_ALT: - case evt.KEY_CAPS_LOCK: - case evt.KEY_LEFT_WINDOW: - case evt.KEY_RIGHT_WINDOW: - case evt.KEY_SELECT: - case evt.KEY_NUM_LOCK: - case evt.KEY_SCROLL_LOCK: - // I'll get these in keypress after the OS munges them based on numlock - case evt.KEY_NUMPAD_0: - case evt.KEY_NUMPAD_1: - case evt.KEY_NUMPAD_2: - case evt.KEY_NUMPAD_3: - case evt.KEY_NUMPAD_4: - case evt.KEY_NUMPAD_5: - case evt.KEY_NUMPAD_6: - case evt.KEY_NUMPAD_7: - case evt.KEY_NUMPAD_8: - case evt.KEY_NUMPAD_9: - case evt.KEY_NUMPAD_PERIOD: - break; // just ignore the keys that can morph - case evt.KEY_NUMPAD_MULTIPLY: - case evt.KEY_NUMPAD_PLUS: - case evt.KEY_NUMPAD_ENTER: - case evt.KEY_NUMPAD_MINUS: - case evt.KEY_NUMPAD_DIVIDE: - break; // I could handle these but just pick them up in keypress - case evt.KEY_PAUSE: - case evt.KEY_TAB: - case evt.KEY_BACKSPACE: - case evt.KEY_ENTER: - case evt.KEY_ESCAPE: - case evt.KEY_PAGE_UP: - case evt.KEY_PAGE_DOWN: - case evt.KEY_END: - case evt.KEY_HOME: - case evt.KEY_LEFT_ARROW: - case evt.KEY_UP_ARROW: - case evt.KEY_RIGHT_ARROW: - case evt.KEY_DOWN_ARROW: - case evt.KEY_INSERT: - case evt.KEY_DELETE: - case evt.KEY_F1: - case evt.KEY_F2: - case evt.KEY_F3: - case evt.KEY_F4: - case evt.KEY_F5: - case evt.KEY_F6: - case evt.KEY_F7: - case evt.KEY_F8: - case evt.KEY_F9: - case evt.KEY_F10: - case evt.KEY_F11: - case evt.KEY_F12: - case evt.KEY_F12: - case evt.KEY_F13: - case evt.KEY_F14: - case evt.KEY_F15: - case evt.KEY_CLEAR: - case evt.KEY_HELP: - evt.key = evt.keyCode; - break; - default: - if(evt.ctrlKey || evt.altKey){ - var unifiedCharCode = evt.keyCode; - // if lower case but keycode is uppercase, convert it - if(unifiedCharCode >= 65 && unifiedCharCode <= 90 && evt.shiftKey == false){ - unifiedCharCode += 32; - } - if(unifiedCharCode >= 1 && unifiedCharCode <= 26 && evt.ctrlKey){ - unifiedCharCode += 96; // 001-032 = ctrl+[a-z] - } - evt.key = String.fromCharCode(unifiedCharCode); - } - } - } else if(evt["type"] == "keypress"){ - if(dojo.render.html.opera){ - if(evt.which == 0){ - evt.key = evt.keyCode; - }else if(evt.which > 0){ - switch(evt.which){ - case evt.KEY_SHIFT: - case evt.KEY_CTRL: - case evt.KEY_ALT: - case evt.KEY_CAPS_LOCK: - case evt.KEY_NUM_LOCK: - case evt.KEY_SCROLL_LOCK: - break; - case evt.KEY_PAUSE: - case evt.KEY_TAB: - case evt.KEY_BACKSPACE: - case evt.KEY_ENTER: - case evt.KEY_ESCAPE: - evt.key = evt.which; - break; - default: - var unifiedCharCode = evt.which; - if((evt.ctrlKey || evt.altKey || evt.metaKey) && (evt.which >= 65 && evt.which <= 90 && evt.shiftKey == false)){ - unifiedCharCode += 32; - } - evt.key = String.fromCharCode(unifiedCharCode); - } - } - }else if(dojo.render.html.ie){ // catch some IE keys that are hard to get in keyDown - // key combinations were handled in onKeyDown - if(!evt.ctrlKey && !evt.altKey && evt.keyCode >= evt.KEY_SPACE){ - evt.key = String.fromCharCode(evt.keyCode); - } - }else if(dojo.render.html.safari){ - switch(evt.keyCode){ - case 25: evt.key = evt.KEY_TAB; evt.shift = true;break; - case 63232: evt.key = evt.KEY_UP_ARROW; break; - case 63233: evt.key = evt.KEY_DOWN_ARROW; break; - case 63234: evt.key = evt.KEY_LEFT_ARROW; break; - case 63235: evt.key = evt.KEY_RIGHT_ARROW; break; - case 63236: evt.key = evt.KEY_F1; break; - case 63237: evt.key = evt.KEY_F2; break; - case 63238: evt.key = evt.KEY_F3; break; - case 63239: evt.key = evt.KEY_F4; break; - case 63240: evt.key = evt.KEY_F5; break; - case 63241: evt.key = evt.KEY_F6; break; - case 63242: evt.key = evt.KEY_F7; break; - case 63243: evt.key = evt.KEY_F8; break; - case 63244: evt.key = evt.KEY_F9; break; - case 63245: evt.key = evt.KEY_F10; break; - case 63246: evt.key = evt.KEY_F11; break; - case 63247: evt.key = evt.KEY_F12; break; - case 63250: evt.key = evt.KEY_PAUSE; break; - case 63272: evt.key = evt.KEY_DELETE; break; - case 63273: evt.key = evt.KEY_HOME; break; - case 63275: evt.key = evt.KEY_END; break; - case 63276: evt.key = evt.KEY_PAGE_UP; break; - case 63277: evt.key = evt.KEY_PAGE_DOWN; break; - case 63302: evt.key = evt.KEY_INSERT; break; - case 63248://prtscr - case 63249://scrolllock - case 63289://numlock - break; - default: - evt.key = evt.charCode >= evt.KEY_SPACE ? String.fromCharCode(evt.charCode) : evt.keyCode; - } - }else{ - evt.key = evt.charCode > 0 ? String.fromCharCode(evt.charCode) : evt.keyCode; - } - } - } - if(dojo.render.html.ie){ - if(!evt.target){ evt.target = evt.srcElement; } - if(!evt.currentTarget){ evt.currentTarget = (sender ? sender : evt.srcElement); } - if(!evt.layerX){ evt.layerX = evt.offsetX; } - if(!evt.layerY){ evt.layerY = evt.offsetY; } - // FIXME: scroll position query is duped from dojo.html to avoid dependency on that entire module - // DONOT replace the following to use dojo.body(), in IE, document.documentElement should be used - // here rather than document.body - var doc = (evt.srcElement && evt.srcElement.ownerDocument) ? evt.srcElement.ownerDocument : document; - var docBody = ((dojo.render.html.ie55)||(doc["compatMode"] == "BackCompat")) ? doc.body : doc.documentElement; - if(!evt.pageX){ evt.pageX = evt.clientX + (docBody.scrollLeft || 0) } - if(!evt.pageY){ evt.pageY = evt.clientY + (docBody.scrollTop || 0) } - // mouseover - if(evt.type == "mouseover"){ evt.relatedTarget = evt.fromElement; } - // mouseout - if(evt.type == "mouseout"){ evt.relatedTarget = evt.toElement; } - this.currentEvent = evt; - evt.callListener = this.callListener; - evt.stopPropagation = this._stopPropagation; - evt.preventDefault = this._preventDefault; - } - return evt; // Event - } - - this.stopEvent = function(/*Event*/evt){ - // summary: - // prevents propigation and clobbers the default action of the - // passed event - // evt: Optional for IE. The native event object. - if(window.event){ - evt.cancelBubble = true; - evt.returnValue = false; - }else{ - evt.preventDefault(); - evt.stopPropagation(); - } - } + this.stopEvent = function(/*Event*/evt){ + // summary: + // prevents propigation and clobbers the default action of the + // passed event + // evt: Optional for IE. The native event object. + if(window.event){ + evt.cancelBubble = true; + evt.returnValue = false; + }else{ + evt.preventDefault(); + evt.stopPropagation(); + } + } } dojo.kwCompoundRequire({ - common: ["dojo.event.common", "dojo.event.topic"], - browser: ["dojo.event.browser"], - dashboard: ["dojo.event.browser"] + common: ["dojo.event.common", "dojo.event.topic"], + browser: ["dojo.event.browser"], + dashboard: ["dojo.event.browser"] }); dojo.provide("dojo.event.*"); @@ -6727,168 +6737,168 @@ dojo.provide("dojo.gfx.color"); // takes an r, g, b, a(lpha) value, [r, g, b, a] array, "rgb(...)" string, hex string (#aaa, #aaaaaa, aaaaaaa) dojo.gfx.color.Color = function(r, g, b, a) { - // dojo.debug("r:", r[0], "g:", r[1], "b:", r[2]); - if(dojo.lang.isArray(r)){ - this.r = r[0]; - this.g = r[1]; - this.b = r[2]; - this.a = r[3]||1.0; - }else if(dojo.lang.isString(r)){ - var rgb = dojo.gfx.color.extractRGB(r); - this.r = rgb[0]; - this.g = rgb[1]; - this.b = rgb[2]; - this.a = g||1.0; - }else if(r instanceof dojo.gfx.color.Color){ - // why does this create a new instance if we were passed one? - this.r = r.r; - this.b = r.b; - this.g = r.g; - this.a = r.a; - }else{ - this.r = r; - this.g = g; - this.b = b; - this.a = a; - } + // dojo.debug("r:", r[0], "g:", r[1], "b:", r[2]); + if(dojo.lang.isArray(r)){ + this.r = r[0]; + this.g = r[1]; + this.b = r[2]; + this.a = r[3]||1.0; + }else if(dojo.lang.isString(r)){ + var rgb = dojo.gfx.color.extractRGB(r); + this.r = rgb[0]; + this.g = rgb[1]; + this.b = rgb[2]; + this.a = g||1.0; + }else if(r instanceof dojo.gfx.color.Color){ + // why does this create a new instance if we were passed one? + this.r = r.r; + this.b = r.b; + this.g = r.g; + this.a = r.a; + }else{ + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } } dojo.gfx.color.Color.fromArray = function(arr) { - return new dojo.gfx.color.Color(arr[0], arr[1], arr[2], arr[3]); + return new dojo.gfx.color.Color(arr[0], arr[1], arr[2], arr[3]); } dojo.extend(dojo.gfx.color.Color, { - toRgb: function(includeAlpha) { - if(includeAlpha) { - return this.toRgba(); - } else { - return [this.r, this.g, this.b]; - } - }, - toRgba: function() { - return [this.r, this.g, this.b, this.a]; - }, - toHex: function() { - return dojo.gfx.color.rgb2hex(this.toRgb()); - }, - toCss: function() { - return "rgb(" + this.toRgb().join() + ")"; - }, - toString: function() { - return this.toHex(); // decent default? - }, - blend: function(color, weight){ - var rgb = null; - if(dojo.lang.isArray(color)){ - rgb = color; - }else if(color instanceof dojo.gfx.color.Color){ - rgb = color.toRgb(); - }else{ - rgb = new dojo.gfx.color.Color(color).toRgb(); - } - return dojo.gfx.color.blend(this.toRgb(), rgb, weight); - } + toRgb: function(includeAlpha) { + if(includeAlpha) { + return this.toRgba(); + } else { + return [this.r, this.g, this.b]; + } + }, + toRgba: function() { + return [this.r, this.g, this.b, this.a]; + }, + toHex: function() { + return dojo.gfx.color.rgb2hex(this.toRgb()); + }, + toCss: function() { + return "rgb(" + this.toRgb().join() + ")"; + }, + toString: function() { + return this.toHex(); // decent default? + }, + blend: function(color, weight){ + var rgb = null; + if(dojo.lang.isArray(color)){ + rgb = color; + }else if(color instanceof dojo.gfx.color.Color){ + rgb = color.toRgb(); + }else{ + rgb = new dojo.gfx.color.Color(color).toRgb(); + } + return dojo.gfx.color.blend(this.toRgb(), rgb, weight); + } }); dojo.gfx.color.named = { - white: [255,255,255], - black: [0,0,0], - red: [255,0,0], - green: [0,255,0], - lime: [0,255,0], - blue: [0,0,255], - navy: [0,0,128], - gray: [128,128,128], - silver: [192,192,192] + white: [255,255,255], + black: [0,0,0], + red: [255,0,0], + green: [0,255,0], + lime: [0,255,0], + blue: [0,0,255], + navy: [0,0,128], + gray: [128,128,128], + silver: [192,192,192] }; dojo.gfx.color.blend = function(a, b, weight){ - // summary: - // blend colors a and b (both as RGB array or hex strings) with weight - // from -1 to +1, 0 being a 50/50 blend - if(typeof a == "string"){ - return dojo.gfx.color.blendHex(a, b, weight); - } - if(!weight){ - weight = 0; - } - weight = Math.min(Math.max(-1, weight), 1); + // summary: + // blend colors a and b (both as RGB array or hex strings) with weight + // from -1 to +1, 0 being a 50/50 blend + if(typeof a == "string"){ + return dojo.gfx.color.blendHex(a, b, weight); + } + if(!weight){ + weight = 0; + } + weight = Math.min(Math.max(-1, weight), 1); - // alex: this interface blows. - // map -1 to 1 to the range 0 to 1 - weight = ((weight + 1)/2); + // alex: this interface blows. + // map -1 to 1 to the range 0 to 1 + weight = ((weight + 1)/2); + + var c = []; - var c = []; - - // var stop = (1000*weight); - for(var x = 0; x < 3; x++){ - c[x] = parseInt( b[x] + ( (a[x] - b[x]) * weight) ); - } - return c; + // var stop = (1000*weight); + for(var x = 0; x < 3; x++){ + c[x] = parseInt( b[x] + ( (a[x] - b[x]) * weight) ); + } + return c; } // very convenient blend that takes and returns hex values // (will get called automatically by blend when blend gets strings) dojo.gfx.color.blendHex = function(a, b, weight) { - return dojo.gfx.color.rgb2hex(dojo.gfx.color.blend(dojo.gfx.color.hex2rgb(a), dojo.gfx.color.hex2rgb(b), weight)); + return dojo.gfx.color.rgb2hex(dojo.gfx.color.blend(dojo.gfx.color.hex2rgb(a), dojo.gfx.color.hex2rgb(b), weight)); } // get RGB array from css-style color declarations dojo.gfx.color.extractRGB = function(color) { - var hex = "0123456789abcdef"; - color = color.toLowerCase(); - if( color.indexOf("rgb") == 0 ) { - var matches = color.match(/rgba*\((\d+), *(\d+), *(\d+)/i); - var ret = matches.splice(1, 3); - return ret; - } else { - var colors = dojo.gfx.color.hex2rgb(color); - if(colors) { - return colors; - } else { - // named color (how many do we support?) - return dojo.gfx.color.named[color] || [255, 255, 255]; - } - } + var hex = "0123456789abcdef"; + color = color.toLowerCase(); + if( color.indexOf("rgb") == 0 ) { + var matches = color.match(/rgba*\((\d+), *(\d+), *(\d+)/i); + var ret = matches.splice(1, 3); + return ret; + } else { + var colors = dojo.gfx.color.hex2rgb(color); + if(colors) { + return colors; + } else { + // named color (how many do we support?) + return dojo.gfx.color.named[color] || [255, 255, 255]; + } + } } dojo.gfx.color.hex2rgb = function(hex) { - var hexNum = "0123456789ABCDEF"; - var rgb = new Array(3); - if( hex.indexOf("#") == 0 ) { hex = hex.substring(1); } - hex = hex.toUpperCase(); - if(hex.replace(new RegExp("["+hexNum+"]", "g"), "") != "") { - return null; - } - if( hex.length == 3 ) { - rgb[0] = hex.charAt(0) + hex.charAt(0) - rgb[1] = hex.charAt(1) + hex.charAt(1) - rgb[2] = hex.charAt(2) + hex.charAt(2); - } else { - rgb[0] = hex.substring(0, 2); - rgb[1] = hex.substring(2, 4); - rgb[2] = hex.substring(4); - } - for(var i = 0; i < rgb.length; i++) { - rgb[i] = hexNum.indexOf(rgb[i].charAt(0)) * 16 + hexNum.indexOf(rgb[i].charAt(1)); - } - return rgb; + var hexNum = "0123456789ABCDEF"; + var rgb = new Array(3); + if( hex.indexOf("#") == 0 ) { hex = hex.substring(1); } + hex = hex.toUpperCase(); + if(hex.replace(new RegExp("["+hexNum+"]", "g"), "") != "") { + return null; + } + if( hex.length == 3 ) { + rgb[0] = hex.charAt(0) + hex.charAt(0) + rgb[1] = hex.charAt(1) + hex.charAt(1) + rgb[2] = hex.charAt(2) + hex.charAt(2); + } else { + rgb[0] = hex.substring(0, 2); + rgb[1] = hex.substring(2, 4); + rgb[2] = hex.substring(4); + } + for(var i = 0; i < rgb.length; i++) { + rgb[i] = hexNum.indexOf(rgb[i].charAt(0)) * 16 + hexNum.indexOf(rgb[i].charAt(1)); + } + return rgb; } dojo.gfx.color.rgb2hex = function(r, g, b) { - if(dojo.lang.isArray(r)) { - g = r[1] || 0; - b = r[2] || 0; - r = r[0] || 0; - } - var ret = dojo.lang.map([r, g, b], function(x) { - x = new Number(x); - var s = x.toString(16); - while(s.length < 2) { s = "0" + s; } - return s; - }); - ret.unshift("#"); - return ret.join(""); + if(dojo.lang.isArray(r)) { + g = r[1] || 0; + b = r[2] || 0; + r = r[0] || 0; + } + var ret = dojo.lang.map([r, g, b], function(x) { + x = new Number(x); + var s = x.toString(16); + while(s.length < 2) { s = "0" + s; } + return s; + }); + ret.unshift("#"); + return ret.join(""); } dojo.provide("dojo.lfx.Animation"); @@ -6896,567 +6906,567 @@ dojo.provide("dojo.lfx.Animation"); /* - Animation package based on Dan Pupius' work: http://pupius.co.uk/js/Toolkit.Drawing.js + Animation package based on Dan Pupius' work: http://pupius.co.uk/js/Toolkit.Drawing.js */ dojo.lfx.Line = function(/*int*/ start, /*int*/ end){ - // summary: dojo.lfx.Line is the object used to generate values - // from a start value to an end value - this.start = start; - this.end = end; - if(dojo.lang.isArray(start)){ - /* start: Array - end: Array - pId: a */ - var diff = []; - dojo.lang.forEach(this.start, function(s,i){ - diff[i] = this.end[i] - s; - }, this); - - this.getValue = function(/*float*/ n){ - var res = []; - dojo.lang.forEach(this.start, function(s, i){ - res[i] = (diff[i] * n) + s; - }, this); - return res; // Array - } - }else{ - var diff = end - start; - - this.getValue = function(/*float*/ n){ - // summary: returns the point on the line - // n: a floating point number greater than 0 and less than 1 - return (diff * n) + this.start; // Decimal - } - } + // summary: dojo.lfx.Line is the object used to generate values + // from a start value to an end value + this.start = start; + this.end = end; + if(dojo.lang.isArray(start)){ + /* start: Array + end: Array + pId: a */ + var diff = []; + dojo.lang.forEach(this.start, function(s,i){ + diff[i] = this.end[i] - s; + }, this); + + this.getValue = function(/*float*/ n){ + var res = []; + dojo.lang.forEach(this.start, function(s, i){ + res[i] = (diff[i] * n) + s; + }, this); + return res; // Array + } + }else{ + var diff = end - start; + + this.getValue = function(/*float*/ n){ + // summary: returns the point on the line + // n: a floating point number greater than 0 and less than 1 + return (diff * n) + this.start; // Decimal + } + } } if((dojo.render.html.khtml)&&(!dojo.render.html.safari)){ - // the cool kids are obviously not using konqueror... - // found a very wierd bug in floats constants, 1.5 evals as 1 - // seems somebody mixed up ints and floats in 3.5.4 ?? - // FIXME: investigate more and post a KDE bug (Fredrik) - dojo.lfx.easeDefault = function(/*Decimal?*/ n){ - // summary: Returns the point for point n on a sin wave. - return (parseFloat("0.5")+((Math.sin( (n+parseFloat("1.5")) * Math.PI))/2)); - } + // the cool kids are obviously not using konqueror... + // found a very wierd bug in floats constants, 1.5 evals as 1 + // seems somebody mixed up ints and floats in 3.5.4 ?? + // FIXME: investigate more and post a KDE bug (Fredrik) + dojo.lfx.easeDefault = function(/*Decimal?*/ n){ + // summary: Returns the point for point n on a sin wave. + return (parseFloat("0.5")+((Math.sin( (n+parseFloat("1.5")) * Math.PI))/2)); + } }else{ - dojo.lfx.easeDefault = function(/*Decimal?*/ n){ - return (0.5+((Math.sin( (n+1.5) * Math.PI))/2)); - } + dojo.lfx.easeDefault = function(/*Decimal?*/ n){ + return (0.5+((Math.sin( (n+1.5) * Math.PI))/2)); + } } dojo.lfx.easeIn = function(/*Decimal?*/ n){ - // summary: returns the point on an easing curve - // n: a floating point number greater than 0 and less than 1 - return Math.pow(n, 3); + // summary: returns the point on an easing curve + // n: a floating point number greater than 0 and less than 1 + return Math.pow(n, 3); } dojo.lfx.easeOut = function(/*Decimal?*/ n){ - // summary: returns the point on the line - // n: a floating point number greater than 0 and less than 1 - return ( 1 - Math.pow(1 - n, 3) ); + // summary: returns the point on the line + // n: a floating point number greater than 0 and less than 1 + return ( 1 - Math.pow(1 - n, 3) ); } dojo.lfx.easeInOut = function(/*Decimal?*/ n){ - // summary: returns the point on the line - // n: a floating point number greater than 0 and less than 1 - return ( (3 * Math.pow(n, 2)) - (2 * Math.pow(n, 3)) ); + // summary: returns the point on the line + // n: a floating point number greater than 0 and less than 1 + return ( (3 * Math.pow(n, 2)) - (2 * Math.pow(n, 3)) ); } dojo.lfx.IAnimation = function(){ - // summary: dojo.lfx.IAnimation is an interface that implements - // commonly used functions of animation objects + // summary: dojo.lfx.IAnimation is an interface that implements + // commonly used functions of animation objects } dojo.lang.extend(dojo.lfx.IAnimation, { - // public properties - curve: null, - duration: 1000, - easing: null, - repeatCount: 0, - rate: 10, + // public properties + curve: null, + duration: 1000, + easing: null, + repeatCount: 0, + rate: 10, + + // events + handler: null, + beforeBegin: null, + onBegin: null, + onAnimate: null, + onEnd: null, + onPlay: null, + onPause: null, + onStop: null, + + // public methods + play: null, + pause: null, + stop: null, + + connect: function(/*Event*/ evt, /*Object*/ scope, /*Function*/ newFunc){ + // summary: Convenience function. Quickly connect to an event + // of this object and save the old functions connected to it. + // evt: The name of the event to connect to. + // scope: the scope in which to run newFunc. + // newFunc: the function to run when evt is fired. + if(!newFunc){ + /* scope: Function + newFunc: null + pId: f */ + newFunc = scope; + scope = this; + } + newFunc = dojo.lang.hitch(scope, newFunc); + var oldFunc = this[evt]||function(){}; + this[evt] = function(){ + var ret = oldFunc.apply(this, arguments); + newFunc.apply(this, arguments); + return ret; + } + return this; // dojo.lfx.IAnimation + }, - // events - handler: null, - beforeBegin: null, - onBegin: null, - onAnimate: null, - onEnd: null, - onPlay: null, - onPause: null, - onStop: null, + fire: function(/*Event*/ evt, /*Array*/ args){ + // summary: Convenience function. Fire event "evt" and pass it + // the arguments specified in "args". + // evt: The event to fire. + // args: The arguments to pass to the event. + if(this[evt]){ + this[evt].apply(this, (args||[])); + } + return this; // dojo.lfx.IAnimation + }, + + repeat: function(/*int*/ count){ + // summary: Set the repeat count of this object. + // count: How many times to repeat the animation. + this.repeatCount = count; + return this; // dojo.lfx.IAnimation + }, - // public methods - play: null, - pause: null, - stop: null, - - connect: function(/*Event*/ evt, /*Object*/ scope, /*Function*/ newFunc){ - // summary: Convenience function. Quickly connect to an event - // of this object and save the old functions connected to it. - // evt: The name of the event to connect to. - // scope: the scope in which to run newFunc. - // newFunc: the function to run when evt is fired. - if(!newFunc){ - /* scope: Function - newFunc: null - pId: f */ - newFunc = scope; - scope = this; - } - newFunc = dojo.lang.hitch(scope, newFunc); - var oldFunc = this[evt]||function(){}; - this[evt] = function(){ - var ret = oldFunc.apply(this, arguments); - newFunc.apply(this, arguments); - return ret; - } - return this; // dojo.lfx.IAnimation - }, - - fire: function(/*Event*/ evt, /*Array*/ args){ - // summary: Convenience function. Fire event "evt" and pass it - // the arguments specified in "args". - // evt: The event to fire. - // args: The arguments to pass to the event. - if(this[evt]){ - this[evt].apply(this, (args||[])); - } - return this; // dojo.lfx.IAnimation - }, - - repeat: function(/*int*/ count){ - // summary: Set the repeat count of this object. - // count: How many times to repeat the animation. - this.repeatCount = count; - return this; // dojo.lfx.IAnimation - }, - - // private properties - _active: false, - _paused: false + // private properties + _active: false, + _paused: false }); -dojo.lfx.Animation = function( /*Object*/ handlers, - /*int*/ duration, - /*dojo.lfx.Line*/ curve, - /*function*/ easing, - /*int*/ repeatCount, - /*int*/ rate){ - // summary - // a generic animation object that fires callbacks into it's handlers - // object at various states - // handlers: { handler: Function?, onstart: Function?, onstop: Function?, onanimate: Function? } - dojo.lfx.IAnimation.call(this); - if(dojo.lang.isNumber(handlers)||(!handlers && duration.getValue)){ - // no handlers argument: - rate = repeatCount; - repeatCount = easing; - easing = curve; - curve = duration; - duration = handlers; - handlers = null; - }else if(handlers.getValue||dojo.lang.isArray(handlers)){ - // no handlers or duration: - rate = easing; - repeatCount = curve; - easing = duration; - curve = handlers; - duration = null; - handlers = null; - } - if(dojo.lang.isArray(curve)){ - /* curve: Array - pId: a */ - this.curve = new dojo.lfx.Line(curve[0], curve[1]); - }else{ - this.curve = curve; - } - if(duration != null && duration > 0){ this.duration = duration; } - if(repeatCount){ this.repeatCount = repeatCount; } - if(rate){ this.rate = rate; } - if(handlers){ - dojo.lang.forEach([ - "handler", "beforeBegin", "onBegin", - "onEnd", "onPlay", "onStop", "onAnimate" - ], function(item){ - if(handlers[item]){ - this.connect(item, handlers[item]); - } - }, this); - } - if(easing && dojo.lang.isFunction(easing)){ - this.easing=easing; - } +dojo.lfx.Animation = function( /*Object*/ handlers, + /*int*/ duration, + /*dojo.lfx.Line*/ curve, + /*function*/ easing, + /*int*/ repeatCount, + /*int*/ rate){ + // summary + // a generic animation object that fires callbacks into it's handlers + // object at various states + // handlers: { handler: Function?, onstart: Function?, onstop: Function?, onanimate: Function? } + dojo.lfx.IAnimation.call(this); + if(dojo.lang.isNumber(handlers)||(!handlers && duration.getValue)){ + // no handlers argument: + rate = repeatCount; + repeatCount = easing; + easing = curve; + curve = duration; + duration = handlers; + handlers = null; + }else if(handlers.getValue||dojo.lang.isArray(handlers)){ + // no handlers or duration: + rate = easing; + repeatCount = curve; + easing = duration; + curve = handlers; + duration = null; + handlers = null; + } + if(dojo.lang.isArray(curve)){ + /* curve: Array + pId: a */ + this.curve = new dojo.lfx.Line(curve[0], curve[1]); + }else{ + this.curve = curve; + } + if(duration != null && duration > 0){ this.duration = duration; } + if(repeatCount){ this.repeatCount = repeatCount; } + if(rate){ this.rate = rate; } + if(handlers){ + dojo.lang.forEach([ + "handler", "beforeBegin", "onBegin", + "onEnd", "onPlay", "onStop", "onAnimate" + ], function(item){ + if(handlers[item]){ + this.connect(item, handlers[item]); + } + }, this); + } + if(easing && dojo.lang.isFunction(easing)){ + this.easing=easing; + } } dojo.inherits(dojo.lfx.Animation, dojo.lfx.IAnimation); dojo.lang.extend(dojo.lfx.Animation, { - // "private" properties - _startTime: null, - _endTime: null, - _timer: null, - _percent: 0, - _startRepeatCount: 0, + // "private" properties + _startTime: null, + _endTime: null, + _timer: null, + _percent: 0, + _startRepeatCount: 0, - // public methods - play: function(/*int?*/ delay, /*bool?*/ gotoStart){ - // summary: Start the animation. - // delay: How many milliseconds to delay before starting. - // gotoStart: If true, starts the animation from the beginning; otherwise, - // starts it from its current position. - if(gotoStart){ - clearTimeout(this._timer); - this._active = false; - this._paused = false; - this._percent = 0; - }else if(this._active && !this._paused){ - return this; // dojo.lfx.Animation - } + // public methods + play: function(/*int?*/ delay, /*bool?*/ gotoStart){ + // summary: Start the animation. + // delay: How many milliseconds to delay before starting. + // gotoStart: If true, starts the animation from the beginning; otherwise, + // starts it from its current position. + if(gotoStart){ + clearTimeout(this._timer); + this._active = false; + this._paused = false; + this._percent = 0; + }else if(this._active && !this._paused){ + return this; // dojo.lfx.Animation + } + + this.fire("handler", ["beforeBegin"]); + this.fire("beforeBegin"); - this.fire("handler", ["beforeBegin"]); - this.fire("beforeBegin"); + if(delay > 0){ + setTimeout(dojo.lang.hitch(this, function(){ this.play(null, gotoStart); }), delay); + return this; // dojo.lfx.Animation + } + + this._startTime = new Date().valueOf(); + if(this._paused){ + this._startTime -= (this.duration * this._percent / 100); + } + this._endTime = this._startTime + this.duration; - if(delay > 0){ - setTimeout(dojo.lang.hitch(this, function(){ this.play(null, gotoStart); }), delay); - return this; // dojo.lfx.Animation - } + this._active = true; + this._paused = false; + + var step = this._percent / 100; + var value = this.curve.getValue(step); + if(this._percent == 0 ){ + if(!this._startRepeatCount){ + this._startRepeatCount = this.repeatCount; + } + this.fire("handler", ["begin", value]); + this.fire("onBegin", [value]); + } - this._startTime = new Date().valueOf(); - if(this._paused){ - this._startTime -= (this.duration * this._percent / 100); - } - this._endTime = this._startTime + this.duration; + this.fire("handler", ["play", value]); + this.fire("onPlay", [value]); - this._active = true; - this._paused = false; + this._cycle(); + return this; // dojo.lfx.Animation + }, - var step = this._percent / 100; - var value = this.curve.getValue(step); - if(this._percent == 0 ){ - if(!this._startRepeatCount){ - this._startRepeatCount = this.repeatCount; - } - this.fire("handler", ["begin", value]); - this.fire("onBegin", [value]); - } + pause: function(){ + // summary: Pauses a running animation. + clearTimeout(this._timer); + if(!this._active){ return this; /*dojo.lfx.Animation*/} + this._paused = true; + var value = this.curve.getValue(this._percent / 100); + this.fire("handler", ["pause", value]); + this.fire("onPause", [value]); + return this; // dojo.lfx.Animation + }, - this.fire("handler", ["play", value]); - this.fire("onPlay", [value]); + gotoPercent: function(/*Decimal*/ pct, /*bool?*/ andPlay){ + // summary: Sets the progress of the animation. + // pct: A percentage in decimal notation (between and including 0.0 and 1.0). + // andPlay: If true, play the animation after setting the progress. + clearTimeout(this._timer); + this._active = true; + this._paused = true; + this._percent = pct; + if(andPlay){ this.play(); } + return this; // dojo.lfx.Animation + }, - this._cycle(); - return this; // dojo.lfx.Animation - }, + stop: function(/*bool?*/ gotoEnd){ + // summary: Stops a running animation. + // gotoEnd: If true, the animation will end. + clearTimeout(this._timer); + var step = this._percent / 100; + if(gotoEnd){ + step = 1; + } + var value = this.curve.getValue(step); + this.fire("handler", ["stop", value]); + this.fire("onStop", [value]); + this._active = false; + this._paused = false; + return this; // dojo.lfx.Animation + }, - pause: function(){ - // summary: Pauses a running animation. - clearTimeout(this._timer); - if(!this._active){ return this; /*dojo.lfx.Animation*/} - this._paused = true; - var value = this.curve.getValue(this._percent / 100); - this.fire("handler", ["pause", value]); - this.fire("onPause", [value]); - return this; // dojo.lfx.Animation - }, + status: function(){ + // summary: Returns a string representation of the status of + // the animation. + if(this._active){ + return this._paused ? "paused" : "playing"; // String + }else{ + return "stopped"; // String + } + return this; + }, - gotoPercent: function(/*Decimal*/ pct, /*bool?*/ andPlay){ - // summary: Sets the progress of the animation. - // pct: A percentage in decimal notation (between and including 0.0 and 1.0). - // andPlay: If true, play the animation after setting the progress. - clearTimeout(this._timer); - this._active = true; - this._paused = true; - this._percent = pct; - if(andPlay){ this.play(); } - return this; // dojo.lfx.Animation - }, + // "private" methods + _cycle: function(){ + clearTimeout(this._timer); + if(this._active){ + var curr = new Date().valueOf(); + var step = (curr - this._startTime) / (this._endTime - this._startTime); - stop: function(/*bool?*/ gotoEnd){ - // summary: Stops a running animation. - // gotoEnd: If true, the animation will end. - clearTimeout(this._timer); - var step = this._percent / 100; - if(gotoEnd){ - step = 1; - } - var value = this.curve.getValue(step); - this.fire("handler", ["stop", value]); - this.fire("onStop", [value]); - this._active = false; - this._paused = false; - return this; // dojo.lfx.Animation - }, + if(step >= 1){ + step = 1; + this._percent = 100; + }else{ + this._percent = step * 100; + } + + // Perform easing + if((this.easing)&&(dojo.lang.isFunction(this.easing))){ + step = this.easing(step); + } - status: function(){ - // summary: Returns a string representation of the status of - // the animation. - if(this._active){ - return this._paused ? "paused" : "playing"; // String - }else{ - return "stopped"; // String - } - return this; - }, + var value = this.curve.getValue(step); + this.fire("handler", ["animate", value]); + this.fire("onAnimate", [value]); - // "private" methods - _cycle: function(){ - clearTimeout(this._timer); - if(this._active){ - var curr = new Date().valueOf(); - var step = (curr - this._startTime) / (this._endTime - this._startTime); + if( step < 1 ){ + this._timer = setTimeout(dojo.lang.hitch(this, "_cycle"), this.rate); + }else{ + this._active = false; + this.fire("handler", ["end"]); + this.fire("onEnd"); - if(step >= 1){ - step = 1; - this._percent = 100; - }else{ - this._percent = step * 100; - } - - // Perform easing - if((this.easing)&&(dojo.lang.isFunction(this.easing))){ - step = this.easing(step); - } - - var value = this.curve.getValue(step); - this.fire("handler", ["animate", value]); - this.fire("onAnimate", [value]); - - if( step < 1 ){ - this._timer = setTimeout(dojo.lang.hitch(this, "_cycle"), this.rate); - }else{ - this._active = false; - this.fire("handler", ["end"]); - this.fire("onEnd"); - - if(this.repeatCount > 0){ - this.repeatCount--; - this.play(null, true); - }else if(this.repeatCount == -1){ - this.play(null, true); - }else{ - if(this._startRepeatCount){ - this.repeatCount = this._startRepeatCount; - this._startRepeatCount = 0; - } - } - } - } - return this; // dojo.lfx.Animation - } + if(this.repeatCount > 0){ + this.repeatCount--; + this.play(null, true); + }else if(this.repeatCount == -1){ + this.play(null, true); + }else{ + if(this._startRepeatCount){ + this.repeatCount = this._startRepeatCount; + this._startRepeatCount = 0; + } + } + } + } + return this; // dojo.lfx.Animation + } }); dojo.lfx.Combine = function(/*dojo.lfx.IAnimation...*/ animations){ - // summary: An animation object to play animations passed to it at the same time. - dojo.lfx.IAnimation.call(this); - this._anims = []; - this._animsEnded = 0; - - var anims = arguments; - if(anims.length == 1 && (dojo.lang.isArray(anims[0]) || dojo.lang.isArrayLike(anims[0]))){ - /* animations: dojo.lfx.IAnimation[] - pId: a */ - anims = anims[0]; - } - - dojo.lang.forEach(anims, function(anim){ - this._anims.push(anim); - anim.connect("onEnd", dojo.lang.hitch(this, "_onAnimsEnded")); - }, this); + // summary: An animation object to play animations passed to it at the same time. + dojo.lfx.IAnimation.call(this); + this._anims = []; + this._animsEnded = 0; + + var anims = arguments; + if(anims.length == 1 && (dojo.lang.isArray(anims[0]) || dojo.lang.isArrayLike(anims[0]))){ + /* animations: dojo.lfx.IAnimation[] + pId: a */ + anims = anims[0]; + } + + dojo.lang.forEach(anims, function(anim){ + this._anims.push(anim); + anim.connect("onEnd", dojo.lang.hitch(this, "_onAnimsEnded")); + }, this); } dojo.inherits(dojo.lfx.Combine, dojo.lfx.IAnimation); dojo.lang.extend(dojo.lfx.Combine, { - // private members - _animsEnded: 0, + // private members + _animsEnded: 0, + + // public methods + play: function(/*int?*/ delay, /*bool?*/ gotoStart){ + // summary: Start the animations. + // delay: How many milliseconds to delay before starting. + // gotoStart: If true, starts the animations from the beginning; otherwise, + // starts them from their current position. + if( !this._anims.length ){ return this; /*dojo.lfx.Combine*/} - // public methods - play: function(/*int?*/ delay, /*bool?*/ gotoStart){ - // summary: Start the animations. - // delay: How many milliseconds to delay before starting. - // gotoStart: If true, starts the animations from the beginning; otherwise, - // starts them from their current position. - if( !this._anims.length ){ return this; /*dojo.lfx.Combine*/} + this.fire("beforeBegin"); - this.fire("beforeBegin"); - - if(delay > 0){ - setTimeout(dojo.lang.hitch(this, function(){ this.play(null, gotoStart); }), delay); - return this; // dojo.lfx.Combine - } - - if(gotoStart || this._anims[0].percent == 0){ - this.fire("onBegin"); - } - this.fire("onPlay"); - this._animsCall("play", null, gotoStart); - return this; // dojo.lfx.Combine - }, - - pause: function(){ - // summary: Pauses the running animations. - this.fire("onPause"); - this._animsCall("pause"); - return this; // dojo.lfx.Combine - }, - - stop: function(/*bool?*/ gotoEnd){ - // summary: Stops the running animations. - // gotoEnd: If true, the animations will end. - this.fire("onStop"); - this._animsCall("stop", gotoEnd); - return this; // dojo.lfx.Combine - }, - - // private methods - _onAnimsEnded: function(){ - this._animsEnded++; - if(this._animsEnded >= this._anims.length){ - this.fire("onEnd"); - } - return this; // dojo.lfx.Combine - }, - - _animsCall: function(/*String*/ funcName){ - var args = []; - if(arguments.length > 1){ - for(var i = 1 ; i < arguments.length ; i++){ - args.push(arguments[i]); - } - } - var _this = this; - dojo.lang.forEach(this._anims, function(anim){ - anim[funcName](args); - }, _this); - return this; // dojo.lfx.Combine - } + if(delay > 0){ + setTimeout(dojo.lang.hitch(this, function(){ this.play(null, gotoStart); }), delay); + return this; // dojo.lfx.Combine + } + + if(gotoStart || this._anims[0].percent == 0){ + this.fire("onBegin"); + } + this.fire("onPlay"); + this._animsCall("play", null, gotoStart); + return this; // dojo.lfx.Combine + }, + + pause: function(){ + // summary: Pauses the running animations. + this.fire("onPause"); + this._animsCall("pause"); + return this; // dojo.lfx.Combine + }, + + stop: function(/*bool?*/ gotoEnd){ + // summary: Stops the running animations. + // gotoEnd: If true, the animations will end. + this.fire("onStop"); + this._animsCall("stop", gotoEnd); + return this; // dojo.lfx.Combine + }, + + // private methods + _onAnimsEnded: function(){ + this._animsEnded++; + if(this._animsEnded >= this._anims.length){ + this.fire("onEnd"); + } + return this; // dojo.lfx.Combine + }, + + _animsCall: function(/*String*/ funcName){ + var args = []; + if(arguments.length > 1){ + for(var i = 1 ; i < arguments.length ; i++){ + args.push(arguments[i]); + } + } + var _this = this; + dojo.lang.forEach(this._anims, function(anim){ + anim[funcName](args); + }, _this); + return this; // dojo.lfx.Combine + } }); dojo.lfx.Chain = function(/*dojo.lfx.IAnimation...*/ animations) { - // summary: An animation object to play animations passed to it - // one after another. - dojo.lfx.IAnimation.call(this); - this._anims = []; - this._currAnim = -1; - - var anims = arguments; - if(anims.length == 1 && (dojo.lang.isArray(anims[0]) || dojo.lang.isArrayLike(anims[0]))){ - /* animations: dojo.lfx.IAnimation[] - pId: a */ - anims = anims[0]; - } - - var _this = this; - dojo.lang.forEach(anims, function(anim, i, anims_arr){ - this._anims.push(anim); - if(i < anims_arr.length - 1){ - anim.connect("onEnd", dojo.lang.hitch(this, "_playNext") ); - }else{ - anim.connect("onEnd", dojo.lang.hitch(this, function(){ this.fire("onEnd"); }) ); - } - }, this); + // summary: An animation object to play animations passed to it + // one after another. + dojo.lfx.IAnimation.call(this); + this._anims = []; + this._currAnim = -1; + + var anims = arguments; + if(anims.length == 1 && (dojo.lang.isArray(anims[0]) || dojo.lang.isArrayLike(anims[0]))){ + /* animations: dojo.lfx.IAnimation[] + pId: a */ + anims = anims[0]; + } + + var _this = this; + dojo.lang.forEach(anims, function(anim, i, anims_arr){ + this._anims.push(anim); + if(i < anims_arr.length - 1){ + anim.connect("onEnd", dojo.lang.hitch(this, "_playNext") ); + }else{ + anim.connect("onEnd", dojo.lang.hitch(this, function(){ this.fire("onEnd"); }) ); + } + }, this); } dojo.inherits(dojo.lfx.Chain, dojo.lfx.IAnimation); dojo.lang.extend(dojo.lfx.Chain, { - // private members - _currAnim: -1, + // private members + _currAnim: -1, + + // public methods + play: function(/*int?*/ delay, /*bool?*/ gotoStart){ + // summary: Start the animation sequence. + // delay: How many milliseconds to delay before starting. + // gotoStart: If true, starts the sequence from the beginning; otherwise, + // starts it from its current position. + if( !this._anims.length ) { return this; /*dojo.lfx.Chain*/} + if( gotoStart || !this._anims[this._currAnim] ) { + this._currAnim = 0; + } - // public methods - play: function(/*int?*/ delay, /*bool?*/ gotoStart){ - // summary: Start the animation sequence. - // delay: How many milliseconds to delay before starting. - // gotoStart: If true, starts the sequence from the beginning; otherwise, - // starts it from its current position. - if( !this._anims.length ) { return this; /*dojo.lfx.Chain*/} - if( gotoStart || !this._anims[this._currAnim] ) { - this._currAnim = 0; - } + var currentAnimation = this._anims[this._currAnim]; - var currentAnimation = this._anims[this._currAnim]; - - this.fire("beforeBegin"); - if(delay > 0){ - setTimeout(dojo.lang.hitch(this, function(){ this.play(null, gotoStart); }), delay); - return this; // dojo.lfx.Chain - } - - if(currentAnimation){ - if(this._currAnim == 0){ - this.fire("handler", ["begin", this._currAnim]); - this.fire("onBegin", [this._currAnim]); - } - this.fire("onPlay", [this._currAnim]); - currentAnimation.play(null, gotoStart); - } - return this; // dojo.lfx.Chain - }, - - pause: function(){ - // summary: Pauses the running animation sequence. - if( this._anims[this._currAnim] ) { - this._anims[this._currAnim].pause(); - this.fire("onPause", [this._currAnim]); - } - return this; // dojo.lfx.Chain - }, - - playPause: function(){ - // summary: If the animation sequence is playing, pause it; otherwise, - // play it. - if(this._anims.length == 0){ return this; } - if(this._currAnim == -1){ this._currAnim = 0; } - var currAnim = this._anims[this._currAnim]; - if( currAnim ) { - if( !currAnim._active || currAnim._paused ) { - this.play(); - } else { - this.pause(); - } - } - return this; // dojo.lfx.Chain - }, - - stop: function(){ - // summary: Stops the running animations. - var currAnim = this._anims[this._currAnim]; - if(currAnim){ - currAnim.stop(); - this.fire("onStop", [this._currAnim]); - } - return currAnim; // dojo.lfx.IAnimation - }, - - // private methods - _playNext: function(){ - if( this._currAnim == -1 || this._anims.length == 0 ) { return this; } - this._currAnim++; - if( this._anims[this._currAnim] ){ - this._anims[this._currAnim].play(null, true); - } - return this; // dojo.lfx.Chain - } + this.fire("beforeBegin"); + if(delay > 0){ + setTimeout(dojo.lang.hitch(this, function(){ this.play(null, gotoStart); }), delay); + return this; // dojo.lfx.Chain + } + + if(currentAnimation){ + if(this._currAnim == 0){ + this.fire("handler", ["begin", this._currAnim]); + this.fire("onBegin", [this._currAnim]); + } + this.fire("onPlay", [this._currAnim]); + currentAnimation.play(null, gotoStart); + } + return this; // dojo.lfx.Chain + }, + + pause: function(){ + // summary: Pauses the running animation sequence. + if( this._anims[this._currAnim] ) { + this._anims[this._currAnim].pause(); + this.fire("onPause", [this._currAnim]); + } + return this; // dojo.lfx.Chain + }, + + playPause: function(){ + // summary: If the animation sequence is playing, pause it; otherwise, + // play it. + if(this._anims.length == 0){ return this; } + if(this._currAnim == -1){ this._currAnim = 0; } + var currAnim = this._anims[this._currAnim]; + if( currAnim ) { + if( !currAnim._active || currAnim._paused ) { + this.play(); + } else { + this.pause(); + } + } + return this; // dojo.lfx.Chain + }, + + stop: function(){ + // summary: Stops the running animations. + var currAnim = this._anims[this._currAnim]; + if(currAnim){ + currAnim.stop(); + this.fire("onStop", [this._currAnim]); + } + return currAnim; // dojo.lfx.IAnimation + }, + + // private methods + _playNext: function(){ + if( this._currAnim == -1 || this._anims.length == 0 ) { return this; } + this._currAnim++; + if( this._anims[this._currAnim] ){ + this._anims[this._currAnim].play(null, true); + } + return this; // dojo.lfx.Chain + } }); dojo.lfx.combine = function(/*dojo.lfx.IAnimation...*/ animations){ - // summary: Convenience function. Returns a dojo.lfx.Combine created - // using the animations passed in. - var anims = arguments; - if(dojo.lang.isArray(arguments[0])){ - /* animations: dojo.lfx.IAnimation[] - pId: a */ - anims = arguments[0]; - } - if(anims.length == 1){ return anims[0]; } - return new dojo.lfx.Combine(anims); // dojo.lfx.Combine + // summary: Convenience function. Returns a dojo.lfx.Combine created + // using the animations passed in. + var anims = arguments; + if(dojo.lang.isArray(arguments[0])){ + /* animations: dojo.lfx.IAnimation[] + pId: a */ + anims = arguments[0]; + } + if(anims.length == 1){ return anims[0]; } + return new dojo.lfx.Combine(anims); // dojo.lfx.Combine } dojo.lfx.chain = function(/*dojo.lfx.IAnimation...*/ animations){ - // summary: Convenience function. Returns a dojo.lfx.Chain created - // using the animations passed in. - var anims = arguments; - if(dojo.lang.isArray(arguments[0])){ - /* animations: dojo.lfx.IAnimation[] - pId: a */ - anims = arguments[0]; - } - if(anims.length == 1){ return anims[0]; } - return new dojo.lfx.Chain(anims); // dojo.lfx.Combine + // summary: Convenience function. Returns a dojo.lfx.Chain created + // using the animations passed in. + var anims = arguments; + if(dojo.lang.isArray(arguments[0])){ + /* animations: dojo.lfx.IAnimation[] + pId: a */ + anims = arguments[0]; + } + if(anims.length == 1){ return anims[0]; } + return new dojo.lfx.Chain(anims); // dojo.lfx.Combine } dojo.provide("dojo.html.common"); @@ -7466,8 +7476,8 @@ dojo.provide("dojo.html.common"); dojo.lang.mixin(dojo.html, dojo.dom); dojo.html.body = function(){ - dojo.deprecated("dojo.html.body() moved to dojo.body()", "0.5"); - return dojo.body(); + dojo.deprecated("dojo.html.body() moved to dojo.body()", "0.5"); + return dojo.body(); } // FIXME: we are going to assume that we can throw any and every rendering @@ -7475,323 +7485,323 @@ dojo.html.body = function(){ // Need to investigate for KHTML and Opera dojo.html.getEventTarget = function(/* DOMEvent */evt){ - // summary - // Returns the target of an event - if(!evt) { evt = dojo.global().event || {} }; - var t = (evt.srcElement ? evt.srcElement : (evt.target ? evt.target : null)); - while((t)&&(t.nodeType!=1)){ t = t.parentNode; } - return t; // HTMLElement + // summary + // Returns the target of an event + if(!evt) { evt = dojo.global().event || {} }; + var t = (evt.srcElement ? evt.srcElement : (evt.target ? evt.target : null)); + while((t)&&(t.nodeType!=1)){ t = t.parentNode; } + return t; // HTMLElement } dojo.html.getViewport = function(){ - // summary - // Returns the dimensions of the viewable area of a browser window - var _window = dojo.global(); - var _document = dojo.doc(); - var w = 0; - var h = 0; + // summary + // Returns the dimensions of the viewable area of a browser window + var _window = dojo.global(); + var _document = dojo.doc(); + var w = 0; + var h = 0; - if(dojo.render.html.mozilla){ - // mozilla - w = _document.documentElement.clientWidth; - h = _window.innerHeight; - }else if(!dojo.render.html.opera && _window.innerWidth){ - //in opera9, dojo.body().clientWidth should be used, instead - //of window.innerWidth/document.documentElement.clientWidth - //so we have to check whether it is opera - w = _window.innerWidth; - h = _window.innerHeight; - } else if (!dojo.render.html.opera && dojo.exists(_document, "documentElement.clientWidth")){ - // IE6 Strict - var w2 = _document.documentElement.clientWidth; - // this lets us account for scrollbars - if(!w || w2 && w2 < w) { - w = w2; - } - h = _document.documentElement.clientHeight; - } else if (dojo.body().clientWidth){ - // IE, Opera - w = dojo.body().clientWidth; - h = dojo.body().clientHeight; - } - return { width: w, height: h }; // object + if(dojo.render.html.mozilla){ + // mozilla + w = _document.documentElement.clientWidth; + h = _window.innerHeight; + }else if(!dojo.render.html.opera && _window.innerWidth){ + //in opera9, dojo.body().clientWidth should be used, instead + //of window.innerWidth/document.documentElement.clientWidth + //so we have to check whether it is opera + w = _window.innerWidth; + h = _window.innerHeight; + } else if (!dojo.render.html.opera && dojo.exists(_document, "documentElement.clientWidth")){ + // IE6 Strict + var w2 = _document.documentElement.clientWidth; + // this lets us account for scrollbars + if(!w || w2 && w2 < w) { + w = w2; + } + h = _document.documentElement.clientHeight; + } else if (dojo.body().clientWidth){ + // IE, Opera + w = dojo.body().clientWidth; + h = dojo.body().clientHeight; + } + return { width: w, height: h }; // object } dojo.html.getScroll = function(){ - // summary - // Returns the scroll position of the document - var _window = dojo.global(); - var _document = dojo.doc(); - var top = _window.pageYOffset || _document.documentElement.scrollTop || dojo.body().scrollTop || 0; - var left = _window.pageXOffset || _document.documentElement.scrollLeft || dojo.body().scrollLeft || 0; - return { - top: top, - left: left, - offset:{ x: left, y: top } // note the change, NOT an Array with added properties. - }; // object + // summary + // Returns the scroll position of the document + var _window = dojo.global(); + var _document = dojo.doc(); + var top = _window.pageYOffset || _document.documentElement.scrollTop || dojo.body().scrollTop || 0; + var left = _window.pageXOffset || _document.documentElement.scrollLeft || dojo.body().scrollLeft || 0; + return { + top: top, + left: left, + offset:{ x: left, y: top } // note the change, NOT an Array with added properties. + }; // object } dojo.html.getParentByType = function(/* HTMLElement */node, /* string */type) { - // summary - // Returns the first ancestor of node with tagName type. - var _document = dojo.doc(); - var parent = dojo.byId(node); - type = type.toLowerCase(); - while((parent)&&(parent.nodeName.toLowerCase()!=type)){ - if(parent==(_document["body"]||_document["documentElement"])){ - return null; - } - parent = parent.parentNode; - } - return parent; // HTMLElement + // summary + // Returns the first ancestor of node with tagName type. + var _document = dojo.doc(); + var parent = dojo.byId(node); + type = type.toLowerCase(); + while((parent)&&(parent.nodeName.toLowerCase()!=type)){ + if(parent==(_document["body"]||_document["documentElement"])){ + return null; + } + parent = parent.parentNode; + } + return parent; // HTMLElement } dojo.html.getAttribute = function(/* HTMLElement */node, /* string */attr){ - // summary - // Returns the value of attribute attr from node. - node = dojo.byId(node); - // FIXME: need to add support for attr-specific accessors - if((!node)||(!node.getAttribute)){ - // if(attr !== 'nwType'){ - // alert("getAttr of '" + attr + "' with bad node"); - // } - return null; - } - var ta = typeof attr == 'string' ? attr : new String(attr); + // summary + // Returns the value of attribute attr from node. + node = dojo.byId(node); + // FIXME: need to add support for attr-specific accessors + if((!node)||(!node.getAttribute)){ + // if(attr !== 'nwType'){ + // alert("getAttr of '" + attr + "' with bad node"); + // } + return null; + } + var ta = typeof attr == 'string' ? attr : new String(attr); - // first try the approach most likely to succeed - var v = node.getAttribute(ta.toUpperCase()); - if((v)&&(typeof v == 'string')&&(v!="")){ - return v; // string - } + // first try the approach most likely to succeed + var v = node.getAttribute(ta.toUpperCase()); + if((v)&&(typeof v == 'string')&&(v!="")){ + return v; // string + } - // try returning the attributes value, if we couldn't get it as a string - if(v && v.value){ - return v.value; // string - } + // try returning the attributes value, if we couldn't get it as a string + if(v && v.value){ + return v.value; // string + } - // this should work on Opera 7, but it's a little on the crashy side - if((node.getAttributeNode)&&(node.getAttributeNode(ta))){ - return (node.getAttributeNode(ta)).value; // string - }else if(node.getAttribute(ta)){ - return node.getAttribute(ta); // string - }else if(node.getAttribute(ta.toLowerCase())){ - return node.getAttribute(ta.toLowerCase()); // string - } - return null; // string + // this should work on Opera 7, but it's a little on the crashy side + if((node.getAttributeNode)&&(node.getAttributeNode(ta))){ + return (node.getAttributeNode(ta)).value; // string + }else if(node.getAttribute(ta)){ + return node.getAttribute(ta); // string + }else if(node.getAttribute(ta.toLowerCase())){ + return node.getAttribute(ta.toLowerCase()); // string + } + return null; // string } - + dojo.html.hasAttribute = function(/* HTMLElement */node, /* string */attr){ - // summary - // Determines whether or not the specified node carries a value for the attribute in question. - return dojo.html.getAttribute(dojo.byId(node), attr) ? true : false; // boolean + // summary + // Determines whether or not the specified node carries a value for the attribute in question. + return dojo.html.getAttribute(dojo.byId(node), attr) ? true : false; // boolean } - + dojo.html.getCursorPosition = function(/* DOMEvent */e){ - // summary - // Returns the mouse position relative to the document (not the viewport). - // For example, if you have a document that is 10000px tall, - // but your browser window is only 100px tall, - // if you scroll to the bottom of the document and call this function it - // will return {x: 0, y: 10000} - // NOTE: for events delivered via dojo.event.connect() and/or dojoAttachEvent (for widgets), - // you can just access evt.pageX and evt.pageY, rather than calling this function. - e = e || dojo.global().event; - var cursor = {x:0, y:0}; - if(e.pageX || e.pageY){ - cursor.x = e.pageX; - cursor.y = e.pageY; - }else{ - var de = dojo.doc().documentElement; - var db = dojo.body(); - cursor.x = e.clientX + ((de||db)["scrollLeft"]) - ((de||db)["clientLeft"]); - cursor.y = e.clientY + ((de||db)["scrollTop"]) - ((de||db)["clientTop"]); - } - return cursor; // object + // summary + // Returns the mouse position relative to the document (not the viewport). + // For example, if you have a document that is 10000px tall, + // but your browser window is only 100px tall, + // if you scroll to the bottom of the document and call this function it + // will return {x: 0, y: 10000} + // NOTE: for events delivered via dojo.event.connect() and/or dojoAttachEvent (for widgets), + // you can just access evt.pageX and evt.pageY, rather than calling this function. + e = e || dojo.global().event; + var cursor = {x:0, y:0}; + if(e.pageX || e.pageY){ + cursor.x = e.pageX; + cursor.y = e.pageY; + }else{ + var de = dojo.doc().documentElement; + var db = dojo.body(); + cursor.x = e.clientX + ((de||db)["scrollLeft"]) - ((de||db)["clientLeft"]); + cursor.y = e.clientY + ((de||db)["scrollTop"]) - ((de||db)["clientTop"]); + } + return cursor; // object } dojo.html.isTag = function(/* HTMLElement */node) { - // summary - // Like dojo.dom.isTag, except case-insensitive - node = dojo.byId(node); - if(node && node.tagName) { - for (var i=1; i, - //which will be treated as an external javascript file in IE - var xscript = dojo.doc().createElement('script'); - xscript.src = "javascript:'dojo.html.createExternalElement=function(doc, tag){ return doc.createElement(tag); }'"; - dojo.doc().getElementsByTagName("head")[0].appendChild(xscript); - })(); - } + //The trick is to define a function in a script.src property: + // , + //which will be treated as an external javascript file in IE + var xscript = dojo.doc().createElement('script'); + xscript.src = "javascript:'dojo.html.createExternalElement=function(doc, tag){ return doc.createElement(tag); }'"; + dojo.doc().getElementsByTagName("head")[0].appendChild(xscript); + })(); + } }else{ - //for other browsers, simply use document.createElement - //is enough - dojo.html.createExternalElement = function(/* HTMLDocument */doc, /* string */tag){ - // summary - // Creates an element in the HTML document, here for ActiveX activation workaround. - return doc.createElement(tag); // HTMLElement - } + //for other browsers, simply use document.createElement + //is enough + dojo.html.createExternalElement = function(/* HTMLDocument */doc, /* string */tag){ + // summary + // Creates an element in the HTML document, here for ActiveX activation workaround. + return doc.createElement(tag); // HTMLElement + } } dojo.html._callDeprecated = function(inFunc, replFunc, args, argName, retValue){ - dojo.deprecated("dojo.html." + inFunc, - "replaced by dojo.html." + replFunc + "(" + (argName ? "node, {"+ argName + ": " + argName + "}" : "" ) + ")" + (retValue ? "." + retValue : ""), "0.5"); - var newArgs = []; - if(argName){ var argsIn = {}; argsIn[argName] = args[1]; newArgs.push(args[0]); newArgs.push(argsIn); } - else { newArgs = args } - var ret = dojo.html[replFunc].apply(dojo.html, args); - if(retValue){ return ret[retValue]; } - else { return ret; } + dojo.deprecated("dojo.html." + inFunc, + "replaced by dojo.html." + replFunc + "(" + (argName ? "node, {"+ argName + ": " + argName + "}" : "" ) + ")" + (retValue ? "." + retValue : ""), "0.5"); + var newArgs = []; + if(argName){ var argsIn = {}; argsIn[argName] = args[1]; newArgs.push(args[0]); newArgs.push(argsIn); } + else { newArgs = args } + var ret = dojo.html[replFunc].apply(dojo.html, args); + if(retValue){ return ret[retValue]; } + else { return ret; } } dojo.html.getViewportWidth = function(){ - return dojo.html._callDeprecated("getViewportWidth", "getViewport", arguments, null, "width"); + return dojo.html._callDeprecated("getViewportWidth", "getViewport", arguments, null, "width"); } dojo.html.getViewportHeight = function(){ - return dojo.html._callDeprecated("getViewportHeight", "getViewport", arguments, null, "height"); + return dojo.html._callDeprecated("getViewportHeight", "getViewport", arguments, null, "height"); } dojo.html.getViewportSize = function(){ - return dojo.html._callDeprecated("getViewportSize", "getViewport", arguments); + return dojo.html._callDeprecated("getViewportSize", "getViewport", arguments); } dojo.html.getScrollTop = function(){ - return dojo.html._callDeprecated("getScrollTop", "getScroll", arguments, null, "top"); + return dojo.html._callDeprecated("getScrollTop", "getScroll", arguments, null, "top"); } dojo.html.getScrollLeft = function(){ - return dojo.html._callDeprecated("getScrollLeft", "getScroll", arguments, null, "left"); + return dojo.html._callDeprecated("getScrollLeft", "getScroll", arguments, null, "left"); } dojo.html.getScrollOffset = function(){ - return dojo.html._callDeprecated("getScrollOffset", "getScroll", arguments, null, "offset"); + return dojo.html._callDeprecated("getScrollOffset", "getScroll", arguments, null, "offset"); } dojo.provide("dojo.uri.Uri"); dojo.uri = new function() { - this.dojoUri = function (/*dojo.uri.Uri||String*/uri) { - // summary: returns a Uri object resolved relative to the dojo root - return new dojo.uri.Uri(dojo.hostenv.getBaseScriptUri(), uri); - } + this.dojoUri = function (/*dojo.uri.Uri||String*/uri) { + // summary: returns a Uri object resolved relative to the dojo root + return new dojo.uri.Uri(dojo.hostenv.getBaseScriptUri(), uri); + } - this.moduleUri = function(/*String*/module, /*dojo.uri.Uri||String*/uri){ - // summary: returns a Uri object relative to a module - // description: Examples: dojo.uri.moduleUri("dojo.widget","templates/template.html"), or dojo.uri.moduleUri("acme","images/small.png") - var loc = dojo.hostenv.getModuleSymbols(module).join('/'); - if(!loc){ - return null; - } - if(loc.lastIndexOf("/") != loc.length-1){ - loc += "/"; - } + this.moduleUri = function(/*String*/module, /*dojo.uri.Uri||String*/uri){ + // summary: returns a Uri object relative to a module + // description: Examples: dojo.uri.moduleUri("dojo.widget","templates/template.html"), or dojo.uri.moduleUri("acme","images/small.png") + var loc = dojo.hostenv.getModuleSymbols(module).join('/'); + if(!loc){ + return null; + } + if(loc.lastIndexOf("/") != loc.length-1){ + loc += "/"; + } + + //If the path is an absolute path (starts with a / or is on another domain/xdomain) + //then don't add the baseScriptUri. + var colonIndex = loc.indexOf(":"); + var slashIndex = loc.indexOf("/"); + if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > slashIndex)){ + loc = dojo.hostenv.getBaseScriptUri() + loc; + } - //If the path is an absolute path (starts with a / or is on another domain/xdomain) - //then don't add the baseScriptUri. - var colonIndex = loc.indexOf(":"); - var slashIndex = loc.indexOf("/"); - if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > slashIndex)){ - loc = dojo.hostenv.getBaseScriptUri() + loc; - } + return new dojo.uri.Uri(loc,uri); + } - return new dojo.uri.Uri(loc,uri); - } + this.Uri = function (/*dojo.uri.Uri||String...*/) { + // summary: Constructor to create an object representing a URI. + // description: + // Each argument is evaluated in order relative to the next until + // a canonical uri is produced. To get an absolute Uri relative + // to the current document use + // new dojo.uri.Uri(document.baseURI, uri) - this.Uri = function (/*dojo.uri.Uri||String...*/) { - // summary: Constructor to create an object representing a URI. - // description: - // Each argument is evaluated in order relative to the next until - // a canonical uri is produced. To get an absolute Uri relative - // to the current document use - // new dojo.uri.Uri(document.baseURI, uri) + // TODO: support for IPv6, see RFC 2732 - // TODO: support for IPv6, see RFC 2732 + // resolve uri components relative to each other + var uri = arguments[0]; + for (var i = 1; i < arguments.length; i++) { + if(!arguments[i]) { continue; } - // resolve uri components relative to each other - var uri = arguments[0]; - for (var i = 1; i < arguments.length; i++) { - if(!arguments[i]) { continue; } + // Safari doesn't support this.constructor so we have to be explicit + var relobj = new dojo.uri.Uri(arguments[i].toString()); + var uriobj = new dojo.uri.Uri(uri.toString()); - // Safari doesn't support this.constructor so we have to be explicit - var relobj = new dojo.uri.Uri(arguments[i].toString()); - var uriobj = new dojo.uri.Uri(uri.toString()); + if ((relobj.path=="")&&(relobj.scheme==null)&&(relobj.authority==null)&&(relobj.query==null)) { + if (relobj.fragment != null) { uriobj.fragment = relobj.fragment; } + relobj = uriobj; + } else if (relobj.scheme == null) { + relobj.scheme = uriobj.scheme; - if ((relobj.path=="")&&(relobj.scheme==null)&&(relobj.authority==null)&&(relobj.query==null)) { - if (relobj.fragment != null) { uriobj.fragment = relobj.fragment; } - relobj = uriobj; - } else if (relobj.scheme == null) { - relobj.scheme = uriobj.scheme; + if (relobj.authority == null) { + relobj.authority = uriobj.authority; - if (relobj.authority == null) { - relobj.authority = uriobj.authority; + if (relobj.path.charAt(0) != "/") { + var path = uriobj.path.substring(0, + uriobj.path.lastIndexOf("/") + 1) + relobj.path; - if (relobj.path.charAt(0) != "/") { - var path = uriobj.path.substring(0, - uriobj.path.lastIndexOf("/") + 1) + relobj.path; + var segs = path.split("/"); + for (var j = 0; j < segs.length; j++) { + if (segs[j] == ".") { + if (j == segs.length - 1) { segs[j] = ""; } + else { segs.splice(j, 1); j--; } + } else if (j > 0 && !(j == 1 && segs[0] == "") && + segs[j] == ".." && segs[j-1] != "..") { - var segs = path.split("/"); - for (var j = 0; j < segs.length; j++) { - if (segs[j] == ".") { - if (j == segs.length - 1) { segs[j] = ""; } - else { segs.splice(j, 1); j--; } - } else if (j > 0 && !(j == 1 && segs[0] == "") && - segs[j] == ".." && segs[j-1] != "..") { + if (j == segs.length - 1) { segs.splice(j, 1); segs[j - 1] = ""; } + else { segs.splice(j - 1, 2); j -= 2; } + } + } + relobj.path = segs.join("/"); + } + } + } - if (j == segs.length - 1) { segs.splice(j, 1); segs[j - 1] = ""; } - else { segs.splice(j - 1, 2); j -= 2; } - } - } - relobj.path = segs.join("/"); - } - } - } + uri = ""; + if (relobj.scheme != null) { uri += relobj.scheme + ":"; } + if (relobj.authority != null) { uri += "//" + relobj.authority; } + uri += relobj.path; + if (relobj.query != null) { uri += "?" + relobj.query; } + if (relobj.fragment != null) { uri += "#" + relobj.fragment; } + } - uri = ""; - if (relobj.scheme != null) { uri += relobj.scheme + ":"; } - if (relobj.authority != null) { uri += "//" + relobj.authority; } - uri += relobj.path; - if (relobj.query != null) { uri += "?" + relobj.query; } - if (relobj.fragment != null) { uri += "#" + relobj.fragment; } - } + this.uri = uri.toString(); - this.uri = uri.toString(); + // break the uri into its main components + var regexp = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"; + var r = this.uri.match(new RegExp(regexp)); - // break the uri into its main components - var regexp = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"; - var r = this.uri.match(new RegExp(regexp)); + this.scheme = r[2] || (r[1] ? "" : null); + this.authority = r[4] || (r[3] ? "" : null); + this.path = r[5]; // can never be undefined + this.query = r[7] || (r[6] ? "" : null); + this.fragment = r[9] || (r[8] ? "" : null); - this.scheme = r[2] || (r[1] ? "" : null); - this.authority = r[4] || (r[3] ? "" : null); - this.path = r[5]; // can never be undefined - this.query = r[7] || (r[6] ? "" : null); - this.fragment = r[9] || (r[8] ? "" : null); + if (this.authority != null) { + // server based naming authority + regexp = "^((([^:]+:)?([^@]+))@)?([^:]*)(:([0-9]+))?$"; + r = this.authority.match(new RegExp(regexp)); - if (this.authority != null) { - // server based naming authority - regexp = "^((([^:]+:)?([^@]+))@)?([^:]*)(:([0-9]+))?$"; - r = this.authority.match(new RegExp(regexp)); + this.user = r[3] || null; + this.password = r[4] || null; + this.host = r[5]; + this.port = r[7] || null; + } - this.user = r[3] || null; - this.password = r[4] || null; - this.host = r[5]; - this.port = r[7] || null; - } - - this.toString = function(){ return this.uri; } - } + this.toString = function(){ return this.uri; } + } }; dojo.provide("dojo.html.style"); @@ -7799,804 +7809,804 @@ dojo.provide("dojo.html.style"); dojo.html.getClass = function(/* HTMLElement */node){ - // summary - // Returns the string value of the list of CSS classes currently assigned directly - // to the node in question. Returns an empty string if no class attribute is found; - node = dojo.byId(node); - if(!node){ return ""; } - var cs = ""; - if(node.className){ - cs = node.className; - }else if(dojo.html.hasAttribute(node, "class")){ - cs = dojo.html.getAttribute(node, "class"); - } - return cs.replace(/^\s+|\s+$/g, ""); // string + // summary + // Returns the string value of the list of CSS classes currently assigned directly + // to the node in question. Returns an empty string if no class attribute is found; + node = dojo.byId(node); + if(!node){ return ""; } + var cs = ""; + if(node.className){ + cs = node.className; + }else if(dojo.html.hasAttribute(node, "class")){ + cs = dojo.html.getAttribute(node, "class"); + } + return cs.replace(/^\s+|\s+$/g, ""); // string } dojo.html.getClasses = function(/* HTMLElement */node) { - // summary - // Returns an array of CSS classes currently assigned directly to the node in question. - // Returns an empty array if no classes are found; - var c = dojo.html.getClass(node); - return (c == "") ? [] : c.split(/\s+/g); // array + // summary + // Returns an array of CSS classes currently assigned directly to the node in question. + // Returns an empty array if no classes are found; + var c = dojo.html.getClass(node); + return (c == "") ? [] : c.split(/\s+/g); // array } dojo.html.hasClass = function(/* HTMLElement */node, /* string */classname){ - // summary - // Returns whether or not the specified classname is a portion of the - // class list currently applied to the node. Does not cover cascaded - // styles, only classes directly applied to the node. - return (new RegExp('(^|\\s+)'+classname+'(\\s+|$)')).test(dojo.html.getClass(node)) // boolean + // summary + // Returns whether or not the specified classname is a portion of the + // class list currently applied to the node. Does not cover cascaded + // styles, only classes directly applied to the node. + return (new RegExp('(^|\\s+)'+classname+'(\\s+|$)')).test(dojo.html.getClass(node)) // boolean } dojo.html.prependClass = function(/* HTMLElement */node, /* string */classStr){ - // summary - // Adds the specified class to the beginning of the class list on the - // passed node. This gives the specified class the highest precidence - // when style cascading is calculated for the node. Returns true or - // false; indicating success or failure of the operation, respectively. - classStr += " " + dojo.html.getClass(node); - return dojo.html.setClass(node, classStr); // boolean + // summary + // Adds the specified class to the beginning of the class list on the + // passed node. This gives the specified class the highest precidence + // when style cascading is calculated for the node. Returns true or + // false; indicating success or failure of the operation, respectively. + classStr += " " + dojo.html.getClass(node); + return dojo.html.setClass(node, classStr); // boolean } dojo.html.addClass = function(/* HTMLElement */node, /* string */classStr){ - // summary - // Adds the specified class to the end of the class list on the - // passed &node;. Returns &true; or &false; indicating success or failure. - if (dojo.html.hasClass(node, classStr)) { - return false; - } - classStr = (dojo.html.getClass(node) + " " + classStr).replace(/^\s+|\s+$/g,""); - return dojo.html.setClass(node, classStr); // boolean + // summary + // Adds the specified class to the end of the class list on the + // passed &node;. Returns &true; or &false; indicating success or failure. + if (dojo.html.hasClass(node, classStr)) { + return false; + } + classStr = (dojo.html.getClass(node) + " " + classStr).replace(/^\s+|\s+$/g,""); + return dojo.html.setClass(node, classStr); // boolean } dojo.html.setClass = function(/* HTMLElement */node, /* string */classStr){ - // summary - // Clobbers the existing list of classes for the node, replacing it with - // the list given in the 2nd argument. Returns true or false - // indicating success or failure. - node = dojo.byId(node); - var cs = new String(classStr); - try{ - if(typeof node.className == "string"){ - node.className = cs; - }else if(node.setAttribute){ - node.setAttribute("class", classStr); - node.className = cs; - }else{ - return false; - } - }catch(e){ - dojo.debug("dojo.html.setClass() failed", e); - } - return true; + // summary + // Clobbers the existing list of classes for the node, replacing it with + // the list given in the 2nd argument. Returns true or false + // indicating success or failure. + node = dojo.byId(node); + var cs = new String(classStr); + try{ + if(typeof node.className == "string"){ + node.className = cs; + }else if(node.setAttribute){ + node.setAttribute("class", classStr); + node.className = cs; + }else{ + return false; + } + }catch(e){ + dojo.debug("dojo.html.setClass() failed", e); + } + return true; } dojo.html.removeClass = function(/* HTMLElement */node, /* string */classStr, /* boolean? */allowPartialMatches){ - // summary - // Removes the className from the node;. Returns true or false indicating success or failure. - try{ - if (!allowPartialMatches) { - var newcs = dojo.html.getClass(node).replace(new RegExp('(^|\\s+)'+classStr+'(\\s+|$)'), "$1$2"); - } else { - var newcs = dojo.html.getClass(node).replace(classStr,''); - } - dojo.html.setClass(node, newcs); - }catch(e){ - dojo.debug("dojo.html.removeClass() failed", e); - } - return true; // boolean + // summary + // Removes the className from the node;. Returns true or false indicating success or failure. + try{ + if (!allowPartialMatches) { + var newcs = dojo.html.getClass(node).replace(new RegExp('(^|\\s+)'+classStr+'(\\s+|$)'), "$1$2"); + } else { + var newcs = dojo.html.getClass(node).replace(classStr,''); + } + dojo.html.setClass(node, newcs); + }catch(e){ + dojo.debug("dojo.html.removeClass() failed", e); + } + return true; // boolean } dojo.html.replaceClass = function(/* HTMLElement */node, /* string */newClass, /* string */oldClass) { - // summary - // Replaces 'oldClass' and adds 'newClass' to node - dojo.html.removeClass(node, oldClass); - dojo.html.addClass(node, newClass); + // summary + // Replaces 'oldClass' and adds 'newClass' to node + dojo.html.removeClass(node, oldClass); + dojo.html.addClass(node, newClass); } // Enum type for getElementsByClass classMatchType arg: dojo.html.classMatchType = { - ContainsAll : 0, // all of the classes are part of the node's class (default) - ContainsAny : 1, // any of the classes are part of the node's class - IsOnly : 2 // only all of the classes are part of the node's class + ContainsAll : 0, // all of the classes are part of the node's class (default) + ContainsAny : 1, // any of the classes are part of the node's class + IsOnly : 2 // only all of the classes are part of the node's class } dojo.html.getElementsByClass = function( - /* string */classStr, - /* HTMLElement? */parent, - /* string? */nodeType, - /* integer? */classMatchType, - /* boolean? */useNonXpath + /* string */classStr, + /* HTMLElement? */parent, + /* string? */nodeType, + /* integer? */classMatchType, + /* boolean? */useNonXpath ){ - // summary - // Returns an array of nodes for the given classStr, children of a - // parent, and optionally of a certain nodeType - // FIXME: temporarily set to false because of several dojo tickets related - // to the xpath version not working consistently in firefox. - useNonXpath = false; - var _document = dojo.doc(); - parent = dojo.byId(parent) || _document; - var classes = classStr.split(/\s+/g); - var nodes = []; - if( classMatchType != 1 && classMatchType != 2 ) classMatchType = 0; // make it enum - var reClass = new RegExp("(\\s|^)((" + classes.join(")|(") + "))(\\s|$)"); - var srtLength = classes.join(" ").length; - var candidateNodes = []; + // summary + // Returns an array of nodes for the given classStr, children of a + // parent, and optionally of a certain nodeType + // FIXME: temporarily set to false because of several dojo tickets related + // to the xpath version not working consistently in firefox. + useNonXpath = false; + var _document = dojo.doc(); + parent = dojo.byId(parent) || _document; + var classes = classStr.split(/\s+/g); + var nodes = []; + if( classMatchType != 1 && classMatchType != 2 ) classMatchType = 0; // make it enum + var reClass = new RegExp("(\\s|^)((" + classes.join(")|(") + "))(\\s|$)"); + var srtLength = classes.join(" ").length; + var candidateNodes = []; + + if(!useNonXpath && _document.evaluate) { // supports dom 3 xpath + var xpath = ".//" + (nodeType || "*") + "[contains("; + if(classMatchType != dojo.html.classMatchType.ContainsAny){ + xpath += "concat(' ',@class,' '), ' " + + classes.join(" ') and contains(concat(' ',@class,' '), ' ") + + " ')"; + if (classMatchType == 2) { + xpath += " and string-length(@class)="+srtLength+"]"; + }else{ + xpath += "]"; + } + }else{ + xpath += "concat(' ',@class,' '), ' " + + classes.join(" ') or contains(concat(' ',@class,' '), ' ") + + " ')]"; + } + var xpathResult = _document.evaluate(xpath, parent, null, XPathResult.ANY_TYPE, null); + var result = xpathResult.iterateNext(); + while(result){ + try{ + candidateNodes.push(result); + result = xpathResult.iterateNext(); + }catch(e){ break; } + } + return candidateNodes; // NodeList + }else{ + if(!nodeType){ + nodeType = "*"; + } + candidateNodes = parent.getElementsByTagName(nodeType); - if(!useNonXpath && _document.evaluate) { // supports dom 3 xpath - var xpath = ".//" + (nodeType || "*") + "[contains("; - if(classMatchType != dojo.html.classMatchType.ContainsAny){ - xpath += "concat(' ',@class,' '), ' " + - classes.join(" ') and contains(concat(' ',@class,' '), ' ") + - " ')"; - if (classMatchType == 2) { - xpath += " and string-length(@class)="+srtLength+"]"; - }else{ - xpath += "]"; - } - }else{ - xpath += "concat(' ',@class,' '), ' " + - classes.join(" ') or contains(concat(' ',@class,' '), ' ") + - " ')]"; - } - var xpathResult = _document.evaluate(xpath, parent, null, XPathResult.ANY_TYPE, null); - var result = xpathResult.iterateNext(); - while(result){ - try{ - candidateNodes.push(result); - result = xpathResult.iterateNext(); - }catch(e){ break; } - } - return candidateNodes; // NodeList - }else{ - if(!nodeType){ - nodeType = "*"; - } - candidateNodes = parent.getElementsByTagName(nodeType); - - var node, i = 0; - outer: - while(node = candidateNodes[i++]){ - var nodeClasses = dojo.html.getClasses(node); - if(nodeClasses.length == 0){ continue outer; } - var matches = 0; - - for(var j = 0; j < nodeClasses.length; j++){ - if(reClass.test(nodeClasses[j])){ - if(classMatchType == dojo.html.classMatchType.ContainsAny){ - nodes.push(node); - continue outer; - }else{ - matches++; - } - }else{ - if(classMatchType == dojo.html.classMatchType.IsOnly){ - continue outer; - } - } - } - - if(matches == classes.length){ - if( (classMatchType == dojo.html.classMatchType.IsOnly)&& - (matches == nodeClasses.length)){ - nodes.push(node); - }else if(classMatchType == dojo.html.classMatchType.ContainsAll){ - nodes.push(node); - } - } - } - return nodes; // NodeList - } + var node, i = 0; + outer: + while(node = candidateNodes[i++]){ + var nodeClasses = dojo.html.getClasses(node); + if(nodeClasses.length == 0){ continue outer; } + var matches = 0; + + for(var j = 0; j < nodeClasses.length; j++){ + if(reClass.test(nodeClasses[j])){ + if(classMatchType == dojo.html.classMatchType.ContainsAny){ + nodes.push(node); + continue outer; + }else{ + matches++; + } + }else{ + if(classMatchType == dojo.html.classMatchType.IsOnly){ + continue outer; + } + } + } + + if(matches == classes.length){ + if( (classMatchType == dojo.html.classMatchType.IsOnly)&& + (matches == nodeClasses.length)){ + nodes.push(node); + }else if(classMatchType == dojo.html.classMatchType.ContainsAll){ + nodes.push(node); + } + } + } + return nodes; // NodeList + } } dojo.html.getElementsByClassName = dojo.html.getElementsByClass; dojo.html.toCamelCase = function(/* string */selector){ - // summary - // Translates a CSS selector string to a camel-cased one. - var arr = selector.split('-'), cc = arr[0]; - for(var i = 1; i < arr.length; i++) { - cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1); - } - return cc; // string + // summary + // Translates a CSS selector string to a camel-cased one. + var arr = selector.split('-'), cc = arr[0]; + for(var i = 1; i < arr.length; i++) { + cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1); + } + return cc; // string } dojo.html.toSelectorCase = function(/* string */selector){ - // summary - // Translates a camel cased string to a selector cased one. - return selector.replace(/([A-Z])/g, "-$1" ).toLowerCase(); // string + // summary + // Translates a camel cased string to a selector cased one. + return selector.replace(/([A-Z])/g, "-$1" ).toLowerCase(); // string } if (dojo.render.html.ie) { - // IE branch - dojo.html.getComputedStyle = function(/*HTMLElement|String*/node, /*String*/property, /*String*/value) { - // summary - // Get the computed style value for style "property" on "node" (IE). - node = dojo.byId(node); // FIXME: remove ability to access nodes by id for this time-critical function - if(!node || !node.currentStyle){return value;} - // FIXME: standardize on camel-case input to improve speed - return node.currentStyle[dojo.html.toCamelCase(property)]; // String - } - // SJM: getComputedStyle should be abandoned and replaced with the below function. - // All our supported browsers can return CSS2 compliant CssStyleDeclaration objects - // which can be queried directly for multiple styles. - dojo.html.getComputedStyles = function(/*HTMLElement*/node) { - // summary - // Get a style object containing computed styles for HTML Element node (IE). - return node.currentStyle; // CSSStyleDeclaration - } + // IE branch + dojo.html.getComputedStyle = function(/*HTMLElement|String*/node, /*String*/property, /*String*/value) { + // summary + // Get the computed style value for style "property" on "node" (IE). + node = dojo.byId(node); // FIXME: remove ability to access nodes by id for this time-critical function + if(!node || !node.currentStyle){return value;} + // FIXME: standardize on camel-case input to improve speed + return node.currentStyle[dojo.html.toCamelCase(property)]; // String + } + // SJM: getComputedStyle should be abandoned and replaced with the below function. + // All our supported browsers can return CSS2 compliant CssStyleDeclaration objects + // which can be queried directly for multiple styles. + dojo.html.getComputedStyles = function(/*HTMLElement*/node) { + // summary + // Get a style object containing computed styles for HTML Element node (IE). + return node.currentStyle; // CSSStyleDeclaration + } } else { - // non-IE branch - dojo.html.getComputedStyle = function(/*HTMLElement|String*/node, /*String*/property, /*Any*/value) { - // summary - // Get the computed style value for style "property" on "node" (non-IE). - node = dojo.byId(node); - if(!node || !node.style){return value;} - var s = document.defaultView.getComputedStyle(node, null); - // s may be null on Safari - return (s&&s[dojo.html.toCamelCase(property)])||''; // String - } - // SJM: getComputedStyle should be abandoned and replaced with the below function. - // All our supported browsers can return CSS2 compliant CssStyleDeclaration objects - // which can be queried directly for multiple styles. - dojo.html.getComputedStyles = function(node) { - // summary - // Get a style object containing computed styles for HTML Element node (non-IE). - return document.defaultView.getComputedStyle(node, null); // CSSStyleDeclaration - } + // non-IE branch + dojo.html.getComputedStyle = function(/*HTMLElement|String*/node, /*String*/property, /*Any*/value) { + // summary + // Get the computed style value for style "property" on "node" (non-IE). + node = dojo.byId(node); + if(!node || !node.style){return value;} + var s = document.defaultView.getComputedStyle(node, null); + // s may be null on Safari + return (s&&s[dojo.html.toCamelCase(property)])||''; // String + } + // SJM: getComputedStyle should be abandoned and replaced with the below function. + // All our supported browsers can return CSS2 compliant CssStyleDeclaration objects + // which can be queried directly for multiple styles. + dojo.html.getComputedStyles = function(node) { + // summary + // Get a style object containing computed styles for HTML Element node (non-IE). + return document.defaultView.getComputedStyle(node, null); // CSSStyleDeclaration + } } dojo.html.getStyleProperty = function(/* HTMLElement */node, /* string */cssSelector){ - // summary - // Returns the value of the passed style - node = dojo.byId(node); - return (node && node.style ? node.style[dojo.html.toCamelCase(cssSelector)] : undefined); // string + // summary + // Returns the value of the passed style + node = dojo.byId(node); + return (node && node.style ? node.style[dojo.html.toCamelCase(cssSelector)] : undefined); // string } dojo.html.getStyle = function(/* HTMLElement */node, /* string */cssSelector){ - // summary - // Returns the computed value of the passed style - var value = dojo.html.getStyleProperty(node, cssSelector); - return (value ? value : dojo.html.getComputedStyle(node, cssSelector)); // string || integer + // summary + // Returns the computed value of the passed style + var value = dojo.html.getStyleProperty(node, cssSelector); + return (value ? value : dojo.html.getComputedStyle(node, cssSelector)); // string || integer } dojo.html.setStyle = function(/* HTMLElement */node, /* string */cssSelector, /* string */value){ - // summary - // Set the value of passed style on node - node = dojo.byId(node); - if(node && node.style){ - var camelCased = dojo.html.toCamelCase(cssSelector); - node.style[camelCased] = value; - } + // summary + // Set the value of passed style on node + node = dojo.byId(node); + if(node && node.style){ + var camelCased = dojo.html.toCamelCase(cssSelector); + node.style[camelCased] = value; + } } dojo.html.setStyleText = function (/* HTMLElement */target, /* string */text) { - // summary - // Try to set the entire cssText property of the passed target; equiv of setting style attribute. - try { - target.style.cssText = text; - } catch (e) { - target.setAttribute("style", text); - } + // summary + // Try to set the entire cssText property of the passed target; equiv of setting style attribute. + try { + target.style.cssText = text; + } catch (e) { + target.setAttribute("style", text); + } } dojo.html.copyStyle = function(/* HTMLElement */target, /* HTMLElement */source){ - // summary - // work around for opera which doesn't have cssText, and for IE which fails on setAttribute - if(!source.style.cssText){ - target.setAttribute("style", source.getAttribute("style")); - }else{ - target.style.cssText = source.style.cssText; - } - dojo.html.addClass(target, dojo.html.getClass(source)); + // summary + // work around for opera which doesn't have cssText, and for IE which fails on setAttribute + if(!source.style.cssText){ + target.setAttribute("style", source.getAttribute("style")); + }else{ + target.style.cssText = source.style.cssText; + } + dojo.html.addClass(target, dojo.html.getClass(source)); } dojo.html.getUnitValue = function(/* HTMLElement */node, /* string */cssSelector, /* boolean? */autoIsZero){ - // summary - // Get the value of passed selector, with the specific units used - var s = dojo.html.getComputedStyle(node, cssSelector); - if((!s)||((s == 'auto')&&(autoIsZero))){ - return { value: 0, units: 'px' }; // object - } - // FIXME: is regex inefficient vs. parseInt or some manual test? - var match = s.match(/(\-?[\d.]+)([a-z%]*)/i); - if (!match){return dojo.html.getUnitValue.bad;} - return { value: Number(match[1]), units: match[2].toLowerCase() }; // object + // summary + // Get the value of passed selector, with the specific units used + var s = dojo.html.getComputedStyle(node, cssSelector); + if((!s)||((s == 'auto')&&(autoIsZero))){ + return { value: 0, units: 'px' }; // object + } + // FIXME: is regex inefficient vs. parseInt or some manual test? + var match = s.match(/(\-?[\d.]+)([a-z%]*)/i); + if (!match){return dojo.html.getUnitValue.bad;} + return { value: Number(match[1]), units: match[2].toLowerCase() }; // object } dojo.html.getUnitValue.bad = { value: NaN, units: '' }; if (dojo.render.html.ie) { - // IE branch - dojo.html.toPixelValue = function(/* HTMLElement */element, /* String */styleValue){ - // summary - // Extract value in pixels from styleValue (IE version). - // If a value cannot be extracted, zero is returned. - if(!styleValue){return 0;} - if(styleValue.slice(-2) == 'px'){return parseFloat(styleValue);} - var pixelValue = 0; - with(element){ - var sLeft = style.left; - var rsLeft = runtimeStyle.left; - runtimeStyle.left = currentStyle.left; - try { - style.left = styleValue || 0; - pixelValue = style.pixelLeft; - style.left = sLeft; - runtimeStyle.left = rsLeft; - }catch(e){ - // FIXME: it's possible for styleValue to be incompatible with - // style.left. In particular, border width values of - // "thick", "medium", or "thin" will provoke an exception. - } - } - return pixelValue; // Number - } + // IE branch + dojo.html.toPixelValue = function(/* HTMLElement */element, /* String */styleValue){ + // summary + // Extract value in pixels from styleValue (IE version). + // If a value cannot be extracted, zero is returned. + if(!styleValue){return 0;} + if(styleValue.slice(-2) == 'px'){return parseFloat(styleValue);} + var pixelValue = 0; + with(element){ + var sLeft = style.left; + var rsLeft = runtimeStyle.left; + runtimeStyle.left = currentStyle.left; + try { + style.left = styleValue || 0; + pixelValue = style.pixelLeft; + style.left = sLeft; + runtimeStyle.left = rsLeft; + }catch(e){ + // FIXME: it's possible for styleValue to be incompatible with + // style.left. In particular, border width values of + // "thick", "medium", or "thin" will provoke an exception. + } + } + return pixelValue; // Number + } } else { - // non-IE branch - dojo.html.toPixelValue = function(/* HTMLElement */element, /* String */styleValue){ - // summary - // Extract value in pixels from styleValue (non-IE version). - // If a value cannot be extracted, zero is returned. - return (styleValue && (styleValue.slice(-2)=='px') ? parseFloat(styleValue) : 0); // Number - } + // non-IE branch + dojo.html.toPixelValue = function(/* HTMLElement */element, /* String */styleValue){ + // summary + // Extract value in pixels from styleValue (non-IE version). + // If a value cannot be extracted, zero is returned. + return (styleValue && (styleValue.slice(-2)=='px') ? parseFloat(styleValue) : 0); // Number + } } dojo.html.getPixelValue = function(/* HTMLElement */node, /* string */styleProperty, /* boolean? */autoIsZero){ - // summary - // Get a computed style value, in pixels. - // node: HTMLElement - // Node to interrogate - // styleProperty: String - // Style property to query, in either css-selector or camelCase (property) format. - // autoIsZero: Boolean - // Deprecated. Any value that cannot be converted to pixels is returned as zero. - // - // summary - // Get the value of passed selector in pixels. - // - return dojo.html.toPixelValue(node, dojo.html.getComputedStyle(node, styleProperty)); -} + // summary + // Get a computed style value, in pixels. + // node: HTMLElement + // Node to interrogate + // styleProperty: String + // Style property to query, in either css-selector or camelCase (property) format. + // autoIsZero: Boolean + // Deprecated. Any value that cannot be converted to pixels is returned as zero. + // + // summary + // Get the value of passed selector in pixels. + // + return dojo.html.toPixelValue(node, dojo.html.getComputedStyle(node, styleProperty)); +} dojo.html.setPositivePixelValue = function(/* HTMLElement */node, /* string */selector, /* integer */value){ - // summary - // Attempt to set the value of selector on node as a positive pixel value. - if(isNaN(value)){return false;} - node.style[selector] = Math.max(0, value) + 'px'; - return true; // boolean + // summary + // Attempt to set the value of selector on node as a positive pixel value. + if(isNaN(value)){return false;} + node.style[selector] = Math.max(0, value) + 'px'; + return true; // boolean } dojo.html.styleSheet = null; // FIXME: this is a really basic stub for adding and removing cssRules, but -// it assumes that you know the index of the cssRule that you want to add -// or remove, making it less than useful. So we need something that can +// it assumes that you know the index of the cssRule that you want to add +// or remove, making it less than useful. So we need something that can // search for the selector that you you want to remove. dojo.html.insertCssRule = function(/* string */selector, /* string */declaration, /* integer? */index) { - // summary - // Attempt to insert declaration as selector on the internal stylesheet; if index try to set it there. - if (!dojo.html.styleSheet) { - if (document.createStyleSheet) { // IE - dojo.html.styleSheet = document.createStyleSheet(); - } else if (document.styleSheets[0]) { // rest - // FIXME: should create a new style sheet here - // fall back on an exsiting style sheet - dojo.html.styleSheet = document.styleSheets[0]; - } else { - return null; // integer - } // fail - } + // summary + // Attempt to insert declaration as selector on the internal stylesheet; if index try to set it there. + if (!dojo.html.styleSheet) { + if (document.createStyleSheet) { // IE + dojo.html.styleSheet = document.createStyleSheet(); + } else if (document.styleSheets[0]) { // rest + // FIXME: should create a new style sheet here + // fall back on an exsiting style sheet + dojo.html.styleSheet = document.styleSheets[0]; + } else { + return null; // integer + } // fail + } - if (arguments.length < 3) { // index may == 0 - if (dojo.html.styleSheet.cssRules) { // W3 - index = dojo.html.styleSheet.cssRules.length; - } else if (dojo.html.styleSheet.rules) { // IE - index = dojo.html.styleSheet.rules.length; - } else { - return null; // integer - } // fail - } + if (arguments.length < 3) { // index may == 0 + if (dojo.html.styleSheet.cssRules) { // W3 + index = dojo.html.styleSheet.cssRules.length; + } else if (dojo.html.styleSheet.rules) { // IE + index = dojo.html.styleSheet.rules.length; + } else { + return null; // integer + } // fail + } - if (dojo.html.styleSheet.insertRule) { // W3 - var rule = selector + " { " + declaration + " }"; - return dojo.html.styleSheet.insertRule(rule, index); // integer - } else if (dojo.html.styleSheet.addRule) { // IE - return dojo.html.styleSheet.addRule(selector, declaration, index); // integer - } else { - return null; // integer - } // fail + if (dojo.html.styleSheet.insertRule) { // W3 + var rule = selector + " { " + declaration + " }"; + return dojo.html.styleSheet.insertRule(rule, index); // integer + } else if (dojo.html.styleSheet.addRule) { // IE + return dojo.html.styleSheet.addRule(selector, declaration, index); // integer + } else { + return null; // integer + } // fail } dojo.html.removeCssRule = function(/* integer? */index){ - // summary - // Attempt to remove the rule at index. - if(!dojo.html.styleSheet){ - dojo.debug("no stylesheet defined for removing rules"); - return false; - } - if(dojo.render.html.ie){ - if(!index){ - index = dojo.html.styleSheet.rules.length; - dojo.html.styleSheet.removeRule(index); - } - }else if(document.styleSheets[0]){ - if(!index){ - index = dojo.html.styleSheet.cssRules.length; - } - dojo.html.styleSheet.deleteRule(index); - } - return true; // boolean + // summary + // Attempt to remove the rule at index. + if(!dojo.html.styleSheet){ + dojo.debug("no stylesheet defined for removing rules"); + return false; + } + if(dojo.render.html.ie){ + if(!index){ + index = dojo.html.styleSheet.rules.length; + dojo.html.styleSheet.removeRule(index); + } + }else if(document.styleSheets[0]){ + if(!index){ + index = dojo.html.styleSheet.cssRules.length; + } + dojo.html.styleSheet.deleteRule(index); + } + return true; // boolean } dojo.html._insertedCssFiles = []; // cache container needed because IE reformats cssText when added to DOM dojo.html.insertCssFile = function(/* string */URI, /* HTMLDocument? */doc, /* boolean? */checkDuplicates, /* boolean */fail_ok){ - // summary - // calls css by XmlHTTP and inserts it into DOM as - if(!URI){ return; } - if(!doc){ doc = document; } - var cssStr = dojo.hostenv.getText(URI, false, fail_ok); - if(cssStr===null){ return; } - cssStr = dojo.html.fixPathsInCssText(cssStr, URI); + // summary + // calls css by XmlHTTP and inserts it into DOM as + if(!URI){ return; } + if(!doc){ doc = document; } + var cssStr = dojo.hostenv.getText(URI, false, fail_ok); + if(cssStr===null){ return; } + cssStr = dojo.html.fixPathsInCssText(cssStr, URI); - if(checkDuplicates){ - var idx = -1, node, ent = dojo.html._insertedCssFiles; - for(var i = 0; i < ent.length; i++){ - if((ent[i].doc == doc) && (ent[i].cssText == cssStr)){ - idx = i; node = ent[i].nodeRef; - break; - } - } - // make sure we havent deleted our node - if(node){ - var styles = doc.getElementsByTagName("style"); - for(var i = 0; i < styles.length; i++){ - if(styles[i] == node){ - return; - } - } - // delete this entry - dojo.html._insertedCssFiles.shift(idx, 1); - } - } + if(checkDuplicates){ + var idx = -1, node, ent = dojo.html._insertedCssFiles; + for(var i = 0; i < ent.length; i++){ + if((ent[i].doc == doc) && (ent[i].cssText == cssStr)){ + idx = i; node = ent[i].nodeRef; + break; + } + } + // make sure we havent deleted our node + if(node){ + var styles = doc.getElementsByTagName("style"); + for(var i = 0; i < styles.length; i++){ + if(styles[i] == node){ + return; + } + } + // delete this entry + dojo.html._insertedCssFiles.shift(idx, 1); + } + } - var style = dojo.html.insertCssText(cssStr, doc); - dojo.html._insertedCssFiles.push({'doc': doc, 'cssText': cssStr, 'nodeRef': style}); + var style = dojo.html.insertCssText(cssStr, doc); + dojo.html._insertedCssFiles.push({'doc': doc, 'cssText': cssStr, 'nodeRef': style}); - // insert custom attribute ex dbgHref="../foo.css" usefull when debugging in DOM inspectors, no? - if(style && djConfig.isDebug){ - style.setAttribute("dbgHref", URI); - } - return style; // HTMLStyleElement + // insert custom attribute ex dbgHref="../foo.css" usefull when debugging in DOM inspectors, no? + if(style && djConfig.isDebug){ + style.setAttribute("dbgHref", URI); + } + return style; // HTMLStyleElement } dojo.html.insertCssText = function(/* string */cssStr, /* HTMLDocument? */doc, /* string? */URI){ - // summary - // Attempt to insert CSS rules into the document through inserting a style element - // DomNode Style = insertCssText(String ".dojoMenu {color: green;}"[, DomDoc document, dojo.uri.Uri Url ]) - if(!cssStr){ - return; // HTMLStyleElement - } - if(!doc){ doc = document; } - if(URI){// fix paths in cssStr - cssStr = dojo.html.fixPathsInCssText(cssStr, URI); - } - var style = doc.createElement("style"); - style.setAttribute("type", "text/css"); - // IE is b0rken enough to require that we add the element to the doc - // before changing it's properties - var head = doc.getElementsByTagName("head")[0]; - if(!head){ // must have a head tag - dojo.debug("No head tag in document, aborting styles"); - return; // HTMLStyleElement - }else{ - head.appendChild(style); - } - if(style.styleSheet){// IE - var setFunc = function(){ - try{ - style.styleSheet.cssText = cssStr; - }catch(e){ dojo.debug(e); } - }; - if(style.styleSheet.disabled){ - setTimeout(setFunc, 10); - }else{ - setFunc(); - } - }else{ // w3c - var cssText = doc.createTextNode(cssStr); - style.appendChild(cssText); - } - return style; // HTMLStyleElement + // summary + // Attempt to insert CSS rules into the document through inserting a style element + // DomNode Style = insertCssText(String ".dojoMenu {color: green;}"[, DomDoc document, dojo.uri.Uri Url ]) + if(!cssStr){ + return; // HTMLStyleElement + } + if(!doc){ doc = document; } + if(URI){// fix paths in cssStr + cssStr = dojo.html.fixPathsInCssText(cssStr, URI); + } + var style = doc.createElement("style"); + style.setAttribute("type", "text/css"); + // IE is b0rken enough to require that we add the element to the doc + // before changing it's properties + var head = doc.getElementsByTagName("head")[0]; + if(!head){ // must have a head tag + dojo.debug("No head tag in document, aborting styles"); + return; // HTMLStyleElement + }else{ + head.appendChild(style); + } + if(style.styleSheet){// IE + var setFunc = function(){ + try{ + style.styleSheet.cssText = cssStr; + }catch(e){ dojo.debug(e); } + }; + if(style.styleSheet.disabled){ + setTimeout(setFunc, 10); + }else{ + setFunc(); + } + }else{ // w3c + var cssText = doc.createTextNode(cssStr); + style.appendChild(cssText); + } + return style; // HTMLStyleElement } dojo.html.fixPathsInCssText = function(/* string */cssStr, /* string */URI){ - // summary - // usage: cssText comes from dojoroot/src/widget/templates/Foobar.css - // it has .dojoFoo { background-image: url(images/bar.png);} then uri should point to dojoroot/src/widget/templates/ - if(!cssStr || !URI){ return; } - var match, str = "", url = "", urlChrs = "[\\t\\s\\w\\(\\)\\/\\.\\\\'\"-:#=&?~]+"; - var regex = new RegExp('url\\(\\s*('+urlChrs+')\\s*\\)'); - var regexProtocol = /(file|https?|ftps?):\/\//; - regexTrim = new RegExp("^[\\s]*(['\"]?)("+urlChrs+")\\1[\\s]*?$"); - if(dojo.render.html.ie55 || dojo.render.html.ie60){ - var regexIe = new RegExp("AlphaImageLoader\\((.*)src\=['\"]("+urlChrs+")['\"]"); - // TODO: need to decide how to handle relative paths and AlphaImageLoader see #1441 - // current implementation breaks on build with intern_strings - while(match = regexIe.exec(cssStr)){ - url = match[2].replace(regexTrim, "$2"); - if(!regexProtocol.exec(url)){ - url = (new dojo.uri.Uri(URI, url).toString()); - } - str += cssStr.substring(0, match.index) + "AlphaImageLoader(" + match[1] + "src='" + url + "'"; - cssStr = cssStr.substr(match.index + match[0].length); - } - cssStr = str + cssStr; - str = ""; - } + // summary + // usage: cssText comes from dojoroot/src/widget/templates/Foobar.css + // it has .dojoFoo { background-image: url(images/bar.png);} then uri should point to dojoroot/src/widget/templates/ + if(!cssStr || !URI){ return; } + var match, str = "", url = "", urlChrs = "[\\t\\s\\w\\(\\)\\/\\.\\\\'\"-:#=&?~]+"; + var regex = new RegExp('url\\(\\s*('+urlChrs+')\\s*\\)'); + var regexProtocol = /(file|https?|ftps?):\/\//; + regexTrim = new RegExp("^[\\s]*(['\"]?)("+urlChrs+")\\1[\\s]*?$"); + if(dojo.render.html.ie55 || dojo.render.html.ie60){ + var regexIe = new RegExp("AlphaImageLoader\\((.*)src\=['\"]("+urlChrs+")['\"]"); + // TODO: need to decide how to handle relative paths and AlphaImageLoader see #1441 + // current implementation breaks on build with intern_strings + while(match = regexIe.exec(cssStr)){ + url = match[2].replace(regexTrim, "$2"); + if(!regexProtocol.exec(url)){ + url = (new dojo.uri.Uri(URI, url).toString()); + } + str += cssStr.substring(0, match.index) + "AlphaImageLoader(" + match[1] + "src='" + url + "'"; + cssStr = cssStr.substr(match.index + match[0].length); + } + cssStr = str + cssStr; + str = ""; + } - while(match = regex.exec(cssStr)){ - url = match[1].replace(regexTrim, "$2"); - if(!regexProtocol.exec(url)){ - url = (new dojo.uri.Uri(URI, url).toString()); - } - str += cssStr.substring(0, match.index) + "url(" + url + ")"; - cssStr = cssStr.substr(match.index + match[0].length); - } - return str + cssStr; // string + while(match = regex.exec(cssStr)){ + url = match[1].replace(regexTrim, "$2"); + if(!regexProtocol.exec(url)){ + url = (new dojo.uri.Uri(URI, url).toString()); + } + str += cssStr.substring(0, match.index) + "url(" + url + ")"; + cssStr = cssStr.substr(match.index + match[0].length); + } + return str + cssStr; // string } dojo.html.setActiveStyleSheet = function(/* string */title){ - // summary - // Activate style sheet with specified title. - var i = 0, a, els = dojo.doc().getElementsByTagName("link"); - while (a = els[i++]) { - if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")){ - a.disabled = true; - if (a.getAttribute("title") == title) { a.disabled = false; } - } - } + // summary + // Activate style sheet with specified title. + var i = 0, a, els = dojo.doc().getElementsByTagName("link"); + while (a = els[i++]) { + if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")){ + a.disabled = true; + if (a.getAttribute("title") == title) { a.disabled = false; } + } + } } dojo.html.getActiveStyleSheet = function(){ - // summary - // return the title of the currently active stylesheet - var i = 0, a, els = dojo.doc().getElementsByTagName("link"); - while (a = els[i++]) { - if (a.getAttribute("rel").indexOf("style") != -1 - && a.getAttribute("title") - && !a.disabled - ){ - return a.getAttribute("title"); // string - } - } - return null; // string + // summary + // return the title of the currently active stylesheet + var i = 0, a, els = dojo.doc().getElementsByTagName("link"); + while (a = els[i++]) { + if (a.getAttribute("rel").indexOf("style") != -1 + && a.getAttribute("title") + && !a.disabled + ){ + return a.getAttribute("title"); // string + } + } + return null; // string } dojo.html.getPreferredStyleSheet = function(){ - // summary - // Return the preferred stylesheet title (i.e. link without alt attribute) - var i = 0, a, els = dojo.doc().getElementsByTagName("link"); - while (a = els[i++]) { - if(a.getAttribute("rel").indexOf("style") != -1 - && a.getAttribute("rel").indexOf("alt") == -1 - && a.getAttribute("title") - ){ - return a.getAttribute("title"); // string - } - } - return null; // string + // summary + // Return the preferred stylesheet title (i.e. link without alt attribute) + var i = 0, a, els = dojo.doc().getElementsByTagName("link"); + while (a = els[i++]) { + if(a.getAttribute("rel").indexOf("style") != -1 + && a.getAttribute("rel").indexOf("alt") == -1 + && a.getAttribute("title") + ){ + return a.getAttribute("title"); // string + } + } + return null; // string } dojo.html.applyBrowserClass = function(/* HTMLElement */node){ - // summary - // Applies pre-set class names based on browser & version to the passed node. - // Modified version of Morris' CSS hack. - var drh=dojo.render.html; - var classes = { - dj_ie: drh.ie, - dj_ie55: drh.ie55, - dj_ie6: drh.ie60, - dj_ie7: drh.ie70, - dj_iequirks: drh.ie && drh.quirks, - dj_opera: drh.opera, - dj_opera8: drh.opera && (Math.floor(dojo.render.version)==8), - dj_opera9: drh.opera && (Math.floor(dojo.render.version)==9), - dj_khtml: drh.khtml, - dj_safari: drh.safari, - dj_gecko: drh.mozilla - }; // no dojo unsupported browsers - for(var p in classes){ - if(classes[p]){ - dojo.html.addClass(node, p); - } - } + // summary + // Applies pre-set class names based on browser & version to the passed node. + // Modified version of Morris' CSS hack. + var drh=dojo.render.html; + var classes = { + dj_ie: drh.ie, + dj_ie55: drh.ie55, + dj_ie6: drh.ie60, + dj_ie7: drh.ie70, + dj_iequirks: drh.ie && drh.quirks, + dj_opera: drh.opera, + dj_opera8: drh.opera && (Math.floor(dojo.render.version)==8), + dj_opera9: drh.opera && (Math.floor(dojo.render.version)==9), + dj_khtml: drh.khtml, + dj_safari: drh.safari, + dj_gecko: drh.mozilla + }; // no dojo unsupported browsers + for(var p in classes){ + if(classes[p]){ + dojo.html.addClass(node, p); + } + } }; dojo.provide("dojo.html.display"); dojo.html._toggle = function(node, tester, setter){ - node = dojo.byId(node); - setter(node, !tester(node)); - return tester(node); + node = dojo.byId(node); + setter(node, !tester(node)); + return tester(node); } dojo.html.show = function(/* HTMLElement */node){ - // summary - // Show the passed element by reverting display property set by dojo.html.hide - node = dojo.byId(node); - if(dojo.html.getStyleProperty(node, 'display')=='none'){ - dojo.html.setStyle(node, 'display', (node.dojoDisplayCache||'')); - node.dojoDisplayCache = undefined; // cannot use delete on a node in IE6 - } + // summary + // Show the passed element by reverting display property set by dojo.html.hide + node = dojo.byId(node); + if(dojo.html.getStyleProperty(node, 'display')=='none'){ + dojo.html.setStyle(node, 'display', (node.dojoDisplayCache||'')); + node.dojoDisplayCache = undefined; // cannot use delete on a node in IE6 + } } dojo.html.hide = function(/* HTMLElement */node){ - // summary - // Hide the passed element by setting display:none - node = dojo.byId(node); - if(typeof node["dojoDisplayCache"] == "undefined"){ // it could == '', so we cannot say !node.dojoDisplayCount - var d = dojo.html.getStyleProperty(node, 'display') - if(d!='none'){ - node.dojoDisplayCache = d; - } - } - dojo.html.setStyle(node, 'display', 'none'); + // summary + // Hide the passed element by setting display:none + node = dojo.byId(node); + if(typeof node["dojoDisplayCache"] == "undefined"){ // it could == '', so we cannot say !node.dojoDisplayCount + var d = dojo.html.getStyleProperty(node, 'display') + if(d!='none'){ + node.dojoDisplayCache = d; + } + } + dojo.html.setStyle(node, 'display', 'none'); } dojo.html.setShowing = function(/* HTMLElement */node, /* boolean? */showing){ - // summary - // Calls show() if showing is true, hide() otherwise - dojo.html[(showing ? 'show' : 'hide')](node); + // summary + // Calls show() if showing is true, hide() otherwise + dojo.html[(showing ? 'show' : 'hide')](node); } dojo.html.isShowing = function(/* HTMLElement */node){ - // summary - // Returns whether the element is displayed or not. - // FIXME: returns true if node is bad, isHidden would be easier to make correct - return (dojo.html.getStyleProperty(node, 'display') != 'none'); // boolean + // summary + // Returns whether the element is displayed or not. + // FIXME: returns true if node is bad, isHidden would be easier to make correct + return (dojo.html.getStyleProperty(node, 'display') != 'none'); // boolean } dojo.html.toggleShowing = function(/* HTMLElement */node){ - // summary - // Call setShowing() on node with the complement of isShowing(), then return the new value of isShowing() - return dojo.html._toggle(node, dojo.html.isShowing, dojo.html.setShowing); // boolean + // summary + // Call setShowing() on node with the complement of isShowing(), then return the new value of isShowing() + return dojo.html._toggle(node, dojo.html.isShowing, dojo.html.setShowing); // boolean } // Simple mapping of tag names to display values -// FIXME: simplistic +// FIXME: simplistic dojo.html.displayMap = { tr: '', td: '', th: '', img: 'inline', span: 'inline', input: 'inline', button: 'inline' }; dojo.html.suggestDisplayByTagName = function(/* HTMLElement */node){ - // summary - // Suggest a value for the display property that will show 'node' based on it's tag - node = dojo.byId(node); - if(node && node.tagName){ - var tag = node.tagName.toLowerCase(); - return (tag in dojo.html.displayMap ? dojo.html.displayMap[tag] : 'block'); // string - } + // summary + // Suggest a value for the display property that will show 'node' based on it's tag + node = dojo.byId(node); + if(node && node.tagName){ + var tag = node.tagName.toLowerCase(); + return (tag in dojo.html.displayMap ? dojo.html.displayMap[tag] : 'block'); // string + } } dojo.html.setDisplay = function(/* HTMLElement */node, /* string */display){ - // summary - // Sets the value of style.display to value of 'display' parameter if it is a string. - // Otherwise, if 'display' is false, set style.display to 'none'. - // Finally, set 'display' to a suggested display value based on the node's tag - dojo.html.setStyle(node, 'display', ((display instanceof String || typeof display == "string") ? display : (display ? dojo.html.suggestDisplayByTagName(node) : 'none'))); + // summary + // Sets the value of style.display to value of 'display' parameter if it is a string. + // Otherwise, if 'display' is false, set style.display to 'none'. + // Finally, set 'display' to a suggested display value based on the node's tag + dojo.html.setStyle(node, 'display', ((display instanceof String || typeof display == "string") ? display : (display ? dojo.html.suggestDisplayByTagName(node) : 'none'))); } dojo.html.isDisplayed = function(/* HTMLElement */node){ - // summary - // Is true if the the computed display style for node is not 'none' - // FIXME: returns true if node is bad, isNotDisplayed would be easier to make correct - return (dojo.html.getComputedStyle(node, 'display') != 'none'); // boolean + // summary + // Is true if the the computed display style for node is not 'none' + // FIXME: returns true if node is bad, isNotDisplayed would be easier to make correct + return (dojo.html.getComputedStyle(node, 'display') != 'none'); // boolean } dojo.html.toggleDisplay = function(/* HTMLElement */node){ - // summary - // Call setDisplay() on node with the complement of isDisplayed(), then - // return the new value of isDisplayed() - return dojo.html._toggle(node, dojo.html.isDisplayed, dojo.html.setDisplay); // boolean + // summary + // Call setDisplay() on node with the complement of isDisplayed(), then + // return the new value of isDisplayed() + return dojo.html._toggle(node, dojo.html.isDisplayed, dojo.html.setDisplay); // boolean } dojo.html.setVisibility = function(/* HTMLElement */node, /* string */visibility){ - // summary - // Sets the value of style.visibility to value of 'visibility' parameter if it is a string. - // Otherwise, if 'visibility' is false, set style.visibility to 'hidden'. Finally, set style.visibility to 'visible'. - dojo.html.setStyle(node, 'visibility', ((visibility instanceof String || typeof visibility == "string") ? visibility : (visibility ? 'visible' : 'hidden'))); + // summary + // Sets the value of style.visibility to value of 'visibility' parameter if it is a string. + // Otherwise, if 'visibility' is false, set style.visibility to 'hidden'. Finally, set style.visibility to 'visible'. + dojo.html.setStyle(node, 'visibility', ((visibility instanceof String || typeof visibility == "string") ? visibility : (visibility ? 'visible' : 'hidden'))); } dojo.html.isVisible = function(/* HTMLElement */node){ - // summary - // Returns true if the the computed visibility style for node is not 'hidden' - // FIXME: returns true if node is bad, isInvisible would be easier to make correct - return (dojo.html.getComputedStyle(node, 'visibility') != 'hidden'); // boolean + // summary + // Returns true if the the computed visibility style for node is not 'hidden' + // FIXME: returns true if node is bad, isInvisible would be easier to make correct + return (dojo.html.getComputedStyle(node, 'visibility') != 'hidden'); // boolean } dojo.html.toggleVisibility = function(node){ - // summary - // Call setVisibility() on node with the complement of isVisible(), then return the new value of isVisible() - return dojo.html._toggle(node, dojo.html.isVisible, dojo.html.setVisibility); // boolean + // summary + // Call setVisibility() on node with the complement of isVisible(), then return the new value of isVisible() + return dojo.html._toggle(node, dojo.html.isVisible, dojo.html.setVisibility); // boolean } dojo.html.setOpacity = function(/* HTMLElement */node, /* float */opacity, /* boolean? */dontFixOpacity){ - // summary - // Sets the opacity of node in a cross-browser way. - // float between 0.0 (transparent) and 1.0 (opaque) - node = dojo.byId(node); - var h = dojo.render.html; - if(!dontFixOpacity){ - if( opacity >= 1.0){ - if(h.ie){ - dojo.html.clearOpacity(node); - return; - }else{ - opacity = 0.999999; - } - }else if( opacity < 0.0){ opacity = 0; } - } - if(h.ie){ - if(node.nodeName.toLowerCase() == "tr"){ - // FIXME: is this too naive? will we get more than we want? - var tds = node.getElementsByTagName("td"); - for(var x=0; x= 1.0){ + if(h.ie){ + dojo.html.clearOpacity(node); + return; + }else{ + opacity = 0.999999; + } + }else if( opacity < 0.0){ opacity = 0; } + } + if(h.ie){ + if(node.nodeName.toLowerCase() == "tr"){ + // FIXME: is this too naive? will we get more than we want? + var tds = node.getElementsByTagName("td"); + for(var x=0; x= 0.999999 ? 1.0 : Number(opac); // float + // summary + // Returns the opacity of the passed element + node = dojo.byId(node); + var h = dojo.render.html; + if(h.ie){ + var opac = (node.filters && node.filters.alpha && + typeof node.filters.alpha.opacity == "number" + ? node.filters.alpha.opacity : 100) / 100; + }else{ + var opac = node.style.opacity || node.style.MozOpacity || + node.style.KhtmlOpacity || 1; + } + return opac >= 0.999999 ? 1.0 : Number(opac); // float } @@ -8606,23 +8616,23 @@ dojo.provide("dojo.html.color"); dojo.html.getBackgroundColor = function(/* HTMLElement */node){ - // summary - // returns the background color of the passed node as a 32-bit color (RGBA) - node = dojo.byId(node); - var color; - do{ - color = dojo.html.getStyle(node, "background-color"); - // Safari doesn't say "transparent" - if(color.toLowerCase() == "rgba(0, 0, 0, 0)") { color = "transparent"; } - if(node == document.getElementsByTagName("body")[0]) { node = null; break; } - node = node.parentNode; - }while(node && dojo.lang.inArray(["transparent", ""], color)); - if(color == "transparent"){ - color = [255, 255, 255, 0]; - }else{ - color = dojo.gfx.color.extractRGB(color); - } - return color; // array + // summary + // returns the background color of the passed node as a 32-bit color (RGBA) + node = dojo.byId(node); + var color; + do{ + color = dojo.html.getStyle(node, "background-color"); + // Safari doesn't say "transparent" + if(color.toLowerCase() == "rgba(0, 0, 0, 0)") { color = "transparent"; } + if(node == document.getElementsByTagName("body")[0]) { node = null; break; } + node = node.parentNode; + }while(node && dojo.lang.inArray(["transparent", ""], color)); + if(color == "transparent"){ + color = [255, 255, 255, 0]; + }else{ + color = dojo.gfx.color.extractRGB(color); + } + return color; // array } dojo.provide("dojo.html.layout"); @@ -8632,480 +8642,480 @@ dojo.provide("dojo.html.layout"); dojo.html.sumAncestorProperties = function(/* HTMLElement */node, /* string */prop){ - // summary - // Returns the sum of the passed property on all ancestors of node. - node = dojo.byId(node); - if(!node){ return 0; } // FIXME: throw an error? - - var retVal = 0; - while(node){ - if(dojo.html.getComputedStyle(node, 'position') == 'fixed'){ - return 0; - } - var val = node[prop]; - if(val){ - retVal += val - 0; - if(node==dojo.body()){ break; }// opera and khtml #body & #html has the same values, we only need one value - } - node = node.parentNode; - } - return retVal; // integer + // summary + // Returns the sum of the passed property on all ancestors of node. + node = dojo.byId(node); + if(!node){ return 0; } // FIXME: throw an error? + + var retVal = 0; + while(node){ + if(dojo.html.getComputedStyle(node, 'position') == 'fixed'){ + return 0; + } + var val = node[prop]; + if(val){ + retVal += val - 0; + if(node==dojo.body()){ break; }// opera and khtml #body & #html has the same values, we only need one value + } + node = node.parentNode; + } + return retVal; // integer } -dojo.html.setStyleAttributes = function(/* HTMLElement */node, /* string */attributes) { - // summary - // allows a dev to pass a string similar to what you'd pass in style="", and apply it to a node. - node = dojo.byId(node); - var splittedAttribs=attributes.replace(/(;)?\s*$/, "").split(";"); - for(var i=0; i0){ - ret.x += isNaN(n) ? 0 : n; - } - var m = curnode["offsetTop"]; - ret.y += isNaN(m) ? 0 : m; - curnode = curnode.offsetParent; - }while((curnode != endNode)&&(curnode != null)); - }else if(node["x"]&&node["y"]){ - ret.x += isNaN(node.x) ? 0 : node.x; - ret.y += isNaN(node.y) ? 0 : node.y; - } - } + if(node.parentNode != db){ + var nd = node; + if(dojo.render.html.opera){ nd = db; } + ret.x -= dojo.html.sumAncestorProperties(nd, "scrollLeft"); + ret.y -= dojo.html.sumAncestorProperties(nd, "scrollTop"); + } + var curnode = node; + do{ + var n = curnode["offsetLeft"]; + //FIXME: ugly hack to workaround the submenu in + //popupmenu2 does not shown up correctly in opera. + //Someone have a better workaround? + if(!h.opera || n>0){ + ret.x += isNaN(n) ? 0 : n; + } + var m = curnode["offsetTop"]; + ret.y += isNaN(m) ? 0 : m; + curnode = curnode.offsetParent; + }while((curnode != endNode)&&(curnode != null)); + }else if(node["x"]&&node["y"]){ + ret.x += isNaN(node.x) ? 0 : node.x; + ret.y += isNaN(node.y) ? 0 : node.y; + } + } - // account for document scrolling! - if(includeScroll){ - var scroll = dojo.html.getScroll(); - ret.y += scroll.top; - ret.x += scroll.left; - } + // account for document scrolling! + if(includeScroll){ + var scroll = dojo.html.getScroll(); + ret.y += scroll.top; + ret.x += scroll.left; + } - var extentFuncArray=[dojo.html.getPaddingExtent, dojo.html.getBorderExtent, dojo.html.getMarginExtent]; - if(nativeBoxType > targetBoxType){ - for(var i=targetBoxType;inativeBoxType;--i){ - ret.y -= extentFuncArray[i-1](node, 'top'); - ret.x -= extentFuncArray[i-1](node, 'left'); - } - } - ret.top = ret.y; - ret.left = ret.x; - return ret; // object + var extentFuncArray=[dojo.html.getPaddingExtent, dojo.html.getBorderExtent, dojo.html.getMarginExtent]; + if(nativeBoxType > targetBoxType){ + for(var i=targetBoxType;inativeBoxType;--i){ + ret.y -= extentFuncArray[i-1](node, 'top'); + ret.x -= extentFuncArray[i-1](node, 'left'); + } + } + ret.top = ret.y; + ret.left = ret.x; + return ret; // object } dojo.html.isPositionAbsolute = function(/* HTMLElement */node){ - // summary - // Returns true if the element is absolutely positioned. - return (dojo.html.getComputedStyle(node, 'position') == 'absolute'); // boolean + // summary + // Returns true if the element is absolutely positioned. + return (dojo.html.getComputedStyle(node, 'position') == 'absolute'); // boolean } dojo.html._sumPixelValues = function(/* HTMLElement */node, selectors, autoIsZero){ - var total = 0; - for(var x=0; x 4 ) { coords.pop(); } - var ret = { - left: coords[0], - top: coords[1], - width: coords[2], - height: coords[3] - }; - }else if(!coords.nodeType && !(coords instanceof String || typeof coords == "string") && - ('width' in coords || 'height' in coords || 'left' in coords || - 'x' in coords || 'top' in coords || 'y' in coords)){ - // coords is a coordinate object or at least part of one - var ret = { - left: coords.left||coords.x||0, - top: coords.top||coords.y||0, - width: coords.width||0, - height: coords.height||0 - }; - }else{ - // coords is an dom object (or dom object id); return it's coordinates - var node = dojo.byId(coords); - var pos = dojo.html.abs(node, includeScroll, boxtype); - var marginbox = dojo.html.getMarginBox(node); - var ret = { - left: pos.left, - top: pos.top, - width: marginbox.width, - height: marginbox.height - }; - } - ret.x = ret.left; - ret.y = ret.top; - return ret; // object + // summary + // Converts an array of coordinates into an object of named arguments. + if(coords instanceof Array || typeof coords == "array"){ + dojo.deprecated("dojo.html.toCoordinateArray", "use dojo.html.toCoordinateObject({left: , top: , width: , height: }) instead", "0.5"); + // coords is already an array (of format [x,y,w,h]), just return it + while ( coords.length < 4 ) { coords.push(0); } + while ( coords.length > 4 ) { coords.pop(); } + var ret = { + left: coords[0], + top: coords[1], + width: coords[2], + height: coords[3] + }; + }else if(!coords.nodeType && !(coords instanceof String || typeof coords == "string") && + ('width' in coords || 'height' in coords || 'left' in coords || + 'x' in coords || 'top' in coords || 'y' in coords)){ + // coords is a coordinate object or at least part of one + var ret = { + left: coords.left||coords.x||0, + top: coords.top||coords.y||0, + width: coords.width||0, + height: coords.height||0 + }; + }else{ + // coords is an dom object (or dom object id); return it's coordinates + var node = dojo.byId(coords); + var pos = dojo.html.abs(node, includeScroll, boxtype); + var marginbox = dojo.html.getMarginBox(node); + var ret = { + left: pos.left, + top: pos.top, + width: marginbox.width, + height: marginbox.height + }; + } + ret.x = ret.left; + ret.y = ret.top; + return ret; // object } dojo.html.setMarginBoxWidth = dojo.html.setOuterWidth = function(node, width){ - return dojo.html._callDeprecated("setMarginBoxWidth", "setMarginBox", arguments, "width"); + return dojo.html._callDeprecated("setMarginBoxWidth", "setMarginBox", arguments, "width"); } dojo.html.setMarginBoxHeight = dojo.html.setOuterHeight = function(){ - return dojo.html._callDeprecated("setMarginBoxHeight", "setMarginBox", arguments, "height"); + return dojo.html._callDeprecated("setMarginBoxHeight", "setMarginBox", arguments, "height"); } dojo.html.getMarginBoxWidth = dojo.html.getOuterWidth = function(){ - return dojo.html._callDeprecated("getMarginBoxWidth", "getMarginBox", arguments, null, "width"); + return dojo.html._callDeprecated("getMarginBoxWidth", "getMarginBox", arguments, null, "width"); } dojo.html.getMarginBoxHeight = dojo.html.getOuterHeight = function(){ - return dojo.html._callDeprecated("getMarginBoxHeight", "getMarginBox", arguments, null, "height"); + return dojo.html._callDeprecated("getMarginBoxHeight", "getMarginBox", arguments, null, "height"); } dojo.html.getTotalOffset = function(node, type, includeScroll){ - return dojo.html._callDeprecated("getTotalOffset", "getAbsolutePosition", arguments, null, type); + return dojo.html._callDeprecated("getTotalOffset", "getAbsolutePosition", arguments, null, type); } dojo.html.getAbsoluteX = function(node, includeScroll){ - return dojo.html._callDeprecated("getAbsoluteX", "getAbsolutePosition", arguments, null, "x"); + return dojo.html._callDeprecated("getAbsoluteX", "getAbsolutePosition", arguments, null, "x"); } dojo.html.getAbsoluteY = function(node, includeScroll){ - return dojo.html._callDeprecated("getAbsoluteY", "getAbsolutePosition", arguments, null, "y"); + return dojo.html._callDeprecated("getAbsoluteY", "getAbsolutePosition", arguments, null, "y"); } dojo.html.totalOffsetLeft = function(node, includeScroll){ - return dojo.html._callDeprecated("totalOffsetLeft", "getAbsolutePosition", arguments, null, "left"); + return dojo.html._callDeprecated("totalOffsetLeft", "getAbsolutePosition", arguments, null, "left"); } dojo.html.totalOffsetTop = function(node, includeScroll){ - return dojo.html._callDeprecated("totalOffsetTop", "getAbsolutePosition", arguments, null, "top"); + return dojo.html._callDeprecated("totalOffsetTop", "getAbsolutePosition", arguments, null, "top"); } dojo.html.getMarginWidth = function(node){ - return dojo.html._callDeprecated("getMarginWidth", "getMargin", arguments, null, "width"); + return dojo.html._callDeprecated("getMarginWidth", "getMargin", arguments, null, "width"); } dojo.html.getMarginHeight = function(node){ - return dojo.html._callDeprecated("getMarginHeight", "getMargin", arguments, null, "height"); + return dojo.html._callDeprecated("getMarginHeight", "getMargin", arguments, null, "height"); } dojo.html.getBorderWidth = function(node){ - return dojo.html._callDeprecated("getBorderWidth", "getBorder", arguments, null, "width"); + return dojo.html._callDeprecated("getBorderWidth", "getBorder", arguments, null, "width"); } dojo.html.getBorderHeight = function(node){ - return dojo.html._callDeprecated("getBorderHeight", "getBorder", arguments, null, "height"); + return dojo.html._callDeprecated("getBorderHeight", "getBorder", arguments, null, "height"); } dojo.html.getPaddingWidth = function(node){ - return dojo.html._callDeprecated("getPaddingWidth", "getPadding", arguments, null, "width"); + return dojo.html._callDeprecated("getPaddingWidth", "getPadding", arguments, null, "width"); } dojo.html.getPaddingHeight = function(node){ - return dojo.html._callDeprecated("getPaddingHeight", "getPadding", arguments, null, "height"); + return dojo.html._callDeprecated("getPaddingHeight", "getPadding", arguments, null, "height"); } dojo.html.getPadBorderWidth = function(node){ - return dojo.html._callDeprecated("getPadBorderWidth", "getPadBorder", arguments, null, "width"); + return dojo.html._callDeprecated("getPadBorderWidth", "getPadBorder", arguments, null, "width"); } dojo.html.getPadBorderHeight = function(node){ - return dojo.html._callDeprecated("getPadBorderHeight", "getPadBorder", arguments, null, "height"); + return dojo.html._callDeprecated("getPadBorderHeight", "getPadBorder", arguments, null, "height"); } dojo.html.getBorderBoxWidth = dojo.html.getInnerWidth = function(){ - return dojo.html._callDeprecated("getBorderBoxWidth", "getBorderBox", arguments, null, "width"); + return dojo.html._callDeprecated("getBorderBoxWidth", "getBorderBox", arguments, null, "width"); } dojo.html.getBorderBoxHeight = dojo.html.getInnerHeight = function(){ - return dojo.html._callDeprecated("getBorderBoxHeight", "getBorderBox", arguments, null, "height"); + return dojo.html._callDeprecated("getBorderBoxHeight", "getBorderBox", arguments, null, "height"); } dojo.html.getContentBoxWidth = dojo.html.getContentWidth = function(){ - return dojo.html._callDeprecated("getContentBoxWidth", "getContentBox", arguments, null, "width"); + return dojo.html._callDeprecated("getContentBoxWidth", "getContentBox", arguments, null, "width"); } dojo.html.getContentBoxHeight = dojo.html.getContentHeight = function(){ - return dojo.html._callDeprecated("getContentBoxHeight", "getContentBox", arguments, null, "height"); + return dojo.html._callDeprecated("getContentBoxHeight", "getContentBox", arguments, null, "height"); } dojo.html.setContentBoxWidth = dojo.html.setContentWidth = function(node, width){ - return dojo.html._callDeprecated("setContentBoxWidth", "setContentBox", arguments, "width"); + return dojo.html._callDeprecated("setContentBoxWidth", "setContentBox", arguments, "width"); } dojo.html.setContentBoxHeight = dojo.html.setContentHeight = function(node, height){ - return dojo.html._callDeprecated("setContentBoxHeight", "setContentBox", arguments, "height"); + return dojo.html._callDeprecated("setContentBoxHeight", "setContentBox", arguments, "height"); } dojo.provide("dojo.lfx.html"); @@ -9118,743 +9128,743 @@ dojo.provide("dojo.lfx.html"); dojo.lfx.html._byId = function(nodes){ - if(!nodes){ return []; } - if(dojo.lang.isArrayLike(nodes)){ - if(!nodes.alreadyChecked){ - var n = []; - dojo.lang.forEach(nodes, function(node){ - n.push(dojo.byId(node)); - }); - n.alreadyChecked = true; - return n; - }else{ - return nodes; - } - }else{ - var n = []; - n.push(dojo.byId(nodes)); - n.alreadyChecked = true; - return n; - } + if(!nodes){ return []; } + if(dojo.lang.isArrayLike(nodes)){ + if(!nodes.alreadyChecked){ + var n = []; + dojo.lang.forEach(nodes, function(node){ + n.push(dojo.byId(node)); + }); + n.alreadyChecked = true; + return n; + }else{ + return nodes; + } + }else{ + var n = []; + n.push(dojo.byId(nodes)); + n.alreadyChecked = true; + return n; + } } -dojo.lfx.html.propertyAnimation = function( /*DOMNode[]*/ nodes, - /*Object[]*/ propertyMap, - /*int*/ duration, - /*function*/ easing, - /*Object*/ handlers){ - // summary: Returns an animation that will transition the properties of "nodes" - // depending how they are defined in "propertyMap". - // nodes: An array of DOMNodes or one DOMNode. - // propertyMap: { property: String, start: Decimal?, end: Decimal?, units: String? } - // An array of objects defining properties to change. - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // handlers: { handler: Function?, onstart: Function?, onstop: Function?, onanimate: Function? } - nodes = dojo.lfx.html._byId(nodes); +dojo.lfx.html.propertyAnimation = function( /*DOMNode[]*/ nodes, + /*Object[]*/ propertyMap, + /*int*/ duration, + /*function*/ easing, + /*Object*/ handlers){ + // summary: Returns an animation that will transition the properties of "nodes" + // depending how they are defined in "propertyMap". + // nodes: An array of DOMNodes or one DOMNode. + // propertyMap: { property: String, start: Decimal?, end: Decimal?, units: String? } + // An array of objects defining properties to change. + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // handlers: { handler: Function?, onstart: Function?, onstop: Function?, onanimate: Function? } + nodes = dojo.lfx.html._byId(nodes); - var targs = { - "propertyMap": propertyMap, - "nodes": nodes, - "duration": duration, - "easing": easing||dojo.lfx.easeDefault - }; + var targs = { + "propertyMap": propertyMap, + "nodes": nodes, + "duration": duration, + "easing": easing||dojo.lfx.easeDefault + }; + + var setEmUp = function(args){ + if(args.nodes.length==1){ + // FIXME: we're only supporting start-value filling when one node is + // passed + + var pm = args.propertyMap; + if(!dojo.lang.isArray(args.propertyMap)){ + // it's stupid to have to pack an array with a set of objects + // when you can just pass in an object list + var parr = []; + for(var pname in pm){ + pm[pname].property = pname; + parr.push(pm[pname]); + } + pm = args.propertyMap = parr; + } + dojo.lang.forEach(pm, function(prop){ + if(dj_undef("start", prop)){ + if(prop.property != "opacity"){ + prop.start = parseInt(dojo.html.getComputedStyle(args.nodes[0], prop.property)); + }else{ + prop.start = dojo.html.getOpacity(args.nodes[0]); + } + } + }); + } + } - var setEmUp = function(args){ - if(args.nodes.length==1){ - // FIXME: we're only supporting start-value filling when one node is - // passed + var coordsAsInts = function(coords){ + var cints = []; + dojo.lang.forEach(coords, function(c){ + cints.push(Math.round(c)); + }); + return cints; + } - var pm = args.propertyMap; - if(!dojo.lang.isArray(args.propertyMap)){ - // it's stupid to have to pack an array with a set of objects - // when you can just pass in an object list - var parr = []; - for(var pname in pm){ - pm[pname].property = pname; - parr.push(pm[pname]); - } - pm = args.propertyMap = parr; - } - dojo.lang.forEach(pm, function(prop){ - if(dj_undef("start", prop)){ - if(prop.property != "opacity"){ - prop.start = parseInt(dojo.html.getComputedStyle(args.nodes[0], prop.property)); - }else{ - prop.start = dojo.html.getOpacity(args.nodes[0]); - } - } - }); - } - } + var setStyle = function(n, style){ + n = dojo.byId(n); + if(!n || !n.style){ return; } + for(var s in style){ + try{ + if(s == "opacity"){ + dojo.html.setOpacity(n, style[s]); + }else{ + n.style[s] = style[s]; + } + }catch(e){ dojo.debug(e); } + } + } - var coordsAsInts = function(coords){ - var cints = []; - dojo.lang.forEach(coords, function(c){ - cints.push(Math.round(c)); - }); - return cints; - } + var propLine = function(properties){ + this._properties = properties; + this.diffs = new Array(properties.length); + dojo.lang.forEach(properties, function(prop, i){ + // calculate the end - start to optimize a bit + if(dojo.lang.isFunction(prop.start)){ + prop.start = prop.start(prop, i); + } + if(dojo.lang.isFunction(prop.end)){ + prop.end = prop.end(prop, i); + } + if(dojo.lang.isArray(prop.start)){ + // don't loop through the arrays + this.diffs[i] = null; + }else if(prop.start instanceof dojo.gfx.color.Color){ + // save these so we don't have to call toRgb() every getValue() call + prop.startRgb = prop.start.toRgb(); + prop.endRgb = prop.end.toRgb(); + }else{ + this.diffs[i] = prop.end - prop.start; + } + }, this); - var setStyle = function(n, style){ - n = dojo.byId(n); - if(!n || !n.style){ return; } - for(var s in style){ - try{ - if(s == "opacity"){ - dojo.html.setOpacity(n, style[s]); - }else{ - n.style[s] = style[s]; - } - }catch(e){ dojo.debug(e); } - } - } - - var propLine = function(properties){ - this._properties = properties; - this.diffs = new Array(properties.length); - dojo.lang.forEach(properties, function(prop, i){ - // calculate the end - start to optimize a bit - if(dojo.lang.isFunction(prop.start)){ - prop.start = prop.start(prop, i); - } - if(dojo.lang.isFunction(prop.end)){ - prop.end = prop.end(prop, i); - } - if(dojo.lang.isArray(prop.start)){ - // don't loop through the arrays - this.diffs[i] = null; - }else if(prop.start instanceof dojo.gfx.color.Color){ - // save these so we don't have to call toRgb() every getValue() call - prop.startRgb = prop.start.toRgb(); - prop.endRgb = prop.end.toRgb(); - }else{ - this.diffs[i] = prop.end - prop.start; - } - }, this); - - this.getValue = function(n){ - var ret = {}; - dojo.lang.forEach(this._properties, function(prop, i){ - var value = null; - if(dojo.lang.isArray(prop.start)){ - // FIXME: what to do here? - }else if(prop.start instanceof dojo.gfx.color.Color){ - value = (prop.units||"rgb") + "("; - for(var j = 0 ; j < prop.startRgb.length ; j++){ - value += Math.round(((prop.endRgb[j] - prop.startRgb[j]) * n) + prop.startRgb[j]) + (j < prop.startRgb.length - 1 ? "," : ""); - } - value += ")"; - }else{ - value = ((this.diffs[i]) * n) + prop.start + (prop.property != "opacity" ? prop.units||"px" : ""); - } - ret[dojo.html.toCamelCase(prop.property)] = value; - }, this); - return ret; - } - } - - var anim = new dojo.lfx.Animation({ - beforeBegin: function(){ - setEmUp(targs); - anim.curve = new propLine(targs.propertyMap); - }, - onAnimate: function(propValues){ - dojo.lang.forEach(targs.nodes, function(node){ - setStyle(node, propValues); - }); - } - }, - targs.duration, - null, - targs.easing - ); - if(handlers){ - for(var x in handlers){ - if(dojo.lang.isFunction(handlers[x])){ - anim.connect(x, anim, handlers[x]); - } - } - } - - return anim; // dojo.lfx.Animation + this.getValue = function(n){ + var ret = {}; + dojo.lang.forEach(this._properties, function(prop, i){ + var value = null; + if(dojo.lang.isArray(prop.start)){ + // FIXME: what to do here? + }else if(prop.start instanceof dojo.gfx.color.Color){ + value = (prop.units||"rgb") + "("; + for(var j = 0 ; j < prop.startRgb.length ; j++){ + value += Math.round(((prop.endRgb[j] - prop.startRgb[j]) * n) + prop.startRgb[j]) + (j < prop.startRgb.length - 1 ? "," : ""); + } + value += ")"; + }else{ + value = ((this.diffs[i]) * n) + prop.start + (prop.property != "opacity" ? prop.units||"px" : ""); + } + ret[dojo.html.toCamelCase(prop.property)] = value; + }, this); + return ret; + } + } + + var anim = new dojo.lfx.Animation({ + beforeBegin: function(){ + setEmUp(targs); + anim.curve = new propLine(targs.propertyMap); + }, + onAnimate: function(propValues){ + dojo.lang.forEach(targs.nodes, function(node){ + setStyle(node, propValues); + }); + } + }, + targs.duration, + null, + targs.easing + ); + if(handlers){ + for(var x in handlers){ + if(dojo.lang.isFunction(handlers[x])){ + anim.connect(x, anim, handlers[x]); + } + } + } + + return anim; // dojo.lfx.Animation } dojo.lfx.html._makeFadeable = function(nodes){ - var makeFade = function(node){ - if(dojo.render.html.ie){ - // only set the zoom if the "tickle" value would be the same as the - // default - if( (node.style.zoom.length == 0) && - (dojo.html.getStyle(node, "zoom") == "normal") ){ - // make sure the node "hasLayout" - // NOTE: this has been tested with larger and smaller user-set text - // sizes and works fine - node.style.zoom = "1"; - // node.style.zoom = "normal"; - } - // don't set the width to auto if it didn't already cascade that way. - // We don't want to f anyones designs - if( (node.style.width.length == 0) && - (dojo.html.getStyle(node, "width") == "auto") ){ - node.style.width = "auto"; - } - } - } - if(dojo.lang.isArrayLike(nodes)){ - dojo.lang.forEach(nodes, makeFade); - }else{ - makeFade(nodes); - } + var makeFade = function(node){ + if(dojo.render.html.ie){ + // only set the zoom if the "tickle" value would be the same as the + // default + if( (node.style.zoom.length == 0) && + (dojo.html.getStyle(node, "zoom") == "normal") ){ + // make sure the node "hasLayout" + // NOTE: this has been tested with larger and smaller user-set text + // sizes and works fine + node.style.zoom = "1"; + // node.style.zoom = "normal"; + } + // don't set the width to auto if it didn't already cascade that way. + // We don't want to f anyones designs + if( (node.style.width.length == 0) && + (dojo.html.getStyle(node, "width") == "auto") ){ + node.style.width = "auto"; + } + } + } + if(dojo.lang.isArrayLike(nodes)){ + dojo.lang.forEach(nodes, makeFade); + }else{ + makeFade(nodes); + } } dojo.lfx.html.fade = function(/*DOMNode[]*/ nodes, - /*Object*/values, - /*int?*/ duration, - /*Function?*/ easing, - /*Function?*/ callback){ - // summary:Returns an animation that will fade the "nodes" from the start to end values passed. - // nodes: An array of DOMNodes or one DOMNode. - // values: { start: Decimal?, end: Decimal? } - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - nodes = dojo.lfx.html._byId(nodes); - var props = { property: "opacity" }; - if(!dj_undef("start", values)){ - props.start = values.start; - }else{ - props.start = function(){ return dojo.html.getOpacity(nodes[0]); }; - } + /*Object*/values, + /*int?*/ duration, + /*Function?*/ easing, + /*Function?*/ callback){ + // summary:Returns an animation that will fade the "nodes" from the start to end values passed. + // nodes: An array of DOMNodes or one DOMNode. + // values: { start: Decimal?, end: Decimal? } + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + nodes = dojo.lfx.html._byId(nodes); + var props = { property: "opacity" }; + if(!dj_undef("start", values)){ + props.start = values.start; + }else{ + props.start = function(){ return dojo.html.getOpacity(nodes[0]); }; + } - if(!dj_undef("end", values)){ - props.end = values.end; - }else{ - dojo.raise("dojo.lfx.html.fade needs an end value"); - } + if(!dj_undef("end", values)){ + props.end = values.end; + }else{ + dojo.raise("dojo.lfx.html.fade needs an end value"); + } - var anim = dojo.lfx.propertyAnimation(nodes, [ props ], duration, easing); - anim.connect("beforeBegin", function(){ - dojo.lfx.html._makeFadeable(nodes); - }); - if(callback){ - anim.connect("onEnd", function(){ callback(nodes, anim); }); - } + var anim = dojo.lfx.propertyAnimation(nodes, [ props ], duration, easing); + anim.connect("beforeBegin", function(){ + dojo.lfx.html._makeFadeable(nodes); + }); + if(callback){ + anim.connect("onEnd", function(){ callback(nodes, anim); }); + } - return anim; // dojo.lfx.Animation + return anim; // dojo.lfx.Animation } dojo.lfx.html.fadeIn = function(/*DOMNode[]*/ nodes, /*int?*/ duration, /*Function?*/ easing, /*Function?*/ callback){ - // summary: Returns an animation that will fade "nodes" from its current opacity to fully opaque. - // nodes: An array of DOMNodes or one DOMNode. - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - return dojo.lfx.html.fade(nodes, { end: 1 }, duration, easing, callback); // dojo.lfx.Animation + // summary: Returns an animation that will fade "nodes" from its current opacity to fully opaque. + // nodes: An array of DOMNodes or one DOMNode. + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + return dojo.lfx.html.fade(nodes, { end: 1 }, duration, easing, callback); // dojo.lfx.Animation } dojo.lfx.html.fadeOut = function(/*DOMNode[]*/ nodes, /*int?*/ duration, /*Function?*/ easing, /*Function?*/ callback){ - // summary: Returns an animation that will fade "nodes" from its current opacity to fully transparent. - // nodes: An array of DOMNodes or one DOMNode. - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - return dojo.lfx.html.fade(nodes, { end: 0 }, duration, easing, callback); // dojo.lfx.Animation + // summary: Returns an animation that will fade "nodes" from its current opacity to fully transparent. + // nodes: An array of DOMNodes or one DOMNode. + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + return dojo.lfx.html.fade(nodes, { end: 0 }, duration, easing, callback); // dojo.lfx.Animation } dojo.lfx.html.fadeShow = function(/*DOMNode[]*/ nodes, /*int?*/ duration, /*Function?*/ easing, /*Function?*/ callback){ - // summary: Returns an animation that will fade "nodes" from transparent to opaque and shows - // "nodes" at the end if it is hidden. - // nodes: An array of DOMNodes or one DOMNode. - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - nodes=dojo.lfx.html._byId(nodes); - dojo.lang.forEach(nodes, function(node){ - dojo.html.setOpacity(node, 0.0); - }); + // summary: Returns an animation that will fade "nodes" from transparent to opaque and shows + // "nodes" at the end if it is hidden. + // nodes: An array of DOMNodes or one DOMNode. + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + nodes=dojo.lfx.html._byId(nodes); + dojo.lang.forEach(nodes, function(node){ + dojo.html.setOpacity(node, 0.0); + }); - var anim = dojo.lfx.html.fadeIn(nodes, duration, easing, callback); - anim.connect("beforeBegin", function(){ - if(dojo.lang.isArrayLike(nodes)){ - dojo.lang.forEach(nodes, dojo.html.show); - }else{ - dojo.html.show(nodes); - } - }); + var anim = dojo.lfx.html.fadeIn(nodes, duration, easing, callback); + anim.connect("beforeBegin", function(){ + if(dojo.lang.isArrayLike(nodes)){ + dojo.lang.forEach(nodes, dojo.html.show); + }else{ + dojo.html.show(nodes); + } + }); - return anim; // dojo.lfx.Animation + return anim; // dojo.lfx.Animation } dojo.lfx.html.fadeHide = function(/*DOMNode[]*/ nodes, /*int?*/ duration, /*Function?*/ easing, /*Function?*/ callback){ - // summary: Returns an animation that will fade "nodes" from its current opacity to opaque and hides - // "nodes" at the end. - // nodes: An array of DOMNodes or one DOMNode. - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - var anim = dojo.lfx.html.fadeOut(nodes, duration, easing, function(){ - if(dojo.lang.isArrayLike(nodes)){ - dojo.lang.forEach(nodes, dojo.html.hide); - }else{ - dojo.html.hide(nodes); - } - if(callback){ callback(nodes, anim); } - }); - - return anim; // dojo.lfx.Animation + // summary: Returns an animation that will fade "nodes" from its current opacity to opaque and hides + // "nodes" at the end. + // nodes: An array of DOMNodes or one DOMNode. + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + var anim = dojo.lfx.html.fadeOut(nodes, duration, easing, function(){ + if(dojo.lang.isArrayLike(nodes)){ + dojo.lang.forEach(nodes, dojo.html.hide); + }else{ + dojo.html.hide(nodes); + } + if(callback){ callback(nodes, anim); } + }); + + return anim; // dojo.lfx.Animation } dojo.lfx.html.wipeIn = function(/*DOMNode[]*/ nodes, /*int?*/ duration, /*Function?*/ easing, /*Function?*/ callback){ - // summary: Returns an animation that will show and wipe in "nodes". - // nodes: An array of DOMNodes or one DOMNode. - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - nodes = dojo.lfx.html._byId(nodes); - var anims = []; + // summary: Returns an animation that will show and wipe in "nodes". + // nodes: An array of DOMNodes or one DOMNode. + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + nodes = dojo.lfx.html._byId(nodes); + var anims = []; - dojo.lang.forEach(nodes, function(node){ - var oprop = { }; // old properties of node (before we mucked w/them) + dojo.lang.forEach(nodes, function(node){ + var oprop = { }; // old properties of node (before we mucked w/them) + + // get node height, either it's natural height or it's height specified via style or class attributes + // (for FF, the node has to be (temporarily) rendered to measure height) + // TODO: should this offscreen code be part of dojo.html, so that getBorderBox() works on hidden nodes? + var origTop, origLeft, origPosition; + with(node.style){ + origTop=top; origLeft=left; origPosition=position; + top="-9999px"; left="-9999px"; position="absolute"; + display=""; + } + var nodeHeight = dojo.html.getBorderBox(node).height; + with(node.style){ + top=origTop; left=origLeft; position=origPosition; + display="none"; + } - // get node height, either it's natural height or it's height specified via style or class attributes - // (for FF, the node has to be (temporarily) rendered to measure height) - // TODO: should this offscreen code be part of dojo.html, so that getBorderBox() works on hidden nodes? - var origTop, origLeft, origPosition; - with(node.style){ - origTop=top; origLeft=left; origPosition=position; - top="-9999px"; left="-9999px"; position="absolute"; - display=""; - } - var nodeHeight = dojo.html.getBorderBox(node).height; - with(node.style){ - top=origTop; left=origLeft; position=origPosition; - display="none"; - } - - var anim = dojo.lfx.propertyAnimation(node, - { "height": { - start: 1, // 0 causes IE to display the whole panel - end: function(){ return nodeHeight; } - } - }, - duration, - easing); - - anim.connect("beforeBegin", function(){ - oprop.overflow = node.style.overflow; - oprop.height = node.style.height; - with(node.style){ - overflow = "hidden"; - height = "1px"; // 0 causes IE to display the whole panel - } - dojo.html.show(node); - }); - - anim.connect("onEnd", function(){ - with(node.style){ - overflow = oprop.overflow; - height = oprop.height; - } - if(callback){ callback(node, anim); } - }); - anims.push(anim); - }); - - return dojo.lfx.combine(anims); // dojo.lfx.Combine + var anim = dojo.lfx.propertyAnimation(node, + { "height": { + start: 1, // 0 causes IE to display the whole panel + end: function(){ return nodeHeight; } + } + }, + duration, + easing); + + anim.connect("beforeBegin", function(){ + oprop.overflow = node.style.overflow; + oprop.height = node.style.height; + with(node.style){ + overflow = "hidden"; + height = "1px"; // 0 causes IE to display the whole panel + } + dojo.html.show(node); + }); + + anim.connect("onEnd", function(){ + with(node.style){ + overflow = oprop.overflow; + height = oprop.height; + } + if(callback){ callback(node, anim); } + }); + anims.push(anim); + }); + + return dojo.lfx.combine(anims); // dojo.lfx.Combine } dojo.lfx.html.wipeOut = function(/*DOMNode[]*/ nodes, /*int?*/ duration, /*Function?*/ easing, /*Function?*/ callback){ - // summary: Returns an animation that will wipe out and hide "nodes". - // nodes: An array of DOMNodes or one DOMNode. - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - nodes = dojo.lfx.html._byId(nodes); - var anims = []; + // summary: Returns an animation that will wipe out and hide "nodes". + // nodes: An array of DOMNodes or one DOMNode. + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + nodes = dojo.lfx.html._byId(nodes); + var anims = []; + + dojo.lang.forEach(nodes, function(node){ + var oprop = { }; // old properties of node (before we mucked w/them) + var anim = dojo.lfx.propertyAnimation(node, + { "height": { + start: function(){ return dojo.html.getContentBox(node).height; }, + end: 1 // 0 causes IE to display the whole panel + } + }, + duration, + easing, + { + "beforeBegin": function(){ + oprop.overflow = node.style.overflow; + oprop.height = node.style.height; + with(node.style){ + overflow = "hidden"; + } + dojo.html.show(node); + }, + + "onEnd": function(){ + dojo.html.hide(node); + with(node.style){ + overflow = oprop.overflow; + height = oprop.height; + } + if(callback){ callback(node, anim); } + } + } + ); + anims.push(anim); + }); - dojo.lang.forEach(nodes, function(node){ - var oprop = { }; // old properties of node (before we mucked w/them) - var anim = dojo.lfx.propertyAnimation(node, - { "height": { - start: function(){ return dojo.html.getContentBox(node).height; }, - end: 1 // 0 causes IE to display the whole panel - } - }, - duration, - easing, - { - "beforeBegin": function(){ - oprop.overflow = node.style.overflow; - oprop.height = node.style.height; - with(node.style){ - overflow = "hidden"; - } - dojo.html.show(node); - }, - - "onEnd": function(){ - dojo.html.hide(node); - with(node.style){ - overflow = oprop.overflow; - height = oprop.height; - } - if(callback){ callback(node, anim); } - } - } - ); - anims.push(anim); - }); - - return dojo.lfx.combine(anims); // dojo.lfx.Combine + return dojo.lfx.combine(anims); // dojo.lfx.Combine } dojo.lfx.html.slideTo = function(/*DOMNode*/ nodes, - /*Object*/ coords, - /*int?*/ duration, - /*Function?*/ easing, - /*Function?*/ callback){ - // summary: Returns an animation that will slide "nodes" from its current position to - // the position defined in "coords". - // nodes: An array of DOMNodes or one DOMNode. - // coords: { top: Decimal?, left: Decimal? } - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - nodes = dojo.lfx.html._byId(nodes); - var anims = []; - var compute = dojo.html.getComputedStyle; + /*Object*/ coords, + /*int?*/ duration, + /*Function?*/ easing, + /*Function?*/ callback){ + // summary: Returns an animation that will slide "nodes" from its current position to + // the position defined in "coords". + // nodes: An array of DOMNodes or one DOMNode. + // coords: { top: Decimal?, left: Decimal? } + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + nodes = dojo.lfx.html._byId(nodes); + var anims = []; + var compute = dojo.html.getComputedStyle; + + if(dojo.lang.isArray(coords)){ + /* coords: Array + pId: a */ + dojo.deprecated('dojo.lfx.html.slideTo(node, array)', 'use dojo.lfx.html.slideTo(node, {top: value, left: value});', '0.5'); + coords = { top: coords[0], left: coords[1] }; + } + dojo.lang.forEach(nodes, function(node){ + var top = null; + var left = null; + + var init = (function(){ + var innerNode = node; + return function(){ + var pos = compute(innerNode, 'position'); + top = (pos == 'absolute' ? node.offsetTop : parseInt(compute(node, 'top')) || 0); + left = (pos == 'absolute' ? node.offsetLeft : parseInt(compute(node, 'left')) || 0); - if(dojo.lang.isArray(coords)){ - /* coords: Array - pId: a */ - dojo.deprecated('dojo.lfx.html.slideTo(node, array)', 'use dojo.lfx.html.slideTo(node, {top: value, left: value});', '0.5'); - coords = { top: coords[0], left: coords[1] }; - } - dojo.lang.forEach(nodes, function(node){ - var top = null; - var left = null; + if (!dojo.lang.inArray(['absolute', 'relative'], pos)) { + var ret = dojo.html.abs(innerNode, true); + dojo.html.setStyleAttributes(innerNode, "position:absolute;top:"+ret.y+"px;left:"+ret.x+"px;"); + top = ret.y; + left = ret.x; + } + } + })(); + init(); + + var anim = dojo.lfx.propertyAnimation(node, + { "top": { start: top, end: (coords.top||0) }, + "left": { start: left, end: (coords.left||0) } + }, + duration, + easing, + { "beforeBegin": init } + ); - var init = (function(){ - var innerNode = node; - return function(){ - var pos = compute(innerNode, 'position'); - top = (pos == 'absolute' ? node.offsetTop : parseInt(compute(node, 'top')) || 0); - left = (pos == 'absolute' ? node.offsetLeft : parseInt(compute(node, 'left')) || 0); + if(callback){ + anim.connect("onEnd", function(){ callback(nodes, anim); }); + } - if (!dojo.lang.inArray(['absolute', 'relative'], pos)) { - var ret = dojo.html.abs(innerNode, true); - dojo.html.setStyleAttributes(innerNode, "position:absolute;top:"+ret.y+"px;left:"+ret.x+"px;"); - top = ret.y; - left = ret.x; - } - } - })(); - init(); - - var anim = dojo.lfx.propertyAnimation(node, - { "top": { start: top, end: (coords.top||0) }, - "left": { start: left, end: (coords.left||0) } - }, - duration, - easing, - { "beforeBegin": init } - ); - - if(callback){ - anim.connect("onEnd", function(){ callback(nodes, anim); }); - } - - anims.push(anim); - }); - - return dojo.lfx.combine(anims); // dojo.lfx.Combine + anims.push(anim); + }); + + return dojo.lfx.combine(anims); // dojo.lfx.Combine } dojo.lfx.html.slideBy = function(/*DOMNode*/ nodes, /*Object*/ coords, /*int?*/ duration, /*Function?*/ easing, /*Function?*/ callback){ - // summary: Returns an animation that will slide "nodes" from its current position - // to its current position plus the numbers defined in "coords". - // nodes: An array of DOMNodes or one DOMNode. - // coords: { top: Decimal?, left: Decimal? } - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - nodes = dojo.lfx.html._byId(nodes); - var anims = []; - var compute = dojo.html.getComputedStyle; + // summary: Returns an animation that will slide "nodes" from its current position + // to its current position plus the numbers defined in "coords". + // nodes: An array of DOMNodes or one DOMNode. + // coords: { top: Decimal?, left: Decimal? } + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + nodes = dojo.lfx.html._byId(nodes); + var anims = []; + var compute = dojo.html.getComputedStyle; - if(dojo.lang.isArray(coords)){ - /* coords: Array - pId: a */ - dojo.deprecated('dojo.lfx.html.slideBy(node, array)', 'use dojo.lfx.html.slideBy(node, {top: value, left: value});', '0.5'); - coords = { top: coords[0], left: coords[1] }; - } + if(dojo.lang.isArray(coords)){ + /* coords: Array + pId: a */ + dojo.deprecated('dojo.lfx.html.slideBy(node, array)', 'use dojo.lfx.html.slideBy(node, {top: value, left: value});', '0.5'); + coords = { top: coords[0], left: coords[1] }; + } - dojo.lang.forEach(nodes, function(node){ - var top = null; - var left = null; + dojo.lang.forEach(nodes, function(node){ + var top = null; + var left = null; + + var init = (function(){ + var innerNode = node; + return function(){ + var pos = compute(innerNode, 'position'); + top = (pos == 'absolute' ? node.offsetTop : parseInt(compute(node, 'top')) || 0); + left = (pos == 'absolute' ? node.offsetLeft : parseInt(compute(node, 'left')) || 0); - var init = (function(){ - var innerNode = node; - return function(){ - var pos = compute(innerNode, 'position'); - top = (pos == 'absolute' ? node.offsetTop : parseInt(compute(node, 'top')) || 0); - left = (pos == 'absolute' ? node.offsetLeft : parseInt(compute(node, 'left')) || 0); + if (!dojo.lang.inArray(['absolute', 'relative'], pos)) { + var ret = dojo.html.abs(innerNode, true); + dojo.html.setStyleAttributes(innerNode, "position:absolute;top:"+ret.y+"px;left:"+ret.x+"px;"); + top = ret.y; + left = ret.x; + } + } + })(); + init(); + + var anim = dojo.lfx.propertyAnimation(node, + { + "top": { start: top, end: top+(coords.top||0) }, + "left": { start: left, end: left+(coords.left||0) } + }, + duration, + easing).connect("beforeBegin", init); - if (!dojo.lang.inArray(['absolute', 'relative'], pos)) { - var ret = dojo.html.abs(innerNode, true); - dojo.html.setStyleAttributes(innerNode, "position:absolute;top:"+ret.y+"px;left:"+ret.x+"px;"); - top = ret.y; - left = ret.x; - } - } - })(); - init(); + if(callback){ + anim.connect("onEnd", function(){ callback(nodes, anim); }); + } - var anim = dojo.lfx.propertyAnimation(node, - { - "top": { start: top, end: top+(coords.top||0) }, - "left": { start: left, end: left+(coords.left||0) } - }, - duration, - easing).connect("beforeBegin", init); + anims.push(anim); + }); - if(callback){ - anim.connect("onEnd", function(){ callback(nodes, anim); }); - } - - anims.push(anim); - }); - - return dojo.lfx.combine(anims); // dojo.lfx.Combine + return dojo.lfx.combine(anims); // dojo.lfx.Combine } dojo.lfx.html.explode = function(/*DOMNode*/ start, - /*DOMNode*/ endNode, - /*int?*/ duration, - /*Function?*/ easing, - /*Function?*/ callback){ - // summary: Returns an animation that will - // start: - // endNode: - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - var h = dojo.html; - start = dojo.byId(start); - endNode = dojo.byId(endNode); - var startCoords = h.toCoordinateObject(start, true); - var outline = document.createElement("div"); - h.copyStyle(outline, endNode); - if(endNode.explodeClassName){ outline.className = endNode.explodeClassName; } - with(outline.style){ - position = "absolute"; - display = "none"; - // border = "1px solid black"; - var backgroundStyle = h.getStyle(start, "background-color"); - backgroundColor = backgroundStyle ? backgroundStyle.toLowerCase() : "transparent"; - backgroundColor = (backgroundColor == "transparent") ? "rgb(221, 221, 221)" : backgroundColor; - } - dojo.body().appendChild(outline); + /*DOMNode*/ endNode, + /*int?*/ duration, + /*Function?*/ easing, + /*Function?*/ callback){ + // summary: Returns an animation that will + // start: + // endNode: + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + var h = dojo.html; + start = dojo.byId(start); + endNode = dojo.byId(endNode); + var startCoords = h.toCoordinateObject(start, true); + var outline = document.createElement("div"); + h.copyStyle(outline, endNode); + if(endNode.explodeClassName){ outline.className = endNode.explodeClassName; } + with(outline.style){ + position = "absolute"; + display = "none"; + // border = "1px solid black"; + var backgroundStyle = h.getStyle(start, "background-color"); + backgroundColor = backgroundStyle ? backgroundStyle.toLowerCase() : "transparent"; + backgroundColor = (backgroundColor == "transparent") ? "rgb(221, 221, 221)" : backgroundColor; + } + dojo.body().appendChild(outline); - with(endNode.style){ - visibility = "hidden"; - display = "block"; - } - var endCoords = h.toCoordinateObject(endNode, true); - with(endNode.style){ - display = "none"; - visibility = "visible"; - } + with(endNode.style){ + visibility = "hidden"; + display = "block"; + } + var endCoords = h.toCoordinateObject(endNode, true); + with(endNode.style){ + display = "none"; + visibility = "visible"; + } - var props = { opacity: { start: 0.5, end: 1.0 } }; - dojo.lang.forEach(["height", "width", "top", "left"], function(type){ - props[type] = { start: startCoords[type], end: endCoords[type] } - }); + var props = { opacity: { start: 0.5, end: 1.0 } }; + dojo.lang.forEach(["height", "width", "top", "left"], function(type){ + props[type] = { start: startCoords[type], end: endCoords[type] } + }); + + var anim = new dojo.lfx.propertyAnimation(outline, + props, + duration, + easing, + { + "beforeBegin": function(){ + h.setDisplay(outline, "block"); + }, + "onEnd": function(){ + h.setDisplay(endNode, "block"); + outline.parentNode.removeChild(outline); + } + } + ); - var anim = new dojo.lfx.propertyAnimation(outline, - props, - duration, - easing, - { - "beforeBegin": function(){ - h.setDisplay(outline, "block"); - }, - "onEnd": function(){ - h.setDisplay(endNode, "block"); - outline.parentNode.removeChild(outline); - } - } - ); - - if(callback){ - anim.connect("onEnd", function(){ callback(endNode, anim); }); - } - return anim; // dojo.lfx.Animation + if(callback){ + anim.connect("onEnd", function(){ callback(endNode, anim); }); + } + return anim; // dojo.lfx.Animation } dojo.lfx.html.implode = function(/*DOMNode*/ startNode, - /*DOMNode*/ end, - /*int?*/ duration, - /*Function?*/ easing, - /*Function?*/ callback){ - // summary: Returns an animation that will - // startNode: - // end: - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - var h = dojo.html; - startNode = dojo.byId(startNode); - end = dojo.byId(end); - var startCoords = dojo.html.toCoordinateObject(startNode, true); - var endCoords = dojo.html.toCoordinateObject(end, true); + /*DOMNode*/ end, + /*int?*/ duration, + /*Function?*/ easing, + /*Function?*/ callback){ + // summary: Returns an animation that will + // startNode: + // end: + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + var h = dojo.html; + startNode = dojo.byId(startNode); + end = dojo.byId(end); + var startCoords = dojo.html.toCoordinateObject(startNode, true); + var endCoords = dojo.html.toCoordinateObject(end, true); - var outline = document.createElement("div"); - dojo.html.copyStyle(outline, startNode); - if (startNode.explodeClassName) { outline.className = startNode.explodeClassName; } - dojo.html.setOpacity(outline, 0.3); - with(outline.style){ - position = "absolute"; - display = "none"; - backgroundColor = h.getStyle(startNode, "background-color").toLowerCase(); - } - dojo.body().appendChild(outline); + var outline = document.createElement("div"); + dojo.html.copyStyle(outline, startNode); + if (startNode.explodeClassName) { outline.className = startNode.explodeClassName; } + dojo.html.setOpacity(outline, 0.3); + with(outline.style){ + position = "absolute"; + display = "none"; + backgroundColor = h.getStyle(startNode, "background-color").toLowerCase(); + } + dojo.body().appendChild(outline); - var props = { opacity: { start: 1.0, end: 0.5 } }; - dojo.lang.forEach(["height", "width", "top", "left"], function(type){ - props[type] = { start: startCoords[type], end: endCoords[type] } - }); + var props = { opacity: { start: 1.0, end: 0.5 } }; + dojo.lang.forEach(["height", "width", "top", "left"], function(type){ + props[type] = { start: startCoords[type], end: endCoords[type] } + }); + + var anim = new dojo.lfx.propertyAnimation(outline, + props, + duration, + easing, + { + "beforeBegin": function(){ + dojo.html.hide(startNode); + dojo.html.show(outline); + }, + "onEnd": function(){ + outline.parentNode.removeChild(outline); + } + } + ); - var anim = new dojo.lfx.propertyAnimation(outline, - props, - duration, - easing, - { - "beforeBegin": function(){ - dojo.html.hide(startNode); - dojo.html.show(outline); - }, - "onEnd": function(){ - outline.parentNode.removeChild(outline); - } - } - ); - - if(callback){ - anim.connect("onEnd", function(){ callback(startNode, anim); }); - } - return anim; // dojo.lfx.Animation + if(callback){ + anim.connect("onEnd", function(){ callback(startNode, anim); }); + } + return anim; // dojo.lfx.Animation } dojo.lfx.html.highlight = function(/*DOMNode[]*/ nodes, - /*dojo.gfx.color.Color*/ startColor, - /*int?*/ duration, - /*Function?*/ easing, - /*Function?*/ callback){ - // summary: Returns an animation that will set the background color - // of "nodes" to startColor and transition it to "nodes" - // original color. - // startColor: Color to transition from. - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - nodes = dojo.lfx.html._byId(nodes); - var anims = []; + /*dojo.gfx.color.Color*/ startColor, + /*int?*/ duration, + /*Function?*/ easing, + /*Function?*/ callback){ + // summary: Returns an animation that will set the background color + // of "nodes" to startColor and transition it to "nodes" + // original color. + // startColor: Color to transition from. + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + nodes = dojo.lfx.html._byId(nodes); + var anims = []; - dojo.lang.forEach(nodes, function(node){ - var color = dojo.html.getBackgroundColor(node); - var bg = dojo.html.getStyle(node, "background-color").toLowerCase(); - var bgImage = dojo.html.getStyle(node, "background-image"); - var wasTransparent = (bg == "transparent" || bg == "rgba(0, 0, 0, 0)"); - while(color.length > 3) { color.pop(); } + dojo.lang.forEach(nodes, function(node){ + var color = dojo.html.getBackgroundColor(node); + var bg = dojo.html.getStyle(node, "background-color").toLowerCase(); + var bgImage = dojo.html.getStyle(node, "background-image"); + var wasTransparent = (bg == "transparent" || bg == "rgba(0, 0, 0, 0)"); + while(color.length > 3) { color.pop(); } - var rgb = new dojo.gfx.color.Color(startColor); - var endRgb = new dojo.gfx.color.Color(color); + var rgb = new dojo.gfx.color.Color(startColor); + var endRgb = new dojo.gfx.color.Color(color); - var anim = dojo.lfx.propertyAnimation(node, - { "background-color": { start: rgb, end: endRgb } }, - duration, - easing, - { - "beforeBegin": function(){ - if(bgImage){ - node.style.backgroundImage = "none"; - } - node.style.backgroundColor = "rgb(" + rgb.toRgb().join(",") + ")"; - }, - "onEnd": function(){ - if(bgImage){ - node.style.backgroundImage = bgImage; - } - if(wasTransparent){ - node.style.backgroundColor = "transparent"; - } - if(callback){ - callback(node, anim); - } - } - } - ); + var anim = dojo.lfx.propertyAnimation(node, + { "background-color": { start: rgb, end: endRgb } }, + duration, + easing, + { + "beforeBegin": function(){ + if(bgImage){ + node.style.backgroundImage = "none"; + } + node.style.backgroundColor = "rgb(" + rgb.toRgb().join(",") + ")"; + }, + "onEnd": function(){ + if(bgImage){ + node.style.backgroundImage = bgImage; + } + if(wasTransparent){ + node.style.backgroundColor = "transparent"; + } + if(callback){ + callback(node, anim); + } + } + } + ); - anims.push(anim); - }); - return dojo.lfx.combine(anims); // dojo.lfx.Combine + anims.push(anim); + }); + return dojo.lfx.combine(anims); // dojo.lfx.Combine } dojo.lfx.html.unhighlight = function(/*DOMNode[]*/ nodes, - /*dojo.gfx.color.Color*/ endColor, - /*int?*/ duration, - /*Function?*/ easing, - /*Function?*/ callback){ - // summary: Returns an animation that will transition "nodes" background color - // from its current color to "endColor". - // endColor: Color to transition to. - // duration: Duration of the animation in milliseconds. - // easing: An easing function. - // callback: Function to run at the end of the animation. - nodes = dojo.lfx.html._byId(nodes); - var anims = []; + /*dojo.gfx.color.Color*/ endColor, + /*int?*/ duration, + /*Function?*/ easing, + /*Function?*/ callback){ + // summary: Returns an animation that will transition "nodes" background color + // from its current color to "endColor". + // endColor: Color to transition to. + // duration: Duration of the animation in milliseconds. + // easing: An easing function. + // callback: Function to run at the end of the animation. + nodes = dojo.lfx.html._byId(nodes); + var anims = []; - dojo.lang.forEach(nodes, function(node){ - var color = new dojo.gfx.color.Color(dojo.html.getBackgroundColor(node)); - var rgb = new dojo.gfx.color.Color(endColor); + dojo.lang.forEach(nodes, function(node){ + var color = new dojo.gfx.color.Color(dojo.html.getBackgroundColor(node)); + var rgb = new dojo.gfx.color.Color(endColor); - var bgImage = dojo.html.getStyle(node, "background-image"); - - var anim = dojo.lfx.propertyAnimation(node, - { "background-color": { start: color, end: rgb } }, - duration, - easing, - { - "beforeBegin": function(){ - if(bgImage){ - node.style.backgroundImage = "none"; - } - node.style.backgroundColor = "rgb(" + color.toRgb().join(",") + ")"; - }, - "onEnd": function(){ - if(callback){ - callback(node, anim); - } - } - } - ); - anims.push(anim); - }); - return dojo.lfx.combine(anims); // dojo.lfx.Combine + var bgImage = dojo.html.getStyle(node, "background-image"); + + var anim = dojo.lfx.propertyAnimation(node, + { "background-color": { start: color, end: rgb } }, + duration, + easing, + { + "beforeBegin": function(){ + if(bgImage){ + node.style.backgroundImage = "none"; + } + node.style.backgroundColor = "rgb(" + color.toRgb().join(",") + ")"; + }, + "onEnd": function(){ + if(callback){ + callback(node, anim); + } + } + } + ); + anims.push(anim); + }); + return dojo.lfx.combine(anims); // dojo.lfx.Combine } dojo.lang.mixin(dojo.lfx, dojo.lfx.html); dojo.kwCompoundRequire({ - browser: ["dojo.lfx.html"], - dashboard: ["dojo.lfx.html"] + browser: ["dojo.lfx.html"], + dashboard: ["dojo.lfx.html"] }); dojo.provide("dojo.lfx.*"); if(!this["dojo"]){ - alert("\"dojo/__package__.js\" is now located at \"dojo/dojo.js\". Please update your includes accordingly"); + alert("\"dojo/__package__.js\" is now located at \"dojo/dojo.js\". Please update your includes accordingly"); } dojo.provide("dojo.xml.Parse"); @@ -9866,268 +9876,268 @@ dojo.provide("dojo.xml.Parse"); // using documentFragment nomenclature to generalize in case we don't want to require passing a collection of nodes with a single parent dojo.xml.Parse = function(){ - // summary: - // generic class for taking a DOM node and parsing it into an object - // based on the "dojo tag name" of that node. - // - // supported dojoTagName's: - // => prefix:tag - // => dojo:tag - // => dojo:tag - // => dojo:type - // => prefix:type - // => dojo:type - // => dojo:type + // summary: + // generic class for taking a DOM node and parsing it into an object + // based on the "dojo tag name" of that node. + // + // supported dojoTagName's: + // => prefix:tag + // => dojo:tag + // => dojo:tag + // => dojo:type + // => prefix:type + // => dojo:type + // => dojo:type - var isIE = ((dojo.render.html.capable)&&(dojo.render.html.ie)); + var isIE = ((dojo.render.html.capable)&&(dojo.render.html.ie)); - // get normalized (lowercase) tagName - // some browsers report tagNames in lowercase no matter what - function getTagName(node){ - /* - return ((node)&&(node["tagName"]) ? node.tagName.toLowerCase() : ''); - */ - try{ - return node.tagName.toLowerCase(); - }catch(e){ - return ""; - } - } + // get normalized (lowercase) tagName + // some browsers report tagNames in lowercase no matter what + function getTagName(node){ + /* + return ((node)&&(node["tagName"]) ? node.tagName.toLowerCase() : ''); + */ + try{ + return node.tagName.toLowerCase(); + }catch(e){ + return ""; + } + } - // locate dojo qualified tag name - function getDojoTagName(node){ - var tagName = getTagName(node); - if (!tagName){ - return ''; - } - // any registered tag - if((dojo.widget)&&(dojo.widget.tags[tagName])){ - return tagName; - } - // => prefix:tag - var p = tagName.indexOf(":"); - if(p>=0){ - return tagName; - } - // => dojo:tag - if(tagName.substr(0,5) == "dojo:"){ - return tagName; - } - if(dojo.render.html.capable && dojo.render.html.ie && node.scopeName != 'HTML'){ - return node.scopeName.toLowerCase() + ':' + tagName; - } - // => dojo:tag - if(tagName.substr(0,4) == "dojo"){ - // FIXME: this assumes tag names are always lower case - return "dojo:" + tagName.substring(4); - } - // => prefix:type - // => dojo:type - var djt = node.getAttribute("dojoType") || node.getAttribute("dojotype"); - if(djt){ - if (djt.indexOf(":")<0){ - djt = "dojo:"+djt; - } - return djt.toLowerCase(); - } - // => dojo:type - djt = node.getAttributeNS && node.getAttributeNS(dojo.dom.dojoml,"type"); - if(djt){ - return "dojo:" + djt.toLowerCase(); - } - // => dojo:type - try{ - // FIXME: IE really really doesn't like this, so we squelch errors for it - djt = node.getAttribute("dojo:type"); - }catch(e){ - // FIXME: log? - } - if(djt){ return "dojo:"+djt.toLowerCase(); } - // => dojo:type - if((dj_global["djConfig"])&&(!djConfig["ignoreClassNames"])){ - // FIXME: should we make this optionally enabled via djConfig? - var classes = node.className||node.getAttribute("class"); - // FIXME: following line, without check for existence of classes.indexOf - // breaks firefox 1.5's svg widgets - if((classes )&&(classes.indexOf)&&(classes.indexOf("dojo-")!=-1)){ - var aclasses = classes.split(" "); - for(var x=0, c=aclasses.length; x => prefix:tag + var p = tagName.indexOf(":"); + if(p>=0){ + return tagName; + } + // => dojo:tag + if(tagName.substr(0,5) == "dojo:"){ + return tagName; + } + if(dojo.render.html.capable && dojo.render.html.ie && node.scopeName != 'HTML'){ + return node.scopeName.toLowerCase() + ':' + tagName; + } + // => dojo:tag + if(tagName.substr(0,4) == "dojo"){ + // FIXME: this assumes tag names are always lower case + return "dojo:" + tagName.substring(4); + } + // => prefix:type + // => dojo:type + var djt = node.getAttribute("dojoType") || node.getAttribute("dojotype"); + if(djt){ + if (djt.indexOf(":")<0){ + djt = "dojo:"+djt; + } + return djt.toLowerCase(); + } + // => dojo:type + djt = node.getAttributeNS && node.getAttributeNS(dojo.dom.dojoml,"type"); + if(djt){ + return "dojo:" + djt.toLowerCase(); + } + // => dojo:type + try{ + // FIXME: IE really really doesn't like this, so we squelch errors for it + djt = node.getAttribute("dojo:type"); + }catch(e){ + // FIXME: log? + } + if(djt){ return "dojo:"+djt.toLowerCase(); } + // => dojo:type + if((dj_global["djConfig"])&&(!djConfig["ignoreClassNames"])){ + // FIXME: should we make this optionally enabled via djConfig? + var classes = node.className||node.getAttribute("class"); + // FIXME: following line, without check for existence of classes.indexOf + // breaks firefox 1.5's svg widgets + if((classes )&&(classes.indexOf)&&(classes.indexOf("dojo-")!=-1)){ + var aclasses = classes.split(" "); + for(var x=0, c=aclasses.length; x as nodes that should be parsed. Ignore these - if(isIE && tagName.indexOf("/")==0){ return null; } + // run shortcuts to bail out of processing up front to save time and + // object alloc if possible. + var tagName = getTagName(node); + //There's a weird bug in IE where it counts end tags, e.g. as nodes that should be parsed. Ignore these + if(isIE && tagName.indexOf("/")==0){ return null; } - try{ - var attr = node.getAttribute("parseWidgets"); - if(attr && attr.toLowerCase() == "false"){ - return {}; - } - }catch(e){/*continue*/} + try{ + var attr = node.getAttribute("parseWidgets"); + if(attr && attr.toLowerCase() == "false"){ + return {}; + } + }catch(e){/*continue*/} + + + // look for a dojoml qualified name + // process dojoml only when optimizeForDojoML is true + var process = true; + if(optimizeForDojoML){ + var dojoTagName = getDojoTagName(node); + tagName = dojoTagName || tagName; + process = Boolean(dojoTagName); + } + + var parsedNodeSet = {}; + parsedNodeSet[tagName] = []; + var pos = tagName.indexOf(":"); + if(pos>0){ + var ns = tagName.substring(0,pos); + parsedNodeSet["ns"] = ns; + // honor user namespace filters + if((dojo.ns)&&(!dojo.ns.allow(ns))){process=false;} + } + + if(process){ + var attributeSet = this.parseAttributes(node); + for(var attr in attributeSet){ + if((!parsedNodeSet[tagName][attr])||(typeof parsedNodeSet[tagName][attr] != "array")){ + parsedNodeSet[tagName][attr] = []; + } + parsedNodeSet[tagName][attr].push(attributeSet[attr]); + } + // FIXME: we might want to make this optional or provide cloning instead of + // referencing, but for now, we include a node reference to allow + // instantiated components to figure out their "roots" + parsedNodeSet[tagName].nodeRef = node; + parsedNodeSet.tagName = tagName; + parsedNodeSet.index = thisIdx||0; + } + + var count = 0; + for(var i = 0; i < node.childNodes.length; i++){ + var tcn = node.childNodes.item(i); + switch(tcn.nodeType){ + case dojo.dom.ELEMENT_NODE: // element nodes, call this function recursively + var ctn = getDojoTagName(tcn) || getTagName(tcn); + if(!parsedNodeSet[ctn]){ + parsedNodeSet[ctn] = []; + } + parsedNodeSet[ctn].push(this.parseElement(tcn, true, optimizeForDojoML, count)); + if( (tcn.childNodes.length == 1)&& + (tcn.childNodes.item(0).nodeType == dojo.dom.TEXT_NODE)){ + parsedNodeSet[ctn][parsedNodeSet[ctn].length-1].value = tcn.childNodes.item(0).nodeValue; + } + count++; + break; + case dojo.dom.TEXT_NODE: // if a single text node is the child, treat it as an attribute + if(node.childNodes.length == 1){ + parsedNodeSet[tagName].push({ value: node.childNodes.item(0).nodeValue }); + } + break; + default: break; + /* + case dojo.dom.ATTRIBUTE_NODE: // attribute node... not meaningful here + break; + case dojo.dom.CDATA_SECTION_NODE: // cdata section... not sure if this would ever be meaningful... might be... + break; + case dojo.dom.ENTITY_REFERENCE_NODE: // entity reference node... not meaningful here + break; + case dojo.dom.ENTITY_NODE: // entity node... not sure if this would ever be meaningful + break; + case dojo.dom.PROCESSING_INSTRUCTION_NODE: // processing instruction node... not meaningful here + break; + case dojo.dom.COMMENT_NODE: // comment node... not not sure if this would ever be meaningful + break; + case dojo.dom.DOCUMENT_NODE: // document node... not sure if this would ever be meaningful + break; + case dojo.dom.DOCUMENT_TYPE_NODE: // document type node... not meaningful here + break; + case dojo.dom.DOCUMENT_FRAGMENT_NODE: // document fragment node... not meaningful here + break; + case dojo.dom.NOTATION_NODE:// notation node... not meaningful here + break; + */ + } + } + //return (hasParentNodeSet) ? parsedNodeSet[node.tagName] : parsedNodeSet; + //if(parsedNodeSet.tagName)dojo.debug("parseElement: RETURNING NODE WITH TAGNAME "+parsedNodeSet.tagName); + return parsedNodeSet; + }; - // look for a dojoml qualified name - // process dojoml only when optimizeForDojoML is true - var process = true; - if(optimizeForDojoML){ - var dojoTagName = getDojoTagName(node); - tagName = dojoTagName || tagName; - process = Boolean(dojoTagName); - } + /* parses a set of attributes on a node into an object tree */ + this.parseAttributes = function(/*DomNode*/node){ + // summary: + // creates an attribute object that maps attribute values for the + // passed node. Note that this is similar to creating a JSON + // representation of a DOM node. + // usage: + // a node with the following serialization: + //
...
+ // would yeild the following return structure when passed into this + // function: + // { + // "foo": { + // "value": "bar" + // }, + // "baz": { + // "value": "thud" + // } + // } + // + var parsedAttributeSet = {}; + var atts = node.attributes; + // TODO: should we allow for duplicate attributes at this point... + // would any of the relevant dom implementations even allow this? + var attnode, i=0; + while((attnode=atts[i++])){ + if(isIE){ + if(!attnode){ continue; } + if((typeof attnode == "object")&& + (typeof attnode.nodeValue == 'undefined')|| + (attnode.nodeValue == null)|| + (attnode.nodeValue == '')){ + continue; + } + } - var parsedNodeSet = {}; - parsedNodeSet[tagName] = []; - var pos = tagName.indexOf(":"); - if(pos>0){ - var ns = tagName.substring(0,pos); - parsedNodeSet["ns"] = ns; - // honor user namespace filters - if((dojo.ns)&&(!dojo.ns.allow(ns))){process=false;} - } - - if(process){ - var attributeSet = this.parseAttributes(node); - for(var attr in attributeSet){ - if((!parsedNodeSet[tagName][attr])||(typeof parsedNodeSet[tagName][attr] != "array")){ - parsedNodeSet[tagName][attr] = []; - } - parsedNodeSet[tagName][attr].push(attributeSet[attr]); - } - // FIXME: we might want to make this optional or provide cloning instead of - // referencing, but for now, we include a node reference to allow - // instantiated components to figure out their "roots" - parsedNodeSet[tagName].nodeRef = node; - parsedNodeSet.tagName = tagName; - parsedNodeSet.index = thisIdx||0; - } - - var count = 0; - for(var i = 0; i < node.childNodes.length; i++){ - var tcn = node.childNodes.item(i); - switch(tcn.nodeType){ - case dojo.dom.ELEMENT_NODE: // element nodes, call this function recursively - var ctn = getDojoTagName(tcn) || getTagName(tcn); - if(!parsedNodeSet[ctn]){ - parsedNodeSet[ctn] = []; - } - parsedNodeSet[ctn].push(this.parseElement(tcn, true, optimizeForDojoML, count)); - if( (tcn.childNodes.length == 1)&& - (tcn.childNodes.item(0).nodeType == dojo.dom.TEXT_NODE)){ - parsedNodeSet[ctn][parsedNodeSet[ctn].length-1].value = tcn.childNodes.item(0).nodeValue; - } - count++; - break; - case dojo.dom.TEXT_NODE: // if a single text node is the child, treat it as an attribute - if(node.childNodes.length == 1){ - parsedNodeSet[tagName].push({ value: node.childNodes.item(0).nodeValue }); - } - break; - default: break; - /* - case dojo.dom.ATTRIBUTE_NODE: // attribute node... not meaningful here - break; - case dojo.dom.CDATA_SECTION_NODE: // cdata section... not sure if this would ever be meaningful... might be... - break; - case dojo.dom.ENTITY_REFERENCE_NODE: // entity reference node... not meaningful here - break; - case dojo.dom.ENTITY_NODE: // entity node... not sure if this would ever be meaningful - break; - case dojo.dom.PROCESSING_INSTRUCTION_NODE: // processing instruction node... not meaningful here - break; - case dojo.dom.COMMENT_NODE: // comment node... not not sure if this would ever be meaningful - break; - case dojo.dom.DOCUMENT_NODE: // document node... not sure if this would ever be meaningful - break; - case dojo.dom.DOCUMENT_TYPE_NODE: // document type node... not meaningful here - break; - case dojo.dom.DOCUMENT_FRAGMENT_NODE: // document fragment node... not meaningful here - break; - case dojo.dom.NOTATION_NODE:// notation node... not meaningful here - break; - */ - } - } - //return (hasParentNodeSet) ? parsedNodeSet[node.tagName] : parsedNodeSet; - //if(parsedNodeSet.tagName)dojo.debug("parseElement: RETURNING NODE WITH TAGNAME "+parsedNodeSet.tagName); - return parsedNodeSet; - }; - - - /* parses a set of attributes on a node into an object tree */ - this.parseAttributes = function(/*DomNode*/node){ - // summary: - // creates an attribute object that maps attribute values for the - // passed node. Note that this is similar to creating a JSON - // representation of a DOM node. - // usage: - // a node with the following serialization: - //
...
- // would yeild the following return structure when passed into this - // function: - // { - // "foo": { - // "value": "bar" - // }, - // "baz": { - // "value": "thud" - // } - // } - // - var parsedAttributeSet = {}; - var atts = node.attributes; - // TODO: should we allow for duplicate attributes at this point... - // would any of the relevant dom implementations even allow this? - var attnode, i=0; - while((attnode=atts[i++])){ - if(isIE){ - if(!attnode){ continue; } - if((typeof attnode == "object")&& - (typeof attnode.nodeValue == 'undefined')|| - (attnode.nodeValue == null)|| - (attnode.nodeValue == '')){ - continue; - } - } - - var nn = attnode.nodeName.split(":"); - nn = (nn.length == 2) ? nn[1] : attnode.nodeName; - - parsedAttributeSet[nn] = { - value: attnode.nodeValue - }; - } - return parsedAttributeSet; - }; + var nn = attnode.nodeName.split(":"); + nn = (nn.length == 2) ? nn[1] : attnode.nodeName; + + parsedAttributeSet[nn] = { + value: attnode.nodeValue + }; + } + return parsedAttributeSet; + }; }; dojo.provide("dojo.lang.declare"); @@ -10135,156 +10145,156 @@ dojo.provide("dojo.lang.declare"); -dojo.lang.declare = function( /*String*/ className, - /*Function|Array*/ superclass, - /*Function?*/ init, - /*Object|Array*/ props){ - /* - * summary: Create a feature-rich constructor with a compact notation - * className: the name of the constructor (loosely, a "class") - * superclass: - * may be a Function, or an Array of Functions. If "superclass" is an - * array, the first element is used as the prototypical ancestor and - * any following Functions become mixin ancestors. - * init: an initializer function - * props: - * an object (or array of objects) whose properties are copied to the - * created prototype - * description: - * Create a constructor using a compact notation for inheritance and - * prototype extension. "superclass" argument may be a Function, or an - * array of Functions. - * - * If "superclass" is an array, the first element is used as the - * prototypical ancestor and any following Functions become mixin - * ancestors. - * - * All "superclass(es)" must be Functions (not mere Objects). - * - * Using mixin ancestors provides a type of multiple inheritance. - * Mixin ancestors prototypical properties are copied to the subclass, - * and any inializater/constructor is invoked. - * - * Properties of object "props" are copied to the constructor - * prototype. If "props" is an array, properties of each object in the - * array are copied to the constructor prototype. - * - * name of the class ("className" argument) is stored in - * "declaredClass" property - * - * Initializer functions are called when an object is instantiated - * from this constructor. - * - * Aliased as "dojo.declare" - * - * Usage: - * - * dojo.declare("my.classes.bar", my.classes.foo, - * function(){ - * // initialization function - * this.myComplicatedObject = new ReallyComplicatedObject(); - * }, - * { // properties to be added to the class prototype - * someValue: 2, - * someMethod: function(){ - * doStuff(); - * } - * } - * ); - * - */ - if((dojo.lang.isFunction(props))||((!props)&&(!dojo.lang.isFunction(init)))){ - // parameter juggling to support omitting init param (also allows - // reordering init and props arguments) - var temp = props; - props = init; - init = temp; - } - var mixins = [ ]; - if(dojo.lang.isArray(superclass)){ - mixins = superclass; - superclass = mixins.shift(); - } - if(!init){ - init = dojo.evalObjPath(className, false); - if((init)&&(!dojo.lang.isFunction(init))){ init = null }; - } - var ctor = dojo.lang.declare._makeConstructor(); - var scp = (superclass ? superclass.prototype : null); - if(scp){ - scp.prototyping = true; - ctor.prototype = new superclass(); - scp.prototyping = false; - } - ctor.superclass = scp; - ctor.mixins = mixins; - for(var i=0,l=mixins.length; i by convention - if(!dojo.hostenv.moduleHasPrefix(name)){ - dojo.registerModulePath(name, "../" + name); - } - req([name, 'manifest'].join('.'), false, true); - } - if(!this.namespaces[name]){ - this.failed[name] = true; //only look for a namespace once - } - }finally{ - this.loading[name]=false; - } - return this.namespaces[name]; // Ns - } + // summary: private object that implements widget namespace management + namespaces: {}, + failed: {}, + loading: {}, + loaded: {}, + register: function(/*String*/name, /*String*/module, /*Function?*/resolver, /*Boolean?*/noOverride){ + // summary: creates and registers a dojo.ns.Ns object + if(!noOverride || !this.namespaces[name]){ + this.namespaces[name] = new dojo.ns.Ns(name, module, resolver); + } + }, + allow: function(/*String*/name){ + // summary: Returns false if 'name' is filtered by configuration or has failed to load, true otherwise + if(this.failed[name]){return false;} // Boolean + if((djConfig.excludeNamespace)&&(dojo.lang.inArray(djConfig.excludeNamespace, name))){return false;} // Boolean + // If the namespace is "dojo", or the user has not specified allowed namespaces return true. + // Otherwise, if the user has specifically allowed this namespace, return true, otherwise false. + return((name==this.dojo)||(!djConfig.includeNamespace)||(dojo.lang.inArray(djConfig.includeNamespace, name))); // Boolean + }, + get: function(/*String*/name){ + // summary + // Return Ns object registered to 'name', if any + return this.namespaces[name]; // Ns + }, + require: function(/*String*/name){ + // summary + // Try to ensure that 'name' is registered, loading a namespace manifest if necessary + var ns = this.namespaces[name]; + if((ns)&&(this.loaded[name])){return ns;} // Ns + if(!this.allow(name)){return false;} // Boolean + if(this.loading[name]){ + // FIXME: do we really ever have re-entrancy situation? this would appear to be really bad + // original code did not throw an exception, although that seems the only course + // adding debug output here to track if this occurs. + dojo.debug('dojo.namespace.require: re-entrant request to load namespace "' + name + '" must fail.'); + return false; // Boolean + } + // workaround so we don't break the build system + var req = dojo.require; + this.loading[name] = true; + try { + //dojo namespace file is always in the Dojo namespaces folder, not any custom folder + if(name=="dojo"){ + req("dojo.namespaces.dojo"); + }else{ + // if no registered module prefix, use ../ by convention + if(!dojo.hostenv.moduleHasPrefix(name)){ + dojo.registerModulePath(name, "../" + name); + } + req([name, 'manifest'].join('.'), false, true); + } + if(!this.namespaces[name]){ + this.failed[name] = true; //only look for a namespace once + } + }finally{ + this.loading[name]=false; + } + return this.namespaces[name]; // Ns + } } dojo.ns.Ns = function(/*String*/name, /*String*/module, /*Function?*/resolver){ - // summary: this object simply encapsulates namespace data - this.name = name; - this.module = module; - this.resolver = resolver; - this._loaded = [ ]; - this._failed = [ ]; + // summary: this object simply encapsulates namespace data + this.name = name; + this.module = module; + this.resolver = resolver; + this._loaded = [ ]; + this._failed = [ ]; } dojo.ns.Ns.prototype.resolve = function(/*String*/name, /*String*/domain, /*Boolean?*/omitModuleCheck){ - //summary: map component with 'name' and 'domain' to a module via namespace resolver, if specified - if(!this.resolver || djConfig["skipAutoRequire"]){return false;} // Boolean - var fullName = this.resolver(name, domain); - //only load a widget once. This is a quicker check than dojo.require does - if((fullName)&&(!this._loaded[fullName])&&(!this._failed[fullName])){ - //workaround so we don't break the build system - var req = dojo.require; - req(fullName, false, true); //omit the module check, we'll do it ourselves. - if(dojo.hostenv.findModule(fullName, false)){ - this._loaded[fullName] = true; - }else{ - if(!omitModuleCheck){dojo.raise("dojo.ns.Ns.resolve: module '" + fullName + "' not found after loading via namespace '" + this.name + "'");} - this._failed[fullName] = true; - } - } - return Boolean(this._loaded[fullName]); // Boolean + //summary: map component with 'name' and 'domain' to a module via namespace resolver, if specified + if(!this.resolver || djConfig["skipAutoRequire"]){return false;} // Boolean + var fullName = this.resolver(name, domain); + //only load a widget once. This is a quicker check than dojo.require does + if((fullName)&&(!this._loaded[fullName])&&(!this._failed[fullName])){ + //workaround so we don't break the build system + var req = dojo.require; + req(fullName, false, true); //omit the module check, we'll do it ourselves. + if(dojo.hostenv.findModule(fullName, false)){ + this._loaded[fullName] = true; + }else{ + if(!omitModuleCheck){dojo.raise("dojo.ns.Ns.resolve: module '" + fullName + "' not found after loading via namespace '" + this.name + "'");} + this._failed[fullName] = true; + } + } + return Boolean(this._loaded[fullName]); // Boolean } dojo.registerNamespace = function(/*String*/name, /*String*/module, /*Function?*/resolver){ - // summary: maps a module name to a namespace for widgets, and optionally maps widget names to modules for auto-loading - // description: An unregistered namespace is mapped to an eponymous module. - // For example, namespace acme is mapped to module acme, and widgets are - // assumed to belong to acme.widget. If you want to use a different widget - // module, use dojo.registerNamespace. - dojo.ns.register.apply(dojo.ns, arguments); + // summary: maps a module name to a namespace for widgets, and optionally maps widget names to modules for auto-loading + // description: An unregistered namespace is mapped to an eponymous module. + // For example, namespace acme is mapped to module acme, and widgets are + // assumed to belong to acme.widget. If you want to use a different widget + // module, use dojo.registerNamespace. + dojo.ns.register.apply(dojo.ns, arguments); } dojo.registerNamespaceResolver = function(/*String*/name, /*Function*/resolver){ - // summary: a resolver function maps widget names to modules, so the - // widget manager can auto-load needed widget implementations - // - // description: The resolver provides information to allow Dojo - // to load widget modules on demand. When a widget is created, - // a namespace resolver can tell Dojo what module to require - // to ensure that the widget implementation code is loaded. - // - // name: will always be lower-case. - // - // example: - // dojo.registerNamespaceResolver("acme", - // function(name){ - // return "acme.widget."+dojo.string.capitalize(name); - // } - // ); - var n = dojo.ns.namespaces[name]; - if(n){ - n.resolver = resolver; - } + // summary: a resolver function maps widget names to modules, so the + // widget manager can auto-load needed widget implementations + // + // description: The resolver provides information to allow Dojo + // to load widget modules on demand. When a widget is created, + // a namespace resolver can tell Dojo what module to require + // to ensure that the widget implementation code is loaded. + // + // name: will always be lower-case. + // + // example: + // dojo.registerNamespaceResolver("acme", + // function(name){ + // return "acme.widget."+dojo.string.capitalize(name); + // } + // ); + var n = dojo.ns.namespaces[name]; + if(n){ + n.resolver = resolver; + } } dojo.registerNamespaceManifest = function(/*String*/module, /*String*/path, /*String*/name, /*String*/widgetModule, /*Function?*/resolver){ - // summary: convenience function to register a module path, a namespace, and optionally a resolver all at once. - dojo.registerModulePath(name, path); - dojo.registerNamespace(name, widgetModule, resolver); + // summary: convenience function to register a module path, a namespace, and optionally a resolver all at once. + dojo.registerModulePath(name, path); + dojo.registerNamespace(name, widgetModule, resolver); } // NOTE: rather put this in dojo.widget.Widget, but that fubars debugAtAllCosts @@ -10428,359 +10438,359 @@ dojo.provide("dojo.widget.Manager"); // summary -// Manager class for the widgets. -// This is an internal class used by dojo; users shouldn't call this class directly. +// Manager class for the widgets. +// This is an internal class used by dojo; users shouldn't call this class directly. dojo.widget.manager = new function(){ - this.widgets = []; - this.widgetIds = []; + this.widgets = []; + this.widgetIds = []; + + // map of widgetId-->widget for widgets without parents (top level widgets) + this.topWidgets = {}; - // map of widgetId-->widget for widgets without parents (top level widgets) - this.topWidgets = {}; + var widgetTypeCtr = {}; + var renderPrefixCache = []; - var widgetTypeCtr = {}; - var renderPrefixCache = []; + this.getUniqueId = function (widgetType) { + var widgetId; + do{ + widgetId = widgetType + "_" + (widgetTypeCtr[widgetType] != undefined ? + ++widgetTypeCtr[widgetType] : widgetTypeCtr[widgetType] = 0); + }while(this.getWidgetById(widgetId)); + return widgetId; + } - this.getUniqueId = function (widgetType) { - var widgetId; - do{ - widgetId = widgetType + "_" + (widgetTypeCtr[widgetType] != undefined ? - ++widgetTypeCtr[widgetType] : widgetTypeCtr[widgetType] = 0); - }while(this.getWidgetById(widgetId)); - return widgetId; - } + this.add = function(widget){ + //dojo.profile.start("dojo.widget.manager.add"); + this.widgets.push(widget); + // Opera9 uses ID (caps) + if(!widget.extraArgs["id"]){ + widget.extraArgs["id"] = widget.extraArgs["ID"]; + } + // FIXME: the rest of this method is very slow! + if(widget.widgetId == ""){ + if(widget["id"]){ + widget.widgetId = widget["id"]; + }else if(widget.extraArgs["id"]){ + widget.widgetId = widget.extraArgs["id"]; + }else{ + widget.widgetId = this.getUniqueId(widget.ns+'_'+widget.widgetType); + } + } + if(this.widgetIds[widget.widgetId]){ + dojo.debug("widget ID collision on ID: "+widget.widgetId); + } + this.widgetIds[widget.widgetId] = widget; + // Widget.destroy already calls removeById(), so we don't need to + // connect() it here + //dojo.profile.end("dojo.widget.manager.add"); + } - this.add = function(widget){ - //dojo.profile.start("dojo.widget.manager.add"); - this.widgets.push(widget); - // Opera9 uses ID (caps) - if(!widget.extraArgs["id"]){ - widget.extraArgs["id"] = widget.extraArgs["ID"]; - } - // FIXME: the rest of this method is very slow! - if(widget.widgetId == ""){ - if(widget["id"]){ - widget.widgetId = widget["id"]; - }else if(widget.extraArgs["id"]){ - widget.widgetId = widget.extraArgs["id"]; - }else{ - widget.widgetId = this.getUniqueId(widget.ns+'_'+widget.widgetType); - } - } - if(this.widgetIds[widget.widgetId]){ - dojo.debug("widget ID collision on ID: "+widget.widgetId); - } - this.widgetIds[widget.widgetId] = widget; - // Widget.destroy already calls removeById(), so we don't need to - // connect() it here - //dojo.profile.end("dojo.widget.manager.add"); - } + this.destroyAll = function(){ + for(var x=this.widgets.length-1; x>=0; x--){ + try{ + // this.widgets[x].destroyChildren(); + this.widgets[x].destroy(true); + delete this.widgets[x]; + }catch(e){ } + } + } - this.destroyAll = function(){ - for(var x=this.widgets.length-1; x>=0; x--){ - try{ - // this.widgets[x].destroyChildren(); - this.widgets[x].destroy(true); - delete this.widgets[x]; - }catch(e){ } - } - } + // FIXME: we should never allow removal of the root widget until all others + // are removed! + this.remove = function(widgetIndex){ + if(dojo.lang.isNumber(widgetIndex)){ + var tw = this.widgets[widgetIndex].widgetId; + delete this.topWidgets[tw]; + delete this.widgetIds[tw]; + this.widgets.splice(widgetIndex, 1); + }else{ + this.removeById(widgetIndex); + } + } + + // FIXME: suboptimal performance + this.removeById = function(id) { + if(!dojo.lang.isString(id)){ + id = id["widgetId"]; + if(!id){ dojo.debug("invalid widget or id passed to removeById"); return; } + } + for (var i=0; i.widget by convention + dojo.ns.register(ns, ns + '.widget'); + nsObj = dojo.ns.get(ns); + } + + // allow the namespace to resolve the widget module + if(nsObj){nsObj.resolve(widgetName);} - var findImplementationInModule = function(lowerCaseWidgetName, module){ - if(!module){return null;} - for(var i=0, l=renderPrefixCache.length, widgetModule; i<=l; i++){ - widgetModule = (i.widget by convention - dojo.ns.register(ns, ns + '.widget'); - nsObj = dojo.ns.get(ns); - } + // Catch window resize events and notify top level widgets + this.resizing=false; + this.onWindowResized = function(){ + if(this.resizing){ + return; // duplicate event + } + try{ + this.resizing=true; + for(var id in this.topWidgets){ + var child = this.topWidgets[id]; + if(child.checkSize ){ + child.checkSize(); + } + } + }catch(e){ + }finally{ + this.resizing=false; + } + } + if(typeof window != "undefined") { + dojo.addOnLoad(this, 'onWindowResized'); // initial sizing + dojo.event.connect(window, 'onresize', this, 'onWindowResized'); // window resize + } - // allow the namespace to resolve the widget module - if(nsObj){nsObj.resolve(widgetName);} - - // locate a widget implementation in the registered module for our current rendering environment - impl = findImplementation(lowerCaseWidgetName, nsObj.module); - if(impl){return(imps[lowerCaseWidgetName] = impl)}; - - // try to load a manifest to resolve this implemenation - nsObj = dojo.ns.require(ns); - if((nsObj)&&(nsObj.resolver)){ - nsObj.resolve(widgetName); - impl = findImplementation(lowerCaseWidgetName, nsObj.module); - if(impl){return(imps[lowerCaseWidgetName] = impl)}; - } - - // this is an error condition under new rules - dojo.deprecated('dojo.widget.Manager.getImplementationName', - 'Could not locate widget implementation for "' + widgetName + '" in "' + nsObj.module + '" registered to namespace "' + nsObj.name + '". ' - + "Developers must specify correct namespaces for all non-Dojo widgets", "0.5"); - - // backward compat: if the user has not specified any namespace and their widget is not in dojo.widget.* - // search registered widget packages [sic] - // note: registerWidgetPackage itself is now deprecated - for(var i=0; i 0) { - return widgets[n]; - } - return widgets; - } - g("registerWidgetPackage"); - g("getImplementation", "getWidgetImplementation"); - g("getImplementationName", "getWidgetImplementationName"); + var dw = dojo.widget; + var dwm = dw.manager; + var h = dojo.lang.curry(dojo.lang, "hitch", dwm); + var g = function(oldName, newName){ + dw[(newName||oldName)] = h(oldName); + } + // copy the methods from the default manager (this) to the widget namespace + g("add", "addWidget"); + g("destroyAll", "destroyAllWidgets"); + g("remove", "removeWidget"); + g("removeById", "removeWidgetById"); + g("getWidgetById"); + g("getWidgetById", "byId"); + g("getWidgetsByType"); + g("getWidgetsByFilter"); + g("getWidgetsByType", "byType"); + g("getWidgetsByFilter", "byFilter"); + g("getWidgetByNode", "byNode"); + dw.all = function(n){ + var widgets = dwm.getAllWidgets.apply(dwm, arguments); + if(arguments.length > 0) { + return widgets[n]; + } + return widgets; + } + g("registerWidgetPackage"); + g("getImplementation", "getWidgetImplementation"); + g("getImplementationName", "getWidgetImplementationName"); - dw.widgets = dwm.widgets; - dw.widgetIds = dwm.widgetIds; - dw.root = dwm.root; + dw.widgets = dwm.widgets; + dw.widgetIds = dwm.widgetIds; + dw.root = dwm.root; })(); dojo.kwCompoundRequire({ - common: [["dojo.uri.Uri", false, false]] + common: [["dojo.uri.Uri", false, false]] }); dojo.provide("dojo.uri.*"); @@ -10790,89 +10800,89 @@ dojo.provide("dojo.a11y"); dojo.a11y = { - // imgPath: String path to the test image for determining if images are displayed or not - // doAccessibleCheck: Boolean if true will perform check for need to create accessible widgets - // accessible: Boolean uninitialized when null (accessible check has not been performed) - // if true generate accessible widgets - imgPath:dojo.uri.moduleUri("dojo.widget", "templates/images"), - doAccessibleCheck: true, - accessible: null, + // imgPath: String path to the test image for determining if images are displayed or not + // doAccessibleCheck: Boolean if true will perform check for need to create accessible widgets + // accessible: Boolean uninitialized when null (accessible check has not been performed) + // if true generate accessible widgets + imgPath:dojo.uri.moduleUri("dojo.widget", "templates/images"), + doAccessibleCheck: true, + accessible: null, - checkAccessible: function(){ - // summary: - // perform check for accessibility if accessibility checking is turned - // on and the accessibility test has not been performed yet - if(this.accessible === null){ - this.accessible = false; //default - if(this.doAccessibleCheck == true){ - this.accessible = this.testAccessible(); - } - } - return this.accessible; /* Boolean */ - }, + checkAccessible: function(){ + // summary: + // perform check for accessibility if accessibility checking is turned + // on and the accessibility test has not been performed yet + if(this.accessible === null){ + this.accessible = false; //default + if(this.doAccessibleCheck == true){ + this.accessible = this.testAccessible(); + } + } + return this.accessible; /* Boolean */ + }, + + testAccessible: function(){ + // summary: + // Always perform the accessibility check to determine if high + // contrast mode is on or display of images are turned off. Currently only checks + // in IE and Mozilla. + this.accessible = false; //default + if (dojo.render.html.ie || dojo.render.html.mozilla){ + var div = document.createElement("div"); + //div.style.color="rgb(153,204,204)"; + div.style.backgroundImage = "url(\"" + this.imgPath + "/tab_close.gif\")"; + // must add to hierarchy before can view currentStyle below + dojo.body().appendChild(div); + // in FF and IE the value for the current background style of the added div + // will be "none" in high contrast mode + // in FF the return value will be url(invalid-url:) when running over http + var bkImg = null; + if (window.getComputedStyle ) { + var cStyle = getComputedStyle(div, ""); + bkImg = cStyle.getPropertyValue("background-image"); + }else{ + bkImg = div.currentStyle.backgroundImage; + } + var bUseImgElem = false; + if (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" )) { + this.accessible = true; + } + /* + if(this.accessible == false && document.images){ + // test if images are off in IE + var testImg = new Image(); + if(testImg.fileSize) { + testImg.src = this.imgPath + "/tab_close.gif"; + if(testImg.fileSize < 0){ + this.accessible = true; + } + } + }*/ + dojo.body().removeChild(div); + } + return this.accessible; /* Boolean */ + }, + + setCheckAccessible: function(/* Boolean */ bTest){ + // summary: + // Set whether or not to check for accessibility mode. Default value + // of module is true - perform check for accessibility modes. + // bTest: Boolean - true to check; false to turn off checking + this.doAccessibleCheck = bTest; + }, - testAccessible: function(){ - // summary: - // Always perform the accessibility check to determine if high - // contrast mode is on or display of images are turned off. Currently only checks - // in IE and Mozilla. - this.accessible = false; //default - if (dojo.render.html.ie || dojo.render.html.mozilla){ - var div = document.createElement("div"); - //div.style.color="rgb(153,204,204)"; - div.style.backgroundImage = "url(\"" + this.imgPath + "/tab_close.gif\")"; - // must add to hierarchy before can view currentStyle below - dojo.body().appendChild(div); - // in FF and IE the value for the current background style of the added div - // will be "none" in high contrast mode - // in FF the return value will be url(invalid-url:) when running over http - var bkImg = null; - if (window.getComputedStyle ) { - var cStyle = getComputedStyle(div, ""); - bkImg = cStyle.getPropertyValue("background-image"); - }else{ - bkImg = div.currentStyle.backgroundImage; - } - var bUseImgElem = false; - if (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" )) { - this.accessible = true; - } - /* - if(this.accessible == false && document.images){ - // test if images are off in IE - var testImg = new Image(); - if(testImg.fileSize) { - testImg.src = this.imgPath + "/tab_close.gif"; - if(testImg.fileSize < 0){ - this.accessible = true; - } - } - }*/ - dojo.body().removeChild(div); - } - return this.accessible; /* Boolean */ - }, - - setCheckAccessible: function(/* Boolean */ bTest){ - // summary: - // Set whether or not to check for accessibility mode. Default value - // of module is true - perform check for accessibility modes. - // bTest: Boolean - true to check; false to turn off checking - this.doAccessibleCheck = bTest; - }, - - setAccessibleMode: function(){ - // summary: - // perform the accessibility check and sets the correct mode to load - // a11y widgets. Only runs if test for accessiiblity has not been performed yet. - // Call testAccessible() to force the test. - if (this.accessible === null){ - if (this.checkAccessible()){ - dojo.render.html.prefixes.unshift("a11y"); - } - } - return this.accessible; /* Boolean */ - } + setAccessibleMode: function(){ + // summary: + // perform the accessibility check and sets the correct mode to load + // a11y widgets. Only runs if test for accessiiblity has not been performed yet. + // Call testAccessible() to force the test. + if (this.accessible === null){ + if (this.checkAccessible()){ + dojo.render.html.prefixes.unshift("a11y"); + } + } + return this.accessible; /* Boolean */ + } }; //dojo.hostenv.modulesLoadedListeners.unshift(function() { dojo.a11y.setAccessibleMode(); }); @@ -10890,591 +10900,591 @@ dojo.provide("dojo.widget.Widget"); dojo.declare("dojo.widget.Widget", null, - function(){ - // these properties aren't primitives and need to be created on a per-item - // basis. + function(){ + // these properties aren't primitives and need to be created on a per-item + // basis. - // children: Array - // a list of all of the widgets that have been added as children of - // this component. Should only have values if isContainer is true. - this.children = []; + // children: Array + // a list of all of the widgets that have been added as children of + // this component. Should only have values if isContainer is true. + this.children = []; - // extraArgs: Object - // a map of properties which the widget system tried to assign from - // user input but did not correspond to any of the properties set on - // the class prototype. These names will also be available in all - // lower-case form in this map - this.extraArgs = {}; - }, + // extraArgs: Object + // a map of properties which the widget system tried to assign from + // user input but did not correspond to any of the properties set on + // the class prototype. These names will also be available in all + // lower-case form in this map + this.extraArgs = {}; + }, { - // parent: Widget - // the parent of this widget - parent: null, + // parent: Widget + // the parent of this widget + parent: null, - // isTopLevel: Boolean - // should this widget eat all events that bubble up to it? - // obviously, top-level and modal widgets should set these appropriately - isTopLevel: false, + // isTopLevel: Boolean + // should this widget eat all events that bubble up to it? + // obviously, top-level and modal widgets should set these appropriately + isTopLevel: false, - // disabled: Boolean - // should this widget respond to user input? - // in markup, this is specified as "disabled='disabled'", or just "disabled" - disabled: false, + // disabled: Boolean + // should this widget respond to user input? + // in markup, this is specified as "disabled='disabled'", or just "disabled" + disabled: false, - // isContainer: Boolean - // can this widget contain other widgets? - isContainer: false, + // isContainer: Boolean + // can this widget contain other widgets? + isContainer: false, - // widgetId: String - // a unique, opaque ID string that can be assigned by users or by the - // system. If the developer passes an ID which is known not to be - // unique, the specified ID is ignored and the system-generated ID is - // used instead. - widgetId: "", + // widgetId: String + // a unique, opaque ID string that can be assigned by users or by the + // system. If the developer passes an ID which is known not to be + // unique, the specified ID is ignored and the system-generated ID is + // used instead. + widgetId: "", - // widgetType: String - // used for building generic widgets - widgetType: "Widget", + // widgetType: String + // used for building generic widgets + widgetType: "Widget", - // ns: String - // defaults to 'dojo'. "namespace" is a reserved word in JavaScript, so we abbreviate - ns: "dojo", + // ns: String + // defaults to 'dojo'. "namespace" is a reserved word in JavaScript, so we abbreviate + ns: "dojo", - getNamespacedType: function(){ - // summary: - // get the "full" name of the widget. If the widget comes from the - // "dojo" namespace and is a Button, calling this method will - // return "dojo:button", all lower-case - return (this.ns ? this.ns + ":" + this.widgetType : this.widgetType).toLowerCase(); // String - }, + getNamespacedType: function(){ + // summary: + // get the "full" name of the widget. If the widget comes from the + // "dojo" namespace and is a Button, calling this method will + // return "dojo:button", all lower-case + return (this.ns ? this.ns + ":" + this.widgetType : this.widgetType).toLowerCase(); // String + }, + + toString: function(){ + // summary: + // returns a string that represents the widget. When a widget is + // cast to a string, this method will be used to generate the + // output. Currently, it does not implement any sort of reversable + // serialization. + return '[Widget ' + this.getNamespacedType() + ', ' + (this.widgetId || 'NO ID') + ']'; // String + }, - toString: function(){ - // summary: - // returns a string that represents the widget. When a widget is - // cast to a string, this method will be used to generate the - // output. Currently, it does not implement any sort of reversable - // serialization. - return '[Widget ' + this.getNamespacedType() + ', ' + (this.widgetId || 'NO ID') + ']'; // String - }, + repr: function(){ + // summary: returns the string representation of the widget. + return this.toString(); // String + }, - repr: function(){ - // summary: returns the string representation of the widget. - return this.toString(); // String - }, + enable: function(){ + // summary: + // enables the widget, usually involving unmasking inputs and + // turning on event handlers. Not implemented here. + this.disabled = false; + }, - enable: function(){ - // summary: - // enables the widget, usually involving unmasking inputs and - // turning on event handlers. Not implemented here. - this.disabled = false; - }, + disable: function(){ + // summary: + // disables the widget, usually involves masking inputs and + // unsetting event handlers. Not implemented here. + this.disabled = true; + }, - disable: function(){ - // summary: - // disables the widget, usually involves masking inputs and - // unsetting event handlers. Not implemented here. - this.disabled = true; - }, + // TODO: + // 1) this would be better in HtmlWidget rather than here? + // 2) since many widgets don't care if they've been resized, maybe this should be a mixin? + onResized: function(){ + // summary: + // A signal that widgets will call when they have been resized. + // Can be connected to for determining if a layout needs to be + // reflowed. Clients should override this function to do special + // processing, then call this.notifyChildrenOfResize() to notify + // children of resize. + this.notifyChildrenOfResize(); + }, + + notifyChildrenOfResize: function(){ + // summary: dispatches resized events to all children of this widget + for(var i=0; i mixInProperties"); + //dojo.profile.start(this.widgetType + " mixInProperties"); + this.mixInProperties(args, fragment, parent); + //dojo.profile.end(this.widgetType + " mixInProperties"); + // dojo.debug(this.widgetType, "-> postMixInProperties"); + //dojo.profile.start(this.widgetType + " postMixInProperties"); + this.postMixInProperties(args, fragment, parent); + //dojo.profile.end(this.widgetType + " postMixInProperties"); + // dojo.debug(this.widgetType, "-> dojo.widget.manager.add"); + dojo.widget.manager.add(this); + // dojo.debug(this.widgetType, "-> buildRendering"); + //dojo.profile.start(this.widgetType + " buildRendering"); + this.buildRendering(args, fragment, parent); + //dojo.profile.end(this.widgetType + " buildRendering"); + // dojo.debug(this.widgetType, "-> initialize"); + //dojo.profile.start(this.widgetType + " initialize"); + this.initialize(args, fragment, parent); + //dojo.profile.end(this.widgetType + " initialize"); + // dojo.debug(this.widgetType, "-> postInitialize"); + // postinitialize includes subcomponent creation + // profile is put directly to function + this.postInitialize(args, fragment, parent); + // dojo.debug(this.widgetType, "-> postCreate"); + //dojo.profile.start(this.widgetType + " postCreate"); + this.postCreate(args, fragment, parent); + //dojo.profile.end(this.widgetType + " postCreate"); + // dojo.debug(this.widgetType, "done!"); + + //dojo.profile.end(this.widgetType + " create"); + + return this; + }, - create: function(args, fragment, parent, ns){ - // summary: - // 'create' manages the initialization part of the widget - // lifecycle. It's called implicitly when any widget is created. - // All other initialization functions for widgets, except for the - // constructor, are called as a result of 'create' being fired. - // args: Object - // a normalized view of the parameters that the widget should take - // fragment: Object - // if the widget is being instantiated from markup, this object - // parent: Widget? - // the widget, if any, that this widget will be the child of. If - // none is passed, the global default widget is used. - // ns: String? - // what namespace the widget belongs to - // description: - // to understand the process by which widgets are instantiated, it - // is critical to understand what other methods 'create' calls and - // which of them you'll want to over-ride. Of course, adventurous - // developers could over-ride 'create' entirely, but this should - // only be done as a last resort. - // - // Below is a list of the methods that are called, in the order - // they are fired, along with notes about what they do and if/when - // you should over-ride them in your widget: - // - // mixInProperties: - // takes the args and does lightweight type introspection - // on pre-existing object properties to initialize widget - // values by casting the values that are passed in args - // postMixInProperties: - // a stub function that you can over-ride to modify - // variables that may have been naively assigned by - // mixInProperties - // # widget is added to manager object here - // buildRendering - // subclasses use this method to handle all UI initialization - // initialize: - // a stub function that you can over-ride. - // postInitialize: - // a stub function that you can over-ride. - // postCreate - // a stub function that you can over-ride to modify take - // actions once the widget has been placed in the UI - // - // all of these functions are passed the same arguments as are - // passed to 'create' + destroy: function(finalize){ + // summary: + // Destroy this widget and it's descendants. This is the generic + // "destructor" function that all widget users should call to + // clealy discard with a widget. Once a widget is destroyed, it's + // removed from the manager object. + // finalize: Boolean + // is this function being called part of global environment + // tear-down? - //dojo.profile.start(this.widgetType + " create"); - if(ns){ - this.ns = ns; - } - // dojo.debug(this.widgetType, "create"); - //dojo.profile.start(this.widgetType + " satisfyPropertySets"); - this.satisfyPropertySets(args, fragment, parent); - //dojo.profile.end(this.widgetType + " satisfyPropertySets"); - // dojo.debug(this.widgetType, "-> mixInProperties"); - //dojo.profile.start(this.widgetType + " mixInProperties"); - this.mixInProperties(args, fragment, parent); - //dojo.profile.end(this.widgetType + " mixInProperties"); - // dojo.debug(this.widgetType, "-> postMixInProperties"); - //dojo.profile.start(this.widgetType + " postMixInProperties"); - this.postMixInProperties(args, fragment, parent); - //dojo.profile.end(this.widgetType + " postMixInProperties"); - // dojo.debug(this.widgetType, "-> dojo.widget.manager.add"); - dojo.widget.manager.add(this); - // dojo.debug(this.widgetType, "-> buildRendering"); - //dojo.profile.start(this.widgetType + " buildRendering"); - this.buildRendering(args, fragment, parent); - //dojo.profile.end(this.widgetType + " buildRendering"); - // dojo.debug(this.widgetType, "-> initialize"); - //dojo.profile.start(this.widgetType + " initialize"); - this.initialize(args, fragment, parent); - //dojo.profile.end(this.widgetType + " initialize"); - // dojo.debug(this.widgetType, "-> postInitialize"); - // postinitialize includes subcomponent creation - // profile is put directly to function - this.postInitialize(args, fragment, parent); - // dojo.debug(this.widgetType, "-> postCreate"); - //dojo.profile.start(this.widgetType + " postCreate"); - this.postCreate(args, fragment, parent); - //dojo.profile.end(this.widgetType + " postCreate"); - // dojo.debug(this.widgetType, "done!"); + // FIXME: this is woefully incomplete + if(this.parent){ + this.parent.removeChild(this); + } + this.destroyChildren(); + this.uninitialize(); + this.destroyRendering(finalize); + dojo.widget.manager.removeById(this.widgetId); + }, - //dojo.profile.end(this.widgetType + " create"); + destroyChildren: function(){ + // summary: + // Recursively destroy the children of this widget and their + // descendents. + var widget; + var i=0; + while(this.children.length > i){ + widget = this.children[i]; + if (widget instanceof dojo.widget.Widget) { // find first widget + this.removeChild(widget); + widget.destroy(); + continue; + } + + i++; // skip data object + } + + }, - return this; - }, + getChildrenOfType: function(/*String*/type, recurse){ + // summary: + // return an array of descendant widgets who match the passed type + // recurse: Boolean + // should we try to get all descendants that match? Defaults to + // false. + var ret = []; + var isFunc = dojo.lang.isFunction(type); + if(!isFunc){ + type = type.toLowerCase(); + } + for(var x=0; x i){ - widget = this.children[i]; - if (widget instanceof dojo.widget.Widget) { // find first widget - this.removeChild(widget); - widget.destroy(); - continue; - } - - i++; // skip data object - } - - }, - - getChildrenOfType: function(/*String*/type, recurse){ - // summary: - // return an array of descendant widgets who match the passed type - // recurse: Boolean - // should we try to get all descendants that match? Defaults to - // false. - var ret = []; - var isFunc = dojo.lang.isFunction(type); - if(!isFunc){ - type = type.toLowerCase(); - } - for(var x=0; xsi)){ + this[x][pairs[y].substr(0, si).replace(/^\s+|\s+$/g, "")] = pairs[y].substr(si+1); + } + } + } + }else{ + // the default is straight-up string assignment. When would + // we ever hit this? + this[x] = args[x]; + } + } + }else{ + // collect any extra 'non mixed in' args + this.extraArgs[x.toLowerCase()] = args[x]; + } + } + // dojo.profile.end("mixInProperties"); + }, + + postMixInProperties: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ + // summary + // Called after the parameters to the widget have been read-in, + // but before the widget template is instantiated. + // Especially useful to set properties that are referenced in the widget template. + }, - // this[x] = new Function(args[x]); + initialize: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ + // summary: stub function. + return false; + // dojo.unimplemented("dojo.widget.Widget.initialize"); + }, - // after an IRC discussion last week, it was decided - // that these event handlers should execute in the - // context of the widget, so that the "this" pointer - // takes correctly. + postInitialize: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ + // summary: stub function. + return false; + }, - // argument that contains no punctuation other than . is - // considered a function spec, not code - if(args[x].search(/[^\w\.]+/i) == -1){ - this[x] = dojo.evalObjPath(args[x], false); - }else{ - var tn = dojo.lang.nameAnonFunc(new Function(args[x]), this); - dojo.event.kwConnect({ - srcObj: this, - srcFunc: x, - adviceObj: this, - adviceFunc: tn - }); - } - }else if(dojo.lang.isArray(this[x])){ // typeof [] == "object" - this[x] = args[x].split(";"); - } else if (this[x] instanceof Date) { - this[x] = new Date(Number(args[x])); // assume timestamp - }else if(typeof this[x] == "object"){ - // FIXME: should we be allowing extension here to handle - // other object types intelligently? + postCreate: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ + // summary: stub function. + return false; + }, - // if a plain string is passed to a property of type dojo.uri.Uri, - // we assume it is relative to root of dojo - if (this[x] instanceof dojo.uri.Uri){ - this[x] = dojo.uri.dojoUri(args[x]); - }else{ - // FIXME: unlike all other types, we do not replace the - // object with a new one here. Should we change that? - var pairs = args[x].split(";"); - for(var y=0; ysi)){ - this[x][pairs[y].substr(0, si).replace(/^\s+|\s+$/g, "")] = pairs[y].substr(si+1); - } - } - } - }else{ - // the default is straight-up string assignment. When would - // we ever hit this? - this[x] = args[x]; - } - } - }else{ - // collect any extra 'non mixed in' args - this.extraArgs[x.toLowerCase()] = args[x]; - } - } - // dojo.profile.end("mixInProperties"); - }, + uninitialize: function(){ + // summary: + // stub function. Over-ride to implement custom widget tear-down + // behavior. + return false; + }, - postMixInProperties: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ - // summary - // Called after the parameters to the widget have been read-in, - // but before the widget template is instantiated. - // Especially useful to set properties that are referenced in the widget template. - }, + buildRendering: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ + // summary: stub function. SUBCLASSES MUST IMPLEMENT + dojo.unimplemented("dojo.widget.Widget.buildRendering, on "+this.toString()+", "); + return false; + }, - initialize: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ - // summary: stub function. - return false; - // dojo.unimplemented("dojo.widget.Widget.initialize"); - }, + destroyRendering: function(){ + // summary: stub function. SUBCLASSES MUST IMPLEMENT + dojo.unimplemented("dojo.widget.Widget.destroyRendering"); + return false; + }, - postInitialize: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ - // summary: stub function. - return false; - }, + addedTo: function(parent){ + // summary: + // stub function this is just a signal that can be caught + // parent: Widget + // instance of dojo.widget.Widget that we were added to + }, - postCreate: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ - // summary: stub function. - return false; - }, + addChild: function(child){ + // summary: stub function. SUBCLASSES MUST IMPLEMENT + dojo.unimplemented("dojo.widget.Widget.addChild"); + return false; + }, - uninitialize: function(){ - // summary: - // stub function. Over-ride to implement custom widget tear-down - // behavior. - return false; - }, + // Detach the given child widget from me, but don't destroy it + removeChild: function(/*Widget*/widget){ + // summary: + // removes the passed widget instance from this widget but does + // not destroy it + for(var x=0; x dojo.widget.tags["dojo:connect"] = function(fragment, widgetParser, parentComp){ - var properties = widgetParser.parseProperties(fragment["dojo:connect"]); + var properties = widgetParser.parseProperties(fragment["dojo:connect"]); } // FIXME: if we know the insertion point (to a reasonable location), why then do we: -// - create a template node -// - clone the template node -// - render the clone and set properties -// - remove the clone from the render tree -// - place the clone +// - create a template node +// - clone the template node +// - render the clone and set properties +// - remove the clone from the render tree +// - place the clone // this is quite dumb -dojo.widget.buildWidgetFromParseTree = function(/*String*/ type, - /*Object*/ frag, - /*dojo.widget.Parse*/ parser, - /*Widget, optional*/ parentComp, - /*int, optional*/ insertionIndex, - /*Object*/ localProps){ +dojo.widget.buildWidgetFromParseTree = function(/*String*/ type, + /*Object*/ frag, + /*dojo.widget.Parse*/ parser, + /*Widget, optional*/ parentComp, + /*int, optional*/ insertionIndex, + /*Object*/ localProps){ - // summary: creates a tree of widgets from the data structure produced by the first-pass parser (frag) - - // test for accessibility mode - dojo.a11y.setAccessibleMode(); - //dojo.profile.start("buildWidgetFromParseTree"); - // FIXME: for codepath from createComponentFromScript, we are now splitting a path - // that we already split and then joined - var stype = type.split(":"); - stype = (stype.length == 2) ? stype[1] : type; - - // FIXME: we don't seem to be doing anything with this! - // var propertySets = parser.getPropertySets(frag); - var localProperties = localProps || parser.parseProperties(frag[frag["ns"]+":"+stype]); - var twidget = dojo.widget.manager.getImplementation(stype,null,null,frag["ns"]); - if(!twidget){ - throw new Error('cannot find "' + type + '" widget'); - }else if (!twidget.create){ - throw new Error('"' + type + '" widget object has no "create" method and does not appear to implement *Widget'); - } - localProperties["dojoinsertionindex"] = insertionIndex; - // FIXME: we lose no less than 5ms in construction! - var ret = twidget.create(localProperties, frag, parentComp, frag["ns"]); - // dojo.profile.end("buildWidgetFromParseTree"); - return ret; + // summary: creates a tree of widgets from the data structure produced by the first-pass parser (frag) + + // test for accessibility mode + dojo.a11y.setAccessibleMode(); + //dojo.profile.start("buildWidgetFromParseTree"); + // FIXME: for codepath from createComponentFromScript, we are now splitting a path + // that we already split and then joined + var stype = type.split(":"); + stype = (stype.length == 2) ? stype[1] : type; + + // FIXME: we don't seem to be doing anything with this! + // var propertySets = parser.getPropertySets(frag); + var localProperties = localProps || parser.parseProperties(frag[frag["ns"]+":"+stype]); + var twidget = dojo.widget.manager.getImplementation(stype,null,null,frag["ns"]); + if(!twidget){ + throw new Error('cannot find "' + type + '" widget'); + }else if (!twidget.create){ + throw new Error('"' + type + '" widget object has no "create" method and does not appear to implement *Widget'); + } + localProperties["dojoinsertionindex"] = insertionIndex; + // FIXME: we lose no less than 5ms in construction! + var ret = twidget.create(localProperties, frag, parentComp, frag["ns"]); + // dojo.profile.end("buildWidgetFromParseTree"); + return ret; } dojo.widget.defineWidget = function(widgetClass, renderer, superclasses, init, props){ - // summary: Create a widget constructor function (aka widgetClass) - // widgetClass: String - // the location in the object hierarchy to place the new widget class constructor - // renderer: String - // usually "html", determines when this delcaration will be used - // superclasses: Function||Function[] - // can be either a single function or an array of functions to be - // mixed in as superclasses. If an array, only the first will be used - // to set prototype inheritance. - // init: Function - // an optional constructor function. Will be called after superclasses are mixed in. - // props: Object - // a map of properties and functions to extend the class prototype with + // summary: Create a widget constructor function (aka widgetClass) + // widgetClass: String + // the location in the object hierarchy to place the new widget class constructor + // renderer: String + // usually "html", determines when this delcaration will be used + // superclasses: Function||Function[] + // can be either a single function or an array of functions to be + // mixed in as superclasses. If an array, only the first will be used + // to set prototype inheritance. + // init: Function + // an optional constructor function. Will be called after superclasses are mixed in. + // props: Object + // a map of properties and functions to extend the class prototype with - // This meta-function does parameter juggling for backward compat and overloading - // if 4th argument is a string, we are using the old syntax - // old sig: widgetClass, superclasses, props (object), renderer (string), init (function) - if(dojo.lang.isString(arguments[3])){ - dojo.widget._defineWidget(arguments[0], arguments[3], arguments[1], arguments[4], arguments[2]); - }else{ - // widgetClass - var args = [ arguments[0] ], p = 3; - if(dojo.lang.isString(arguments[1])){ - // renderer, superclass - args.push(arguments[1], arguments[2]); - }else{ - // superclass - args.push('', arguments[1]); - p = 2; - } - if(dojo.lang.isFunction(arguments[p])){ - // init (function), props (object) - args.push(arguments[p], arguments[p+1]); - }else{ - // props (object) - args.push(null, arguments[p]); - } - dojo.widget._defineWidget.apply(this, args); - } + // This meta-function does parameter juggling for backward compat and overloading + // if 4th argument is a string, we are using the old syntax + // old sig: widgetClass, superclasses, props (object), renderer (string), init (function) + if(dojo.lang.isString(arguments[3])){ + dojo.widget._defineWidget(arguments[0], arguments[3], arguments[1], arguments[4], arguments[2]); + }else{ + // widgetClass + var args = [ arguments[0] ], p = 3; + if(dojo.lang.isString(arguments[1])){ + // renderer, superclass + args.push(arguments[1], arguments[2]); + }else{ + // superclass + args.push('', arguments[1]); + p = 2; + } + if(dojo.lang.isFunction(arguments[p])){ + // init (function), props (object) + args.push(arguments[p], arguments[p+1]); + }else{ + // props (object) + args.push(null, arguments[p]); + } + dojo.widget._defineWidget.apply(this, args); + } } dojo.widget.defineWidget.renderers = "html|svg|vml"; dojo.widget._defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){ - // FIXME: uncomment next line to test parameter juggling ... remove when confidence improves - // dojo.debug('(c:)' + widgetClass + '\n\n(r:)' + renderer + '\n\n(i:)' + init + '\n\n(p:)' + props); - // widgetClass takes the form foo.bar.baz<.renderer>.WidgetName (e.g. foo.bar.baz.WidgetName or foo.bar.baz.html.WidgetName) - var module = widgetClass.split("."); - var type = module.pop(); // type <= WidgetName, module <= foo.bar.baz<.renderer> - var regx = "\\.(" + (renderer ? renderer + '|' : '') + dojo.widget.defineWidget.renderers + ")\\."; - var r = widgetClass.search(new RegExp(regx)); - module = (r < 0 ? module.join(".") : widgetClass.substr(0, r)); + // FIXME: uncomment next line to test parameter juggling ... remove when confidence improves + // dojo.debug('(c:)' + widgetClass + '\n\n(r:)' + renderer + '\n\n(i:)' + init + '\n\n(p:)' + props); + // widgetClass takes the form foo.bar.baz<.renderer>.WidgetName (e.g. foo.bar.baz.WidgetName or foo.bar.baz.html.WidgetName) + var module = widgetClass.split("."); + var type = module.pop(); // type <= WidgetName, module <= foo.bar.baz<.renderer> + var regx = "\\.(" + (renderer ? renderer + '|' : '') + dojo.widget.defineWidget.renderers + ")\\."; + var r = widgetClass.search(new RegExp(regx)); + module = (r < 0 ? module.join(".") : widgetClass.substr(0, r)); - // deprecated in favor of namespace system, remove for 0.5 - dojo.widget.manager.registerWidgetPackage(module); + // deprecated in favor of namespace system, remove for 0.5 + dojo.widget.manager.registerWidgetPackage(module); + + var pos = module.indexOf("."); + var nsName = (pos > -1) ? module.substring(0,pos) : module; - var pos = module.indexOf("."); - var nsName = (pos > -1) ? module.substring(0,pos) : module; - - // FIXME: hrm, this might make things simpler - //dojo.widget.tags.addParseTreeHandler(nsName+":"+type.toLowerCase()); - - props=(props)||{}; - props.widgetType = type; - if((!init)&&(props["classConstructor"])){ - init = props.classConstructor; - delete props.classConstructor; - } - dojo.declare(widgetClass, superclasses, init, props); + // FIXME: hrm, this might make things simpler + //dojo.widget.tags.addParseTreeHandler(nsName+":"+type.toLowerCase()); + + props=(props)||{}; + props.widgetType = type; + if((!init)&&(props["classConstructor"])){ + init = props.classConstructor; + delete props.classConstructor; + } + dojo.declare(widgetClass, superclasses, init, props); } dojo.provide("dojo.widget.Parse"); @@ -11640,324 +11650,324 @@ dojo.provide("dojo.widget.Parse"); // // a particular dojoML tag would be handled by a registered tagHandler with a hook for a default handler // if the widget system is loaded, a widget builder would be attach itself as the default handler -// +// // widget tags are no longer registered themselves: -// they are now arbitrarily namespaced, so we cannot register them all, and the non-prefixed portions -// are no longer guaranteed unique -// +// they are now arbitrarily namespaced, so we cannot register them all, and the non-prefixed portions +// are no longer guaranteed unique +// // therefore dojo.widget.tags should go with this parser code out of the widget module // dojo.widget.Parse = function(/*Object*/fragment){ - this.propertySetsList = []; - this.fragment = fragment; + this.propertySetsList = []; + this.fragment = fragment; - this.createComponents = function(/*Object*/frag, /*Object*/parentComp){ - var comps = []; - var built = false; - // if we have items to parse/create at this level, do it! - try{ - if(frag && frag.tagName && (frag != frag.nodeRef)){ + this.createComponents = function(/*Object*/frag, /*Object*/parentComp){ + var comps = []; + var built = false; + // if we have items to parse/create at this level, do it! + try{ + if(frag && frag.tagName && (frag != frag.nodeRef)){ + + // these are in fact, not ever for widgets per-se anymore, + // but for other markup elements (aka components) + var djTags = dojo.widget.tags; + + // we split so that you can declare multiple + // non-destructive components from the same ctor node + var tna = String(frag.tagName).split(";"); + for(var x=0; x -1) ? name.substring(0,pos) : "dojo"; - if(pos > -1){ name = name.substring(pos+1); } - var lowerCaseName = name.toLowerCase(); - var namespacedName = ns + ":" + lowerCaseName; - isNode = (dojo.byId(name) && !dojo.widget.tags[namespacedName]); - } + var isNode = false; + var isNameStr = (typeof name == "string"); + if(isNameStr){ + var pos = name.indexOf(":"); + var ns = (pos > -1) ? name.substring(0,pos) : "dojo"; + if(pos > -1){ name = name.substring(pos+1); } + var lowerCaseName = name.toLowerCase(); + var namespacedName = ns + ":" + lowerCaseName; + isNode = (dojo.byId(name) && !dojo.widget.tags[namespacedName]); + } - if((arguments.length == 1) && (isNode || !isNameStr)){ - // we got a DOM node - var xp = new dojo.xml.Parse(); - // FIXME: we should try to find the parent! - var tn = isNode ? dojo.byId(name) : name; - return dojo.widget.getParser().createComponents(xp.parseElement(tn, null, true))[0]; - } + if((arguments.length == 1) && (isNode || !isNameStr)){ + // we got a DOM node + var xp = new dojo.xml.Parse(); + // FIXME: we should try to find the parent! + var tn = isNode ? dojo.byId(name) : name; + return dojo.widget.getParser().createComponents(xp.parseElement(tn, null, true))[0]; + } - function fromScript(placeKeeperNode, name, props, ns){ - props[namespacedName] = { - dojotype: [{value: lowerCaseName}], - nodeRef: placeKeeperNode, - fastMixIn: true - }; - props.ns = ns; - return dojo.widget.getParser().createComponentFromScript(placeKeeperNode, name, props, ns); - } + function fromScript(placeKeeperNode, name, props, ns){ + props[namespacedName] = { + dojotype: [{value: lowerCaseName}], + nodeRef: placeKeeperNode, + fastMixIn: true + }; + props.ns = ns; + return dojo.widget.getParser().createComponentFromScript(placeKeeperNode, name, props, ns); + } - props = props||{}; - var notRef = false; - var tn = null; - var h = dojo.render.html.capable; - if(h){ - tn = document.createElement("span"); - } - if(!refNode){ - notRef = true; - refNode = tn; - if(h){ - dojo.body().appendChild(refNode); - } - }else if(position){ - dojo.dom.insertAtPosition(tn, refNode, position); - }else{ // otherwise don't replace, but build in-place - tn = refNode; - } - var widgetArray = fromScript(tn, name.toLowerCase(), props, ns); - if( (!widgetArray)||(!widgetArray[0])|| - (typeof widgetArray[0].widgetType == "undefined") ){ - throw new Error("createWidget: Creation of \"" + name + "\" widget failed."); - } - try{ - if(notRef && widgetArray[0].domNode.parentNode){ - widgetArray[0].domNode.parentNode.removeChild(widgetArray[0].domNode); - } - }catch(e){ - /* squelch for Safari */ - dojo.debug(e); - } - return widgetArray[0]; // Widget + props = props||{}; + var notRef = false; + var tn = null; + var h = dojo.render.html.capable; + if(h){ + tn = document.createElement("span"); + } + if(!refNode){ + notRef = true; + refNode = tn; + if(h){ + dojo.body().appendChild(refNode); + } + }else if(position){ + dojo.dom.insertAtPosition(tn, refNode, position); + }else{ // otherwise don't replace, but build in-place + tn = refNode; + } + var widgetArray = fromScript(tn, name.toLowerCase(), props, ns); + if( (!widgetArray)||(!widgetArray[0])|| + (typeof widgetArray[0].widgetType == "undefined") ){ + throw new Error("createWidget: Creation of \"" + name + "\" widget failed."); + } + try{ + if(notRef && widgetArray[0].domNode.parentNode){ + widgetArray[0].domNode.parentNode.removeChild(widgetArray[0].domNode); + } + }catch(e){ + /* squelch for Safari */ + dojo.debug(e); + } + return widgetArray[0]; // Widget } dojo.provide("dojo.widget.DomWidget"); @@ -11976,87 +11986,87 @@ dojo.widget._cssStrings = {}; dojo.widget._templateCache = {}; dojo.widget.defaultStrings = { - // summary: a mapping of strings that are used in template variable replacement - dojoRoot: dojo.hostenv.getBaseScriptUri(), - dojoWidgetModuleUri: dojo.uri.moduleUri("dojo.widget"), - baseScriptUri: dojo.hostenv.getBaseScriptUri() + // summary: a mapping of strings that are used in template variable replacement + dojoRoot: dojo.hostenv.getBaseScriptUri(), + dojoWidgetModuleUri: dojo.uri.moduleUri("dojo.widget"), + baseScriptUri: dojo.hostenv.getBaseScriptUri() }; dojo.widget.fillFromTemplateCache = function(obj, templatePath, templateString, avoidCache){ - // summary: - // static method to build from a template w/ or w/o a real widget in - // place - // obj: DomWidget - // an instance of dojo.widget.DomWidget to initialize the template for - // templatePath: String - // the URL to get the template from. dojo.uri.Uri is often passed as well. - // templateString: String? - // a string to use in lieu of fetching the template from a URL - // avoidCache: Boolean? - // should the template system not use whatever is in the cache and - // always use the passed templatePath or templateString? + // summary: + // static method to build from a template w/ or w/o a real widget in + // place + // obj: DomWidget + // an instance of dojo.widget.DomWidget to initialize the template for + // templatePath: String + // the URL to get the template from. dojo.uri.Uri is often passed as well. + // templateString: String? + // a string to use in lieu of fetching the template from a URL + // avoidCache: Boolean? + // should the template system not use whatever is in the cache and + // always use the passed templatePath or templateString? - // dojo.debug("avoidCache:", avoidCache); - var tpath = templatePath || obj.templatePath; + // dojo.debug("avoidCache:", avoidCache); + var tpath = templatePath || obj.templatePath; - var tmplts = dojo.widget._templateCache; - if(!tpath && !obj["widgetType"]) { // don't have a real template here - do { - var dummyName = "__dummyTemplate__" + dojo.widget._templateCache.dummyCount++; - } while(tmplts[dummyName]); - obj.widgetType = dummyName; - } - var wt = tpath?tpath.toString():obj.widgetType; + var tmplts = dojo.widget._templateCache; + if(!tpath && !obj["widgetType"]) { // don't have a real template here + do { + var dummyName = "__dummyTemplate__" + dojo.widget._templateCache.dummyCount++; + } while(tmplts[dummyName]); + obj.widgetType = dummyName; + } + var wt = tpath?tpath.toString():obj.widgetType; - var ts = tmplts[wt]; - if(!ts){ - tmplts[wt] = {"string": null, "node": null}; - if(avoidCache){ - ts = {}; - }else{ - ts = tmplts[wt]; - } - } + var ts = tmplts[wt]; + if(!ts){ + tmplts[wt] = {"string": null, "node": null}; + if(avoidCache){ + ts = {}; + }else{ + ts = tmplts[wt]; + } + } - if((!obj.templateString)&&(!avoidCache)){ - obj.templateString = templateString || ts["string"]; - } - if(obj.templateString){ - obj.templateString = this._sanitizeTemplateString(obj.templateString); - } + if((!obj.templateString)&&(!avoidCache)){ + obj.templateString = templateString || ts["string"]; + } + if(obj.templateString){ + obj.templateString = this._sanitizeTemplateString(obj.templateString); + } - if((!obj.templateNode)&&(!avoidCache)){ - obj.templateNode = ts["node"]; - } - if((!obj.templateNode)&&(!obj.templateString)&&(tpath)){ - // fetch a text fragment and assign it to templateString - // NOTE: we rely on blocking IO here! - var tstring = this._sanitizeTemplateString(dojo.hostenv.getText(tpath)); + if((!obj.templateNode)&&(!avoidCache)){ + obj.templateNode = ts["node"]; + } + if((!obj.templateNode)&&(!obj.templateString)&&(tpath)){ + // fetch a text fragment and assign it to templateString + // NOTE: we rely on blocking IO here! + var tstring = this._sanitizeTemplateString(dojo.hostenv.getText(tpath)); - obj.templateString = tstring; - if(!avoidCache){ - tmplts[wt]["string"] = tstring; - } - } - if((!ts["string"])&&(!avoidCache)){ - ts.string = obj.templateString; - } + obj.templateString = tstring; + if(!avoidCache){ + tmplts[wt]["string"] = tstring; + } + } + if((!ts["string"])&&(!avoidCache)){ + ts.string = obj.templateString; + } } dojo.widget._sanitizeTemplateString = function(/*String*/tString){ - //summary: Strips declarations so that external SVG and XML - //documents can be added to a document without worry. Also, if the string - //is an HTML document, only the part inside the body tag is returned. - if(tString){ - tString = tString.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, ""); - var matches = tString.match(/]*>\s*([\s\S]+)\s*<\/body>/im); - if(matches){ - tString = matches[1]; - } - }else{ - tString = ""; - } - return tString; //String + //summary: Strips declarations so that external SVG and XML + //documents can be added to a document without worry. Also, if the string + //is an HTML document, only the part inside the body tag is returned. + if(tString){ + tString = tString.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, ""); + var matches = tString.match(/]*>\s*([\s\S]+)\s*<\/body>/im); + if(matches){ + tString = matches[1]; + } + }else{ + tString = ""; + } + return tString; //String } dojo.widget._templateCache.dummyCount = 0; @@ -12074,875 +12084,875 @@ dojo.widget.onBuildProperty = "dojoOnBuild"; dojo.widget.waiNames = ["waiRole", "waiState"]; dojo.widget.wai = { - // summary: Contains functions to set accessibility roles and states - // onto widget elements - waiRole: { - // name: String: - // information for mapping accessibility role - name: "waiRole", - // namespace: String: - // URI of the namespace for the set of roles - "namespace": "http://www.w3.org/TR/xhtml2", - // alias: String: - // The alias to assign the namespace - alias: "x2", - // prefix: String: - // The prefix to assign to the role value - prefix: "wairole:" - }, - waiState: { - // name: String: - // information for mapping accessibility state - name: "waiState", - // namespace: String: - // URI of the namespace for the set of states - "namespace": "http://www.w3.org/2005/07/aaa", - // alias: String: - // The alias to assign the namespace - alias: "aaa", - // prefix: String: - // empty string - state value does not require prefix - prefix: "" - }, - setAttr: function(/*DomNode*/node, /*String*/ ns, /*String*/ attr, /*String|Boolean*/value){ - // summary: Use appropriate API to set the role or state attribute onto the element. - // description: In IE use the generic setAttribute() api. Append a namespace - // alias to the attribute name and appropriate prefix to the value. - // Otherwise, use the setAttribueNS api to set the namespaced attribute. Also - // add the appropriate prefix to the attribute value. - if(dojo.render.html.ie){ - node.setAttribute(this[ns].alias+":"+ attr, this[ns].prefix+value); - }else{ - node.setAttributeNS(this[ns]["namespace"], attr, this[ns].prefix+value); - } - }, + // summary: Contains functions to set accessibility roles and states + // onto widget elements + waiRole: { + // name: String: + // information for mapping accessibility role + name: "waiRole", + // namespace: String: + // URI of the namespace for the set of roles + "namespace": "http://www.w3.org/TR/xhtml2", + // alias: String: + // The alias to assign the namespace + alias: "x2", + // prefix: String: + // The prefix to assign to the role value + prefix: "wairole:" + }, + waiState: { + // name: String: + // information for mapping accessibility state + name: "waiState", + // namespace: String: + // URI of the namespace for the set of states + "namespace": "http://www.w3.org/2005/07/aaa", + // alias: String: + // The alias to assign the namespace + alias: "aaa", + // prefix: String: + // empty string - state value does not require prefix + prefix: "" + }, + setAttr: function(/*DomNode*/node, /*String*/ ns, /*String*/ attr, /*String|Boolean*/value){ + // summary: Use appropriate API to set the role or state attribute onto the element. + // description: In IE use the generic setAttribute() api. Append a namespace + // alias to the attribute name and appropriate prefix to the value. + // Otherwise, use the setAttribueNS api to set the namespaced attribute. Also + // add the appropriate prefix to the attribute value. + if(dojo.render.html.ie){ + node.setAttribute(this[ns].alias+":"+ attr, this[ns].prefix+value); + }else{ + node.setAttributeNS(this[ns]["namespace"], attr, this[ns].prefix+value); + } + }, - getAttr: function(/*DomNode*/ node, /*String*/ ns, /*String|Boolena*/ attr){ - // Summary: Use the appropriate API to retrieve the role or state value - // Description: In IE use the generic getAttribute() api. An alias value - // was added to the attribute name to simulate a namespace when the attribute - // was set. Otherwise use the getAttributeNS() api to retrieve the state value - if(dojo.render.html.ie){ - return node.getAttribute(this[ns].alias+":"+attr); - }else{ - return node.getAttributeNS(this[ns]["namespace"], attr); - } - }, - removeAttr: function(/*DomNode*/ node, /*String*/ ns, /*String|Boolena*/ attr){ - // summary: Use the appropriate API to remove the role or state value - // description: In IE use the generic removeAttribute() api. An alias value - // was added to the attribute name to simulate a namespace when the attribute - // was set. Otherwise use the removeAttributeNS() api to remove the state value - var success = true; //only IE returns a value - if(dojo.render.html.ie){ - success = node.removeAttribute(this[ns].alias+":"+attr); - }else{ - node.removeAttributeNS(this[ns]["namespace"], attr); - } - return success; - } + getAttr: function(/*DomNode*/ node, /*String*/ ns, /*String|Boolena*/ attr){ + // Summary: Use the appropriate API to retrieve the role or state value + // Description: In IE use the generic getAttribute() api. An alias value + // was added to the attribute name to simulate a namespace when the attribute + // was set. Otherwise use the getAttributeNS() api to retrieve the state value + if(dojo.render.html.ie){ + return node.getAttribute(this[ns].alias+":"+attr); + }else{ + return node.getAttributeNS(this[ns]["namespace"], attr); + } + }, + removeAttr: function(/*DomNode*/ node, /*String*/ ns, /*String|Boolena*/ attr){ + // summary: Use the appropriate API to remove the role or state value + // description: In IE use the generic removeAttribute() api. An alias value + // was added to the attribute name to simulate a namespace when the attribute + // was set. Otherwise use the removeAttributeNS() api to remove the state value + var success = true; //only IE returns a value + if(dojo.render.html.ie){ + success = node.removeAttribute(this[ns].alias+":"+attr); + }else{ + node.removeAttributeNS(this[ns]["namespace"], attr); + } + return success; + } }; dojo.widget.attachTemplateNodes = function(rootNode, /*Widget*/ targetObj, events ){ - // summary: - // map widget properties and functions to the handlers specified in - // the dom node and it's descendants. This function iterates over all - // nodes and looks for these properties: - // * dojoAttachPoint - // * dojoAttachEvent - // * waiRole - // * waiState - // * any "dojoOn*" proprties passed in the events array - // rootNode: DomNode - // the node to search for properties. All children will be searched. - // events: Array - // a list of properties generated from getDojoEventsFromStr. + // summary: + // map widget properties and functions to the handlers specified in + // the dom node and it's descendants. This function iterates over all + // nodes and looks for these properties: + // * dojoAttachPoint + // * dojoAttachEvent + // * waiRole + // * waiState + // * any "dojoOn*" proprties passed in the events array + // rootNode: DomNode + // the node to search for properties. All children will be searched. + // events: Array + // a list of properties generated from getDojoEventsFromStr. - // FIXME: this method is still taking WAAAY too long. We need ways of optimizing: - // a.) what we are looking for on each node - // b.) the nodes that are subject to interrogation (use xpath instead?) - // c.) how expensive event assignment is (less eval(), more connect()) - // var start = new Date(); - var elementNodeType = dojo.dom.ELEMENT_NODE; + // FIXME: this method is still taking WAAAY too long. We need ways of optimizing: + // a.) what we are looking for on each node + // b.) the nodes that are subject to interrogation (use xpath instead?) + // c.) how expensive event assignment is (less eval(), more connect()) + // var start = new Date(); + var elementNodeType = dojo.dom.ELEMENT_NODE; - function trim(str){ - return str.replace(/^\s+|\s+$/g, ""); - } + function trim(str){ + return str.replace(/^\s+|\s+$/g, ""); + } - if(!rootNode){ - rootNode = targetObj.domNode; - } + if(!rootNode){ + rootNode = targetObj.domNode; + } - if(rootNode.nodeType != elementNodeType){ - return; - } - // alert(events.length); + if(rootNode.nodeType != elementNodeType){ + return; + } + // alert(events.length); - var nodes = rootNode.all || rootNode.getElementsByTagName("*"); - var _this = targetObj; - for(var x=-1; x= 0){ - // oh, if only JS had tuple assignment - var funcNameArr = tevt.split(":"); - tevt = trim(funcNameArr[0]); - thisFunc = trim(funcNameArr[1]); - } - if(!thisFunc){ - thisFunc = tevt; - } + var attachEvent = baseNode.getAttribute(this.eventAttachProperty); + if(attachEvent){ + // NOTE: we want to support attributes that have the form + // "domEvent: nativeEvent; ..." + var evts = attachEvent.split(";"); + for(var y=0; y= 0){ + // oh, if only JS had tuple assignment + var funcNameArr = tevt.split(":"); + tevt = trim(funcNameArr[0]); + thisFunc = trim(funcNameArr[1]); + } + if(!thisFunc){ + thisFunc = tevt; + } + + var tf = function(){ + var ntf = new String(thisFunc); + return function(evt){ + if(_this[ntf]){ + _this[ntf](dojo.event.browser.fixEvent(evt, this)); + } + }; + }(); + dojo.event.browser.addListener(baseNode, tevt, tf, false, true); + // dojo.event.browser.addListener(baseNode, tevt, dojo.lang.hitch(_this, thisFunc)); + } + } + + for(var y=0; y=0){ + funcs = dojo.lang.map(thisFunc.split(";"), trim); + } + for(var z=0; z=0){ - funcs = dojo.lang.map(thisFunc.split(";"), trim); - } - for(var z=0; z0)&&(typeof arguments[0] == "object")){ - this.create(arguments[0]); - } - }, - { - // templateNode: DomNode - // a node that represents the widget template. Pre-empts both templateString and templatePath. - templateNode: null, +dojo.declare("dojo.widget.DomWidget", + dojo.widget.Widget, + function(){ + // summary: + // dojo.widget.DomWidget is the superclass that provides behavior for all + // DOM-based renderers, including HtmlWidget and SvgWidget. DomWidget + // implements the templating system that most widget authors use to define + // the UI for their widgets. + if((arguments.length>0)&&(typeof arguments[0] == "object")){ + this.create(arguments[0]); + } + }, + { + // templateNode: DomNode + // a node that represents the widget template. Pre-empts both templateString and templatePath. + templateNode: null, - // templateString String: - // a string that represents the widget template. Pre-empts the - // templatePath. In builds that have their strings "interned", the - // templatePath is converted to an inline templateString, thereby - // preventing a synchronous network call. - templateString: null, + // templateString String: + // a string that represents the widget template. Pre-empts the + // templatePath. In builds that have their strings "interned", the + // templatePath is converted to an inline templateString, thereby + // preventing a synchronous network call. + templateString: null, - // templateCssString String: - // a string that represents the CSS for the widgettemplate. - // Pre-empts the templateCssPath. In builds that have their - // strings "interned", the templateCssPath is converted to an - // inline templateCssString, thereby preventing a synchronous - // network call. - templateCssString: null, + // templateCssString String: + // a string that represents the CSS for the widgettemplate. + // Pre-empts the templateCssPath. In builds that have their + // strings "interned", the templateCssPath is converted to an + // inline templateCssString, thereby preventing a synchronous + // network call. + templateCssString: null, - // preventClobber Boolean: - // should the widget not replace the node from which it was - // constructed? Widgets that apply behaviors to pre-existing parts - // of a page can be implemented easily by setting this to "true". - // In these cases, the domNode property will point to the node - // which the widget was created from. - preventClobber: false, + // preventClobber Boolean: + // should the widget not replace the node from which it was + // constructed? Widgets that apply behaviors to pre-existing parts + // of a page can be implemented easily by setting this to "true". + // In these cases, the domNode property will point to the node + // which the widget was created from. + preventClobber: false, - // domNode DomNode: - // this is our visible representation of the widget! Other DOM - // Nodes may by assigned to other properties, usually through the - // template system's dojoAttachPonit syntax, but the domNode - // property is the canonical "top level" node in widget UI. - domNode: null, + // domNode DomNode: + // this is our visible representation of the widget! Other DOM + // Nodes may by assigned to other properties, usually through the + // template system's dojoAttachPonit syntax, but the domNode + // property is the canonical "top level" node in widget UI. + domNode: null, - // containerNode DomNode: - // holds child elements. "containerNode" is generally set via a - // dojoAttachPoint assignment and it designates where widgets that - // are defined as "children" of the parent will be placed - // visually. - containerNode: null, + // containerNode DomNode: + // holds child elements. "containerNode" is generally set via a + // dojoAttachPoint assignment and it designates where widgets that + // are defined as "children" of the parent will be placed + // visually. + containerNode: null, - // widgetsInTemplate Boolean: - // should we parse the template to find widgets that might be - // declared in markup inside it? false by default. - widgetsInTemplate: false, + // widgetsInTemplate Boolean: + // should we parse the template to find widgets that might be + // declared in markup inside it? false by default. + widgetsInTemplate: false, - addChild: function(/*Widget*/ widget, overrideContainerNode, pos, ref, insertIndex){ - // summary: - // Process the given child widget, inserting it's dom node as - // a child of our dom node - // overrideContainerNode: DomNode? - // a non-default container node for the widget - // pos: String? - // can be one of "before", "after", "first", or "last". This - // has the same meaning as in dojo.dom.insertAtPosition() - // ref: DomNode? - // a node to place the widget relative to - // insertIndex: int? - // DOM index, same meaning as in dojo.dom.insertAtIndex() - // returns: the widget that was inserted + addChild: function(/*Widget*/ widget, overrideContainerNode, pos, ref, insertIndex){ + // summary: + // Process the given child widget, inserting it's dom node as + // a child of our dom node + // overrideContainerNode: DomNode? + // a non-default container node for the widget + // pos: String? + // can be one of "before", "after", "first", or "last". This + // has the same meaning as in dojo.dom.insertAtPosition() + // ref: DomNode? + // a node to place the widget relative to + // insertIndex: int? + // DOM index, same meaning as in dojo.dom.insertAtIndex() + // returns: the widget that was inserted - // FIXME: should we support addition at an index in the children arr and - // order the display accordingly? Right now we always append. - if(!this.isContainer){ // we aren't allowed to contain other widgets, it seems - dojo.debug("dojo.widget.DomWidget.addChild() attempted on non-container widget"); - return null; - }else{ - if(insertIndex == undefined){ - insertIndex = this.children.length; - } - this.addWidgetAsDirectChild(widget, overrideContainerNode, pos, ref, insertIndex); - this.registerChild(widget, insertIndex); - } - return widget; // Widget - }, + // FIXME: should we support addition at an index in the children arr and + // order the display accordingly? Right now we always append. + if(!this.isContainer){ // we aren't allowed to contain other widgets, it seems + dojo.debug("dojo.widget.DomWidget.addChild() attempted on non-container widget"); + return null; + }else{ + if(insertIndex == undefined){ + insertIndex = this.children.length; + } + this.addWidgetAsDirectChild(widget, overrideContainerNode, pos, ref, insertIndex); + this.registerChild(widget, insertIndex); + } + return widget; // Widget + }, + + addWidgetAsDirectChild: function(/*Widget*/ widget, overrideContainerNode, pos, ref, insertIndex){ + // summary: + // Process the given child widget, inserting it's dom node as + // a child of our dom node + // overrideContainerNode: DomNode + // a non-default container node for the widget + // pos: String? + // can be one of "before", "after", "first", or "last". This + // has the same meaning as in dojo.dom.insertAtPosition() + // ref: DomNode? + // a node to place the widget relative to + // insertIndex: int? + // DOM index, same meaning as in dojo.dom.insertAtIndex() + if((!this.containerNode)&&(!overrideContainerNode)){ + this.containerNode = this.domNode; + } + var cn = (overrideContainerNode) ? overrideContainerNode : this.containerNode; + if(!pos){ pos = "after"; } + if(!ref){ + if(!cn){ cn = dojo.body(); } + ref = cn.lastChild; + } + if(!insertIndex) { insertIndex = 0; } + widget.domNode.setAttribute("dojoinsertionindex", insertIndex); - addWidgetAsDirectChild: function(/*Widget*/ widget, overrideContainerNode, pos, ref, insertIndex){ - // summary: - // Process the given child widget, inserting it's dom node as - // a child of our dom node - // overrideContainerNode: DomNode - // a non-default container node for the widget - // pos: String? - // can be one of "before", "after", "first", or "last". This - // has the same meaning as in dojo.dom.insertAtPosition() - // ref: DomNode? - // a node to place the widget relative to - // insertIndex: int? - // DOM index, same meaning as in dojo.dom.insertAtIndex() - if((!this.containerNode)&&(!overrideContainerNode)){ - this.containerNode = this.domNode; - } - var cn = (overrideContainerNode) ? overrideContainerNode : this.containerNode; - if(!pos){ pos = "after"; } - if(!ref){ - if(!cn){ cn = dojo.body(); } - ref = cn.lastChild; - } - if(!insertIndex) { insertIndex = 0; } - widget.domNode.setAttribute("dojoinsertionindex", insertIndex); + // insert the child widget domNode directly underneath my domNode, in the + // specified position (by default, append to end) + if(!ref){ + cn.appendChild(widget.domNode); + }else{ + // FIXME: was this meant to be the (ugly hack) way to support insert @ index? + //dojo.dom[pos](widget.domNode, ref, insertIndex); - // insert the child widget domNode directly underneath my domNode, in the - // specified position (by default, append to end) - if(!ref){ - cn.appendChild(widget.domNode); - }else{ - // FIXME: was this meant to be the (ugly hack) way to support insert @ index? - //dojo.dom[pos](widget.domNode, ref, insertIndex); + // CAL: this appears to be the intended way to insert a node at a given position... + if (pos == 'insertAtIndex'){ + // dojo.debug("idx:", insertIndex, "isLast:", ref === cn.lastChild); + dojo.dom.insertAtIndex(widget.domNode, ref.parentNode, insertIndex); + }else{ + // dojo.debug("pos:", pos, "isLast:", ref === cn.lastChild); + if((pos == "after")&&(ref === cn.lastChild)){ + cn.appendChild(widget.domNode); + }else{ + dojo.dom.insertAtPosition(widget.domNode, cn, pos); + } + } + } + }, - // CAL: this appears to be the intended way to insert a node at a given position... - if (pos == 'insertAtIndex'){ - // dojo.debug("idx:", insertIndex, "isLast:", ref === cn.lastChild); - dojo.dom.insertAtIndex(widget.domNode, ref.parentNode, insertIndex); - }else{ - // dojo.debug("pos:", pos, "isLast:", ref === cn.lastChild); - if((pos == "after")&&(ref === cn.lastChild)){ - cn.appendChild(widget.domNode); - }else{ - dojo.dom.insertAtPosition(widget.domNode, cn, pos); - } - } - } - }, + registerChild: function(widget, insertionIndex){ + // summary: record that given widget descends from me + // widget: Widget + // the widget that is now a child + // insertionIndex: int + // where in the children[] array to place it - registerChild: function(widget, insertionIndex){ - // summary: record that given widget descends from me - // widget: Widget - // the widget that is now a child - // insertionIndex: int - // where in the children[] array to place it + // we need to insert the child at the right point in the parent's + // 'children' array, based on the insertionIndex - // we need to insert the child at the right point in the parent's - // 'children' array, based on the insertionIndex + widget.dojoInsertionIndex = insertionIndex; - widget.dojoInsertionIndex = insertionIndex; + var idx = -1; + for(var i=0; i node that can't be inserted back into the original DOM tree + parentComp.addWidgetAsDirectChild(this, "", "insertAtIndex", "", args["dojoinsertionindex"], sourceNodeRef); + } else if (sourceNodeRef){ + // Do in-place replacement of the my source node with my generated dom + if(this.domNode && (this.domNode !== sourceNodeRef)){ + this._sourceNodeRef = dojo.dom.replaceNode(sourceNodeRef, this.domNode); + } + } - // remove child widget from parent widget - return dojo.widget.DomWidget.superclass.removeChild.call(this, widget); // Widget - }, + // Register myself with my parent, or with the widget manager if + // I have no parent + // TODO: the code below erroneously adds all programatically generated widgets + // to topWidgets (since we don't know who the parent is until after creation finishes) + if ( parentComp ) { + parentComp.registerChild(this, args.dojoinsertionindex); + } else { + dojo.widget.manager.topWidgets[this.widgetId]=this; + } - getFragNodeRef: function(frag){ - // summary: - // returns the source node, if any, that the widget was - // declared from - // frag: Object - // an opaque data structure generated by the first-pass parser - if(!frag){return null;} // null - if(!frag[this.getNamespacedType()]){ - dojo.raise("Error: no frag for widget type " + this.getNamespacedType() - + ", id " + this.widgetId - + " (maybe a widget has set it's type incorrectly)"); - } - return frag[this.getNamespacedType()]["nodeRef"]; // DomNode - }, + if(this.widgetsInTemplate){ + var parser = new dojo.xml.Parse(); - postInitialize: function(/*Object*/ args, /*Object*/ frag, /*Widget*/ parentComp){ - // summary: - // Replace the source domNode with the generated dom - // structure, and register the widget with its parent. - // This is an implementation of the stub function defined in - // dojo.widget.Widget. + var subContainerNode; + //TODO: use xpath here? + var subnodes = this.domNode.getElementsByTagName("*"); + for(var i=0;i= 0){ + // oh, if only JS had tuple assignment + var funcNameArr = tevt.split(":"); + tevt = dojo.string.trim(funcNameArr[0]); + thisFunc = dojo.string.trim(funcNameArr[1]); + } + if(!thisFunc){ + thisFunc = tevt; + } + if(dojo.lang.isFunction(widget[tevt])){ + dojo.event.kwConnect({ + srcObj: widget, + srcFunc: tevt, + targetObj: this, + targetFunc: thisFunc + }); + }else{ + alert(tevt+" is not a function in widget "+widget); + } + } + } + + if(widget.extraArgs['dojoattachpoint']){ + //don't attach widget.domNode here, as we do not know which + //dom node we should connect to (in checkbox widget case, + //it is inputNode). So we make the widget itself available + this[widget.extraArgs['dojoattachpoint']] = widget; + } + } + } - var sourceNodeRef = this.getFragNodeRef(frag); - // Stick my generated dom into the output tree - //alert(this.widgetId + ": replacing " + sourceNodeRef + " with " + this.domNode.innerHTML); - if (parentComp && (parentComp.snarfChildDomOutput || !sourceNodeRef)){ - // Add my generated dom as a direct child of my parent widget - // This is important for generated widgets, and also cases where I am generating an - //
  • node that can't be inserted back into the original DOM tree - parentComp.addWidgetAsDirectChild(this, "", "insertAtIndex", "", args["dojoinsertionindex"], sourceNodeRef); - } else if (sourceNodeRef){ - // Do in-place replacement of the my source node with my generated dom - if(this.domNode && (this.domNode !== sourceNodeRef)){ - this._sourceNodeRef = dojo.dom.replaceNode(sourceNodeRef, this.domNode); - } - } + //dojo.profile.end(this.widgetType + " postInitialize"); - // Register myself with my parent, or with the widget manager if - // I have no parent - // TODO: the code below erroneously adds all programatically generated widgets - // to topWidgets (since we don't know who the parent is until after creation finishes) - if ( parentComp ) { - parentComp.registerChild(this, args.dojoinsertionindex); - } else { - dojo.widget.manager.topWidgets[this.widgetId]=this; - } + // Expand my children widgets + /* dojoDontFollow is important for a very special case + * basically if you have a widget that you instantiate from script + * and that widget is a container, and it contains a reference to a parent + * instance, the parser will start recursively parsing until the browser + * complains. So the solution is to set an initialization property of + * dojoDontFollow: true and then it won't recurse where it shouldn't + */ + if(this.isContainer && !frag["dojoDontFollow"]){ + //alert("recurse from " + this.widgetId); + // build any sub-components with us as the parent + dojo.widget.getParser().createSubComponents(frag, this); + } + }, - if(this.widgetsInTemplate){ - var parser = new dojo.xml.Parse(); + // method over-ride + buildRendering: function(/*Object*/ args, /*Object*/ frag){ + // summary: + // Construct the UI for this widget, generally from a + // template. This can be over-ridden for custom UI creation to + // to side-step the template system. This is an + // implementation of the stub function defined in + // dojo.widget.Widget. - var subContainerNode; - //TODO: use xpath here? - var subnodes = this.domNode.getElementsByTagName("*"); - for(var i=0;i -1) { + value=value.replace("\"","""); + } + tstr = tstr.replace(matches[i], value); + } + } + }else{ + // otherwise, we are required to instantiate a copy of the template + // string if one is provided. + + // FIXME: need to be able to distinguish here what should be done + // or provide a generic interface across all DOM implementations + // FIMXE: this breaks if the template has whitespace as its first + // characters + // node = this.createNodesFromText(this.templateString, true); + // this.templateNode = node[0].cloneNode(true); // we're optimistic here + this.templateNode = this.createNodesFromText(this.templateString, true)[0]; + if(!avoidCache){ + ts.node = this.templateNode; + } + } + } + if((!this.templateNode)&&(!matches)){ + dojo.debug("DomWidget.buildFromTemplate: could not create template"); + return false; + }else if(!matches){ + node = this.templateNode.cloneNode(true); + if(!node){ return false; } + }else{ + node = this.createNodesFromText(tstr, true)[0]; + } - //connect event to this widget/attach dom node - for(var i = 0; i < subwidgets.length; i++){ - var widget = subwidgets[i]; - if(widget._processedSubWidgets){ - dojo.debug("This should not happen: widget._processedSubWidgets is already true!"); - return; - } - widget._processedSubWidgets = true; - if(widget.extraArgs['dojoattachevent']){ - var evts = widget.extraArgs['dojoattachevent'].split(";"); - for(var j=0; j= 0){ - // oh, if only JS had tuple assignment - var funcNameArr = tevt.split(":"); - tevt = dojo.string.trim(funcNameArr[0]); - thisFunc = dojo.string.trim(funcNameArr[1]); - } - if(!thisFunc){ - thisFunc = tevt; - } - if(dojo.lang.isFunction(widget[tevt])){ - dojo.event.kwConnect({ - srcObj: widget, - srcFunc: tevt, - targetObj: this, - targetFunc: thisFunc - }); - }else{ - alert(tevt+" is not a function in widget "+widget); - } - } - } + // recurse through the node, looking for, and attaching to, our + // attachment points which should be defined on the template node. - if(widget.extraArgs['dojoattachpoint']){ - //don't attach widget.domNode here, as we do not know which - //dom node we should connect to (in checkbox widget case, - //it is inputNode). So we make the widget itself available - this[widget.extraArgs['dojoattachpoint']] = widget; - } - } - } + this.domNode = node; + // dojo.profile.start("attachTemplateNodes"); + this.attachTemplateNodes(); + // dojo.profile.end("attachTemplateNodes"); + + // relocate source contents to templated container node + // this.containerNode must be able to receive children, or exceptions will be thrown + if (this.isContainer && this.containerNode){ + var src = this.getFragNodeRef(frag); + if (src){ + dojo.dom.moveChildren(src, this.containerNode); + } + } + }, - //dojo.profile.end(this.widgetType + " postInitialize"); + attachTemplateNodes: function(baseNode, targetObj){ + // summary: + // hooks up event handlers and property/node linkages. Calls + // dojo.widget.attachTemplateNodes to do all the hard work. + // baseNode: DomNode + // defaults to "this.domNode" + // targetObj: Widget + // defaults to "this" + if(!baseNode){ baseNode = this.domNode; } + if(!targetObj){ targetObj = this; } + return dojo.widget.attachTemplateNodes(baseNode, targetObj, + dojo.widget.getDojoEventsFromStr(this.templateString)); + }, - // Expand my children widgets - /* dojoDontFollow is important for a very special case - * basically if you have a widget that you instantiate from script - * and that widget is a container, and it contains a reference to a parent - * instance, the parser will start recursively parsing until the browser - * complains. So the solution is to set an initialization property of - * dojoDontFollow: true and then it won't recurse where it shouldn't - */ - if(this.isContainer && !frag["dojoDontFollow"]){ - //alert("recurse from " + this.widgetId); - // build any sub-components with us as the parent - dojo.widget.getParser().createSubComponents(frag, this); - } - }, + fillInTemplate: function(){ + // summary: + // stub function! sub-classes may use as a default UI + // initializer function. The UI rendering will be available by + // the time this is called from buildRendering. If + // buildRendering is over-ridden, this function may not be + // fired! - // method over-ride - buildRendering: function(/*Object*/ args, /*Object*/ frag){ - // summary: - // Construct the UI for this widget, generally from a - // template. This can be over-ridden for custom UI creation to - // to side-step the template system. This is an - // implementation of the stub function defined in - // dojo.widget.Widget. + // dojo.unimplemented("dojo.widget.DomWidget.fillInTemplate"); + }, + + // method over-ride + destroyRendering: function(){ + // summary: UI destructor. Destroy the dom nodes associated w/this widget. + try{ + dojo.dom.destroyNode(this.domNode); + delete this.domNode; + }catch(e){ /* squelch! */ } + if(this._sourceNodeRef){ + try{ + dojo.dom.destroyNode(this._sourceNodeRef); + }catch(e){ /* squelch! */ } + } + }, - // DOM widgets construct themselves from a template - var ts = dojo.widget._templateCache[this.widgetType]; - - // Handle style for this widget here, as even if templatePath - // is not set, style specified by templateCssString or templateCssPath - // should be applied. templateCssString has higher priority - // than templateCssPath - if(args["templatecsspath"]){ - args["templateCssPath"] = args["templatecsspath"]; - } - var cpath = args["templateCssPath"] || this.templateCssPath; - if(cpath && !dojo.widget._cssFiles[cpath.toString()]){ - if((!this.templateCssString)&&(cpath)){ - this.templateCssString = dojo.hostenv.getText(cpath); - this.templateCssPath = null; - } - dojo.widget._cssFiles[cpath.toString()] = true; - } - - if((this["templateCssString"])&&(!dojo.widget._cssStrings[this.templateCssString])){ - dojo.html.insertCssText(this.templateCssString, null, cpath); - dojo.widget._cssStrings[this.templateCssString] = true; - } - if( - (!this.preventClobber)&&( - (this.templatePath)|| - (this.templateNode)|| - ( - (this["templateString"])&&(this.templateString.length) - )|| - ( - (typeof ts != "undefined")&&( (ts["string"])||(ts["node"]) ) - ) - ) - ){ - // if it looks like we can build the thing from a template, do it! - this.buildFromTemplate(args, frag); - }else{ - // otherwise, assign the DOM node that was the source of the widget - // parsing to be the root node - this.domNode = this.getFragNodeRef(frag); - } - this.fillInTemplate(args, frag); // this is where individual widgets - // will handle population of data - // from properties, remote data - // sets, etc. - }, - - buildFromTemplate: function(/*Object*/ args, /*Object*/ frag){ - // summary: - // Called by buildRendering, creates the actual UI in a DomWidget. - - // var start = new Date(); - // copy template properties if they're already set in the templates object - // dojo.debug("buildFromTemplate:", this); - var avoidCache = false; - if(args["templatepath"]){ -// avoidCache = true; - args["templatePath"] = args["templatepath"]; - } - dojo.widget.fillFromTemplateCache( this, - args["templatePath"], - null, - avoidCache); - var ts = dojo.widget._templateCache[this.templatePath?this.templatePath.toString():this.widgetType]; - if((ts)&&(!avoidCache)){ - if(!this.templateString.length){ - this.templateString = ts["string"]; - } - if(!this.templateNode){ - this.templateNode = ts["node"]; - } - } - var matches = false; - var node = null; - // var tstr = new String(this.templateString); - var tstr = this.templateString; - // attempt to clone a template node, if there is one - if((!this.templateNode)&&(this.templateString)){ - matches = this.templateString.match(/\$\{([^\}]+)\}/g); - if(matches) { - // if we do property replacement, don't create a templateNode - // to clone from. - var hash = this.strings || {}; - // FIXME: should this hash of default replacements be cached in - // templateString? - for(var key in dojo.widget.defaultStrings) { - if(dojo.lang.isUndefined(hash[key])) { - hash[key] = dojo.widget.defaultStrings[key]; - } - } - // FIXME: this is a lot of string munging. Can we make it faster? - for(var i = 0; i < matches.length; i++) { - var key = matches[i]; - key = key.substring(2, key.length-1); - var kval = (key.substring(0, 5) == "this.") ? dojo.lang.getObjPathValue(key.substring(5), this) : hash[key]; - var value; - if((kval)||(dojo.lang.isString(kval))){ - value = new String((dojo.lang.isFunction(kval)) ? kval.call(this, key, this.templateString) : kval); - // Safer substitution, see heading "Attribute values" in - // http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2 - while (value.indexOf("\"") > -1) { - value=value.replace("\"","""); - } - tstr = tstr.replace(matches[i], value); - } - } - }else{ - // otherwise, we are required to instantiate a copy of the template - // string if one is provided. - - // FIXME: need to be able to distinguish here what should be done - // or provide a generic interface across all DOM implementations - // FIMXE: this breaks if the template has whitespace as its first - // characters - // node = this.createNodesFromText(this.templateString, true); - // this.templateNode = node[0].cloneNode(true); // we're optimistic here - this.templateNode = this.createNodesFromText(this.templateString, true)[0]; - if(!avoidCache){ - ts.node = this.templateNode; - } - } - } - if((!this.templateNode)&&(!matches)){ - dojo.debug("DomWidget.buildFromTemplate: could not create template"); - return false; - }else if(!matches){ - node = this.templateNode.cloneNode(true); - if(!node){ return false; } - }else{ - node = this.createNodesFromText(tstr, true)[0]; - } - - // recurse through the node, looking for, and attaching to, our - // attachment points which should be defined on the template node. - - this.domNode = node; - // dojo.profile.start("attachTemplateNodes"); - this.attachTemplateNodes(); - // dojo.profile.end("attachTemplateNodes"); - - // relocate source contents to templated container node - // this.containerNode must be able to receive children, or exceptions will be thrown - if (this.isContainer && this.containerNode){ - var src = this.getFragNodeRef(frag); - if (src){ - dojo.dom.moveChildren(src, this.containerNode); - } - } - }, - - attachTemplateNodes: function(baseNode, targetObj){ - // summary: - // hooks up event handlers and property/node linkages. Calls - // dojo.widget.attachTemplateNodes to do all the hard work. - // baseNode: DomNode - // defaults to "this.domNode" - // targetObj: Widget - // defaults to "this" - if(!baseNode){ baseNode = this.domNode; } - if(!targetObj){ targetObj = this; } - return dojo.widget.attachTemplateNodes(baseNode, targetObj, - dojo.widget.getDojoEventsFromStr(this.templateString)); - }, - - fillInTemplate: function(){ - // summary: - // stub function! sub-classes may use as a default UI - // initializer function. The UI rendering will be available by - // the time this is called from buildRendering. If - // buildRendering is over-ridden, this function may not be - // fired! - - // dojo.unimplemented("dojo.widget.DomWidget.fillInTemplate"); - }, - - // method over-ride - destroyRendering: function(){ - // summary: UI destructor. Destroy the dom nodes associated w/this widget. - try{ - dojo.dom.destroyNode(this.domNode); - delete this.domNode; - }catch(e){ /* squelch! */ } - if(this._sourceNodeRef){ - try{ - dojo.dom.destroyNode(this._sourceNodeRef); - }catch(e){ /* squelch! */ } - } - }, - - createNodesFromText: function(){ - // summary - // Attempts to create a set of nodes based on the structure of the passed text. - // Implemented in HtmlWidget and SvgWidget. - dojo.unimplemented("dojo.widget.DomWidget.createNodesFromText"); - } - } + createNodesFromText: function(){ + // summary + // Attempts to create a set of nodes based on the structure of the passed text. + // Implemented in HtmlWidget and SvgWidget. + dojo.unimplemented("dojo.widget.DomWidget.createNodesFromText"); + } + } ); dojo.provide("dojo.html.util"); dojo.html.getElementWindow = function(/* HTMLElement */element){ - // summary - // Get the window object where the element is placed in. - return dojo.html.getDocumentWindow( element.ownerDocument ); // Window + // summary + // Get the window object where the element is placed in. + return dojo.html.getDocumentWindow( element.ownerDocument ); // Window } dojo.html.getDocumentWindow = function(doc){ - // summary - // Get window object associated with document doc + // summary + // Get window object associated with document doc - // With Safari, there is not wa to retrieve the window from the document, so we must fix it. - if(dojo.render.html.safari && !doc._parentWindow){ - /* - This is a Safari specific function that fix the reference to the parent - window from the document object. - */ + // With Safari, there is not wa to retrieve the window from the document, so we must fix it. + if(dojo.render.html.safari && !doc._parentWindow){ + /* + This is a Safari specific function that fix the reference to the parent + window from the document object. + */ - var fix=function(win){ - win.document._parentWindow=win; - for(var i=0; i - // If you wanted to insert a node into a DOM tree based on the mouse - // position you might use the following code: - //
    -  //  if (gravity(node, e) & gravity.NORTH) { [insert before]; }
    -  //  else { [insert after]; }
    -  //  
    - // - // @param node The node - // @param e The event containing the mouse coordinates - // @return The directions, NORTH or SOUTH and EAST or WEST. These - // are properties of the function. - node = dojo.byId(node); - var mouse = dojo.html.getCursorPosition(e); + // summary + // Calculates the mouse's direction of gravity relative to the centre + // of the given node. + //

    + // If you wanted to insert a node into a DOM tree based on the mouse + // position you might use the following code: + //

    +	//	if (gravity(node, e) & gravity.NORTH) { [insert before]; }
    +	//	else { [insert after]; }
    +	//	
    + // + // @param node The node + // @param e The event containing the mouse coordinates + // @return The directions, NORTH or SOUTH and EAST or WEST. These + // are properties of the function. + node = dojo.byId(node); + var mouse = dojo.html.getCursorPosition(e); - with (dojo.html) { - var absolute = getAbsolutePosition(node, true); - var bb = getBorderBox(node); - var nodecenterx = absolute.x + (bb.width / 2); - var nodecentery = absolute.y + (bb.height / 2); - } + with (dojo.html) { + var absolute = getAbsolutePosition(node, true); + var bb = getBorderBox(node); + var nodecenterx = absolute.x + (bb.width / 2); + var nodecentery = absolute.y + (bb.height / 2); + } - with (dojo.html.gravity) { - return ((mouse.x < nodecenterx ? WEST : EAST) | (mouse.y < nodecentery ? NORTH : SOUTH)); // integer - } + with (dojo.html.gravity) { + return ((mouse.x < nodecenterx ? WEST : EAST) | (mouse.y < nodecentery ? NORTH : SOUTH)); // integer + } } dojo.html.gravity.NORTH = 1; @@ -12951,439 +12961,439 @@ dojo.html.gravity.EAST = 1 << 2; dojo.html.gravity.WEST = 1 << 3; dojo.html.overElement = function(/* HTMLElement */element, /* DOMEvent */e){ - // summary - // Returns whether the mouse is over the passed element. - // Element must be display:block (ie, not a ) - element = dojo.byId(element); - var mouse = dojo.html.getCursorPosition(e); - var bb = dojo.html.getBorderBox(element); - var absolute = dojo.html.getAbsolutePosition(element, true, dojo.html.boxSizing.BORDER_BOX); - var top = absolute.y; - var bottom = top + bb.height; - var left = absolute.x; - var right = left + bb.width; + // summary + // Returns whether the mouse is over the passed element. + // Element must be display:block (ie, not a ) + element = dojo.byId(element); + var mouse = dojo.html.getCursorPosition(e); + var bb = dojo.html.getBorderBox(element); + var absolute = dojo.html.getAbsolutePosition(element, true, dojo.html.boxSizing.BORDER_BOX); + var top = absolute.y; + var bottom = top + bb.height; + var left = absolute.x; + var right = left + bb.width; - return (mouse.x >= left - && mouse.x <= right - && mouse.y >= top - && mouse.y <= bottom - ); // boolean + return (mouse.x >= left + && mouse.x <= right + && mouse.y >= top + && mouse.y <= bottom + ); // boolean } dojo.html.renderedTextContent = function(/* HTMLElement */node){ - // summary - // Attempts to return the text as it would be rendered, with the line breaks - // sorted out nicely. Unfinished. - node = dojo.byId(node); - var result = ""; - if (node == null) { return result; } - for (var i = 0; i < node.childNodes.length; i++) { - switch (node.childNodes[i].nodeType) { - case 1: // ELEMENT_NODE - case 5: // ENTITY_REFERENCE_NODE - var display = "unknown"; - try { - display = dojo.html.getStyle(node.childNodes[i], "display"); - } catch(E) {} - switch (display) { - case "block": case "list-item": case "run-in": - case "table": case "table-row-group": case "table-header-group": - case "table-footer-group": case "table-row": case "table-column-group": - case "table-column": case "table-cell": case "table-caption": - // TODO: this shouldn't insert double spaces on aligning blocks - result += "\n"; - result += dojo.html.renderedTextContent(node.childNodes[i]); - result += "\n"; - break; + // summary + // Attempts to return the text as it would be rendered, with the line breaks + // sorted out nicely. Unfinished. + node = dojo.byId(node); + var result = ""; + if (node == null) { return result; } + for (var i = 0; i < node.childNodes.length; i++) { + switch (node.childNodes[i].nodeType) { + case 1: // ELEMENT_NODE + case 5: // ENTITY_REFERENCE_NODE + var display = "unknown"; + try { + display = dojo.html.getStyle(node.childNodes[i], "display"); + } catch(E) {} + switch (display) { + case "block": case "list-item": case "run-in": + case "table": case "table-row-group": case "table-header-group": + case "table-footer-group": case "table-row": case "table-column-group": + case "table-column": case "table-cell": case "table-caption": + // TODO: this shouldn't insert double spaces on aligning blocks + result += "\n"; + result += dojo.html.renderedTextContent(node.childNodes[i]); + result += "\n"; + break; - case "none": break; + case "none": break; - default: - if(node.childNodes[i].tagName && node.childNodes[i].tagName.toLowerCase() == "br") { - result += "\n"; - } else { - result += dojo.html.renderedTextContent(node.childNodes[i]); - } - break; - } - break; - case 3: // TEXT_NODE - case 2: // ATTRIBUTE_NODE - case 4: // CDATA_SECTION_NODE - var text = node.childNodes[i].nodeValue; - var textTransform = "unknown"; - try { - textTransform = dojo.html.getStyle(node, "text-transform"); - } catch(E) {} - switch (textTransform){ - case "capitalize": - var words = text.split(' '); - for(var i=0; i]/i).test(txt.replace(/^\s+/))) { - txt = "" + txt + "
    "; - tableType = "cell"; - } else if((/^]/i).test(txt.replace(/^\s+/))) { - txt = "" + txt + "
    "; - tableType = "row"; - } else if((/^<(thead|tbody|tfoot)[\s\r\n>]/i).test(txt.replace(/^\s+/))) { - txt = "" + txt + "
    "; - tableType = "section"; - } - tn.innerHTML = txt; - if(tn["normalize"]){ - tn.normalize(); - } + var tn = dojo.doc().createElement("div"); + // tn.style.display = "none"; + tn.style.visibility= "hidden"; + dojo.body().appendChild(tn); + var tableType = "none"; + if((/^]/i).test(txt.replace(/^\s+/))) { + txt = "" + txt + "
    "; + tableType = "cell"; + } else if((/^]/i).test(txt.replace(/^\s+/))) { + txt = "" + txt + "
    "; + tableType = "row"; + } else if((/^<(thead|tbody|tfoot)[\s\r\n>]/i).test(txt.replace(/^\s+/))) { + txt = "" + txt + "
    "; + tableType = "section"; + } + tn.innerHTML = txt; + if(tn["normalize"]){ + tn.normalize(); + } - var parent = null; - switch(tableType) { - case "cell": - parent = tn.getElementsByTagName("tr")[0]; - break; - case "row": - parent = tn.getElementsByTagName("tbody")[0]; - break; - case "section": - parent = tn.getElementsByTagName("table")[0]; - break; - default: - parent = tn; - break; - } + var parent = null; + switch(tableType) { + case "cell": + parent = tn.getElementsByTagName("tr")[0]; + break; + case "row": + parent = tn.getElementsByTagName("tbody")[0]; + break; + case "section": + parent = tn.getElementsByTagName("table")[0]; + break; + default: + parent = tn; + break; + } - /* this doesn't make much sense, I'm assuming it just meant trim() so wrap was replaced with trim - if(wrap){ - var ret = []; - // start hack - var fc = tn.firstChild; - ret[0] = ((fc.nodeValue == " ")||(fc.nodeValue == "\t")) ? fc.nextSibling : fc; - // end hack - // tn.style.display = "none"; - dojo.body().removeChild(tn); - return ret; - } - */ - var nodes = []; - for(var x=0; x view.width) { - x = view.width - w; - match = false; - } else { - x = tryX; - } - x = Math.max(padding[0], x) + scroll.x; + var x = tryX + w; + if(x > view.width) { + x = view.width - w; + match = false; + } else { + x = tryX; + } + x = Math.max(padding[0], x) + scroll.x; - var y = tryY + h; - if(y > view.height) { - y = view.height - h; - match = false; - } else { - y = tryY; - } - y = Math.max(padding[1], y) + scroll.y; + var y = tryY + h; + if(y > view.height) { + y = view.height - h; + match = false; + } else { + y = tryY; + } + y = Math.max(padding[1], y) + scroll.y; - if(match){ //perfect match, return now - bestx = x; - besty = y; - bestDistance = 0; - bestCorner = corner; - break; - }else{ - //not perfect, find out whether it is better than the saved one - var dist = Math.pow(x-tryX-scroll.x,2)+Math.pow(y-tryY-scroll.y,2); - if(bestDistance > dist){ - bestDistance = dist; - bestx = x; - besty = y; - bestCorner = corner; - } - } - } + if(match){ //perfect match, return now + bestx = x; + besty = y; + bestDistance = 0; + bestCorner = corner; + break; + }else{ + //not perfect, find out whether it is better than the saved one + var dist = Math.pow(x-tryX-scroll.x,2)+Math.pow(y-tryY-scroll.y,2); + if(bestDistance > dist){ + bestDistance = dist; + bestx = x; + besty = y; + bestCorner = corner; + } + } + } - if(!tryOnly){ - node.style.left = bestx + "px"; - node.style.top = besty + "px"; - } + if(!tryOnly){ + node.style.left = bestx + "px"; + node.style.top = besty + "px"; + } - return { left: bestx, top: besty, x: bestx, y: besty, dist: bestDistance, corner: bestCorner}; // object + return { left: bestx, top: besty, x: bestx, y: besty, dist: bestDistance, corner: bestCorner}; // object } dojo.html.placeOnScreenPoint = function(node, desiredX, desiredY, padding, hasScroll) { - dojo.deprecated("dojo.html.placeOnScreenPoint", "use dojo.html.placeOnScreen() instead", "0.5"); - return dojo.html.placeOnScreen(node, desiredX, desiredY, padding, hasScroll, ['TL', 'TR', 'BL', 'BR']); + dojo.deprecated("dojo.html.placeOnScreenPoint", "use dojo.html.placeOnScreen() instead", "0.5"); + return dojo.html.placeOnScreen(node, desiredX, desiredY, padding, hasScroll, ['TL', 'TR', 'BL', 'BR']); } dojo.html.placeOnScreenAroundElement = function( - /* HTMLElement */node, - /* HTMLElement */aroundNode, - /* integer */padding, - /* string? */aroundType, - /* string? */aroundCorners, - /* boolean? */tryOnly + /* HTMLElement */node, + /* HTMLElement */aroundNode, + /* integer */padding, + /* string? */aroundType, + /* string? */aroundCorners, + /* boolean? */tryOnly ){ - // summary - // Like placeOnScreen, except it accepts aroundNode instead of x,y - // and attempts to place node around it. aroundType (see - // dojo.html.boxSizing in html/layout.js) determines which box of the - // aroundNode should be used to calculate the outer box. - // aroundCorners specify Which corner of aroundNode should be - // used to place the node => which corner(s) of node to use (see the - // corners parameter in dojo.html.placeOnScreen) - // aroundCorners: {'TL': 'BL', 'BL': 'TL'} + // summary + // Like placeOnScreen, except it accepts aroundNode instead of x,y + // and attempts to place node around it. aroundType (see + // dojo.html.boxSizing in html/layout.js) determines which box of the + // aroundNode should be used to calculate the outer box. + // aroundCorners specify Which corner of aroundNode should be + // used to place the node => which corner(s) of node to use (see the + // corners parameter in dojo.html.placeOnScreen) + // aroundCorners: {'TL': 'BL', 'BL': 'TL'} - var best, bestDistance=Infinity; - aroundNode = dojo.byId(aroundNode); - var oldDisplay = aroundNode.style.display; - aroundNode.style.display=""; - var mb = dojo.html.getElementBox(aroundNode, aroundType); - var aroundNodeW = mb.width; - var aroundNodeH = mb.height; - var aroundNodePos = dojo.html.getAbsolutePosition(aroundNode, true, aroundType); - aroundNode.style.display=oldDisplay; + var best, bestDistance=Infinity; + aroundNode = dojo.byId(aroundNode); + var oldDisplay = aroundNode.style.display; + aroundNode.style.display=""; + var mb = dojo.html.getElementBox(aroundNode, aroundType); + var aroundNodeW = mb.width; + var aroundNodeH = mb.height; + var aroundNodePos = dojo.html.getAbsolutePosition(aroundNode, true, aroundType); + aroundNode.style.display=oldDisplay; - for(var nodeCorner in aroundCorners){ - var pos, desiredX, desiredY; - var corners = aroundCorners[nodeCorner]; + for(var nodeCorner in aroundCorners){ + var pos, desiredX, desiredY; + var corners = aroundCorners[nodeCorner]; - desiredX = aroundNodePos.x + (nodeCorner.charAt(1)=='L' ? 0 : aroundNodeW); - desiredY = aroundNodePos.y + (nodeCorner.charAt(0)=='T' ? 0 : aroundNodeH); + desiredX = aroundNodePos.x + (nodeCorner.charAt(1)=='L' ? 0 : aroundNodeW); + desiredY = aroundNodePos.y + (nodeCorner.charAt(0)=='T' ? 0 : aroundNodeH); - pos = dojo.html.placeOnScreen(node, desiredX, desiredY, padding, true, corners, true); - if(pos.dist == 0){ - best = pos; - break; - }else{ - //not perfect, find out whether it is better than the saved one - if(bestDistance > pos.dist){ - bestDistance = pos.dist; - best = pos; - } - } - } + pos = dojo.html.placeOnScreen(node, desiredX, desiredY, padding, true, corners, true); + if(pos.dist == 0){ + best = pos; + break; + }else{ + //not perfect, find out whether it is better than the saved one + if(bestDistance > pos.dist){ + bestDistance = pos.dist; + best = pos; + } + } + } - if(!tryOnly){ - node.style.left = best.left + "px"; - node.style.top = best.top + "px"; - } - return best; // object + if(!tryOnly){ + node.style.left = best.left + "px"; + node.style.top = best.top + "px"; + } + return best; // object } dojo.html.scrollIntoView = function(/* HTMLElement */node){ - // summary - // Scroll the passed node into view, if it is not. - if(!node){ return; } + // summary + // Scroll the passed node into view, if it is not. + if(!node){ return; } - // don't rely on that node.scrollIntoView works just because the function is there - // it doesnt work in Konqueror or Opera even though the function is there and probably - // not safari either - // dont like browser sniffs implementations but sometimes you have to use it - if(dojo.render.html.ie){ - //only call scrollIntoView if there is a scrollbar for this menu, - //otherwise, scrollIntoView will scroll the window scrollbar - if(dojo.html.getBorderBox(node.parentNode).height <= node.parentNode.scrollHeight){ - node.scrollIntoView(false); - } - }else if(dojo.render.html.mozilla){ - // IE, mozilla - node.scrollIntoView(false); - }else{ - var parent = node.parentNode; - var parentBottom = parent.scrollTop + dojo.html.getBorderBox(parent).height; - var nodeBottom = node.offsetTop + dojo.html.getMarginBox(node).height; - if(parentBottom < nodeBottom){ - parent.scrollTop += (nodeBottom - parentBottom); - }else if(parent.scrollTop > node.offsetTop){ - parent.scrollTop -= (parent.scrollTop - node.offsetTop); - } - } + // don't rely on that node.scrollIntoView works just because the function is there + // it doesnt work in Konqueror or Opera even though the function is there and probably + // not safari either + // dont like browser sniffs implementations but sometimes you have to use it + if(dojo.render.html.ie){ + //only call scrollIntoView if there is a scrollbar for this menu, + //otherwise, scrollIntoView will scroll the window scrollbar + if(dojo.html.getBorderBox(node.parentNode).height <= node.parentNode.scrollHeight){ + node.scrollIntoView(false); + } + }else if(dojo.render.html.mozilla){ + // IE, mozilla + node.scrollIntoView(false); + }else{ + var parent = node.parentNode; + var parentBottom = parent.scrollTop + dojo.html.getBorderBox(parent).height; + var nodeBottom = node.offsetTop + dojo.html.getMarginBox(node).height; + if(parentBottom < nodeBottom){ + parent.scrollTop += (nodeBottom - parentBottom); + }else if(parent.scrollTop > node.offsetTop){ + parent.scrollTop -= (parent.scrollTop - node.offsetTop); + } + } } dojo.provide("dojo.lfx.toggle"); dojo.lfx.toggle.plain = { - show: function(node, duration, easing, callback){ - dojo.html.show(node); - if(dojo.lang.isFunction(callback)){ callback(); } - }, - - hide: function(node, duration, easing, callback){ - dojo.html.hide(node); - if(dojo.lang.isFunction(callback)){ callback(); } - } + show: function(node, duration, easing, callback){ + dojo.html.show(node); + if(dojo.lang.isFunction(callback)){ callback(); } + }, + + hide: function(node, duration, easing, callback){ + dojo.html.hide(node); + if(dojo.lang.isFunction(callback)){ callback(); } + } } dojo.lfx.toggle.fade = { - show: function(node, duration, easing, callback){ - dojo.lfx.fadeShow(node, duration, easing, callback).play(); - }, + show: function(node, duration, easing, callback){ + dojo.lfx.fadeShow(node, duration, easing, callback).play(); + }, - hide: function(node, duration, easing, callback){ - dojo.lfx.fadeHide(node, duration, easing, callback).play(); - } + hide: function(node, duration, easing, callback){ + dojo.lfx.fadeHide(node, duration, easing, callback).play(); + } } dojo.lfx.toggle.wipe = { - show: function(node, duration, easing, callback){ - dojo.lfx.wipeIn(node, duration, easing, callback).play(); - }, + show: function(node, duration, easing, callback){ + dojo.lfx.wipeIn(node, duration, easing, callback).play(); + }, - hide: function(node, duration, easing, callback){ - dojo.lfx.wipeOut(node, duration, easing, callback).play(); - } + hide: function(node, duration, easing, callback){ + dojo.lfx.wipeOut(node, duration, easing, callback).play(); + } } dojo.lfx.toggle.explode = { - show: function(node, duration, easing, callback, explodeSrc){ - dojo.lfx.explode(explodeSrc||{x:0,y:0,width:0,height:0}, node, duration, easing, callback).play(); - }, + show: function(node, duration, easing, callback, explodeSrc){ + dojo.lfx.explode(explodeSrc||{x:0,y:0,width:0,height:0}, node, duration, easing, callback).play(); + }, - hide: function(node, duration, easing, callback, explodeSrc){ - dojo.lfx.implode(node, explodeSrc||{x:0,y:0,width:0,height:0}, duration, easing, callback).play(); - } + hide: function(node, duration, easing, callback, explodeSrc){ + dojo.lfx.implode(node, explodeSrc||{x:0,y:0,width:0,height:0}, duration, easing, callback).play(); + } } dojo.provide("dojo.widget.HtmlWidget"); @@ -13395,197 +13405,197 @@ dojo.provide("dojo.widget.HtmlWidget"); -dojo.declare("dojo.widget.HtmlWidget", dojo.widget.DomWidget, { - // summary - // Base class for all browser based widgets, or at least "html" widgets. - // The meaning of "html" has become unclear; in practice, all widgets derive from this class. +dojo.declare("dojo.widget.HtmlWidget", dojo.widget.DomWidget, { + // summary + // Base class for all browser based widgets, or at least "html" widgets. + // The meaning of "html" has become unclear; in practice, all widgets derive from this class. + + // templateCssPath: String + // Path to CSS file for this widget + templateCssPath: null, + + // templatePath: String + // Path to template (HTML file) for this widget + templatePath: null, - // templateCssPath: String - // Path to CSS file for this widget - templateCssPath: null, + // lang: String + // Language to display this widget in (like en-us). + // Defaults to brower's specified preferred language (typically the language of the OS) + lang: "", - // templatePath: String - // Path to template (HTML file) for this widget - templatePath: null, + // toggle: String + // Controls animation effect for when show() and hide() (or toggle()) are called. + // Possible values: "plain", "wipe", "fade", "explode" + toggle: "plain", - // lang: String - // Language to display this widget in (like en-us). - // Defaults to brower's specified preferred language (typically the language of the OS) - lang: "", + // toggleDuration: Integer + // Number of milliseconds for toggle animation effect to complete + toggleDuration: 150, - // toggle: String - // Controls animation effect for when show() and hide() (or toggle()) are called. - // Possible values: "plain", "wipe", "fade", "explode" - toggle: "plain", + initialize: function(args, frag){ + // summary: called after the widget is rendered; most subclasses won't override or call this function + }, - // toggleDuration: Integer - // Number of milliseconds for toggle animation effect to complete - toggleDuration: 150, + postMixInProperties: function(args, frag){ + if(this.lang === ""){this.lang = null;} + // now that we know the setting for toggle, get toggle object + // (default to plain toggler if user specified toggler not present) + this.toggleObj = + dojo.lfx.toggle[this.toggle.toLowerCase()] || dojo.lfx.toggle.plain; + }, - initialize: function(args, frag){ - // summary: called after the widget is rendered; most subclasses won't override or call this function - }, + createNodesFromText: function(txt, wrap){ + return dojo.html.createNodesFromText(txt, wrap); + }, - postMixInProperties: function(args, frag){ - if(this.lang === ""){this.lang = null;} - // now that we know the setting for toggle, get toggle object - // (default to plain toggler if user specified toggler not present) - this.toggleObj = - dojo.lfx.toggle[this.toggle.toLowerCase()] || dojo.lfx.toggle.plain; - }, + destroyRendering: function(finalize){ + try{ + if(this.bgIframe){ + this.bgIframe.remove(); + delete this.bgIframe; + } + if(!finalize && this.domNode){ + dojo.event.browser.clean(this.domNode); + } + dojo.widget.HtmlWidget.superclass.destroyRendering.call(this); + }catch(e){ /* squelch! */ } + }, - createNodesFromText: function(txt, wrap){ - return dojo.html.createNodesFromText(txt, wrap); - }, + ///////////////////////////////////////////////////////// + // Displaying/hiding the widget + ///////////////////////////////////////////////////////// + isShowing: function(){ + // summary + // Tests whether widget is set to show-mode or hide-mode (see show() and + // hide() methods) + // + // This function is poorly named. Even if widget is in show-mode, + // if it's inside a container that's hidden + // (either a container widget, or just a domnode with display:none), + // then it won't be displayed + return dojo.html.isShowing(this.domNode); // Boolean + }, - destroyRendering: function(finalize){ - try{ - if(this.bgIframe){ - this.bgIframe.remove(); - delete this.bgIframe; - } - if(!finalize && this.domNode){ - dojo.event.browser.clean(this.domNode); - } - dojo.widget.HtmlWidget.superclass.destroyRendering.call(this); - }catch(e){ /* squelch! */ } - }, + toggleShowing: function(){ + // summary: show or hide the widget, to switch it's state + if(this.isShowing()){ + this.hide(); + }else{ + this.show(); + } + }, - ///////////////////////////////////////////////////////// - // Displaying/hiding the widget - ///////////////////////////////////////////////////////// - isShowing: function(){ - // summary - // Tests whether widget is set to show-mode or hide-mode (see show() and - // hide() methods) - // - // This function is poorly named. Even if widget is in show-mode, - // if it's inside a container that's hidden - // (either a container widget, or just a domnode with display:none), - // then it won't be displayed - return dojo.html.isShowing(this.domNode); // Boolean - }, + show: function(){ + // summary: show the widget + if(this.isShowing()){ return; } + this.animationInProgress=true; + this.toggleObj.show(this.domNode, this.toggleDuration, null, + dojo.lang.hitch(this, this.onShow), this.explodeSrc); + }, - toggleShowing: function(){ - // summary: show or hide the widget, to switch it's state - if(this.isShowing()){ - this.hide(); - }else{ - this.show(); - } - }, + onShow: function(){ + // summary: called after the show() animation has completed + this.animationInProgress=false; + this.checkSize(); + }, - show: function(){ - // summary: show the widget - if(this.isShowing()){ return; } - this.animationInProgress=true; - this.toggleObj.show(this.domNode, this.toggleDuration, null, - dojo.lang.hitch(this, this.onShow), this.explodeSrc); - }, + hide: function(){ + // summary: hide the widget (ending up with display:none) + if(!this.isShowing()){ return; } + this.animationInProgress = true; + this.toggleObj.hide(this.domNode, this.toggleDuration, null, + dojo.lang.hitch(this, this.onHide), this.explodeSrc); + }, - onShow: function(){ - // summary: called after the show() animation has completed - this.animationInProgress=false; - this.checkSize(); - }, + onHide: function(){ + // summary: called after the hide() animation has completed + this.animationInProgress=false; + }, - hide: function(){ - // summary: hide the widget (ending up with display:none) - if(!this.isShowing()){ return; } - this.animationInProgress = true; - this.toggleObj.hide(this.domNode, this.toggleDuration, null, - dojo.lang.hitch(this, this.onHide), this.explodeSrc); - }, + ////////////////////////////////////////////////////////////////////////////// + // Sizing related methods + // If the parent changes size then for each child it should call either + // - resizeTo(): size the child explicitly + // - or checkSize(): notify the child the the parent has changed size + ////////////////////////////////////////////////////////////////////////////// - onHide: function(){ - // summary: called after the hide() animation has completed - this.animationInProgress=false; - }, + _isResized: function(w, h){ + // summary + // Test if my size has changed. + // If width & height are specified then that's my new size; otherwise, + // query outerWidth/outerHeight of my domNode - ////////////////////////////////////////////////////////////////////////////// - // Sizing related methods - // If the parent changes size then for each child it should call either - // - resizeTo(): size the child explicitly - // - or checkSize(): notify the child the the parent has changed size - ////////////////////////////////////////////////////////////////////////////// + // If I'm not being displayed then disregard (show() must + // check if the size has changed) + if(!this.isShowing()){ return false; } - _isResized: function(w, h){ - // summary - // Test if my size has changed. - // If width & height are specified then that's my new size; otherwise, - // query outerWidth/outerHeight of my domNode + // If my parent has been resized and I have style="height: 100%" + // or something similar then my size has changed too. + var wh = dojo.html.getMarginBox(this.domNode); + var width=w||wh.width; + var height=h||wh.height; + if(this.width == width && this.height == height){ return false; } - // If I'm not being displayed then disregard (show() must - // check if the size has changed) - if(!this.isShowing()){ return false; } + this.width=width; + this.height=height; + return true; + }, - // If my parent has been resized and I have style="height: 100%" - // or something similar then my size has changed too. - var wh = dojo.html.getMarginBox(this.domNode); - var width=w||wh.width; - var height=h||wh.height; - if(this.width == width && this.height == height){ return false; } + checkSize: function(){ + // summary + // Called when my parent has changed size, but my parent won't call resizeTo(). + // This is useful if my size is height:100% or something similar. + // Also called whenever I am shown, because the first time I am shown I may need + // to do size calculations. + if(!this._isResized()){ return; } + this.onResized(); + }, - this.width=width; - this.height=height; - return true; - }, + resizeTo: function(w, h){ + // summary: explicitly set this widget's size (in pixels). + dojo.html.setMarginBox(this.domNode, { width: w, height: h }); + + // can't do sizing if widget is hidden because referencing node.offsetWidth/node.offsetHeight returns 0. + // do sizing on show() instead. + if(this.isShowing()){ + this.onResized(); + } + }, - checkSize: function(){ - // summary - // Called when my parent has changed size, but my parent won't call resizeTo(). - // This is useful if my size is height:100% or something similar. - // Also called whenever I am shown, because the first time I am shown I may need - // to do size calculations. - if(!this._isResized()){ return; } - this.onResized(); - }, + resizeSoon: function(){ + // summary + // schedule onResized() to be called soon, after browser has had + // a little more time to calculate the sizes + if(this.isShowing()){ + dojo.lang.setTimeout(this, this.onResized, 0); + } + }, - resizeTo: function(w, h){ - // summary: explicitly set this widget's size (in pixels). - dojo.html.setMarginBox(this.domNode, { width: w, height: h }); - - // can't do sizing if widget is hidden because referencing node.offsetWidth/node.offsetHeight returns 0. - // do sizing on show() instead. - if(this.isShowing()){ - this.onResized(); - } - }, - - resizeSoon: function(){ - // summary - // schedule onResized() to be called soon, after browser has had - // a little more time to calculate the sizes - if(this.isShowing()){ - dojo.lang.setTimeout(this, this.onResized, 0); - } - }, - - onResized: function(){ - // summary - // Called when my size has changed. - // Must notify children if their size has (possibly) changed. - dojo.lang.forEach(this.children, function(child){ if(child.checkSize){child.checkSize();} }); - } + onResized: function(){ + // summary + // Called when my size has changed. + // Must notify children if their size has (possibly) changed. + dojo.lang.forEach(this.children, function(child){ if(child.checkSize){child.checkSize();} }); + } }); dojo.kwCompoundRequire({ - common: ["dojo.xml.Parse", - "dojo.widget.Widget", - "dojo.widget.Parse", - "dojo.widget.Manager"], - browser: ["dojo.widget.DomWidget", - "dojo.widget.HtmlWidget"], - dashboard: ["dojo.widget.DomWidget", - "dojo.widget.HtmlWidget"], - svg: ["dojo.widget.SvgWidget"], - rhino: ["dojo.widget.SwtWidget"] + common: ["dojo.xml.Parse", + "dojo.widget.Widget", + "dojo.widget.Parse", + "dojo.widget.Manager"], + browser: ["dojo.widget.DomWidget", + "dojo.widget.HtmlWidget"], + dashboard: ["dojo.widget.DomWidget", + "dojo.widget.HtmlWidget"], + svg: ["dojo.widget.SvgWidget"], + rhino: ["dojo.widget.SwtWidget"] }); dojo.provide("dojo.widget.*"); dojo.kwCompoundRequire({ - common: [ "dojo.html.common", - "dojo.html.style" ] + common: [ "dojo.html.common", + "dojo.html.style" ] }); dojo.provide("dojo.html.*"); @@ -13599,665 +13609,665 @@ dojo.provide("dojo.html.selection"); * type of selection **/ dojo.html.selectionType = { - NONE : 0, //selection is empty - TEXT : 1, //selection contains text (may also contains CONTROL objects) - CONTROL : 2 //only one element is selected (such as img, table etc) + NONE : 0, //selection is empty + TEXT : 1, //selection contains text (may also contains CONTROL objects) + CONTROL : 2 //only one element is selected (such as img, table etc) }; dojo.html.clearSelection = function(){ - // summary: deselect the current selection to make it empty - var _window = dojo.global(); - var _document = dojo.doc(); - try{ - if(_window["getSelection"]){ - if(dojo.render.html.safari){ - // pulled from WebCore/ecma/kjs_window.cpp, line 2536 - _window.getSelection().collapse(); - }else{ - _window.getSelection().removeAllRanges(); - } - }else if(_document.selection){ - if(_document.selection.empty){ - _document.selection.empty(); - }else if(_document.selection.clear){ - _document.selection.clear(); - } - } - return true; - }catch(e){ - dojo.debug(e); - return false; - } + // summary: deselect the current selection to make it empty + var _window = dojo.global(); + var _document = dojo.doc(); + try{ + if(_window["getSelection"]){ + if(dojo.render.html.safari){ + // pulled from WebCore/ecma/kjs_window.cpp, line 2536 + _window.getSelection().collapse(); + }else{ + _window.getSelection().removeAllRanges(); + } + }else if(_document.selection){ + if(_document.selection.empty){ + _document.selection.empty(); + }else if(_document.selection.clear){ + _document.selection.clear(); + } + } + return true; + }catch(e){ + dojo.debug(e); + return false; + } } dojo.html.disableSelection = function(/*DomNode*/element){ - // summary: disable selection on a node - element = dojo.byId(element)||dojo.body(); - var h = dojo.render.html; - - if(h.mozilla){ - element.style.MozUserSelect = "none"; - }else if(h.safari){ - element.style.KhtmlUserSelect = "none"; - }else if(h.ie){ - element.unselectable = "on"; - }else{ - return false; - } - return true; + // summary: disable selection on a node + element = dojo.byId(element)||dojo.body(); + var h = dojo.render.html; + + if(h.mozilla){ + element.style.MozUserSelect = "none"; + }else if(h.safari){ + element.style.KhtmlUserSelect = "none"; + }else if(h.ie){ + element.unselectable = "on"; + }else{ + return false; + } + return true; } dojo.html.enableSelection = function(/*DomNode*/element){ - // summary: enable selection on a node - element = dojo.byId(element)||dojo.body(); - - var h = dojo.render.html; - if(h.mozilla){ - element.style.MozUserSelect = ""; - }else if(h.safari){ - element.style.KhtmlUserSelect = ""; - }else if(h.ie){ - element.unselectable = "off"; - }else{ - return false; - } - return true; + // summary: enable selection on a node + element = dojo.byId(element)||dojo.body(); + + var h = dojo.render.html; + if(h.mozilla){ + element.style.MozUserSelect = ""; + }else if(h.safari){ + element.style.KhtmlUserSelect = ""; + }else if(h.ie){ + element.unselectable = "off"; + }else{ + return false; + } + return true; } dojo.html.selectElement = function(/*DomNode*/element){ - dojo.deprecated("dojo.html.selectElement", "replaced by dojo.html.selection.selectElementChildren", 0.5); + dojo.deprecated("dojo.html.selectElement", "replaced by dojo.html.selection.selectElementChildren", 0.5); } dojo.html.selectInputText = function(/*DomNode*/element){ - // summary: select all the text in an input element - var _window = dojo.global(); - var _document = dojo.doc(); - element = dojo.byId(element); - if(_document["selection"] && dojo.body()["createTextRange"]){ // IE - var range = element.createTextRange(); - range.moveStart("character", 0); - range.moveEnd("character", element.value.length); - range.select(); - }else if(_window["getSelection"]){ - var selection = _window.getSelection(); - // FIXME: does this work on Safari? - element.setSelectionRange(0, element.value.length); - } - element.focus(); + // summary: select all the text in an input element + var _window = dojo.global(); + var _document = dojo.doc(); + element = dojo.byId(element); + if(_document["selection"] && dojo.body()["createTextRange"]){ // IE + var range = element.createTextRange(); + range.moveStart("character", 0); + range.moveEnd("character", element.value.length); + range.select(); + }else if(_window["getSelection"]){ + var selection = _window.getSelection(); + // FIXME: does this work on Safari? + element.setSelectionRange(0, element.value.length); + } + element.focus(); } dojo.html.isSelectionCollapsed = function(){ - dojo.deprecated("dojo.html.isSelectionCollapsed", "replaced by dojo.html.selection.isCollapsed", 0.5); - return dojo.html.selection.isCollapsed(); + dojo.deprecated("dojo.html.isSelectionCollapsed", "replaced by dojo.html.selection.isCollapsed", 0.5); + return dojo.html.selection.isCollapsed(); } dojo.lang.mixin(dojo.html.selection, { - getType: function() { - // summary: Get the selection type (like document.select.type in IE). - if(dojo.doc()["selection"]){ //IE - return dojo.html.selectionType[dojo.doc().selection.type.toUpperCase()]; - }else{ - var stype = dojo.html.selectionType.TEXT; + getType: function() { + // summary: Get the selection type (like document.select.type in IE). + if(dojo.doc()["selection"]){ //IE + return dojo.html.selectionType[dojo.doc().selection.type.toUpperCase()]; + }else{ + var stype = dojo.html.selectionType.TEXT; + + // Check if the actual selection is a CONTROL (IMG, TABLE, HR, etc...). + var oSel; + try {oSel = dojo.global().getSelection();} + catch (e) {} + + if(oSel && oSel.rangeCount==1){ + var oRange = oSel.getRangeAt(0); + if (oRange.startContainer == oRange.endContainer && (oRange.endOffset - oRange.startOffset) == 1 + && oRange.startContainer.nodeType != dojo.dom.TEXT_NODE) { + stype = dojo.html.selectionType.CONTROL; + } + } + return stype; + } + }, + isCollapsed: function() { + // summary: return whether the current selection is empty + var _window = dojo.global(); + var _document = dojo.doc(); + if(_document["selection"]){ // IE + return _document.selection.createRange().text == ""; + }else if(_window["getSelection"]){ + var selection = _window.getSelection(); + if(dojo.lang.isString(selection)){ // Safari + return selection == ""; + }else{ // Mozilla/W3 + return selection.isCollapsed || selection.toString() == ""; + } + } + }, + getSelectedElement: function() { + // summary: + // Retrieves the selected element (if any), just in the case that a single + // element (object like and image or a table) is selected. + if ( dojo.html.selection.getType() == dojo.html.selectionType.CONTROL ){ + if(dojo.doc()["selection"]){ //IE + var range = dojo.doc().selection.createRange(); + + if ( range && range.item ){ + return dojo.doc().selection.createRange().item(0); + } + }else{ + var selection = dojo.global().getSelection(); + return selection.anchorNode.childNodes[ selection.anchorOffset ]; + } + } + }, + getParentElement: function() { + // summary: + // Get the parent element of the current selection + if(dojo.html.selection.getType() == dojo.html.selectionType.CONTROL){ + var p = dojo.html.selection.getSelectedElement(); + if(p){ return p.parentNode; } + }else{ + if(dojo.doc()["selection"]){ //IE + return dojo.doc().selection.createRange().parentElement(); + }else{ + var selection = dojo.global().getSelection(); + if(selection){ + var node = selection.anchorNode; + + while ( node && node.nodeType != dojo.dom.ELEMENT_NODE ){ + node = node.parentNode; + } + + return node; + } + } + } + }, + getSelectedText: function(){ + // summary: + // Return the text (no html tags) included in the current selection or null if no text is selected + if(dojo.doc()["selection"]){ //IE + if(dojo.html.selection.getType() == dojo.html.selectionType.CONTROL){ + return null; + } + return dojo.doc().selection.createRange().text; + }else{ + var selection = dojo.global().getSelection(); + if(selection){ + return selection.toString(); + } + } + }, + getSelectedHtml: function(){ + // summary: + // Return the html of the current selection or null if unavailable + if(dojo.doc()["selection"]){ //IE + if(dojo.html.selection.getType() == dojo.html.selectionType.CONTROL){ + return null; + } + return dojo.doc().selection.createRange().htmlText; + }else{ + var selection = dojo.global().getSelection(); + if(selection && selection.rangeCount){ + var frag = selection.getRangeAt(0).cloneContents(); + var div = document.createElement("div"); + div.appendChild(frag); + return div.innerHTML; + } + return null; + } + }, + hasAncestorElement: function(/*String*/tagName /* ... */){ + // summary: + // Check whether current selection has a parent element which is of type tagName (or one of the other specified tagName) + return (dojo.html.selection.getAncestorElement.apply(this, arguments) != null); + }, + getAncestorElement: function(/*String*/tagName /* ... */){ + // summary: + // Return the parent element of the current selection which is of type tagName (or one of the other specified tagName) + var node = dojo.html.selection.getSelectedElement() || dojo.html.selection.getParentElement(); + while(node /*&& node.tagName.toLowerCase() != 'body'*/){ + if(dojo.html.selection.isTag(node, arguments).length>0){ + return node; + } + node = node.parentNode; + } + return null; + }, + //modified from dojo.html.isTag to take an array as second parameter + isTag: function(/*DomNode*/node, /*Array*/tags) { + if(node && node.tagName) { + for (var i=0; i0){ - return node; - } - node = node.parentNode; - } - return null; - }, - //modified from dojo.html.isTag to take an array as second parameter - isTag: function(/*DomNode*/node, /*Array*/tags) { - if(node && node.tagName) { - for (var i=0; i. + Encapsulates a sequence of callbacks in response to a value that + may not yet be available. This is modeled after the Deferred class + from Twisted . - Why do we want this? JavaScript has no threads, and even if it did, - threads are hard. Deferreds are a way of abstracting non-blocking - events, such as the final response to an XMLHttpRequest. + Why do we want this? JavaScript has no threads, and even if it did, + threads are hard. Deferreds are a way of abstracting non-blocking + events, such as the final response to an XMLHttpRequest. - The sequence of callbacks is internally represented as a list - of 2-tuples containing the callback/errback pair. For example, - the following call sequence:: + The sequence of callbacks is internally represented as a list + of 2-tuples containing the callback/errback pair. For example, + the following call sequence:: - var d = new Deferred(); - d.addCallback(myCallback); - d.addErrback(myErrback); - d.addBoth(myBoth); - d.addCallbacks(myCallback, myErrback); + var d = new Deferred(); + d.addCallback(myCallback); + d.addErrback(myErrback); + d.addBoth(myBoth); + d.addCallbacks(myCallback, myErrback); - is translated into a Deferred with the following internal - representation:: + is translated into a Deferred with the following internal + representation:: - [ - [myCallback, null], - [null, myErrback], - [myBoth, myBoth], - [myCallback, myErrback] - ] + [ + [myCallback, null], + [null, myErrback], + [myBoth, myBoth], + [myCallback, myErrback] + ] - The Deferred also keeps track of its current status (fired). - Its status may be one of three things: + The Deferred also keeps track of its current status (fired). + Its status may be one of three things: - -1: no value yet (initial condition) - 0: success - 1: error + -1: no value yet (initial condition) + 0: success + 1: error - A Deferred will be in the error state if one of the following - three conditions are met: + A Deferred will be in the error state if one of the following + three conditions are met: - 1. The result given to callback or errback is "instanceof" Error - 2. The previous callback or errback raised an exception while - executing - 3. The previous callback or errback returned a value "instanceof" - Error + 1. The result given to callback or errback is "instanceof" Error + 2. The previous callback or errback raised an exception while + executing + 3. The previous callback or errback returned a value "instanceof" + Error - Otherwise, the Deferred will be in the success state. The state of - the Deferred determines the next element in the callback sequence to - run. + Otherwise, the Deferred will be in the success state. The state of + the Deferred determines the next element in the callback sequence to + run. - When a callback or errback occurs with the example deferred chain, - something equivalent to the following will happen (imagine that - exceptions are caught and returned):: + When a callback or errback occurs with the example deferred chain, + something equivalent to the following will happen (imagine that + exceptions are caught and returned):: - // d.callback(result) or d.errback(result) - if(!(result instanceof Error)){ - result = myCallback(result); - } - if(result instanceof Error){ - result = myErrback(result); - } - result = myBoth(result); - if(result instanceof Error){ - result = myErrback(result); - }else{ - result = myCallback(result); - } + // d.callback(result) or d.errback(result) + if(!(result instanceof Error)){ + result = myCallback(result); + } + if(result instanceof Error){ + result = myErrback(result); + } + result = myBoth(result); + if(result instanceof Error){ + result = myErrback(result); + }else{ + result = myCallback(result); + } - The result is then stored away in case another step is added to the - callback sequence. Since the Deferred already has a value available, - any new callbacks added will be called immediately. + The result is then stored away in case another step is added to the + callback sequence. Since the Deferred already has a value available, + any new callbacks added will be called immediately. - There are two other "advanced" details about this implementation that - are useful: + There are two other "advanced" details about this implementation that + are useful: - Callbacks are allowed to return Deferred instances themselves, so you - can build complicated sequences of events with ease. + Callbacks are allowed to return Deferred instances themselves, so you + can build complicated sequences of events with ease. - The creator of the Deferred may specify a canceller. The canceller - is a function that will be called if Deferred.cancel is called before - the Deferred fires. You can use this to implement clean aborting of - an XMLHttpRequest, etc. Note that cancel will fire the deferred with - a CancelledError (unless your canceller returns another kind of - error), so the errbacks should be prepared to handle that error for - cancellable Deferreds. + The creator of the Deferred may specify a canceller. The canceller + is a function that will be called if Deferred.cancel is called before + the Deferred fires. You can use this to implement clean aborting of + an XMLHttpRequest, etc. Note that cancel will fire the deferred with + a CancelledError (unless your canceller returns another kind of + error), so the errbacks should be prepared to handle that error for + cancellable Deferreds. - */ - - this.chain = []; - this.id = this._nextId(); - this.fired = -1; - this.paused = 0; - this.results = [null, null]; - this.canceller = canceller; - this.silentlyCancelled = false; + */ + + this.chain = []; + this.id = this._nextId(); + this.fired = -1; + this.paused = 0; + this.results = [null, null]; + this.canceller = canceller; + this.silentlyCancelled = false; }; dojo.lang.extend(dojo.Deferred, { - getFunctionFromArgs: function(){ - var a = arguments; - if((a[0])&&(!a[1])){ - if(dojo.lang.isFunction(a[0])){ - return a[0]; - }else if(dojo.lang.isString(a[0])){ - return dj_global[a[0]]; - } - }else if((a[0])&&(a[1])){ - return dojo.lang.hitch(a[0], a[1]); - } - return null; - }, + getFunctionFromArgs: function(){ + var a = arguments; + if((a[0])&&(!a[1])){ + if(dojo.lang.isFunction(a[0])){ + return a[0]; + }else if(dojo.lang.isString(a[0])){ + return dj_global[a[0]]; + } + }else if((a[0])&&(a[1])){ + return dojo.lang.hitch(a[0], a[1]); + } + return null; + }, - makeCalled: function() { - var deferred = new dojo.Deferred(); - deferred.callback(); - return deferred; - }, + makeCalled: function() { + var deferred = new dojo.Deferred(); + deferred.callback(); + return deferred; + }, - repr: function(){ - var state; - if(this.fired == -1){ - state = 'unfired'; - }else if(this.fired == 0){ - state = 'success'; - } else { - state = 'error'; - } - return 'Deferred(' + this.id + ', ' + state + ')'; - }, + repr: function(){ + var state; + if(this.fired == -1){ + state = 'unfired'; + }else if(this.fired == 0){ + state = 'success'; + } else { + state = 'error'; + } + return 'Deferred(' + this.id + ', ' + state + ')'; + }, - toString: dojo.lang.forward("repr"), + toString: dojo.lang.forward("repr"), - _nextId: (function(){ - var n = 1; - return function(){ return n++; }; - })(), + _nextId: (function(){ + var n = 1; + return function(){ return n++; }; + })(), - cancel: function(){ - // summary: Cancels a Deferred that has not yet received a value, or is - // waiting on another Deferred as its value. - // description: - // If a canceller is defined, the canceller is called. If the - // canceller did not return an error, or there was no canceller, - // then the errback chain is started with CancelledError. - if(this.fired == -1){ - if (this.canceller){ - this.canceller(this); - }else{ - this.silentlyCancelled = true; - } - if(this.fired == -1){ - this.errback(new Error(this.repr())); - } - }else if( (this.fired == 0)&& - (this.results[0] instanceof dojo.Deferred)){ - this.results[0].cancel(); - } - }, + cancel: function(){ + // summary: Cancels a Deferred that has not yet received a value, or is + // waiting on another Deferred as its value. + // description: + // If a canceller is defined, the canceller is called. If the + // canceller did not return an error, or there was no canceller, + // then the errback chain is started with CancelledError. + if(this.fired == -1){ + if (this.canceller){ + this.canceller(this); + }else{ + this.silentlyCancelled = true; + } + if(this.fired == -1){ + this.errback(new Error(this.repr())); + } + }else if( (this.fired == 0)&& + (this.results[0] instanceof dojo.Deferred)){ + this.results[0].cancel(); + } + }, + + _pause: function(){ + // summary: Used internally to signal that it's waiting on another Deferred + this.paused++; + }, - _pause: function(){ - // summary: Used internally to signal that it's waiting on another Deferred - this.paused++; - }, + _unpause: function(){ + // summary: Used internally to signal that it's no longer waiting on + // another Deferred. + this.paused--; + if ((this.paused == 0) && (this.fired >= 0)) { + this._fire(); + } + }, - _unpause: function(){ - // summary: Used internally to signal that it's no longer waiting on - // another Deferred. - this.paused--; - if ((this.paused == 0) && (this.fired >= 0)) { - this._fire(); - } - }, + _continue: function(res){ + // summary: Used internally when a dependent deferred fires. + this._resback(res); + this._unpause(); + }, - _continue: function(res){ - // summary: Used internally when a dependent deferred fires. - this._resback(res); - this._unpause(); - }, + _resback: function(res){ + // The primitive that means either callback or errback + this.fired = ((res instanceof Error) ? 1 : 0); + this.results[this.fired] = res; + this._fire(); + }, - _resback: function(res){ - // The primitive that means either callback or errback - this.fired = ((res instanceof Error) ? 1 : 0); - this.results[this.fired] = res; - this._fire(); - }, + _check: function(){ + if(this.fired != -1){ + if(!this.silentlyCancelled){ + dojo.raise("already called!"); + } + this.silentlyCancelled = false; + return; + } + }, - _check: function(){ - if(this.fired != -1){ - if(!this.silentlyCancelled){ - dojo.raise("already called!"); - } - this.silentlyCancelled = false; - return; - } - }, + callback: function(res){ + // summary: Begin the callback sequence with a non-error value. + + /* + callback or errback should only be called once on a given + Deferred. + */ + this._check(); + this._resback(res); + }, - callback: function(res){ - // summary: Begin the callback sequence with a non-error value. + errback: function(res){ + // summary: Begin the callback sequence with an error result. + this._check(); + if(!(res instanceof Error)){ + res = new Error(res); + } + this._resback(res); + }, - /* - callback or errback should only be called once on a given - Deferred. - */ - this._check(); - this._resback(res); - }, + addBoth: function(cb, cbfn){ + /* summary + Add the same function as both a callback and an errback as the + next element on the callback sequence. This is useful for code + that you want to guarantee to run, e.g. a finalizer. + */ + var enclosed = this.getFunctionFromArgs(cb, cbfn); + if(arguments.length > 2){ + enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2); + } + return this.addCallbacks(enclosed, enclosed); + }, - errback: function(res){ - // summary: Begin the callback sequence with an error result. - this._check(); - if(!(res instanceof Error)){ - res = new Error(res); - } - this._resback(res); - }, + addCallback: function(cb, cbfn){ + // summary: Add a single callback to the end of the callback sequence. + var enclosed = this.getFunctionFromArgs(cb, cbfn); + if(arguments.length > 2){ + enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2); + } + return this.addCallbacks(enclosed, null); + }, - addBoth: function(cb, cbfn){ - /* summary - Add the same function as both a callback and an errback as the - next element on the callback sequence. This is useful for code - that you want to guarantee to run, e.g. a finalizer. - */ - var enclosed = this.getFunctionFromArgs(cb, cbfn); - if(arguments.length > 2){ - enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2); - } - return this.addCallbacks(enclosed, enclosed); - }, + addErrback: function(cb, cbfn){ + // summary: Add a single callback to the end of the callback sequence. + var enclosed = this.getFunctionFromArgs(cb, cbfn); + if(arguments.length > 2){ + enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2); + } + return this.addCallbacks(null, enclosed); + return this.addCallbacks(null, cbfn); + }, - addCallback: function(cb, cbfn){ - // summary: Add a single callback to the end of the callback sequence. - var enclosed = this.getFunctionFromArgs(cb, cbfn); - if(arguments.length > 2){ - enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2); - } - return this.addCallbacks(enclosed, null); - }, + addCallbacks: function (cb, eb) { + // summary: Add separate callback and errback to the end of the callback + // sequence. + this.chain.push([cb, eb]) + if (this.fired >= 0) { + this._fire(); + } + return this; + }, - addErrback: function(cb, cbfn){ - // summary: Add a single callback to the end of the callback sequence. - var enclosed = this.getFunctionFromArgs(cb, cbfn); - if(arguments.length > 2){ - enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2); - } - return this.addCallbacks(null, enclosed); - return this.addCallbacks(null, cbfn); - }, - - addCallbacks: function (cb, eb) { - // summary: Add separate callback and errback to the end of the callback - // sequence. - this.chain.push([cb, eb]) - if (this.fired >= 0) { - this._fire(); - } - return this; - }, - - _fire: function(){ - // summary: Used internally to exhaust the callback sequence when a result - // is available. - var chain = this.chain; - var fired = this.fired; - var res = this.results[fired]; - var self = this; - var cb = null; - while (chain.length > 0 && this.paused == 0) { - // Array - var pair = chain.shift(); - var f = pair[fired]; - if (f == null) { - continue; - } - try { - res = f(res); - fired = ((res instanceof Error) ? 1 : 0); - if(res instanceof dojo.Deferred) { - cb = function(res){ - self._continue(res); - } - this._pause(); - } - }catch(err){ - fired = 1; - res = err; - } - } - this.fired = fired; - this.results[fired] = res; - if((cb)&&(this.paused)){ - // this is for "tail recursion" in case the dependent - // deferred is already fired - res.addBoth(cb); - } - } + _fire: function(){ + // summary: Used internally to exhaust the callback sequence when a result + // is available. + var chain = this.chain; + var fired = this.fired; + var res = this.results[fired]; + var self = this; + var cb = null; + while (chain.length > 0 && this.paused == 0) { + // Array + var pair = chain.shift(); + var f = pair[fired]; + if (f == null) { + continue; + } + try { + res = f(res); + fired = ((res instanceof Error) ? 1 : 0); + if(res instanceof dojo.Deferred) { + cb = function(res){ + self._continue(res); + } + this._pause(); + } + }catch(err){ + fired = 1; + res = err; + } + } + this.fired = fired; + this.results[fired] = res; + if((cb)&&(this.paused)){ + // this is for "tail recursion" in case the dependent + // deferred is already fired + res.addBoth(cb); + } + } }); /* -*- tab-width: 4 -*- */ @@ -14278,1992 +14288,1992 @@ dojo.provide("dojo.widget.RichText"); // file. If it is included in dojo.js and you want to allow rich text saving // for back/forward actions, then set djConfig.allowXdRichTextSave = true. if(!djConfig["useXDomain"] || djConfig["allowXdRichTextSave"]){ - if(dojo.hostenv.post_load_){ - (function(){ - var savetextarea = dojo.doc().createElement('textarea'); - savetextarea.id = "dojo.widget.RichText.savedContent"; - savetextarea.style = "display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"; - dojo.body().appendChild(savetextarea); - })(); - }else{ - //dojo.body() is not available before onLoad is fired - try { - dojo.doc().write(''); - }catch(e){ } - } + if(dojo.hostenv.post_load_){ + (function(){ + var savetextarea = dojo.doc().createElement('textarea'); + savetextarea.id = "dojo.widget.RichText.savedContent"; + savetextarea.style = "display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"; + dojo.body().appendChild(savetextarea); + })(); + }else{ + //dojo.body() is not available before onLoad is fired + try { + dojo.doc().write(''); + }catch(e){ } + } } dojo.widget.defineWidget( - "dojo.widget.RichText", - dojo.widget.HtmlWidget, - function(){ - // summary: - // dojo.widget.RichText is the core of the WYSIWYG editor in dojo, which - // provides the basic editing features. It also encapsulates the differences - // of different js engines for various browsers - - // contentPreFilters: Array - // pre content filter function register array - this.contentPreFilters = []; - - // contentPostFilters: Array - // post content filter function register array - this.contentPostFilters = []; - - // contentDomPreFilters: Array - // pre content dom filter function register array - this.contentDomPreFilters = []; - - // contentDomPostFilters: Array - // post content dom filter function register array - this.contentDomPostFilters = []; - - // editingAreaStyleSheets: Array - // array to store all the stylesheets applied to the editing area - this.editingAreaStyleSheets=[]; - - if(dojo.render.html.moz){ - this.contentPreFilters.push(this._fixContentForMoz); - } - - this._keyHandlers = {}; - - if(dojo.Deferred){ - this.onLoadDeferred = new dojo.Deferred(); - } - }, - { - // inheritWidth: Boolean - // whether to inherit the parent's width or simply use 100% - inheritWidth: false, - - // focusOnLoad: Boolean - // whether focusing into this instance of richtext when page onload - focusOnLoad: false, - - // saveName: String - // If a save name is specified the content is saved and restored when the user - // leave this page can come back, or if the editor is not properly closed after - // editing has started. - saveName: "", - - // styleSheets: String - // semicolon (";") separated list of css files for the editing area - styleSheets: "", - - // _content: String - // temporary content storage - _content: "", - - // height: String - // set height to fix the editor at a specific height, with scrolling - height: "", - - // minHeight: String - // The minimum height that the editor should have - minHeight: "1em", - - // isClosed: Boolean - isClosed: true, - - // isLoaded: Boolean - isLoaded: false, - - // useActiveX: Boolean - // whether to use the active-x object in IE - useActiveX: false, - - // relativeImageUrls: Boolean - // whether to use relative URLs for images - if this is enabled - // images will be given absolute URLs when inside the editor but - // will be changed to use relative URLs (to the current page) on save - relativeImageUrls: false, - - // _SEPARATOR: String - // used to concat contents from multiple textareas into a single string - _SEPARATOR: "@@**%%__RICHTEXTBOUNDRY__%%**@@", - - // onLoadDeferred: dojo.Deferred - // deferred that can be used to connect to the onLoad function. This - // will only be set if dojo.Deferred is required - onLoadDeferred: null, - - /* Init - *******/ - - fillInTemplate: function(){ - // summary: see dojo.widget.DomWidget - dojo.event.topic.publish("dojo.widget.RichText::init", this); - this.open(); - - - // backwards compatibility, needs to be removed - dojo.event.connect(this, "onKeyPressed", this, "afterKeyPress"); - dojo.event.connect(this, "onKeyPress", this, "keyPress"); - dojo.event.connect(this, "onKeyDown", this, "keyDown"); - dojo.event.connect(this, "onKeyUp", this, "keyUp"); - - this.setupDefaultShortcuts(); - }, - - setupDefaultShortcuts: function(){ - // summary: add some default key handlers - // description: - // Overwrite this to setup your own handlers. The default - // implementation does not use Editor2 commands, but directly - // executes the builtin commands within the underlying browser - // support. - var ctrl = this.KEY_CTRL; - var exec = function (cmd, arg) { - return arguments.length == 1 ? function () { this.execCommand(cmd); } : - function () { this.execCommand(cmd, arg); } - } - this.addKeyHandler("b", ctrl, exec("bold")); - this.addKeyHandler("i", ctrl, exec("italic")); - this.addKeyHandler("u", ctrl, exec("underline")); - this.addKeyHandler("a", ctrl, exec("selectall")); - this.addKeyHandler("s", ctrl, function () { this.save(true); }); - - this.addKeyHandler("1", ctrl, exec("formatblock", "h1")); - this.addKeyHandler("2", ctrl, exec("formatblock", "h2")); - this.addKeyHandler("3", ctrl, exec("formatblock", "h3")); - this.addKeyHandler("4", ctrl, exec("formatblock", "h4")); - - this.addKeyHandler("\\", ctrl, exec("insertunorderedlist")); - if(!dojo.render.html.ie){ - this.addKeyHandler("Z", ctrl, exec("redo")); - } - }, - - // events: Array - // events which should be connected to the underlying editing area - events: ["onBlur", "onFocus", "onKeyPress", "onKeyDown", "onKeyUp", "onClick"], - - /** - * Transforms the node referenced in this.domNode into a rich text editing - * node. This can result in the creation and replacement with an