From 791acbbebad01a33cce22209ea561b282ee876e4 Mon Sep 17 00:00:00 2001 From: wei <> Date: Thu, 5 Apr 2007 07:46:04 +0000 Subject: adds TClientScriptLoader --- .gitattributes | 1 + HISTORY | 1 + framework/Web/Javascripts/clientscripts.php | 5 +- framework/Web/UI/WebControls/TClientScript.php | 77 -------- .../Web/UI/WebControls/TClientScriptLoader.php | 218 +++++++++++++++++++++ 5 files changed, 224 insertions(+), 78 deletions(-) create mode 100644 framework/Web/UI/WebControls/TClientScriptLoader.php diff --git a/.gitattributes b/.gitattributes index c93a83ae..afcc4036 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2112,6 +2112,7 @@ framework/Web/UI/WebControls/TCheckBox.php -text framework/Web/UI/WebControls/TCheckBoxColumn.php -text framework/Web/UI/WebControls/TCheckBoxList.php -text framework/Web/UI/WebControls/TClientScript.php -text +framework/Web/UI/WebControls/TClientScriptLoader.php -text framework/Web/UI/WebControls/TColorPicker.php -text framework/Web/UI/WebControls/TCompareValidator.php -text framework/Web/UI/WebControls/TContent.php -text diff --git a/HISTORY b/HISTORY index 9de3a5af..f9b67180 100644 --- a/HISTORY +++ b/HISTORY @@ -49,6 +49,7 @@ NEW: TDbCache (Qiang) NEW: TDbUserManager and TDbUser (Qiang) NEW: Active Record driver for IBM DB2 (Cesar Ramos) NEW: TActiveRecord Scaffold support (Wei) +NEW: TClientScriptLoader combines and loads javascript libraries (Wei) Version 3.1.0 alpha January 15, 2007 ==================================== diff --git a/framework/Web/Javascripts/clientscripts.php b/framework/Web/Javascripts/clientscripts.php index 21da56bf..f810901b 100644 --- a/framework/Web/Javascripts/clientscripts.php +++ b/framework/Web/Javascripts/clientscripts.php @@ -74,7 +74,7 @@ function get_script_requests($max=25) */ function get_package_files($package_file, $request) { - list($packages, $dependencies) = @include($package_file); + list($packages, $dependencies) = include($package_file); if(!(is_array($packages) && is_array($dependencies))) { error_log('Prado client script: invalid package file '.$package_file); @@ -240,6 +240,9 @@ function print_headers() */ function supports_gzip_encoding() { + if(isset($_GET['gzip']) && $_GET['gzip']==='false') + return false; + if (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { $encodings = explode(',', strtolower(preg_replace("/\s+/", "", $_SERVER['HTTP_ACCEPT_ENCODING']))); diff --git a/framework/Web/UI/WebControls/TClientScript.php b/framework/Web/UI/WebControls/TClientScript.php index 8b80eb69..2021a933 100644 --- a/framework/Web/UI/WebControls/TClientScript.php +++ b/framework/Web/UI/WebControls/TClientScript.php @@ -38,8 +38,6 @@ */ class TClientScript extends TControl { - const SCRIPT_LOADER = 'Web/Javascripts/clientscripts.php'; - /** * @return string comma delimited list of javascript libraries to included * on the page. @@ -77,38 +75,6 @@ class TClientScript extends TControl $this->setViewState('ScriptUrl', $value, ''); } - /** - * @param string custom javascript library directory. - */ - public function setPackagePath($value) - { - $this->setViewState('PackagePath', $value); - } - - /** - * @return string custom javascript library directory. - */ - public function getPackagePath() - { - return $this->getViewState('PackagePath'); - } - - /** - * @param string load specific packages from the javascript library in the PackagePath, comma delimited package names - */ - public function setPackageScripts($value) - { - $this->setViewState('PackageScripts', $value,''); - } - - /** - * @return string comma delimited list of javascript library packages to load. - */ - public function getPackageScripts() - { - return $this->getViewState('PackageScripts',''); - } - /** * Calls the client script manager to add each of the requested client * script libraries. @@ -135,7 +101,6 @@ class TClientScript extends TControl public function render($writer) { $this->renderCustomScriptFile($writer); - $this->renderPackageScriptFile($writer); $this->renderCustomScript($writer); } @@ -162,48 +127,6 @@ class TClientScript extends TControl $writer->write("\n/*]]>*/\n\n"); } } - - protected function renderPackageScriptFile($writer) - { - $baseUrl = $this->publishScriptLoader(); - $scripts = split('/\s*[, ]+\s*/', $this->getPackageScripts()); - $url = $baseUrl . '?js=' . implode(',', $scripts); - if($this->getApplication()->getMode()===TApplicationMode::Debug) - $url.='&mode=debug'; - $writer->write("\n"); - } - - protected function publishScriptLoader() - { - list($path, $url) = $this->getPublishedPackagePath(); - if(is_dir($path)) - { - $scriptLoader = Prado::getFrameworkPath().'/'.self::SCRIPT_LOADER; - $scriptLoaderFile = basename($scriptLoader); - $dest = $path.'/'.$scriptLoaderFile; - if(!is_file($dest)) - copy($scriptLoader,$dest); - return $url.'/'.$scriptLoaderFile; - } - else - throw new TConfigurationException('clientscript_invalid_package_path', - $this->getPackagePath(), $this->getUniqueID()); - } - - protected function getPublishedPackagePath() - { - $assets = $this->getApplication()->getAssetManager(); - //assumes dot path first - $dir = Prado::getPathOfNameSpace($packageDir); - if(!is_null($dir)) - { - $url = $assets->publishFilePath($dir); //show throw an excemption if invalid - return array($dir, $url); - } - $url = $this->getPackagePath(); - $packageDir = str_replace($assets->getBaseUrl(), '', $url); - return array($assets->getBasePath().$packageDir,$url); - } } ?> \ No newline at end of file diff --git a/framework/Web/UI/WebControls/TClientScriptLoader.php b/framework/Web/UI/WebControls/TClientScriptLoader.php new file mode 100644 index 00000000..1c5b9d29 --- /dev/null +++ b/framework/Web/UI/WebControls/TClientScriptLoader.php @@ -0,0 +1,218 @@ + + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id: TClientScriptLoader.php 1827 2007-04-02 06:19:55Z wei $ + * @package System.Web.UI.WebControls + */ + +/** + * The TClientScriptLoader publish a collection of javascript files as assets. + * The {@link PackagePath setPackagePath} property can be an existing asset directory + * or a namespace path to the directory containing javascript files. E.g. + * + * /> + * + * + * + * When the files in the {@link PackagePath setPackagePath} are published as assets, a script loader + * php file corresponding to TClientScriptLoader::SCRIPT_LOADER is also copied to that asset directory. + * + * The script loader, combines multiple javascript files and serve up as gzip if possible. + * Allowable scripts and script dependencies can be specified in a "packages.php" file + * with the following format. This "packages.php" is optional, if absent the filenames + * without ".js" extension are used. The "packages.php" must be in the directory given by + * {@link PackagePath setPackagePath}. + * + * + * array('file1.js', 'file2.js'), + * 'package2' => array('file3.js', 'file4.js')); + * + * $deps = array( + * 'package1' => array('package1'), + * 'package2' => array('package1', 'package2')); //package2 requires package1 first. + * + * return array($packages,$deps); //must return $packages and $deps in an array + * + * + * Set the {@link PackageScripts setPackageScripts} property with value 'package1' to serve + * up the 'package1' scripts. A maxium of 25 packages separated by commas is allowed. + * + * Dependencies of the packages are automatically resolved by the script loader php file. + * E.g. + * + * PackageScripts="package2" /> + * + * + * The {@link setDebugMode DebugMode} property when false + * removes comments and whitespaces from the published javascript files. If + * the DebugMode property is not set, the debug mode is determined from the application mode. + * + * The {@link setEnableGzip EnableGzip} property (default is true) enables the + * published javascripts to be served as zipped if the browser and php server allows it. + + * If the DebugMode is false either explicitly or when the application mode is non-debug, + * then cache headers are also sent to inform the browser and proxies to cache the file. + * Moreover, the post-processed (comments removed and zipped) are saved in the assets + * directory for the next requests. That is, in non-debug mode the scripts are cached + * in the assets directory until they are deleted. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Web.WebControls + * @since 3.1 + */ +class TClientScriptLoader extends TWebControl +{ + const SCRIPT_LOADER = 'Web/Javascripts/clientscripts.php'; + + /** + * @return string tag name of the script element + */ + protected function getTagName() + { + return 'script'; + } + + /** + * Adds attribute name-value pairs to renderer. + * This overrides the parent implementation with additional button specific attributes. + * @param THtmlWriter the writer used for the rendering purpose + */ + protected function addAttributesToRender($writer) + { + $writer->addAttribute('type','text/javascript'); + $writer->addAttribute('src',$this->getClientScriptUrl()); + parent::addAttributesToRender($writer); + } + + /** + * @return string clientscript.php url. + */ + protected function getClientScriptUrl() + { + $baseUrl = $this->publishScriptLoader(); + $scripts = split('/\s*[, ]+\s*/', $this->getPackageScripts()); + $url = $baseUrl . '?js=' . implode(',', $scripts); + if($this->getDebugMode()!==false && $this->getApplication()->getMode()===TApplicationMode::Debug) + $url.='&mode=debug'; + if($this->getEnableGzip()===false) + $url.='&gzip=false'; + return $url; + } + + /** + * Copies the client script loader php file to the asset directory if appropriate. + * @return string clientscript.php url + * @throws TConfigurationException if error in publishing the package path. + */ + protected function publishScriptLoader() + { + list($path, $url) = $this->getPublishedPackagePath(); + if(is_dir($path)) + { + $scriptLoader = Prado::getFrameworkPath().'/'.self::SCRIPT_LOADER; + $scriptLoaderFile = basename($scriptLoader); + $dest = $path.'/'.$scriptLoaderFile; + if(!is_file($dest)) + copy($scriptLoader,$dest); + return $url.'/'.$scriptLoaderFile; + } + else + throw new TConfigurationException('clientscript_invalid_package_path', + $this->getPackagePath(), $this->getUniqueID()); + } + + /** + * Publishes the package path assets, tries path as namespace first. + * @return array tuple ($path, $url). + */ + protected function getPublishedPackagePath() + { + $assets = $this->getApplication()->getAssetManager(); + //assumes dot path first + $dir = Prado::getPathOfNameSpace($this->getPackagePath()); + if(!is_null($dir)) + { + $url = $assets->publishFilePath($dir); //show throw an excemption if invalid + return array($dir, $url); + } + $url = $this->getPackagePath(); + $packageDir = str_replace($assets->getBaseUrl(), '', $url); + return array($assets->getBasePath().$packageDir,$url); + } + + /** + * @param string custom javascript library directory. + */ + public function setPackagePath($value) + { + $this->setViewState('PackagePath', $value); + } + + /** + * @return string custom javascript library directory. + */ + public function getPackagePath() + { + return $this->getViewState('PackagePath'); + } + + /** + * @param string load specific packages from the javascript library in the PackagePath, + * comma delimited package names. A maximum of 25 packages is allowed. + */ + public function setPackageScripts($value) + { + $this->setViewState('PackageScripts', $value,''); + } + + /** + * @return string comma delimited list of javascript library packages to load. + */ + public function getPackageScripts() + { + return $this->getViewState('PackageScripts',''); + } + + /** + * @param boolean enables gzip compression of the javascript. + */ + public function setEnableGzip($value) + { + $this->setViewState('EnableGzip', TPropertyValue::ensureBoolean($value), true); + } + + /** + * @return boolean enables gzip compression of the javascript if possible, default is true. + */ + public function getEnableGzip() + { + return $this->getViewState('EnableGzip', true); + } + + /** + * @return boolean javascript comments stripped in non-debug mode. + * Debug mode will depend on the application mode if null. + */ + public function getDebugMode() + { + return $this->getViewState('DebugMode'); + } + + /** + * @param boolean true to enable debug mode, default is null thus dependent on the application mode. + */ + public function setDebugMode($value) + { + $this->setViewState('DebugMode', TPropertyValue::ensureBoolean($value), null); + } +} + +?> \ No newline at end of file -- cgit v1.2.3