diff options
-rw-r--r-- | .gitattributes | 2 | ||||
-rw-r--r-- | framework/Web/Javascripts/js/ajax.js | 709 | ||||
-rw-r--r-- | framework/Web/Javascripts/js/clientscripts.php | 53 | ||||
-rw-r--r-- | framework/Web/UI/TClientScriptManager.php | 61 | ||||
-rw-r--r-- | framework/Web/UI/WebControls/TLabel.php | 10 | ||||
-rw-r--r-- | tests/FunctionalTests/protected/pages/Layout.tpl | 2 | ||||
-rw-r--r-- | tests/FunctionalTests/protected/pages/ViewSource.page | 7 | ||||
-rw-r--r-- | tests/FunctionalTests/protected/pages/ViewSource.php | 79 |
8 files changed, 917 insertions, 6 deletions
diff --git a/.gitattributes b/.gitattributes index 47600178..0a84c9c6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -475,7 +475,9 @@ framework/Web/Javascripts/extra/behaviour.js -text framework/Web/Javascripts/extra/getElementsBySelector.js -text framework/Web/Javascripts/extra/logger.js -text framework/Web/Javascripts/extra/tp_template.js -text +framework/Web/Javascripts/js/ajax.js -text framework/Web/Javascripts/js/base.js -text +framework/Web/Javascripts/js/clientscripts.php -text framework/Web/Javascripts/js/dom.js -text framework/Web/Javascripts/js/logger.js -text framework/Web/Javascripts/js/validator.js -text diff --git a/framework/Web/Javascripts/js/ajax.js b/framework/Web/Javascripts/js/ajax.js new file mode 100644 index 00000000..c4a56254 --- /dev/null +++ b/framework/Web/Javascripts/js/ajax.js @@ -0,0 +1,709 @@ +var Ajax={getTransport:function(){ +return Try.these(function(){ +return new ActiveXObject("Msxml2.XMLHTTP"); +},function(){ +return new ActiveXObject("Microsoft.XMLHTTP"); +},function(){ +return new XMLHttpRequest(); +})||false; +},activeRequestCount:0}; +Ajax.Responders={responders:[],_each:function(_1){ +this.responders._each(_1); +},register:function(_2){ +if(!this.include(_2)){ +this.responders.push(_2); +} +},unregister:function(_3){ +this.responders=this.responders.without(_3); +},dispatch:function(_4,_5,_6,_7){ +this.each(function(_8){ +if(_8[_4]&&typeof _8[_4]=="function"){ +try{ +_8[_4].apply(_8,[_5,_6,_7]); +} +catch(e){ +} +} +}); +}}; +Object.extend(Ajax.Responders,Enumerable); +Ajax.Responders.register({onCreate:function(){ +Ajax.activeRequestCount++; +},onComplete:function(){ +Ajax.activeRequestCount--; +}}); +Ajax.Base=function(){ +}; +Ajax.Base.prototype={setOptions:function(_9){ +this.options={method:"post",asynchronous:true,parameters:""}; +Object.extend(this.options,_9||{}); +},responseIsSuccess:function(){ +return this.transport.status==undefined||this.transport.status==0||(this.transport.status>=200&&this.transport.status<300); +},responseIsFailure:function(){ +return !this.responseIsSuccess(); +}}; +Ajax.Request=Class.create(); +Ajax.Request.Events=["Uninitialized","Loading","Loaded","Interactive","Complete"]; +Ajax.Request.prototype=Object.extend(new Ajax.Base(),{initialize:function(url,_11){ +this.transport=Ajax.getTransport(); +this.setOptions(_11); +this.request(url); +},request:function(url){ +var _12=this.options.parameters||""; +if(_12.length>0){ +_12+="&_="; +} +try{ +this.url=url; +if(this.options.method=="get"&&_12.length>0){ +this.url+=(this.url.match(/\?/)?"&":"?")+_12; +} +Ajax.Responders.dispatch("onCreate",this,this.transport); +this.transport.open(this.options.method,this.url,this.options.asynchronous); +if(this.options.asynchronous){ +this.transport.onreadystatechange=this.onStateChange.bind(this); +setTimeout((function(){ +this.respondToReadyState(1); +}).bind(this),10); +} +this.setRequestHeaders(); +var _13=this.options.postBody?this.options.postBody:_12; +this.transport.send(this.options.method=="post"?_13:null); +} +catch(e){ +this.dispatchException(e); +} +},setRequestHeaders:function(){ +var _14=["X-Requested-With","XMLHttpRequest","X-Prototype-Version",Prototype.Version]; +if(this.options.method=="post"){ +_14.push("Content-type","application/x-www-form-urlencoded"); +if(this.transport.overrideMimeType){ +_14.push("Connection","close"); +} +} +if(this.options.requestHeaders){ +_14.push.apply(_14,this.options.requestHeaders); +} +for(var i=0;i<_14.length;i+=2){ +this.transport.setRequestHeader(_14[i],_14[i+1]); +} +},onStateChange:function(){ +var _16=this.transport.readyState; +if(_16!=1){ +this.respondToReadyState(this.transport.readyState); +} +},header:function(_17){ +try{ +return this.transport.getResponseHeader(_17); +} +catch(e){ +} +},evalJSON:function(){ +try{ +return eval(this.header("X-JSON")); +} +catch(e){ +} +},evalResponse:function(){ +try{ +return eval(this.transport.responseText); +} +catch(e){ +this.dispatchException(e); +} +},respondToReadyState:function(_18){ +var _19=Ajax.Request.Events[_18]; +var _20=this.transport,json=this.evalJSON(); +if(_19=="Complete"){ +try{ +(this.options["on"+this.transport.status]||this.options["on"+(this.responseIsSuccess()?"Success":"Failure")]||Prototype.emptyFunction)(_20,json); +} +catch(e){ +this.dispatchException(e); +} +if((this.header("Content-type")||"").match(/^text\/javascript/i)){ +this.evalResponse(); +} +} +try{ +(this.options["on"+_19]||Prototype.emptyFunction)(_20,json); +Ajax.Responders.dispatch("on"+_19,this,_20,json); +} +catch(e){ +this.dispatchException(e); +} +if(_19=="Complete"){ +this.transport.onreadystatechange=Prototype.emptyFunction; +} +},dispatchException:function(_21){ +(this.options.onException||Prototype.emptyFunction)(this,_21); +Ajax.Responders.dispatch("onException",this,_21); +}}); +Ajax.Updater=Class.create(); +Object.extend(Object.extend(Ajax.Updater.prototype,Ajax.Request.prototype),{initialize:function(_22,url,_23){ +this.containers={success:_22.success?$(_22.success):$(_22),failure:_22.failure?$(_22.failure):(_22.success?null:$(_22))}; +this.transport=Ajax.getTransport(); +this.setOptions(_23); +var _24=this.options.onComplete||Prototype.emptyFunction; +this.options.onComplete=(function(_25,_26){ +this.updateContent(); +_24(_25,_26); +}).bind(this); +this.request(url); +},updateContent:function(){ +var _27=this.responseIsSuccess()?this.containers.success:this.containers.failure; +var _28=this.transport.responseText; +if(!this.options.evalScripts){ +_28=_28.stripScripts(); +} +if(_27){ +if(this.options.insertion){ +new this.options.insertion(_27,_28); +}else{ +Element.update(_27,_28); +} +} +if(this.responseIsSuccess()){ +if(this.onComplete){ +setTimeout(this.onComplete.bind(this),10); +} +} +}}); +Ajax.PeriodicalUpdater=Class.create(); +Ajax.PeriodicalUpdater.prototype=Object.extend(new Ajax.Base(),{initialize:function(_29,url,_30){ +this.setOptions(_30); +this.onComplete=this.options.onComplete; +this.frequency=(this.options.frequency||2); +this.decay=(this.options.decay||1); +this.updater={}; +this.container=_29; +this.url=url; +this.start(); +},start:function(){ +this.options.onComplete=this.updateComplete.bind(this); +this.onTimerEvent(); +},stop:function(){ +this.updater.onComplete=undefined; +clearTimeout(this.timer); +(this.onComplete||Prototype.emptyFunction).apply(this,arguments); +},updateComplete:function(_31){ +if(this.options.decay){ +this.decay=(_31.responseText==this.lastText?this.decay*this.options.decay:1); +this.lastText=_31.responseText; +} +this.timer=setTimeout(this.onTimerEvent.bind(this),this.decay*this.frequency*1000); +},onTimerEvent:function(){ +this.updater=new Ajax.Updater(this.container,this.url,this.options); +}}); +
+Prado.AJAX={Service:"Prototype"}; +Prado.AJAX.EvalScript=function(_1){ +var _2=new RegExp(Ajax.Updater.ScriptFragment,"img"); +var _3=_1.match(_2); +if(_3){ +_2=new RegExp(Ajax.Updater.ScriptFragment,"im"); +setTimeout((function(){ +for(var i=0;i<_3.length;i++){ +eval(_3[i].match(_2)[1]); +} +}).bind(this),50); +} +}; +Prado.AJAX.Request=Class.create(); +Prado.AJAX.Request.prototype=Object.extend(Ajax.Request.prototype,{evalJSON:function(){ +try{ +var _5=this.transport.getResponseHeader("X-JSON"),object; +object=eval(_5); +return object; +} +catch(e){ +if(isString(_5)){ +return Prado.AJAX.JSON.parse(_5); +} +} +},respondToReadyState:function(_6){ +var _7=Ajax.Request.Events[_6]; +var _8=this.transport,json=this.evalJSON(); +if(_7=="Complete"&&_8.status){ +Ajax.Responders.dispatch("on"+_8.status,this,_8,json); +} +(this.options["on"+_7]||Prototype.emptyFunction)(_8,json); +Ajax.Responders.dispatch("on"+_7,this,_8,json); +if(_7=="Complete"){ +(this.options["on"+this.transport.status]||this.options["on"+(this.responseIsSuccess()?"Success":"Failure")]||Prototype.emptyFunction)(_8,json); +} +if(_7=="Complete"){ +this.transport.onreadystatechange=Prototype.emptyFunction; +} +}}); +Prado.AJAX.Error=function(e,_10){ +e.name="Prado.AJAX.Error"; +e.code=_10; +return e; +}; +Prado.AJAX.RequestBuilder=Class.create(); +Prado.AJAX.RequestBuilder.prototype={initialize:function(){ +this.body=""; +this.data=[]; +},encode:function(_11){ +return Prado.AJAX.JSON.stringify(_11); +},build:function(_12){ +var sep=""; +for(var _14 in _12){ +if(isFunction(_12[_14])){ +continue; +} +try{ +this.body+=sep+_14+"="; +this.body+=encodeURIComponent(this.encode(_12[_14])); +} +catch(e){ +throw Prado.AJAX.Error(e,1006); +} +sep="&"; +} +},getAll:function(){ +this.build(this.data); +return this.body; +}}; +Prado.AJAX.RemoteObject=function(){ +}; +Prado.AJAX.RemoteObject.Request=Class.create(); +Prado.AJAX.RemoteObject.Request.prototype=Object.extend(Prado.AJAX.Request.prototype,{initialize:function(_15){ +this.transport=Ajax.getTransport(); +this.setOptions(_15); +this.post=new Prado.AJAX.RequestBuilder(); +},invokeRemoteObject:function(url,_17){ +this.initParameters(_17); +this.options.postBody=this.post.getAll(); +this.request(url); +},initParameters:function(_18){ +this.post.data["__parameters"]=[]; +for(var i=0;i<_18.length;i++){ +this.post.data["__parameters"][i]=_18[i]; +} +}}); +Prado.AJAX.RemoteObject.prototype={baseInitialize:function(_19,_20){ +this.__handlers=_19||{}; +this.__service=new Prado.AJAX.RemoteObject.Request(_20); +},__call:function(url,_21,_22){ +this.__service.options.onSuccess=this.__onSuccess.bind(this); +this.__callback=_21; +return this.__service.invokeRemoteObject(url+"/"+_21,_22); +},__onSuccess:function(_23,_24){ +if(this.__handlers[this.__callback]){ +this.__handlers[this.__callback](_24,_23.responseText); +} +}}; +Prado.AJAX.Exception={"on505":function(_25,_26,e){ +var msg="HTTP "+_26.status+" with response"; +Logger.error(msg,_26.responseText); +Logger.exception(e); +},onComplete:function(_28,_29,e){ +if(_29.status!=505){ +var msg="HTTP "+_29.status+" with response : \n"; +msg+=_29.responseText+"\n"; +msg+="Data : \n"+inspect(e); +Logger.warn(msg); +} +},format:function(e){ +var msg=e.type+" with message \""+e.message+"\""; +msg+=" in "+e.file+"("+e.line+")\n"; +msg+="Stack trace:\n"; +var _30=e.trace; +for(var i=0;i<_30.length;i++){ +msg+=" #"+i+" "+_30[i].file; +msg+="("+_30[i].line+"): "; +msg+=_30[i]["class"]+"->"+_30[i]["function"]+"()"+"\n"; +} +return msg; +},logException:function(e){ +var msg=Prado.AJAX.Exception.format(e); +Logger.error("Server Error "+e.code,msg); +}}; +Event.OnLoad(function(){ +if(typeof Logger!="undefined"){ +Logger.exception=Prado.AJAX.Exception.logException; +Ajax.Responders.register(Prado.AJAX.Exception); +} +}); +Prado.AJAX.Callback=Class.create(); +Prado.AJAX.Callback.prototype=Object.extend(new Prado.AJAX.RemoteObject(),{initialize:function(ID,_32){ +if(!isString(ID)&&typeof (ID.id)!="undefined"){ +ID=ID.id; +} +if(!isString(ID)){ +throw new Error("A Control ID must be specified"); +} +this.baseInitialize(this,_32); +this.options=_32||[]; +this.__service.post.data["__ID"]=ID; +this.requestCallback(); +},collectPostData:function(){ +var IDs=Prado.AJAX.Callback.IDs; +this.__service.post.data["__data"]={}; +for(var i=0;i<IDs.length;i++){ +var id=IDs[i]; +if(id.indexOf("[]")>-1){ +this.__service.post.data["__data"][id]=this.collectArrayPostData(id); +}else{ +if(isObject($(id))){ +this.__service.post.data["__data"][id]=$F(id); +} +} +} +},collectArrayPostData:function(_35){ +var _36=document.getElementsByName(_35); +var _37=[]; +$A(_36).each(function(el){ +if($F(el)){ +_37.push($F(el)); +} +}); +return _37; +},requestCallback:function(){ +this.collectPostData(); +if(Prado.AJAX.Validate(this.options)){ +return this.__call(Prado.AJAX.Callback.Server,"handleCallback",this.options.params); +} +},handleCallback:function(_39,_40){ +if(typeof (_39)!="undefined"&&!isNull(_39)){ +this.options.onSuccess(_39["data"],_40); +if(_39["actions"]){ +_39.actions.each(Prado.AJAX.Callback.Action.__run); +} +} +}}); +Prado.AJAX.Callback.Action={__run:function(_41){ +for(var _42 in _41){ +if(_41[_42][0]&&($(_41[_42][0])||_41[_42][0].indexOf("[]")>-1)){ +_42.toFunction().apply(this,_41[_42]); +} +} +}}; +Prado.AJAX.Validate=function(_43){ +if(_43.CausesValidation){ +if(_43.ValidatorGroup){ +return Prado.Validation.ValidateValidatorGroup(_43.ValidatorGroup); +}else{ +if(_43.ValidationGroup){ +return Prado.Validation.ValidateValidationGroup(_43.ValidationGroup); +}else{ +return Prado.Validation.ValidateNonGroup(_43.ValidationForm); +} +} +}else{ +return true; +} +}; +Prado.AJAX.Callback.Server=""; +Prado.AJAX.Callback.IDs=[]; +Prado.Callback=function(ID,_44,_45,_46){ +var _47={"params":[_44]||[],"onSuccess":_45||Prototype.emptyFunction,"CausesValidation":true}; +Object.extend(_47,_46||{}); +new Prado.AJAX.Callback(ID,_47); +return false; +}; +
+Array.prototype.______array="______array"; +Prado.AJAX.JSON={org:"http://www.JSON.org",copyright:"(c)2005 JSON.org",license:"http://www.crockford.com/JSON/license.html",stringify:function(_1){ +var c,i,l,s="",v; +switch(typeof _1){ +case "object": +if(_1){ +if(_1.______array=="______array"){ +for(i=0;i<_1.length;++i){ +v=this.stringify(_1[i]); +if(s){ +s+=","; +} +s+=v; +} +return "["+s+"]"; +}else{ +if(typeof _1.toString!="undefined"){ +for(i in _1){ +v=_1[i]; +if(typeof v!="undefined"&&typeof v!="function"){ +v=this.stringify(v); +if(s){ +s+=","; +} +s+=this.stringify(i)+":"+v; +} +} +return "{"+s+"}"; +} +} +} +return "null"; +case "number": +return isFinite(_1)?String(_1):"null"; +case "string": +l=_1.length; +s="\""; +for(i=0;i<l;i+=1){ +c=_1.charAt(i); +if(c>=" "){ +if(c=="\\"||c=="\""){ +s+="\\"; +} +s+=c; +}else{ +switch(c){ +case "\b": +s+="\\b"; +break; +case "\f": +s+="\\f"; +break; +case "\n": +s+="\\n"; +break; +case "\r": +s+="\\r"; +break; +case "\t": +s+="\\t"; +break; +default: +c=c.charCodeAt(); +s+="\\u00"+Math.floor(c/16).toString(16)+(c%16).toString(16); +} +} +} +return s+"\""; +case "boolean": +return String(_1); +default: +return "null"; +} +},parse:function(_3){ +var at=0; +var ch=" "; +function error(m){ +throw {name:"JSONError",message:m,at:at-1,text:_3}; +} +function next(){ +ch=_3.charAt(at); +at+=1; +return ch; +} +function white(){ +while(ch){ +if(ch<=" "){ +next(); +}else{ +if(ch=="/"){ +switch(next()){ +case "/": +while(next()&&ch!="\n"&&ch!="\r"){ +} +break; +case "*": +next(); +for(;;){ +if(ch){ +if(ch=="*"){ +if(next()=="/"){ +next(); +break; +} +}else{ +next(); +} +}else{ +error("Unterminated comment"); +} +} +break; +default: +error("Syntax error"); +} +}else{ +break; +} +} +} +} +function string(){ +var i,s="",t,u; +if(ch=="\""){ +outer: +while(next()){ +if(ch=="\""){ +next(); +return s; +}else{ +if(ch=="\\"){ +switch(next()){ +case "b": +s+="\b"; +break; +case "f": +s+="\f"; +break; +case "n": +s+="\n"; +break; +case "r": +s+="\r"; +break; +case "t": +s+="\t"; +break; +case "u": +u=0; +for(i=0;i<4;i+=1){ +t=parseInt(next(),16); +if(!isFinite(t)){ +break outer; +} +u=u*16+t; +} +s+=String.fromCharCode(u); +break; +default: +s+=ch; +} +}else{ +s+=ch; +} +} +} +} +error("Bad string"); +} +function array(){ +var a=[]; +if(ch=="["){ +next(); +white(); +if(ch=="]"){ +next(); +return a; +} +while(ch){ +a.push(value()); +white(); +if(ch=="]"){ +next(); +return a; +}else{ +if(ch!=","){ +break; +} +} +next(); +white(); +} +} +error("Bad array"); +} +function object(){ +var k,o={}; +if(ch=="{"){ +next(); +white(); +if(ch=="}"){ +next(); +return o; +} +while(ch){ +k=string(); +white(); +if(ch!=":"){ +break; +} +next(); +o[k]=value(); +white(); +if(ch=="}"){ +next(); +return o; +}else{ +if(ch!=","){ +break; +} +} +next(); +white(); +} +} +error("Bad object"); +} +function number(){ +var n="",v; +if(ch=="-"){ +n="-"; +next(); +} +while(ch>="0"&&ch<="9"){ +n+=ch; +next(); +} +if(ch=="."){ +n+="."; +while(next()&&ch>="0"&&ch<="9"){ +n+=ch; +} +} +if(ch=="e"||ch=="E"){ +n+="e"; +next(); +if(ch=="-"||ch=="+"){ +n+=ch; +next(); +} +while(ch>="0"&&ch<="9"){ +n+=ch; +next(); +} +} +v=+n; +if(!isFinite(v)){ +}else{ +return v; +} +} +function word(){ +switch(ch){ +case "t": +if(next()=="r"&&next()=="u"&&next()=="e"){ +next(); +return true; +} +break; +case "f": +if(next()=="a"&&next()=="l"&&next()=="s"&&next()=="e"){ +next(); +return false; +} +break; +case "n": +if(next()=="u"&&next()=="l"&&next()=="l"){ +next(); +return null; +} +break; +} +error("Syntax error"); +} +function value(){ +white(); +switch(ch){ +case "{": +return object(); +case "[": +return array(); +case "\"": +return string(); +case "-": +return number(); +default: +return ch>="0"&&ch<="9"?number():word(); +} +} +return value(); +}}; +
diff --git a/framework/Web/Javascripts/js/clientscripts.php b/framework/Web/Javascripts/js/clientscripts.php new file mode 100644 index 00000000..2bc206da --- /dev/null +++ b/framework/Web/Javascripts/js/clientscripts.php @@ -0,0 +1,53 @@ +<?php
+/**
+ * This file compresses the javascript files using GZip
+ *
+ * Todo:
+ * - Add local file cache for the GZip:ed version.
+ */
+
+if(isset($_GET['nocache']))
+ $expiresOffset = -10000; //no cache
+else
+ $expiresOffset = 3600 * 24 * 10; // 10 days util client cache expires
+
+// Get data to load
+$library = array( 'base', 'dom', 'effects', 'controls', 'logger',
+ 'ajax', 'rico', 'validator', 'datepicker');
+
+$param = isset($_GET['js']) ? $_GET['js'] : '';
+
+//check for proper matching parameters, otherwise exit;
+if(preg_match('/(\w)+(,\w+)*/', $param)) $js = explode(',', $param); else exit();
+foreach($js as $lib) if(!in_array($lib, $library)) exit();
+
+// Only gzip the contents if clients and server support it
+if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
+ $encodings = explode(',', strtolower($_SERVER['HTTP_ACCEPT_ENCODING']));
+else
+ $encodings = array();
+
+// Check for gzip header or northon internet securities
+if ((in_array('gzip', $encodings) || isset($_SERVER['---------------']))
+ && function_exists('ob_gzhandler') && !ini_get('zlib.output_compression'))
+ ob_start("ob_gzhandler");
+
+// Output rest of headers
+header('Content-type: text/javascript; charset: UTF-8');
+// header("Cache-Control: must-revalidate");
+header('Vary: Accept-Encoding'); // Handle proxies
+header('Expires: ' . @gmdate('D, d M Y H:i:s', @time() + $expiresOffset) . ' GMT');
+
+foreach($js as $lib)
+{
+ $file = realpath($lib.'.js');
+ if(is_file($file))
+ echo file_get_contents($file);
+ else //log missings files to console logger
+ {
+ echo 'setTimeout(function(){ if(Logger) Logger.error("Missing file", "'.$lib.'.js"); }, 1000);';
+ error_log("Unable to find asset file {$lib}.js");
+ }
+}
+
+?>
\ No newline at end of file diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php index 9537859d..f7778de9 100644 --- a/framework/Web/UI/TClientScriptManager.php +++ b/framework/Web/UI/TClientScriptManager.php @@ -163,7 +163,7 @@ class TClientScriptManager extends TComponent return $javascriptPrefix?'javascript:'.$postback:$postback; } - public function registerPradoScript($script) + /*public function registerPradoScript($script) { foreach(TPradoClientScript::getScripts($script) as $scriptFile) { @@ -181,8 +181,67 @@ class TClientScriptManager extends TComponent } } //return $url; + }*/ + + /** + * Register Prado client scripts. + */ + public function registerPradoScript($script) + { + static $scripts = array(); + $scripts = array_unique(array_merge($scripts, + TPradoClientScript::getScripts($script))); + + $this->publishClientScriptAssets($scripts); + + //create the client script url + $url = $this->publishClientScriptCompressorAsset(); + $url .= '?js='.implode(',', $scripts); + if(Prado::getApplication()->getMode() == TApplication::STATE_DEBUG) + $url .= '&nocache'; + $this->registerScriptFile('prado:gzipscripts', $url); } + /** + * Publish each individual javascript file. + */ + private function publishClientScriptAssets($scripts) + { + foreach($scripts as $lib) + { + if(!isset($this->_publishedScriptFiles[$lib])) + { + $base = Prado::getFrameworkPath(); + $clientScripts = self::SCRIPT_DIR; + $assetManager = $this->_page->getService()->getAssetManager(); + $file = "{$base}/{$clientScripts}/{$lib}.js"; + $assetManager->publishFilePath($file); + $this->_publishedScriptFiles[$lib] = true; + } + } + } + + /** + * @return string URL of the compressor asset script. + */ + private function publishClientScriptCompressorAsset() + { + $scriptFile = 'clientscripts.php'; + if(isset($this->_publishedScriptFiles[$scriptFile])) + return $this->_publishedScriptFiles[$scriptFile]; + else + { + $base = Prado::getFrameworkPath(); + $clientScripts = self::SCRIPT_DIR; + $assetManager = $this->_page->getService()->getAssetManager(); + $file = "{$base}/{$clientScripts}/{$scriptFile}"; + $url= $assetManager->publishFilePath($file); + $this->_publishedScriptFiles[$scriptFile] = $url; + return $url; + } + } + + protected function registerPostBackScript() { if(!$this->_postBackScriptRegistered) diff --git a/framework/Web/UI/WebControls/TLabel.php b/framework/Web/UI/WebControls/TLabel.php index 5a53def4..51e990d2 100644 --- a/framework/Web/UI/WebControls/TLabel.php +++ b/framework/Web/UI/WebControls/TLabel.php @@ -101,6 +101,16 @@ class TLabel extends TWebControl {
$this->setViewState('AssociatedControlID',$value,'');
}
+
+ public function setFor($value)
+ {
+ $this->setAssociatedControlID($value);
+ }
+
+ public function getFor()
+ {
+ return $this->getAssociatedControlID();
+ }
}
?>
\ No newline at end of file diff --git a/tests/FunctionalTests/protected/pages/Layout.tpl b/tests/FunctionalTests/protected/pages/Layout.tpl index 36fabe71..9a798b3c 100644 --- a/tests/FunctionalTests/protected/pages/Layout.tpl +++ b/tests/FunctionalTests/protected/pages/Layout.tpl @@ -27,7 +27,7 @@ <a href="http://validator.w3.org/check?uri=referer">
Validate XHTML 1.0
</a>
-<a href="?page=ViewSource&source=<%= $this->Request->ServiceParameter %>"
+<a href="?page=ViewSource&path=<%= str_replace('.','/', $this->Request->ServiceParameter) %>.page"
style="margin: 0 1em;"
onclick="window.open(this.href); return false;"
onkeypress="window.open(this.href); return false;">View Source</a>
diff --git a/tests/FunctionalTests/protected/pages/ViewSource.page b/tests/FunctionalTests/protected/pages/ViewSource.page index 900c45f6..218cc901 100644 --- a/tests/FunctionalTests/protected/pages/ViewSource.page +++ b/tests/FunctionalTests/protected/pages/ViewSource.page @@ -6,13 +6,18 @@ </com:THead>
<body>
+<com:TForm>
<div id="sourceList">
<com:TLiteral ID="SourceList" />
+<com:TCheckBox ID="showLineNumbers" AutoPostBack="true" />
+<com:TLabel For="showLineNumbers">Show Line Numbers</com:TLabel>
</div>
<div id="sourceView">
-<com:TTextHighlighter ID="Highlighter" ShowLineNumbers="true" CssClass="source">
+<com:TTextHighlighter ID="Highlighter" CssClass="source"
+ ShowLineNumbers="<%# $this->Page->showLineNumbers->Checked %>" >
<com:TLiteral ID="SourceView" />
</com:TTextHighlighter>
+</com:TForm>
</div>
</body>
</html>
\ No newline at end of file diff --git a/tests/FunctionalTests/protected/pages/ViewSource.php b/tests/FunctionalTests/protected/pages/ViewSource.php index eeaf0f80..84f39161 100644 --- a/tests/FunctionalTests/protected/pages/ViewSource.php +++ b/tests/FunctionalTests/protected/pages/ViewSource.php @@ -2,10 +2,83 @@ class ViewSource extends TPage
{
- protected function onLoad($param)
+ private $_path=null;
+ private $_fullPath=null;
+ private $_fileType=null;
+
+ protected function isFileTypeAllowed($extension)
+ {
+ return in_array($extension,array('tpl','page','php'));
+ }
+
+ protected function getFileExtension($fileName)
+ {
+ if(($pos=strrpos($fileName,'.'))===false)
+ return '';
+ else
+ return substr($fileName,$pos+1);
+ }
+
+ public function onLoad($param)
{
- $pageName = $this->Request->getParameter("source");
- var_dump($pageName);
+ parent::onLoad($param);
+ $path=$this->Request->Items['path'];
+ $fullPath=realpath($this->Service->BasePath.'/'.$path);
+ $fileExt=$this->getFileExtension($fullPath);
+ if($fullPath!==false && is_file($fullPath) && strpos($fullPath,$this->Service->BasePath)!==false)
+ {
+ if($this->isFileTypeAllowed($fileExt))
+ {
+ $this->_fullPath=strtr($fullPath,'\\','/');
+ $this->_path=strtr(substr($fullPath,strlen($this->Service->BasePath)),'\\','/');
+ }
+ }
+ if($this->_fullPath===null)
+ throw new THttpException(500,'File Not Found: %s',$path);
+ $basePath=dirname($this->_fullPath);
+ if($dh=opendir($basePath))
+ {
+ $str="<h2>{$this->_path}</h2>\n";
+ while(($file=readdir($dh))!==false)
+ {
+ if(is_file($basePath.'/'.$file))
+ {
+ $fileType=$this->getFileExtension($basePath.'/'.$file);
+ if($this->isFileTypeAllowed($fileType))
+ {
+ if($fileType==='tpl' || $fileType==='page')
+ $type='Template file';
+ else
+ $type='Class file';
+ $path='/'.ltrim(strtr(dirname($this->_path),'\\','/').'/'.$file,'/');
+ $str.="$type: <a href=\"?page=ViewSource&path=$path\">$file</a><br/>";
+ }
+ }
+
+ }
+ closedir($dh);
+ $this->SourceList->Text=$str;
+ }
+
+ switch($fileExt)
+ {
+ case 'page' :
+ case 'tpl' :
+ $this->Highlighter->Language='prado';
+ break;
+ case 'php' :
+ $this->Highlighter->Language='php';
+ break;
+ case 'xml' :
+ $this->Highlighter->Language='xml';
+ break;
+ default :
+ $this->Highlighter->Language='html';
+ break;
+ }
+
+ $this->SourceView->Text=file_get_contents($this->_fullPath);
+ $this->dataBind();
}
}
|