From f51a263570781c6ee76b1d72f9ae138ee8217c77 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 27 Aug 2014 16:44:00 -0400 Subject: [PATCH 01/12] new asset management WIP --- apps/basic/.bowerrc | 3 + apps/basic/bower.json | 8 + docs/guide/output-client-scripts.md | 15 +- docs/guide/structure-assets.md | 13 +- extensions/smarty/Extension.php | 8 +- framework/helpers/BaseUrl.php | 11 ++ framework/web/AssetBundle.php | 111 ++----------- framework/web/AssetManager.php | 308 +++++------------------------------- framework/web/JqueryAsset.php | 3 +- framework/web/View.php | 49 +++--- framework/web/YiiAsset.php | 3 +- 11 files changed, 125 insertions(+), 407 deletions(-) create mode 100644 apps/basic/.bowerrc create mode 100644 apps/basic/bower.json diff --git a/apps/basic/.bowerrc b/apps/basic/.bowerrc new file mode 100644 index 0000000..16098e9 --- /dev/null +++ b/apps/basic/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory" : "web/assets" +} \ No newline at end of file diff --git a/apps/basic/bower.json b/apps/basic/bower.json new file mode 100644 index 0000000..b3ec7cd --- /dev/null +++ b/apps/basic/bower.json @@ -0,0 +1,8 @@ +{ + "name": "yii2-basic", + "version": "1.0.0", + "dependencies": { + }, + "devDependencies": { + } +} diff --git a/docs/guide/output-client-scripts.md b/docs/guide/output-client-scripts.md index ec3b6b0..05a629a 100644 --- a/docs/guide/output-client-scripts.md +++ b/docs/guide/output-client-scripts.md @@ -30,7 +30,7 @@ instead of adding a new one. If you don't provide it, the JS code itself will be An external script can be added like the following: ```php -$this->registerJsFile('http://example.com/js/main.js', [JqueryAsset::className()]); +$this->registerJsFile('http://example.com/js/main.js', ['depends' => [JqueryAsset::className()]]); ``` The arguments for [[yii\web\View::registerJsFile()|registerJsFile()]] are similar to those for @@ -76,16 +76,19 @@ If you want to specify additional properties of the style tag, pass an array of If you need to make sure there's only a single style tag use fourth argument as was mentioned in meta tags description. ```php -$this->registerCssFile("http://example.com/css/themes/black-and-white.css", [BootstrapAsset::className()], ['media' => 'print'], 'css-print-theme'); +$this->registerCssFile("http://example.com/css/themes/black-and-white.css", [ + 'depends' => [BootstrapAsset::className()], + 'media' => 'print', +], 'css-print-theme'); ``` The code above will add a link to CSS file to the head section of the page. * The first argument specifies the CSS file to be registered. -* The second argument specifies that this CSS file depends on [[yii\bootstrap\BootstrapAsset|BootstrapAsset]], meaning it will be added - AFTER the CSS files in [[yii\bootstrap\BootstrapAsset|BootstrapAsset]]. Without this dependency specification, the relative order - between this CSS file and the [[yii\bootstrap\BootstrapAsset|BootstrapAsset]] CSS files would be undefined. -* The third argument specifies the attributes for the resulting `` tag. +* The second argument specifies the HTML attributes for the resulting `` tag. The option `depends` + is specially handled. It specifies which asset bundles this CSS file depends on. In this case, the dependent + asset bundle is [[yii\bootstrap\BootstrapAsset|BootstrapAsset]]. This means the CSS file will be added + *after* the CSS files in [[yii\bootstrap\BootstrapAsset|BootstrapAsset]]. * The last argument specifies an ID identifying this CSS file. If it is not provided, the URL of the CSS file will be used instead. diff --git a/docs/guide/structure-assets.md b/docs/guide/structure-assets.md index 16f1c33..a735f37 100644 --- a/docs/guide/structure-assets.md +++ b/docs/guide/structure-assets.md @@ -76,7 +76,7 @@ class can be placed anywhere but the convention for it is to be under `assets` d Additionally you may specify `$jsOptions`, `$cssOptions` and `$publishOptions` that will be passed to [[yii\web\View::registerJsFile()]], [[yii\web\View::registerCssFile()]] and [[yii\web\AssetManager::publish()]] -respectively during registering and publising an asset. For more details on this see [Setting special options](#setting-special-options). +respectively during registering and publishing an asset. For more details on this see [Setting special options](#setting-special-options). [alias]: basics.md#path-aliases "Yii Path alias" @@ -89,16 +89,16 @@ following way: ```php class LanguageAsset extends AssetBundle { - public $language; + public static $language; public $sourcePath = '@app/assets/language'; public $js = [ ]; - public function registerAssetFiles($view) + public function init() { - $language = $this->language ? $this->language : Yii::$app->language; + parent::init(); + $language = self::$language ? self::$language : Yii::$app->language; $this->js[] = 'language-' . $language . '.js'; - parent::registerAssetFiles($view); } } ``` @@ -106,7 +106,8 @@ class LanguageAsset extends AssetBundle In order to set language use the following code when registering an asset bundle in a view: ```php -LanguageAsset::register($this)->language = $language; +LanguageAsset::$language = $language; +LanguageAsset::register($this); ``` diff --git a/extensions/smarty/Extension.php b/extensions/smarty/Extension.php index b81099f..011dbdd 100644 --- a/extensions/smarty/Extension.php +++ b/extensions/smarty/Extension.php @@ -319,11 +319,10 @@ PHP; $url = ArrayHelper::remove($params, 'url'); $key = ArrayHelper::remove($params, 'key', null); - $depends = ArrayHelper::remove($params, 'depends', null); if (isset($params['position'])) $params['position'] = $this->getViewConstVal($params['position'], View::POS_END); - Yii::$app->getView()->registerJsFile($url, $depends, $params, $key); + Yii::$app->getView()->registerJsFile($url, $params, $key); } /** @@ -379,9 +378,8 @@ PHP; $url = ArrayHelper::remove($params, 'url'); $key = ArrayHelper::remove($params, 'key', null); - $depends = ArrayHelper::remove($params, 'depends', null); - Yii::$app->getView()->registerCssFile($url, $depends, $params, $key); + Yii::$app->getView()->registerCssFile($url, $params, $key); } /** @@ -427,4 +425,4 @@ PHP; $val = @constant('yii\web\View::' . $string); return isset($val) ? $val : $default; } -} \ No newline at end of file +} diff --git a/framework/helpers/BaseUrl.php b/framework/helpers/BaseUrl.php index ac0d9e0..8b9418b 100644 --- a/framework/helpers/BaseUrl.php +++ b/framework/helpers/BaseUrl.php @@ -319,4 +319,15 @@ class BaseUrl return $url; } + + /** + * Returns a value indicating whether a URL is relative. + * A relative URL does not have host info part. + * @param string $url the URL to be checked + * @return boolean whether the URL is relative + */ + public static function isRelative($url) + { + return strncmp($url, '//', 2) && strpos($url, '://') === false; + } } diff --git a/framework/web/AssetBundle.php b/framework/web/AssetBundle.php index f6a04d3..eb2bea9 100644 --- a/framework/web/AssetBundle.php +++ b/framework/web/AssetBundle.php @@ -26,41 +26,21 @@ use yii\base\Object; class AssetBundle extends Object { /** - * @var string the root directory of the source asset files. A source asset file - * is a file that is part of your source code repository of your Web application. + * @var string the directory that contains the asset files in this bundle. * - * You must set this property if the directory containing the source asset files - * is not Web accessible (this is usually the case for extensions). - * - * By setting this property, the asset manager will publish the source asset files - * to a Web-accessible directory [[basePath]]. - * - * You can use either a directory or an alias of the directory. - */ - public $sourcePath; - /** - * @var string the Web-accessible directory that contains the asset files in this bundle. - * - * If [[sourcePath]] is set, this property will be *overwritten* by [[AssetManager]] - * when it publishes the asset files from [[sourcePath]]. - * - * If the bundle contains any assets that are specified in terms of relative file path, - * then this property must be set either manually or automatically (by [[AssetManager]] via - * asset publishing). + * The value of this property can be prefixed to every relative asset file path listed in [[js]] and [[css]] + * to form an absolute file path. If this property is null (meaning not set), the value of + * [[AssetManager::basePath]] will be used instead. * * You can use either a directory or an alias of the directory. */ public $basePath; /** - * @var string the base URL that will be prefixed to the asset files for them to - * be accessed via Web server. + * @var string the base URL for the relative asset files listed in [[js]] and [[css]]. * - * If [[sourcePath]] is set, this property will be *overwritten* by [[AssetManager]] - * when it publishes the asset files from [[sourcePath]]. - * - * If the bundle contains any assets that are specified in terms of relative file path, - * then this property must be set either manually or automatically (by asset manager via - * asset publishing). + * The value of this property will be prefixed to every relative asset file path listed in [[js]] and [[css]] + * when they are being registered in a view so that they can be Web accessible. + * If this property is null (meaning not set), the value of [[AssetManager::baseUrl]] will be used instead. * * You can use either a URL or an alias of the URL. */ @@ -80,16 +60,16 @@ class AssetBundle extends Object public $depends = []; /** * @var array list of JavaScript files that this bundle contains. Each JavaScript file can - * be either a file path (without leading slash) relative to [[basePath]] or a URL representing - * an external JavaScript file. + * be either a file path (without leading slash) relative to [[basePath]] and [[baseUrl]], + * or a URL representing an external JavaScript file. * - * Note that only forward slash "/" can be used as directory separator. + * Note that only forward slash "/" can be used as directory separators. */ public $js = []; /** * @var array list of CSS files that this bundle contains. Each CSS file can - * be either a file path (without leading slash) relative to [[basePath]] or a URL representing - * an external CSS file. + * be either a file path (without leading slash) relative to [[basePath]] and [[baseUrl]], + * or a URL representing an external CSS file. * * Note that only forward slash "/" can be used as directory separator. */ @@ -104,15 +84,11 @@ class AssetBundle extends Object * when registering the CSS files in this bundle. */ public $cssOptions = []; - /** - * @var array the options to be passed to [[AssetManager::publish()]] when the asset bundle - * is being published. - */ - public $publishOptions = []; /** - * @param View $view + * Registers this asset bundle with a view. + * @param View $view the view to be registered with * @return static the registered asset bundle instance */ public static function register($view) @@ -126,9 +102,6 @@ class AssetBundle extends Object */ public function init() { - if ($this->sourcePath !== null) { - $this->sourcePath = rtrim(Yii::getAlias($this->sourcePath), '/\\'); - } if ($this->basePath !== null) { $this->basePath = rtrim(Yii::getAlias($this->basePath), '/\\'); } @@ -136,58 +109,4 @@ class AssetBundle extends Object $this->baseUrl = rtrim(Yii::getAlias($this->baseUrl), '/'); } } - - /** - * Registers the CSS and JS files with the given view. - * @param \yii\web\View $view the view that the asset files are to be registered with. - */ - public function registerAssetFiles($view) - { - foreach ($this->js as $js) { - if ($js[0] !== '/' && $js[0] !== '.' && strpos($js, '://') === false) { - $view->registerJsFile($this->baseUrl . '/' . $js, [], $this->jsOptions); - } else { - $view->registerJsFile($js, [], $this->jsOptions); - } - } - foreach ($this->css as $css) { - if ($css[0] !== '/' && $css[0] !== '.' && strpos($css, '://') === false) { - $view->registerCssFile($this->baseUrl . '/' . $css, [], $this->cssOptions); - } else { - $view->registerCssFile($css, [], $this->cssOptions); - } - } - } - - /** - * Publishes the asset bundle if its source code is not under Web-accessible directory. - * It will also try to convert non-CSS or JS files (e.g. LESS, Sass) into the corresponding - * CSS or JS files using [[AssetManager::converter|asset converter]]. - * @param AssetManager $am the asset manager to perform the asset publishing - */ - public function publish($am) - { - if ($this->sourcePath !== null && !isset($this->basePath, $this->baseUrl)) { - list ($this->basePath, $this->baseUrl) = $am->publish($this->sourcePath, $this->publishOptions); - } - $converter = $am->getConverter(); - foreach ($this->js as $i => $js) { - if (strpos($js, '/') !== 0 && strpos($js, '://') === false) { - if (isset($this->basePath, $this->baseUrl)) { - $this->js[$i] = $converter->convert($js, $this->basePath); - } else { - $this->js[$i] = '/' . $js; - } - } - } - foreach ($this->css as $i => $css) { - if (strpos($css, '/') !== 0 && strpos($css, '://') === false) { - if (isset($this->basePath, $this->baseUrl)) { - $this->css[$i] = $converter->convert($css, $this->basePath); - } else { - $this->css[$i] = '/' . $css; - } - } - } - } } diff --git a/framework/web/AssetManager.php b/framework/web/AssetManager.php index d7144bc..84b4786 100644 --- a/framework/web/AssetManager.php +++ b/framework/web/AssetManager.php @@ -12,6 +12,7 @@ use yii\base\Component; use yii\base\InvalidConfigException; use yii\base\InvalidParamException; use yii\helpers\FileHelper; +use yii\helpers\Url; /** * AssetManager manages asset bundles and asset publishing. @@ -63,64 +64,7 @@ class AssetManager extends Component * @return string the base URL through which the published asset files can be accessed. */ public $baseUrl = '@web/assets'; - /** - * @var boolean whether to use symbolic link to publish asset files. Defaults to false, meaning - * asset files are copied to [[basePath]]. Using symbolic links has the benefit that the published - * assets will always be consistent with the source assets and there is no copy operation required. - * This is especially useful during development. - * - * However, there are special requirements for hosting environments in order to use symbolic links. - * In particular, symbolic links are supported only on Linux/Unix, and Windows Vista/2008 or greater. - * - * Moreover, some Web servers need to be properly configured so that the linked assets are accessible - * to Web users. For example, for Apache Web server, the following configuration directive should be added - * for the Web folder: - * - * ~~~ - * Options FollowSymLinks - * ~~~ - */ - public $linkAssets = false; - /** - * @var integer the permission to be set for newly published asset files. - * This value will be used by PHP chmod() function. No umask will be applied. - * If not set, the permission will be determined by the current environment. - */ - public $fileMode; - /** - * @var integer the permission to be set for newly generated asset directories. - * This value will be used by PHP chmod() function. No umask will be applied. - * Defaults to 0775, meaning the directory is read-writable by owner and group, - * but read-only for other users. - */ - public $dirMode = 0775; - /** - * @var callback a PHP callback that is called before copying each sub-directory or file. - * This option is used only when publishing a directory. If the callback returns false, the copy - * operation for the sub-directory or file will be cancelled. - * - * The signature of the callback should be: `function ($from, $to)`, where `$from` is the sub-directory or - * file to be copied from, while `$to` is the copy target. - * - * This is passed as a parameter `beforeCopy` to [[\yii\helpers\FileHelper::copyDirectory()]]. - */ - public $beforeCopy; - /** - * @var callback a PHP callback that is called after a sub-directory or file is successfully copied. - * This option is used only when publishing a directory. The signature of the callback is the same as - * for [[beforeCopy]]. - * This is passed as a parameter `afterCopy` to [[\yii\helpers\FileHelper::copyDirectory()]]. - */ - public $afterCopy; - /** - * @var boolean whether the directory being published should be copied even if - * it is found in the target directory. This option is used only when publishing a directory. - * You may want to set this to be `true` during the development stage to make sure the published - * directory is always up-to-date. Do not set this to true on production servers as it will - * significantly degrade the performance. - */ - public $forceCopy = false; - + public $assetMap = []; /** * Initializes the component. @@ -130,12 +74,10 @@ class AssetManager extends Component { parent::init(); $this->basePath = Yii::getAlias($this->basePath); - if (!is_dir($this->basePath)) { - throw new InvalidConfigException("The directory does not exist: {$this->basePath}"); - } elseif (!is_writable($this->basePath)) { - throw new InvalidConfigException("The directory is not writable by the Web process: {$this->basePath}"); - } else { + if (is_dir($this->basePath)) { $this->basePath = realpath($this->basePath); + } else { + throw new InvalidConfigException("The directory does not exist: {$this->basePath}"); } $this->baseUrl = rtrim(Yii::getAlias($this->baseUrl), '/'); } @@ -147,233 +89,63 @@ class AssetManager extends Component * it will treat `$name` as the class of the asset bundle and create a new instance of it. * * @param string $name the class name of the asset bundle - * @param boolean $publish whether to publish the asset files in the asset bundle before it is returned. - * If you set this false, you must manually call `AssetBundle::publish()` to publish the asset files. * @return AssetBundle the asset bundle instance * @throws InvalidConfigException if $name does not refer to a valid asset bundle */ - public function getBundle($name, $publish = true) + public function getBundle($name) { - if (isset($this->bundles[$name])) { - if ($this->bundles[$name] instanceof AssetBundle) { - return $this->bundles[$name]; - } elseif (is_array($this->bundles[$name])) { - $bundle = Yii::createObject(array_merge(['class' => $name], $this->bundles[$name])); - } else { - throw new InvalidConfigException("Invalid asset bundle: $name"); - } + if ($this->bundles === false) { + return null; + } elseif (!isset($this->bundles[$name])) { + return $this->bundles[$name] = $this->loadBundle($name); + } elseif ($this->bundles[$name] instanceof AssetBundle) { + return $this->bundles[$name]; + } elseif (is_array($this->bundles[$name])) { + return $this->bundles[$name] = $this->loadBundle($name, $this->bundles[$name]); + } elseif ($this->bundles[$name] === false) { + return null; } else { - $bundle = Yii::createObject($name); - } - if ($publish) { - /* @var $bundle AssetBundle */ - $bundle->publish($this); - } - - return $this->bundles[$name] = $bundle; - } - - private $_converter; - - /** - * Returns the asset converter. - * @return AssetConverterInterface the asset converter. - */ - public function getConverter() - { - if ($this->_converter === null) { - $this->_converter = Yii::createObject(AssetConverter::className()); - } elseif (is_array($this->_converter) || is_string($this->_converter)) { - if (is_array($this->_converter) && !isset($this->_converter['class'])) { - $this->_converter['class'] = AssetConverter::className(); - } - $this->_converter = Yii::createObject($this->_converter); + throw new InvalidConfigException("Invalid asset bundle configuration: $name"); } - - return $this->_converter; - } - - /** - * Sets the asset converter. - * @param array|AssetConverterInterface $value the asset converter. This can be either - * an object implementing the [[AssetConverterInterface]], or a configuration - * array that can be used to create the asset converter object. - */ - public function setConverter($value) - { - $this->_converter = $value; } - /** - * @var array published assets - */ - private $_published = []; - - /** - * Publishes a file or a directory. - * - * This method will copy the specified file or directory to [[basePath]] so that - * it can be accessed via the Web server. - * - * If the asset is a file, its file modification time will be checked to avoid - * unnecessary file copying. - * - * If the asset is a directory, all files and subdirectories under it will be published recursively. - * Note, in case $forceCopy is false the method only checks the existence of the target - * directory to avoid repetitive copying (which is very expensive). - * - * By default, when publishing a directory, subdirectories and files whose name starts with a dot "." - * will NOT be published. If you want to change this behavior, you may specify the "beforeCopy" option - * as explained in the `$options` parameter. - * - * Note: On rare scenario, a race condition can develop that will lead to a - * one-time-manifestation of a non-critical problem in the creation of the directory - * that holds the published assets. This problem can be avoided altogether by 'requesting' - * in advance all the resources that are supposed to trigger a 'publish()' call, and doing - * that in the application deployment phase, before system goes live. See more in the following - * discussion: http://code.google.com/p/yii/issues/detail?id=2579 - * - * @param string $path the asset (file or directory) to be published - * @param array $options the options to be applied when publishing a directory. - * The following options are supported: - * - * - beforeCopy: callback, a PHP callback that is called before copying each sub-directory or file. - * This overrides [[beforeCopy]] if set. - * - afterCopy: callback, a PHP callback that is called after a sub-directory or file is successfully copied. - * This overrides [[afterCopy]] if set. - * - forceCopy: boolean, whether the directory being published should be copied even if - * it is found in the target directory. This option is used only when publishing a directory. - * This overrides [[forceCopy]] if set. - * - * @return array the path (directory or file path) and the URL that the asset is published as. - * @throws InvalidParamException if the asset to be published does not exist. - */ - public function publish($path, $options = []) + protected function loadBundle($name, $config = []) { - $path = Yii::getAlias($path); - - if (isset($this->_published[$path])) { - return $this->_published[$path]; + if (!isset($config['class'])) { + $config['class'] = $name; } - - if (!is_string($path) || ($src = realpath($path)) === false) { - throw new InvalidParamException("The file or directory to be published does not exist: $path"); + $bundle = Yii::createObject($config); + if ($bundle->basePath === null) { + $bundle->basePath = $this->basePath; } - - if (is_file($src)) { - $dir = $this->hash(dirname($src) . filemtime($src)); - $fileName = basename($src); - $dstDir = $this->basePath . DIRECTORY_SEPARATOR . $dir; - $dstFile = $dstDir . DIRECTORY_SEPARATOR . $fileName; - - if (!is_dir($dstDir)) { - FileHelper::createDirectory($dstDir, $this->dirMode, true); - } - - if ($this->linkAssets) { - if (!is_file($dstFile)) { - symlink($src, $dstFile); - } - } elseif (@filemtime($dstFile) < @filemtime($src)) { - copy($src, $dstFile); - if ($this->fileMode !== null) { - @chmod($dstFile, $this->fileMode); - } - } - - return $this->_published[$path] = [$dstFile, $this->baseUrl . "/$dir/$fileName"]; - } else { - $dir = $this->hash($src . filemtime($src)); - $dstDir = $this->basePath . DIRECTORY_SEPARATOR . $dir; - if ($this->linkAssets) { - if (!is_dir($dstDir)) { - symlink($src, $dstDir); - } - } elseif (!is_dir($dstDir) || !empty($options['forceCopy']) || (!isset($options['forceCopy']) && $this->forceCopy)) { - $opts = [ - 'dirMode' => $this->dirMode, - 'fileMode' => $this->fileMode, - ]; - if (isset($options['beforeCopy'])) { - $opts['beforeCopy'] = $options['beforeCopy']; - } elseif ($this->beforeCopy !== null) { - $opts['beforeCopy'] = $this->beforeCopy; - } else { - $opts['beforeCopy'] = function ($from, $to) { - return strncmp(basename($from), '.', 1) !== 0; - }; - } - if (isset($options['afterCopy'])) { - $opts['afterCopy'] = $options['afterCopy']; - } elseif ($this->afterCopy !== null) { - $opts['afterCopy'] = $this->afterCopy; - } - FileHelper::copyDirectory($src, $dstDir, $opts); - } - - return $this->_published[$path] = [$dstDir, $this->baseUrl . '/' . $dir]; + if ($bundle->baseUrl === null) { + $bundle->baseUrl = $this->baseUrl; } + return $bundle; } /** - * Returns the published path of a file path. - * This method does not perform any publishing. It merely tells you - * if the file or directory is published, where it will go. - * @param string $path directory or file path being published - * @return string the published file path. False if the file or directory does not exist + * @param View $view + * @param AssetBundle $bundle */ - public function getPublishedPath($path) + public function registerAssetFiles($view, $bundle) { - $path = Yii::getAlias($path); - - if (isset($this->_published[$path])) { - return $this->_published[$path][0]; + foreach ($bundle->js as $js) { + $view->registerJsFile($this->getAssetUrl($bundle, $js), $bundle->jsOptions); } - if (is_string($path) && ($path = realpath($path)) !== false) { - $base = $this->basePath . DIRECTORY_SEPARATOR; - if (is_file($path)) { - return $base . $this->hash(dirname($path) . filemtime($path)) . DIRECTORY_SEPARATOR . basename($path); - } else { - return $base . $this->hash($path . filemtime($path)); - } - } else { - return false; + foreach ($bundle->css as $css) { + $view->registerCssFile($this->getAssetUrl($bundle, $css), $bundle->cssOptions); } } - /** - * Returns the URL of a published file path. - * This method does not perform any publishing. It merely tells you - * if the file path is published, what the URL will be to access it. - * @param string $path directory or file path being published - * @return string the published URL for the file or directory. False if the file or directory does not exist. - */ - public function getPublishedUrl($path) + protected function getAssetUrl($bundle, $file) { - $path = Yii::getAlias($path); - - if (isset($this->_published[$path])) { - return $this->_published[$path][1]; + if (strncmp($file, '@/', 2) === 0) { + $file = $this->baseUrl . substr($file, 1); + } elseif (Url::isRelative($file)) { + $file = $bundle->baseUrl . '/' . $file; } - if (is_string($path) && ($path = realpath($path)) !== false) { - if (is_file($path)) { - return $this->baseUrl . '/' . $this->hash(dirname($path) . filemtime($path)) . '/' . basename($path); - } else { - return $this->baseUrl . '/' . $this->hash($path . filemtime($path)); - } - } else { - return false; - } - } - - /** - * Generate a CRC32 hash for the directory path. Collisions are higher - * than MD5 but generates a much smaller hash string. - * @param string $path string to be hashed. - * @return string hashed string. - */ - protected function hash($path) - { - return sprintf('%x', crc32($path . Yii::getVersion())); + // todo: assetMap + return $file; } } diff --git a/framework/web/JqueryAsset.php b/framework/web/JqueryAsset.php index 96cbf03..bc5b896 100644 --- a/framework/web/JqueryAsset.php +++ b/framework/web/JqueryAsset.php @@ -15,8 +15,7 @@ namespace yii\web; */ class JqueryAsset extends AssetBundle { - public $sourcePath = '@vendor/yiisoft/jquery'; public $js = [ - 'jquery.js', + 'jquery/dist/jquery.js', ]; } diff --git a/framework/web/View.php b/framework/web/View.php index cccfd1d..c1ce75a 100644 --- a/framework/web/View.php +++ b/framework/web/View.php @@ -8,9 +8,9 @@ namespace yii\web; use Yii; +use yii\helpers\ArrayHelper; use yii\helpers\Html; use yii\base\InvalidConfigException; -use yii\helpers\Url; /** * View represents a view object in the MVC pattern. @@ -261,7 +261,7 @@ class View extends \yii\base\View foreach ($bundle->depends as $dep) { $this->registerAssetFiles($dep); } - $bundle->registerAssetFiles($this); + $this->getAssetManager()->registerAssetFiles($this, $bundle); } unset($this->assetBundles[$name]); } @@ -360,23 +360,27 @@ class View extends \yii\base\View /** * Registers a CSS file. * @param string $url the CSS file to be registered. - * @param array $depends the names of the asset bundles that this CSS file depends on - * @param array $options the HTML attributes for the link tag. - * Please refer to [[Html::cssFile()]] for supported options. + * @param array $options the HTML attributes for the link tag. Please refer to [[Html::cssFile()]] for + * the supported options. The following options are specially handled and are not treated as HTML attributes: + * + * - `depends`: array, specifies the names of the asset bundles that this CSS file depends on. + * * @param string $key the key that identifies the CSS script file. If null, it will use * $url as the key. If two CSS files are registered with the same key, the latter * will overwrite the former. */ - public function registerCssFile($url, $depends = [], $options = [], $key = null) + public function registerCssFile($url, $options = [], $key = null) { $url = Yii::getAlias($url); $key = $key ?: $url; + $depends = ArrayHelper::remove($options, 'depends', []); + if (empty($depends)) { $this->cssFiles[$key] = Html::cssFile($url, $options); } else { - $am = $this->getAssetManager(); - $am->bundles[$key] = new AssetBundle([ - 'css' => [Url::to($url)], + $this->getAssetManager()->bundles[$key] = new AssetBundle([ + 'baseUrl' => '', + 'css' => [$url], 'cssOptions' => $options, 'depends' => (array) $depends, ]); @@ -414,14 +418,14 @@ class View extends \yii\base\View /** * Registers a JS file. * @param string $url the JS file to be registered. - * @param array $depends the names of the asset bundles that this JS file depends on - * @param array $options the HTML attributes for the script tag. A special option - * named "position" is supported which specifies where the JS script tag should be inserted - * in a page. The possible values of "position" are: + * @param array $options the HTML attributes for the script tag. The following options are specially handled + * and are not treated as HTML attributes: * - * - [[POS_HEAD]]: in the head section - * - [[POS_BEGIN]]: at the beginning of the body section - * - [[POS_END]]: at the end of the body section. This is the default value. + * - `depends`: array, specifies the names of the asset bundles that this JS file depends on. + * - `position`: specifies where the JS script tag should be inserted in a page. The possible values are: + * * [[POS_HEAD]]: in the head section + * * [[POS_BEGIN]]: at the beginning of the body section + * * [[POS_END]]: at the end of the body section. This is the default value. * * Please refer to [[Html::jsFile()]] for other supported options. * @@ -429,18 +433,19 @@ class View extends \yii\base\View * $url as the key. If two JS files are registered with the same key, the latter * will overwrite the former. */ - public function registerJsFile($url, $depends = [], $options = [], $key = null) + public function registerJsFile($url, $options = [], $key = null) { $url = Yii::getAlias($url); $key = $key ?: $url; + $depends = ArrayHelper::remove($options, 'depends', []); + if (empty($depends)) { - $position = isset($options['position']) ? $options['position'] : self::POS_END; - unset($options['position']); + $position = ArrayHelper::remove($options, 'position', self::POS_END); $this->jsFiles[$position][$key] = Html::jsFile($url, $options); } else { - $am = $this->getAssetManager(); - $am->bundles[$key] = new AssetBundle([ - 'js' => [Url::to($url)], + $this->getAssetManager()->bundles[$key] = new AssetBundle([ + 'baseUrl' => '', + 'js' => [$url], 'jsOptions' => $options, 'depends' => (array) $depends, ]); diff --git a/framework/web/YiiAsset.php b/framework/web/YiiAsset.php index db7e85e..79fd235 100644 --- a/framework/web/YiiAsset.php +++ b/framework/web/YiiAsset.php @@ -15,9 +15,8 @@ namespace yii\web; */ class YiiAsset extends AssetBundle { - public $sourcePath = '@yii/assets'; public $js = [ - 'yii.js', + 'yii2/assets/yii.js', ]; public $depends = [ 'yii\web\JqueryAsset', From 04f49de88115d4c645b08197a8cd001abfd51a83 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 28 Aug 2014 14:21:27 -0400 Subject: [PATCH 02/12] new asset WIP --- extensions/bootstrap/composer.json | 54 ++++++++++++++-------------- framework/web/AssetBundle.php | 26 ++++++++------ framework/web/AssetManager.php | 72 +++++++++++++++++++++++++++++--------- 3 files changed, 99 insertions(+), 53 deletions(-) diff --git a/extensions/bootstrap/composer.json b/extensions/bootstrap/composer.json index 8b717c8..ba3a326 100644 --- a/extensions/bootstrap/composer.json +++ b/extensions/bootstrap/composer.json @@ -1,29 +1,29 @@ { - "name": "yiisoft/yii2-bootstrap", - "description": "The Twitter Bootstrap extension for the Yii framework", - "keywords": ["yii2", "bootstrap"], - "type": "yii2-extension", - "license": "BSD-3-Clause", - "support": { - "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Abootstrap", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", - "source": "https://github.com/yiisoft/yii2" - }, - "authors": [ - { - "name": "Qiang Xue", - "email": "qiang.xue@gmail.com" - } - ], - "require": { - "yiisoft/yii2": "*", - "twbs/bootstrap": "3.2.* | 3.1.* | 3.0.*" - }, - "autoload": { - "psr-4": { - "yii\\bootstrap\\": "" - } - } + "name": "yiisoft/yii2-bootstrap", + "description": "The Twitter Bootstrap extension for the Yii framework", + "keywords": ["yii2", "bootstrap"], + "type": "yii2-extension", + "license": "BSD-3-Clause", + "support": { + "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Abootstrap", + "forum": "http://www.yiiframework.com/forum/", + "wiki": "http://www.yiiframework.com/wiki/", + "irc": "irc://irc.freenode.net/yii", + "source": "https://github.com/yiisoft/yii2" + }, + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com" + } + ], + "require": { + "yiisoft/yii2": "*", + "twbs/bootstrap": "3.2.* | 3.1.* | 3.0.*" + }, + "autoload": { + "psr-4": { + "yii\\bootstrap\\": "" + } + } } diff --git a/framework/web/AssetBundle.php b/framework/web/AssetBundle.php index eb2bea9..b37ed8e 100644 --- a/framework/web/AssetBundle.php +++ b/framework/web/AssetBundle.php @@ -29,8 +29,8 @@ class AssetBundle extends Object * @var string the directory that contains the asset files in this bundle. * * The value of this property can be prefixed to every relative asset file path listed in [[js]] and [[css]] - * to form an absolute file path. If this property is null (meaning not set), the value of - * [[AssetManager::basePath]] will be used instead. + * to form an absolute file path. If this property is null (meaning not set), it will be filled with the value of + * [[AssetManager::basePath]] when the bundle is being loaded by [[AssetManager::getBundle()]]. * * You can use either a directory or an alias of the directory. */ @@ -40,7 +40,8 @@ class AssetBundle extends Object * * The value of this property will be prefixed to every relative asset file path listed in [[js]] and [[css]] * when they are being registered in a view so that they can be Web accessible. - * If this property is null (meaning not set), the value of [[AssetManager::baseUrl]] will be used instead. + * If this property is null (meaning not set), it will be filled with the value of + * [[AssetManager::baseUrl]] when the bundle is being loaded by [[AssetManager::getBundle()]]. * * You can use either a URL or an alias of the URL. */ @@ -59,17 +60,22 @@ class AssetBundle extends Object */ public $depends = []; /** - * @var array list of JavaScript files that this bundle contains. Each JavaScript file can - * be either a file path (without leading slash) relative to [[basePath]] and [[baseUrl]], - * or a URL representing an external JavaScript file. + * @var array list of JavaScript files that this bundle contains. Each JavaScript file can be + * specified in one of the following formats: * - * Note that only forward slash "/" can be used as directory separators. + * - an absolute URL representing an external asset. For example, + * `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` or + * `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`. + * - a path relative to [[basePath]] and [[baseUrl]]: for example, `js/main.js`. There should be no leading slash. + * - a path relative to [[AssetManager::basePath]] and [[AssetManager::baseUrl]]: for example, + * `@/jquery/dist/jquery.js`. The path must begin with `@/`. + * + * Note that only forward slash "/" should be used as directory separators. */ public $js = []; /** - * @var array list of CSS files that this bundle contains. Each CSS file can - * be either a file path (without leading slash) relative to [[basePath]] and [[baseUrl]], - * or a URL representing an external CSS file. + * @var array list of CSS files that this bundle contains. Each CSS file can be specified + * in one of the three formats as explained in [[js]]. * * Note that only forward slash "/" can be used as directory separator. */ diff --git a/framework/web/AssetManager.php b/framework/web/AssetManager.php index 84b4786..225a1db 100644 --- a/framework/web/AssetManager.php +++ b/framework/web/AssetManager.php @@ -10,31 +10,24 @@ namespace yii\web; use Yii; use yii\base\Component; use yii\base\InvalidConfigException; -use yii\base\InvalidParamException; -use yii\helpers\FileHelper; use yii\helpers\Url; /** - * AssetManager manages asset bundles and asset publishing. + * AssetManager manages asset bundle configuration and loading. * * AssetManager is configured as an application component in [[\yii\web\Application]] by default. * You can access that instance via `Yii::$app->assetManager`. * * You can modify its configuration by adding an array to your application config under `components` - * as it is shown in the following example: + * as shown in the following example: * - * ~~~ + * ```php * 'assetManager' => [ * 'bundles' => [ * // you can override AssetBundle configs here * ], - * //'linkAssets' => true, - * // ... * ] - * ~~~ - * - * @property AssetConverterInterface $converter The asset converter. Note that the type of this property - * differs in getter and setter. See [[getConverter()]] and [[setConverter()]] for details. + * ``` * * @author Qiang Xue * @since 2.0 @@ -42,10 +35,19 @@ use yii\helpers\Url; class AssetManager extends Component { /** - * @var array list of available asset bundles. The keys are the class names (**without leading backslash**) - * of the asset bundles, and the values are either the configuration arrays for creating the [[AssetBundle]] - * objects or the corresponding asset bundle instances. For example, the following code disables - * the bootstrap css file used by Bootstrap widgets (because you want to use your own styles): + * @var array|boolean list of asset bundle configurations. This property is provided to customize asset bundles. + * When a bundle is being loaded by [[getBundle()]], if it has a corresponding configuration specified here, + * the configuration will be applied to the bundle. + * + * The array keys are the asset bundle names, which typically are asset bundle class names without leading backslash. + * The array values are the corresponding configurations. If a value is false, it means the corresponding asset + * bundle is disabled and [[getBundle()]] should return null. + * + * If this this property is false, it means the whole asset bundle feature is disabled and [[getBundle()]] + * will always return null. + * + * The following example shows how to disable the bootstrap css file used by Bootstrap widgets + * (because you want to use your own styles): * * ~~~ * [ @@ -64,8 +66,25 @@ class AssetManager extends Component * @return string the base URL through which the published asset files can be accessed. */ public $baseUrl = '@web/assets'; + /** + * @var array mapping from source asset files (keys) to target asset files (values). + * When an asset bundle is being loaded by [[getBundle()]], each of its asset files (listed in either + * [[AssetBundle::css]] or [[AssetBundle::js]] will be examined to see if it matches any key + * in this map. If so, the corresponding value will be used to replace the asset file. + * + * Note that the target asset files should be either absolute URLs or paths relative to [[baseUrl]] and [[basePath]]. + * + * In the following example, any occurrence of `jquery.min.js` will be replaced with `jquery/dist/jquery.js`. + * + * ```php + * [ + * 'jquery.min.js' => 'jquery/dist/jquery.js', + * ] + * ``` + */ public $assetMap = []; + /** * Initializes the component. * @throws InvalidConfigException if [[basePath]] is invalid @@ -140,12 +159,33 @@ class AssetManager extends Component protected function getAssetUrl($bundle, $file) { + if (($mappedFile = $this->mapAsset($file)) !== false) { + return Url::isRelative($mappedFile) ? $this->baseUrl . '/' . $mappedFile : $mappedFile; + } + if (strncmp($file, '@/', 2) === 0) { $file = $this->baseUrl . substr($file, 1); } elseif (Url::isRelative($file)) { $file = $bundle->baseUrl . '/' . $file; } - // todo: assetMap + return $file; } + + protected function mapAsset($file) + { + if (isset($this->assetMap[$file])) { + return $this->assetMap[$file]; + } + + $n = strlen($file); + foreach ($this->assetMap as $from => $to) { + $n2 = strlen($from); + if ($n2 <= $n && substr_compare($file, $from, $n - $n2, $n2) === 0) { + return $to; + } + } + + return false; + } } From eb7ffc8e7aa121ca41a4e36a3557959e7fe62761 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 28 Aug 2014 15:11:50 -0400 Subject: [PATCH 03/12] new asset WIP --- extensions/bootstrap/BootstrapAsset.php | 3 +-- extensions/bootstrap/BootstrapPluginAsset.php | 3 +-- extensions/bootstrap/BootstrapThemeAsset.php | 3 +-- extensions/debug/DebugAsset.php | 5 ++--- extensions/gii/GiiAsset.php | 23 ++++++----------------- 5 files changed, 11 insertions(+), 26 deletions(-) diff --git a/extensions/bootstrap/BootstrapAsset.php b/extensions/bootstrap/BootstrapAsset.php index d5b1244..78ead6b 100644 --- a/extensions/bootstrap/BootstrapAsset.php +++ b/extensions/bootstrap/BootstrapAsset.php @@ -17,8 +17,7 @@ use yii\web\AssetBundle; */ class BootstrapAsset extends AssetBundle { - public $sourcePath = '@vendor/twbs/bootstrap/dist'; public $css = [ - 'css/bootstrap.css', + 'bootstrap/dist/css/bootstrap.css', ]; } diff --git a/extensions/bootstrap/BootstrapPluginAsset.php b/extensions/bootstrap/BootstrapPluginAsset.php index 13aa162..8fd6d47 100644 --- a/extensions/bootstrap/BootstrapPluginAsset.php +++ b/extensions/bootstrap/BootstrapPluginAsset.php @@ -17,9 +17,8 @@ use yii\web\AssetBundle; */ class BootstrapPluginAsset extends AssetBundle { - public $sourcePath = '@vendor/twbs/bootstrap/dist'; public $js = [ - 'js/bootstrap.js', + 'bootstrap/dist/js/bootstrap.js', ]; public $depends = [ 'yii\web\JqueryAsset', diff --git a/extensions/bootstrap/BootstrapThemeAsset.php b/extensions/bootstrap/BootstrapThemeAsset.php index 584573a..007f355 100644 --- a/extensions/bootstrap/BootstrapThemeAsset.php +++ b/extensions/bootstrap/BootstrapThemeAsset.php @@ -17,9 +17,8 @@ use yii\web\AssetBundle; */ class BootstrapThemeAsset extends AssetBundle { - public $sourcePath = '@vendor/twbs/bootstrap/dist'; public $css = [ - 'css/bootstrap-theme.css', + 'bootstrap/dist/css/bootstrap-theme.css', ]; public $depends = [ 'yii\bootstrap\BootstrapAsset', diff --git a/extensions/debug/DebugAsset.php b/extensions/debug/DebugAsset.php index 4d9d3c9..f1ba95b 100644 --- a/extensions/debug/DebugAsset.php +++ b/extensions/debug/DebugAsset.php @@ -17,10 +17,9 @@ use yii\web\AssetBundle; */ class DebugAsset extends AssetBundle { - public $sourcePath = '@yii/debug/assets'; public $css = [ - 'main.css', - 'toolbar.css', + 'yii2-debug\assets\main.css', + 'yii2-debug\assets\toolbar.css', ]; public $depends = [ 'yii\web\YiiAsset', diff --git a/extensions/gii/GiiAsset.php b/extensions/gii/GiiAsset.php index 3eeb673..3132da9 100644 --- a/extensions/gii/GiiAsset.php +++ b/extensions/gii/GiiAsset.php @@ -17,27 +17,16 @@ use yii\web\AssetBundle; */ class GiiAsset extends AssetBundle { - /** - * @inheritdoc - */ - public $sourcePath = '@yii/gii/assets'; - /** - * @inheritdoc - */ public $css = [ - 'main.css', - 'typeahead.js-bootstrap.css', + 'yii2-gii/assets/main.css', +// 'typeahead.js-bootstrap.css', ]; - /** - * @inheritdoc - */ + public $js = [ - 'gii.js', - 'typeahead.js', + 'yii2-gii/assets/gii.js', + 'typeahead.js/dist/typeahead.jquery.js', ]; - /** - * @inheritdoc - */ + public $depends = [ 'yii\web\YiiAsset', 'yii\bootstrap\BootstrapAsset', From 1a625516911430b32cf9c70ce5825d6b93eef4c7 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 28 Aug 2014 17:02:56 -0400 Subject: [PATCH 04/12] new asset WIP --- extensions/debug/DebugAsset.php | 4 ++-- framework/captcha/CaptchaAsset.php | 3 +-- framework/grid/GridViewAsset.php | 3 +-- framework/validators/PunycodeAsset.php | 1 - framework/validators/ValidationAsset.php | 3 +-- framework/widgets/ActiveFormAsset.php | 3 +-- framework/widgets/MaskedInputAsset.php | 3 +-- framework/widgets/PjaxAsset.php | 3 +-- 8 files changed, 8 insertions(+), 15 deletions(-) diff --git a/extensions/debug/DebugAsset.php b/extensions/debug/DebugAsset.php index f1ba95b..09d5f31 100644 --- a/extensions/debug/DebugAsset.php +++ b/extensions/debug/DebugAsset.php @@ -18,8 +18,8 @@ use yii\web\AssetBundle; class DebugAsset extends AssetBundle { public $css = [ - 'yii2-debug\assets\main.css', - 'yii2-debug\assets\toolbar.css', + 'yii2-debug/assets/main.css', + 'yii2-debug/assets/toolbar.css', ]; public $depends = [ 'yii\web\YiiAsset', diff --git a/framework/captcha/CaptchaAsset.php b/framework/captcha/CaptchaAsset.php index 8af07e1..bf10100 100644 --- a/framework/captcha/CaptchaAsset.php +++ b/framework/captcha/CaptchaAsset.php @@ -17,9 +17,8 @@ use yii\web\AssetBundle; */ class CaptchaAsset extends AssetBundle { - public $sourcePath = '@yii/assets'; public $js = [ - 'yii.captcha.js', + 'yii2/assets/yii.captcha.js', ]; public $depends = [ 'yii\web\YiiAsset', diff --git a/framework/grid/GridViewAsset.php b/framework/grid/GridViewAsset.php index 0403e9f..3ecf136 100644 --- a/framework/grid/GridViewAsset.php +++ b/framework/grid/GridViewAsset.php @@ -17,9 +17,8 @@ use yii\web\AssetBundle; */ class GridViewAsset extends AssetBundle { - public $sourcePath = '@yii/assets'; public $js = [ - 'yii.gridView.js', + 'yii2/assets/yii.gridView.js', ]; public $depends = [ 'yii\web\YiiAsset', diff --git a/framework/validators/PunycodeAsset.php b/framework/validators/PunycodeAsset.php index 1988da5..b8d0d12 100644 --- a/framework/validators/PunycodeAsset.php +++ b/framework/validators/PunycodeAsset.php @@ -17,7 +17,6 @@ use yii\web\AssetBundle; */ class PunycodeAsset extends AssetBundle { - public $sourcePath = '@yii/assets'; public $js = [ 'punycode/punycode.js', ]; diff --git a/framework/validators/ValidationAsset.php b/framework/validators/ValidationAsset.php index a25acff..3fbd40c 100644 --- a/framework/validators/ValidationAsset.php +++ b/framework/validators/ValidationAsset.php @@ -17,9 +17,8 @@ use yii\web\AssetBundle; */ class ValidationAsset extends AssetBundle { - public $sourcePath = '@yii/assets'; public $js = [ - 'yii.validation.js', + 'yii2/assets/yii.validation.js', ]; public $depends = [ 'yii\web\YiiAsset', diff --git a/framework/widgets/ActiveFormAsset.php b/framework/widgets/ActiveFormAsset.php index 9716063..c95ff07 100644 --- a/framework/widgets/ActiveFormAsset.php +++ b/framework/widgets/ActiveFormAsset.php @@ -15,9 +15,8 @@ use yii\web\AssetBundle; */ class ActiveFormAsset extends AssetBundle { - public $sourcePath = '@yii/assets'; public $js = [ - 'yii.activeForm.js', + 'yii2/assets/yii.activeForm.js', ]; public $depends = [ 'yii\web\YiiAsset', diff --git a/framework/widgets/MaskedInputAsset.php b/framework/widgets/MaskedInputAsset.php index fea33d0..086855a 100644 --- a/framework/widgets/MaskedInputAsset.php +++ b/framework/widgets/MaskedInputAsset.php @@ -19,9 +19,8 @@ use yii\web\AssetBundle; */ class MaskedInputAsset extends AssetBundle { - public $sourcePath = '@yii/assets'; public $js = [ - 'jquery.inputmask.bundle.min.js' + 'jquery.inputmask/dist/jquery.inputmask.bundle.js' ]; public $depends = [ 'yii\web\YiiAsset' diff --git a/framework/widgets/PjaxAsset.php b/framework/widgets/PjaxAsset.php index 4844f79..dfbfcc2 100644 --- a/framework/widgets/PjaxAsset.php +++ b/framework/widgets/PjaxAsset.php @@ -17,9 +17,8 @@ use yii\web\AssetBundle; */ class PjaxAsset extends AssetBundle { - public $sourcePath = '@vendor/yiisoft/jquery-pjax'; public $js = [ - 'jquery.pjax.js', + 'yii2-pjax/jquery.pjax.js', ]; public $depends = [ 'yii\web\YiiAsset', From d184fbb8ed02dcafa775e3682478463c85bb3b40 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 29 Aug 2014 14:54:49 -0400 Subject: [PATCH 05/12] new asset WIP [skip ci] --- apps/advanced/backend/.bowerrc | 3 + apps/advanced/backend/assets/AppAsset.php | 7 +- apps/advanced/backend/bower.json | 8 + apps/advanced/backend/web/assets/.gitignore | 2 - apps/advanced/backend/web/assets/.gitkeep | 1 + apps/advanced/frontend/.bowerrc | 3 + apps/advanced/frontend/bower.json | 8 + apps/advanced/frontend/web/assets/.gitignore | 2 - apps/advanced/frontend/web/assets/.gitkeep | 1 + apps/basic/bower.json | 2 +- apps/basic/web/assets/.gitignore | 2 - apps/basic/web/assets/.gitkeep | 1 + extensions/README.md | 3 + extensions/authclient/widgets/AuthChoiceAsset.php | 5 +- extensions/bootstrap/composer.json | 3 +- extensions/gii/GiiAsset.php | 3 +- extensions/gii/assets/main.css | 44 +- extensions/gii/assets/typeahead.js | 1640 --------------------- extensions/gii/assets/typeahead.js-bootstrap.css | 51 - extensions/gii/components/ActiveField.php | 2 +- extensions/gii/views/layouts/main.php | 2 +- framework/assets/jquery.inputmask.bundle.min.js | 106 -- framework/assets/punycode/LICENSE-GPL.txt | 278 ---- framework/assets/punycode/LICENSE-MIT.txt | 20 - framework/assets/punycode/punycode.js | 502 ------- framework/assets/punycode/punycode.min.js | 2 - framework/composer.json | 2 - 27 files changed, 80 insertions(+), 2623 deletions(-) create mode 100644 apps/advanced/backend/.bowerrc create mode 100644 apps/advanced/backend/bower.json delete mode 100644 apps/advanced/backend/web/assets/.gitignore create mode 100644 apps/advanced/backend/web/assets/.gitkeep create mode 100644 apps/advanced/frontend/.bowerrc create mode 100644 apps/advanced/frontend/bower.json delete mode 100644 apps/advanced/frontend/web/assets/.gitignore create mode 100644 apps/advanced/frontend/web/assets/.gitkeep delete mode 100644 apps/basic/web/assets/.gitignore create mode 100644 apps/basic/web/assets/.gitkeep delete mode 100644 extensions/gii/assets/typeahead.js delete mode 100644 extensions/gii/assets/typeahead.js-bootstrap.css delete mode 100644 framework/assets/jquery.inputmask.bundle.min.js delete mode 100644 framework/assets/punycode/LICENSE-GPL.txt delete mode 100644 framework/assets/punycode/LICENSE-MIT.txt delete mode 100644 framework/assets/punycode/punycode.js delete mode 100644 framework/assets/punycode/punycode.min.js diff --git a/apps/advanced/backend/.bowerrc b/apps/advanced/backend/.bowerrc new file mode 100644 index 0000000..16098e9 --- /dev/null +++ b/apps/advanced/backend/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory" : "web/assets" +} \ No newline at end of file diff --git a/apps/advanced/backend/assets/AppAsset.php b/apps/advanced/backend/assets/AppAsset.php index b6c3268..c262142 100644 --- a/apps/advanced/backend/assets/AppAsset.php +++ b/apps/advanced/backend/assets/AppAsset.php @@ -17,8 +17,11 @@ class AppAsset extends AssetBundle { public $basePath = '@webroot'; public $baseUrl = '@web'; - public $css = ['css/site.css']; - public $js = []; + public $css = [ + 'css/site.css', + ]; + public $js = [ + ]; public $depends = [ 'yii\web\YiiAsset', 'yii\bootstrap\BootstrapAsset', diff --git a/apps/advanced/backend/bower.json b/apps/advanced/backend/bower.json new file mode 100644 index 0000000..4e165e6 --- /dev/null +++ b/apps/advanced/backend/bower.json @@ -0,0 +1,8 @@ +{ + "name": "yii2-advanced-backend", + "version": "1.0.0", + "dependencies": { + }, + "devDependencies": { + } +} diff --git a/apps/advanced/backend/web/assets/.gitignore b/apps/advanced/backend/web/assets/.gitignore deleted file mode 100644 index c96a04f..0000000 --- a/apps/advanced/backend/web/assets/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/apps/advanced/backend/web/assets/.gitkeep b/apps/advanced/backend/web/assets/.gitkeep new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/apps/advanced/backend/web/assets/.gitkeep @@ -0,0 +1 @@ +* diff --git a/apps/advanced/frontend/.bowerrc b/apps/advanced/frontend/.bowerrc new file mode 100644 index 0000000..16098e9 --- /dev/null +++ b/apps/advanced/frontend/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory" : "web/assets" +} \ No newline at end of file diff --git a/apps/advanced/frontend/bower.json b/apps/advanced/frontend/bower.json new file mode 100644 index 0000000..cad1f7e --- /dev/null +++ b/apps/advanced/frontend/bower.json @@ -0,0 +1,8 @@ +{ + "name": "yii2-advanced-frontend", + "version": "1.0.0", + "dependencies": { + }, + "devDependencies": { + } +} diff --git a/apps/advanced/frontend/web/assets/.gitignore b/apps/advanced/frontend/web/assets/.gitignore deleted file mode 100644 index c96a04f..0000000 --- a/apps/advanced/frontend/web/assets/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/apps/advanced/frontend/web/assets/.gitkeep b/apps/advanced/frontend/web/assets/.gitkeep new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/apps/advanced/frontend/web/assets/.gitkeep @@ -0,0 +1 @@ +* diff --git a/apps/basic/bower.json b/apps/basic/bower.json index b3ec7cd..2bcac4f 100644 --- a/apps/basic/bower.json +++ b/apps/basic/bower.json @@ -1,5 +1,5 @@ { - "name": "yii2-basic", + "name": "yii2-basic-app", "version": "1.0.0", "dependencies": { }, diff --git a/apps/basic/web/assets/.gitignore b/apps/basic/web/assets/.gitignore deleted file mode 100644 index c96a04f..0000000 --- a/apps/basic/web/assets/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/apps/basic/web/assets/.gitkeep b/apps/basic/web/assets/.gitkeep new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/apps/basic/web/assets/.gitkeep @@ -0,0 +1 @@ +* diff --git a/extensions/README.md b/extensions/README.md index 3662b22..a840f05 100644 --- a/extensions/README.md +++ b/extensions/README.md @@ -10,3 +10,6 @@ To add a new extension named `xyz` (must be in lower case), take the following s * `LICENSE.md` 3. ask Qiang to create a subsplit for `xyz` and a composer package named `yii2-xyz`; 4. modify `/composer.json` and add `xyz` to the `replace` section; +5. If an extension contains js/css files or depends on external bower packages: + * create `bower.json` + * ask Qiang to register a bower package with the name `yii2-xyz` diff --git a/extensions/authclient/widgets/AuthChoiceAsset.php b/extensions/authclient/widgets/AuthChoiceAsset.php index bef31b2..7e58370 100644 --- a/extensions/authclient/widgets/AuthChoiceAsset.php +++ b/extensions/authclient/widgets/AuthChoiceAsset.php @@ -17,12 +17,11 @@ use yii\web\AssetBundle; */ class AuthChoiceAsset extends AssetBundle { - public $sourcePath = '@yii/authclient/assets'; public $js = [ - 'authchoice.js', + 'yii2-authclient/assets/authchoice.js', ]; public $css = [ - 'authchoice.css', + 'yii2-authclient/assets/authchoice.css', ]; public $depends = [ 'yii\web\YiiAsset', diff --git a/extensions/bootstrap/composer.json b/extensions/bootstrap/composer.json index ba3a326..0e43773 100644 --- a/extensions/bootstrap/composer.json +++ b/extensions/bootstrap/composer.json @@ -18,8 +18,7 @@ } ], "require": { - "yiisoft/yii2": "*", - "twbs/bootstrap": "3.2.* | 3.1.* | 3.0.*" + "yiisoft/yii2": "*" }, "autoload": { "psr-4": { diff --git a/extensions/gii/GiiAsset.php b/extensions/gii/GiiAsset.php index 3132da9..5a76a32 100644 --- a/extensions/gii/GiiAsset.php +++ b/extensions/gii/GiiAsset.php @@ -19,12 +19,11 @@ class GiiAsset extends AssetBundle { public $css = [ 'yii2-gii/assets/main.css', -// 'typeahead.js-bootstrap.css', ]; public $js = [ 'yii2-gii/assets/gii.js', - 'typeahead.js/dist/typeahead.jquery.js', + 'typeahead.js/dist/typeahead.bundle.js', ]; public $depends = [ diff --git a/extensions/gii/assets/main.css b/extensions/gii/assets/main.css index 0fcde56..87d5f90 100644 --- a/extensions/gii/assets/main.css +++ b/extensions/gii/assets/main.css @@ -125,7 +125,6 @@ body { text-decoration: none; } - .Differences { width: 100%; border-collapse: collapse; @@ -214,10 +213,47 @@ body { content: attr(data-line-number); } -/* additional styles for typeahead.js-bootstrap.css */ +/* additional styles for typeahead.js, adapted from http://twitter.github.io/typeahead.js/examples/ */ + .twitter-typeahead { display: block !important; } -.twitter-typeahead .tt-hint { - padding: 6px 12px !important; + +.tt-query { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.tt-hint { + color: #999 +} + +.tt-dropdown-menu { + width: 422px; + margin-top: 2px; + padding: 8px 0; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); +} + +.tt-suggestion { + padding: 3px 20px; + font-size: 18px; + line-height: 24px; +} + +.tt-suggestion.tt-cursor { + color: #fff; + background-color: #0097cf; + } + +.tt-suggestion p { + margin: 0; +} + diff --git a/extensions/gii/assets/typeahead.js b/extensions/gii/assets/typeahead.js deleted file mode 100644 index ffba71d..0000000 --- a/extensions/gii/assets/typeahead.js +++ /dev/null @@ -1,1640 +0,0 @@ -/*! - * typeahead.js 0.10.0 - * https://github.com/twitter/typeahead.js - * Copyright 2013 Twitter, Inc. and other contributors; Licensed MIT - */ - -(function($) { - var _ = { - isMsie: function() { - return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; - }, - isBlankString: function(str) { - return !str || /^\s*$/.test(str); - }, - escapeRegExChars: function(str) { - return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - }, - isString: function(obj) { - return typeof obj === "string"; - }, - isNumber: function(obj) { - return typeof obj === "number"; - }, - isArray: $.isArray, - isFunction: $.isFunction, - isObject: $.isPlainObject, - isUndefined: function(obj) { - return typeof obj === "undefined"; - }, - bind: $.proxy, - each: function(collection, cb) { - $.each(collection, reverseArgs); - function reverseArgs(index, value) { - return cb(value, index); - } - }, - map: $.map, - filter: $.grep, - every: function(obj, test) { - var result = true; - if (!obj) { - return result; - } - $.each(obj, function(key, val) { - if (!(result = test.call(null, val, key, obj))) { - return false; - } - }); - return !!result; - }, - some: function(obj, test) { - var result = false; - if (!obj) { - return result; - } - $.each(obj, function(key, val) { - if (result = test.call(null, val, key, obj)) { - return false; - } - }); - return !!result; - }, - mixin: $.extend, - getUniqueId: function() { - var counter = 0; - return function() { - return counter++; - }; - }(), - templatify: function templatify(obj) { - return $.isFunction(obj) ? obj : template; - function template() { - return String(obj); - } - }, - defer: function(fn) { - setTimeout(fn, 0); - }, - debounce: function(func, wait, immediate) { - var timeout, result; - return function() { - var context = this, args = arguments, later, callNow; - later = function() { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - } - }; - callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) { - result = func.apply(context, args); - } - return result; - }; - }, - throttle: function(func, wait) { - var context, args, timeout, result, previous, later; - previous = 0; - later = function() { - previous = new Date(); - timeout = null; - result = func.apply(context, args); - }; - return function() { - var now = new Date(), remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - } else if (!timeout) { - timeout = setTimeout(later, remaining); - } - return result; - }; - }, - noop: function() {} - }; - var VERSION = "0.10.0"; - var LruCache = function(root, undefined) { - function LruCache(maxSize) { - this.maxSize = maxSize || 100; - this.size = 0; - this.hash = {}; - this.list = new List(); - } - _.mixin(LruCache.prototype, { - set: function set(key, val) { - var tailItem = this.list.tail, node; - if (this.size >= this.maxSize) { - this.list.remove(tailItem); - delete this.hash[tailItem.key]; - } - if (node = this.hash[key]) { - node.val = val; - this.list.moveToFront(node); - } else { - node = new Node(key, val); - this.list.add(node); - this.hash[key] = node; - this.size++; - } - }, - get: function get(key) { - var node = this.hash[key]; - if (node) { - this.list.moveToFront(node); - return node.val; - } - } - }); - function List() { - this.head = this.tail = null; - } - _.mixin(List.prototype, { - add: function add(node) { - if (this.head) { - node.next = this.head; - this.head.prev = node; - } - this.head = node; - this.tail = this.tail || node; - }, - remove: function remove(node) { - node.prev ? node.prev.next = node.next : this.head = node.next; - node.next ? node.next.prev = node.prev : this.tail = node.prev; - }, - moveToFront: function(node) { - this.remove(node); - this.add(node); - } - }); - function Node(key, val) { - this.key = key; - this.val = val; - this.prev = this.next = null; - } - return LruCache; - }(this); - var PersistentStorage = function() { - var ls, methods; - try { - ls = window.localStorage; - ls.setItem("~~~", "!"); - ls.removeItem("~~~"); - } catch (err) { - ls = null; - } - function PersistentStorage(namespace) { - this.prefix = [ "__", namespace, "__" ].join(""); - this.ttlKey = "__ttl__"; - this.keyMatcher = new RegExp("^" + this.prefix); - } - if (ls && window.JSON) { - methods = { - _prefix: function(key) { - return this.prefix + key; - }, - _ttlKey: function(key) { - return this._prefix(key) + this.ttlKey; - }, - get: function(key) { - if (this.isExpired(key)) { - this.remove(key); - } - return decode(ls.getItem(this._prefix(key))); - }, - set: function(key, val, ttl) { - if (_.isNumber(ttl)) { - ls.setItem(this._ttlKey(key), encode(now() + ttl)); - } else { - ls.removeItem(this._ttlKey(key)); - } - return ls.setItem(this._prefix(key), encode(val)); - }, - remove: function(key) { - ls.removeItem(this._ttlKey(key)); - ls.removeItem(this._prefix(key)); - return this; - }, - clear: function() { - var i, key, keys = [], len = ls.length; - for (i = 0; i < len; i++) { - if ((key = ls.key(i)).match(this.keyMatcher)) { - keys.push(key.replace(this.keyMatcher, "")); - } - } - for (i = keys.length; i--; ) { - this.remove(keys[i]); - } - return this; - }, - isExpired: function(key) { - var ttl = decode(ls.getItem(this._ttlKey(key))); - return _.isNumber(ttl) && now() > ttl ? true : false; - } - }; - } else { - methods = { - get: _.noop, - set: _.noop, - remove: _.noop, - clear: _.noop, - isExpired: _.noop - }; - } - _.mixin(PersistentStorage.prototype, methods); - return PersistentStorage; - function now() { - return new Date().getTime(); - } - function encode(val) { - return JSON.stringify(_.isUndefined(val) ? null : val); - } - function decode(val) { - return JSON.parse(val); - } - }(); - var Transport = function() { - var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, requestCache = new LruCache(10); - function Transport(o) { - o = o || {}; - this._send = o.send ? callbackToDeferred(o.send) : $.ajax; - this._get = o.rateLimiter ? o.rateLimiter(this._get) : this._get; - } - Transport.setMaxPendingRequests = function setMaxPendingRequests(num) { - maxPendingRequests = num; - }; - Transport.resetCache = function clearCache() { - requestCache = new LruCache(10); - }; - _.mixin(Transport.prototype, { - _get: function(url, o, cb) { - var that = this, jqXhr; - if (jqXhr = pendingRequests[url]) { - jqXhr.done(done); - } else if (pendingRequestsCount < maxPendingRequests) { - pendingRequestsCount++; - pendingRequests[url] = this._send(url, o).done(done).always(always); - } else { - this.onDeckRequestArgs = [].slice.call(arguments, 0); - } - function done(resp) { - cb && cb(resp); - requestCache.set(url, resp); - } - function always() { - pendingRequestsCount--; - delete pendingRequests[url]; - if (that.onDeckRequestArgs) { - that._get.apply(that, that.onDeckRequestArgs); - that.onDeckRequestArgs = null; - } - } - }, - get: function(url, o, cb) { - var that = this, resp; - if (_.isFunction(o)) { - cb = o; - o = {}; - } - if (resp = requestCache.get(url)) { - _.defer(function() { - cb && cb(resp); - }); - } else { - this._get(url, o, cb); - } - return !!resp; - } - }); - return Transport; - function callbackToDeferred(fn) { - return function customSendWrapper(url, o) { - var deferred = $.Deferred(); - fn(url, o, onSuccess, onError); - return deferred; - function onSuccess(resp) { - _.defer(function() { - deferred.resolve(resp); - }); - } - function onError(err) { - _.defer(function() { - deferred.reject(err); - }); - } - }; - } - }(); - var SearchIndex = function() { - function SearchIndex(o) { - o = o || {}; - if (!o.datumTokenizer || !o.queryTokenizer) { - $.error("datumTokenizer and queryTokenizer are both required"); - } - this.datumTokenizer = o.datumTokenizer; - this.queryTokenizer = o.queryTokenizer; - this.datums = []; - this.trie = newNode(); - } - _.mixin(SearchIndex.prototype, { - bootstrap: function bootstrap(o) { - this.datums = o.datums; - this.trie = o.trie; - }, - add: function(data) { - var that = this; - data = _.isArray(data) ? data : [ data ]; - _.each(data, function(datum) { - var id, tokens; - id = that.datums.push(datum) - 1; - tokens = normalizeTokens(that.datumTokenizer(datum)); - _.each(tokens, function(token) { - var node, chars, ch, ids; - node = that.trie; - chars = token.split(""); - while (ch = chars.shift()) { - node = node.children[ch] || (node.children[ch] = newNode()); - node.ids.push(id); - } - }); - }); - }, - get: function get(query) { - var that = this, tokens, matches; - tokens = normalizeTokens(this.queryTokenizer(query)); - _.each(tokens, function(token) { - var node, chars, ch, ids; - if (matches && matches.length === 0) { - return false; - } - node = that.trie; - chars = token.split(""); - while (node && (ch = chars.shift())) { - node = node.children[ch]; - } - if (node && chars.length === 0) { - ids = node.ids.slice(0); - matches = matches ? getIntersection(matches, ids) : ids; - } else { - matches = []; - return false; - } - }); - return matches ? _.map(unique(matches), function(id) { - return that.datums[id]; - }) : []; - }, - serialize: function serialize() { - return { - datums: this.datums, - trie: this.trie - }; - } - }); - return SearchIndex; - function normalizeTokens(tokens) { - tokens = _.filter(tokens, function(token) { - return !!token; - }); - tokens = _.map(tokens, function(token) { - return token.toLowerCase(); - }); - return tokens; - } - function newNode() { - return { - ids: [], - children: {} - }; - } - function unique(array) { - var seen = {}, uniques = []; - for (var i = 0; i < array.length; i++) { - if (!seen[array[i]]) { - seen[array[i]] = true; - uniques.push(array[i]); - } - } - return uniques; - } - function getIntersection(arrayA, arrayB) { - var ai = 0, bi = 0, intersection = []; - arrayA = arrayA.sort(compare); - arrayB = arrayB.sort(compare); - while (ai < arrayA.length && bi < arrayB.length) { - if (arrayA[ai] < arrayB[bi]) { - ai++; - } else if (arrayA[ai] > arrayB[bi]) { - bi++; - } else { - intersection.push(arrayA[ai]); - ai++; - bi++; - } - } - return intersection; - function compare(a, b) { - return a - b; - } - } - }(); - var oParser = function() { - return { - local: getLocal, - prefetch: getPrefetch, - remote: getRemote - }; - function getLocal(o) { - return o.local || null; - } - function getPrefetch(o) { - var prefetch, defaults; - defaults = { - url: null, - thumbprint: "", - ttl: 24 * 60 * 60 * 1e3, - filter: null, - ajax: {} - }; - if (prefetch = o.prefetch || null) { - prefetch = _.isString(prefetch) ? { - url: prefetch - } : prefetch; - prefetch = _.mixin(defaults, prefetch); - prefetch.thumbprint = VERSION + prefetch.thumbprint; - prefetch.ajax.method = prefetch.ajax.method || "get"; - prefetch.ajax.dataType = prefetch.ajax.dataType || "json"; - !prefetch.url && $.error("prefetch requires url to be set"); - } - return prefetch; - } - function getRemote(o) { - var remote, defaults; - defaults = { - url: null, - wildcard: "%QUERY", - replace: null, - rateLimitBy: "debounce", - rateLimitWait: 300, - send: null, - filter: null, - ajax: {} - }; - if (remote = o.remote || null) { - remote = _.isString(remote) ? { - url: remote - } : remote; - remote = _.mixin(defaults, remote); - remote.rateLimiter = /^throttle$/i.test(remote.rateLimitBy) ? byThrottle(remote.rateLimitWait) : byDebounce(remote.rateLimitWait); - remote.ajax.method = remote.ajax.method || "get"; - remote.ajax.dataType = remote.ajax.dataType || "json"; - delete remote.rateLimitBy; - delete remote.rateLimitWait; - !remote.url && $.error("remote requires url to be set"); - } - return remote; - function byDebounce(wait) { - return function(fn) { - return _.debounce(fn, wait); - }; - } - function byThrottle(wait) { - return function(fn) { - return _.throttle(fn, wait); - }; - } - } - }(); - var Bloodhound = window.Bloodhound = function() { - var keys; - keys = { - data: "data", - protocol: "protocol", - thumbprint: "thumbprint" - }; - function Bloodhound(o) { - if (!o || !o.local && !o.prefetch && !o.remote) { - $.error("one of local, prefetch, or remote is required"); - } - this.limit = o.limit || 5; - this.sorter = o.sorter || noSort; - this.dupDetector = o.dupDetector || ignoreDuplicates; - this.local = oParser.local(o); - this.prefetch = oParser.prefetch(o); - this.remote = oParser.remote(o); - this.cacheKey = this.prefetch ? this.prefetch.cacheKey || this.prefetch.url : null; - this.index = new SearchIndex({ - datumTokenizer: o.datumTokenizer, - queryTokenizer: o.queryTokenizer - }); - this.storage = this.cacheKey ? new PersistentStorage(this.cacheKey) : null; - } - Bloodhound.tokenizers = { - whitespace: function whitespaceTokenizer(s) { - return s.split(/\s+/); - }, - nonword: function nonwordTokenizer(s) { - return s.split(/\W+/); - } - }; - _.mixin(Bloodhound.prototype, { - _loadPrefetch: function loadPrefetch(o) { - var that = this, serialized, deferred; - if (serialized = this._readFromStorage(o.thumbprint)) { - this.index.bootstrap(serialized); - deferred = $.Deferred().resolve(); - } else { - deferred = $.ajax(o.url, o.ajax).done(handlePrefetchResponse); - } - return deferred; - function handlePrefetchResponse(resp) { - var filtered; - filtered = o.filter ? o.filter(resp) : resp; - that.add(filtered); - that._saveToStorage(that.index.serialize(), o.thumbprint, o.ttl); - } - }, - _getFromRemote: function getFromRemote(query, cb) { - var that = this, url, uriEncodedQuery; - query = query || ""; - uriEncodedQuery = encodeURIComponent(query); - url = this.remote.replace ? this.remote.replace(this.remote.url, query) : this.remote.url.replace(this.remote.wildcard, uriEncodedQuery); - return this.transport.get(url, this.remote.ajax, handleRemoteResponse); - function handleRemoteResponse(resp) { - var filtered = that.remote.filter ? that.remote.filter(resp) : resp; - cb(filtered); - } - }, - _saveToStorage: function saveToStorage(data, thumbprint, ttl) { - if (this.storage) { - this.storage.set(keys.data, data, ttl); - this.storage.set(keys.protocol, location.protocol, ttl); - this.storage.set(keys.thumbprint, thumbprint, ttl); - } - }, - _readFromStorage: function readFromStorage(thumbprint) { - var stored = {}; - if (this.storage) { - stored.data = this.storage.get(keys.data); - stored.protocol = this.storage.get(keys.protocol); - stored.thumbprint = this.storage.get(keys.thumbprint); - } - isExpired = stored.thumbprint !== thumbprint || stored.protocol !== location.protocol; - return stored.data && !isExpired ? stored.data : null; - }, - initialize: function initialize() { - var that = this, deferred; - deferred = this.prefetch ? this._loadPrefetch(this.prefetch) : $.Deferred().resolve(); - this.local && deferred.done(addLocalToIndex); - this.transport = this.remote ? new Transport(this.remote) : null; - this.initialize = function initialize() { - return deferred.promise(); - }; - return deferred.promise(); - function addLocalToIndex() { - that.add(that.local); - } - }, - add: function add(data) { - this.index.add(data); - }, - get: function get(query, cb) { - var that = this, matches, cacheHit = false; - matches = this.index.get(query).sort(this.sorter).slice(0, this.limit); - if (matches.length < this.limit && this.transport) { - cacheHit = this._getFromRemote(query, returnRemoteMatches); - } - !cacheHit && cb && cb(matches); - function returnRemoteMatches(remoteMatches) { - var matchesWithBackfill = matches.slice(0); - _.each(remoteMatches, function(remoteMatch) { - var isDuplicate; - isDuplicate = _.some(matchesWithBackfill, function(match) { - return that.dupDetector(remoteMatch, match); - }); - !isDuplicate && matchesWithBackfill.push(remoteMatch); - return matchesWithBackfill.length < that.limit; - }); - cb && cb(matchesWithBackfill.sort(that.sorter)); - } - }, - ttAdapter: function ttAdapter() { - return _.bind(this.get, this); - } - }); - return Bloodhound; - function noSort() { - return 0; - } - function ignoreDuplicates() { - return false; - } - }(); - var html = { - wrapper: '', - dropdown: '', - dataset: '
', - suggestions: '', - suggestion: '
%BODY%
' - }; - var css = { - wrapper: { - position: "relative", - display: "inline-block" - }, - hint: { - position: "absolute", - top: "0", - left: "0", - borderColor: "transparent", - boxShadow: "none" - }, - input: { - position: "relative", - verticalAlign: "top", - backgroundColor: "transparent" - }, - inputWithNoHint: { - position: "relative", - verticalAlign: "top" - }, - dropdown: { - position: "absolute", - top: "100%", - left: "0", - zIndex: "100", - display: "none" - }, - suggestions: { - display: "block" - }, - suggestion: { - whiteSpace: "nowrap", - cursor: "pointer" - }, - suggestionChild: { - whiteSpace: "normal" - }, - ltr: { - left: "0", - right: "auto" - }, - rtl: { - left: "auto", - right: " 0" - } - }; - if (_.isMsie()) { - _.mixin(css.input, { - backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" - }); - } - if (_.isMsie() && _.isMsie() <= 7) { - _.mixin(css.input, { - marginTop: "-1px" - }); - } - var EventBus = function() { - var namespace = "typeahead:"; - function EventBus(o) { - if (!o || !o.el) { - $.error("EventBus initialized without el"); - } - this.$el = $(o.el); - } - _.mixin(EventBus.prototype, { - trigger: function(type) { - var args = [].slice.call(arguments, 1); - this.$el.trigger(namespace + type, args); - } - }); - return EventBus; - }(); - var EventEmitter = function() { - var splitter = /\s+/, nextTick = getNextTick(); - return { - onSync: onSync, - onAsync: onAsync, - off: off, - trigger: trigger - }; - function on(method, types, cb, context) { - var type; - if (!cb) { - return this; - } - types = types.split(splitter); - cb = context ? bindContext(cb, context) : cb; - this._callbacks = this._callbacks || {}; - while (type = types.shift()) { - this._callbacks[type] = this._callbacks[type] || { - sync: [], - async: [] - }; - this._callbacks[type][method].push(cb); - } - return this; - } - function onAsync(types, cb, context) { - return on.call(this, "async", types, cb, context); - } - function onSync(types, cb, context) { - return on.call(this, "sync", types, cb, context); - } - function off(types) { - var type; - if (!this._callbacks) { - return this; - } - types = types.split(splitter); - while (type = types.shift()) { - delete this._callbacks[type]; - } - return this; - } - function trigger(types) { - var that = this, type, callbacks, args, syncFlush, asyncFlush; - if (!this._callbacks) { - return this; - } - types = types.split(splitter); - args = [].slice.call(arguments, 1); - while ((type = types.shift()) && (callbacks = this._callbacks[type])) { - syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args)); - asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args)); - syncFlush() && nextTick(asyncFlush); - } - return this; - } - function getFlush(callbacks, context, args) { - return flush; - function flush() { - var cancelled; - for (var i = 0; !cancelled && i < callbacks.length; i += 1) { - cancelled = callbacks[i].apply(context, args) === false; - } - return !cancelled; - } - } - function getNextTick() { - var nextTickFn, messageChannel; - if (window.setImmediate) { - nextTickFn = function nextTickSetImmediate(fn) { - setImmediate(function() { - fn(); - }); - }; - } else { - nextTickFn = function nextTickSetTimeout(fn) { - setTimeout(function() { - fn(); - }, 0); - }; - } - return nextTickFn; - } - function bindContext(fn, context) { - return fn.bind ? fn.bind(context) : function() { - fn.apply(context, [].slice.call(arguments, 0)); - }; - } - }(); - var highlight = function(doc) { - var defaults = { - node: null, - pattern: null, - tagName: "strong", - className: null, - wordsOnly: false, - caseSensitive: false - }; - return function hightlight(o) { - var regex; - o = _.mixin({}, defaults, o); - if (!o.node || !o.pattern) { - return; - } - o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; - regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly); - traverse(o.node, hightlightTextNode); - function hightlightTextNode(textNode) { - var match, patternNode; - if (match = regex.exec(textNode.data)) { - wrapperNode = doc.createElement(o.tagName); - o.className && (wrapperNode.className = o.className); - patternNode = textNode.splitText(match.index); - patternNode.splitText(match[0].length); - wrapperNode.appendChild(patternNode.cloneNode(true)); - textNode.parentNode.replaceChild(wrapperNode, patternNode); - } - return !!match; - } - function traverse(el, hightlightTextNode) { - var childNode, TEXT_NODE_TYPE = 3; - for (var i = 0; i < el.childNodes.length; i++) { - childNode = el.childNodes[i]; - if (childNode.nodeType === TEXT_NODE_TYPE) { - i += hightlightTextNode(childNode) ? 1 : 0; - } else { - traverse(childNode, hightlightTextNode); - } - } - } - }; - function getRegex(patterns, caseSensitive, wordsOnly) { - var escapedPatterns = [], regexStr; - for (var i = 0; i < patterns.length; i++) { - escapedPatterns.push(_.escapeRegExChars(patterns[i])); - } - regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; - return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); - } - }(window.document); - var Input = function() { - var specialKeyCodeMap; - specialKeyCodeMap = { - 9: "tab", - 27: "esc", - 37: "left", - 39: "right", - 13: "enter", - 38: "up", - 40: "down" - }; - function Input(o) { - var that = this, onBlur, onFocus, onKeydown, onInput; - o = o || {}; - if (!o.input) { - $.error("input is missing"); - } - onBlur = _.bind(this._onBlur, this); - onFocus = _.bind(this._onFocus, this); - onKeydown = _.bind(this._onKeydown, this); - onInput = _.bind(this._onInput, this); - this.$hint = $(o.hint); - this.$input = $(o.input).on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown); - if (this.$hint.length === 0) { - this.setHintValue = this.getHintValue = this.clearHint = _.noop; - } - if (!_.isMsie()) { - this.$input.on("input.tt", onInput); - } else { - this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) { - if (specialKeyCodeMap[$e.which || $e.keyCode]) { - return; - } - _.defer(_.bind(that._onInput, that, $e)); - }); - } - this.query = this.$input.val(); - this.$overflowHelper = buildOverflowHelper(this.$input); - } - Input.normalizeQuery = function(str) { - return (str || "").replace(/^\s*/g, "").replace(/\s{2,}/g, " "); - }; - _.mixin(Input.prototype, EventEmitter, { - _onBlur: function onBlur($e) { - this.resetInputValue(); - this.trigger("blurred"); - }, - _onFocus: function onFocus($e) { - this.trigger("focused"); - }, - _onKeydown: function onKeydown($e) { - var keyName = specialKeyCodeMap[$e.which || $e.keyCode]; - this._managePreventDefault(keyName, $e); - if (keyName && this._shouldTrigger(keyName, $e)) { - this.trigger(keyName + "Keyed", $e); - } - }, - _onInput: function onInput($e) { - this._checkInputValue(); - }, - _managePreventDefault: function managePreventDefault(keyName, $e) { - var preventDefault, hintValue, inputValue; - switch (keyName) { - case "tab": - hintValue = this.getHintValue(); - inputValue = this.getInputValue(); - preventDefault = hintValue && hintValue !== inputValue && !withModifier($e); - break; - - case "up": - case "down": - preventDefault = !withModifier($e); - break; - - default: - preventDefault = false; - } - preventDefault && $e.preventDefault(); - }, - _shouldTrigger: function shouldTrigger(keyName, $e) { - var trigger; - switch (keyName) { - case "tab": - trigger = !withModifier($e); - break; - - default: - trigger = true; - } - return trigger; - }, - _checkInputValue: function checkInputValue() { - var inputValue, areEquivalent, hasDifferentWhitespace; - inputValue = this.getInputValue(); - areEquivalent = areQueriesEquivalent(inputValue, this.query); - hasDifferentWhitespace = areEquivalent ? this.query.length !== inputValue.length : false; - if (!areEquivalent) { - this.trigger("queryChanged", this.query = inputValue); - } else if (hasDifferentWhitespace) { - this.trigger("whitespaceChanged", this.query); - } - }, - focus: function focus() { - this.$input.focus(); - }, - blur: function blur() { - this.$input.blur(); - }, - getQuery: function getQuery() { - return this.query; - }, - setQuery: function setQuery(query) { - this.query = query; - }, - getInputValue: function getInputValue() { - return this.$input.val(); - }, - setInputValue: function setInputValue(value, silent) { - this.$input.val(value); - !silent && this._checkInputValue(); - }, - getHintValue: function getHintValue() { - return this.$hint.val(); - }, - setHintValue: function setHintValue(value) { - this.$hint.val(value); - }, - resetInputValue: function resetInputValue() { - this.$input.val(this.query); - }, - clearHint: function clearHint() { - this.$hint.val(""); - }, - getLanguageDirection: function getLanguageDirection() { - return (this.$input.css("direction") || "ltr").toLowerCase(); - }, - hasOverflow: function hasOverflow() { - var constraint = this.$input.width() - 2; - this.$overflowHelper.text(this.getInputValue()); - return this.$overflowHelper.width() >= constraint; - }, - isCursorAtEnd: function() { - var valueLength, selectionStart, range; - valueLength = this.$input.val().length; - selectionStart = this.$input[0].selectionStart; - if (_.isNumber(selectionStart)) { - return selectionStart === valueLength; - } else if (document.selection) { - range = document.selection.createRange(); - range.moveStart("character", -valueLength); - return valueLength === range.text.length; - } - return true; - }, - destroy: function destroy() { - this.$hint.off(".tt"); - this.$input.off(".tt"); - this.$hint = this.$input = this.$overflowHelper = null; - } - }); - return Input; - function buildOverflowHelper($input) { - return $('').css({ - position: "absolute", - visibility: "hidden", - whiteSpace: "nowrap", - fontFamily: $input.css("font-family"), - fontSize: $input.css("font-size"), - fontStyle: $input.css("font-style"), - fontVariant: $input.css("font-variant"), - fontWeight: $input.css("font-weight"), - wordSpacing: $input.css("word-spacing"), - letterSpacing: $input.css("letter-spacing"), - textIndent: $input.css("text-indent"), - textRendering: $input.css("text-rendering"), - textTransform: $input.css("text-transform") - }).insertAfter($input); - } - function areQueriesEquivalent(a, b) { - return Input.normalizeQuery(a) === Input.normalizeQuery(b); - } - function withModifier($e) { - return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey; - } - }(); - var Dataset = function() { - var datasetKey = "ttDataset", valueKey = "ttValue", datumKey = "ttDatum"; - function Dataset(o) { - o = o || {}; - o.templates = o.templates || {}; - if (!o.source) { - $.error("missing source"); - } - this.query = null; - this.highlight = !!o.highlight; - this.name = o.name || _.getUniqueId(); - this.source = o.source; - this.valueKey = o.displayKey || "value"; - this.templates = getTemplates(o.templates, this.valueKey); - this.$el = $(html.dataset.replace("%CLASS%", this.name)); - } - Dataset.extractDatasetName = function extractDatasetName(el) { - return $(el).data(datasetKey); - }; - Dataset.extractValue = function extractDatum(el) { - return $(el).data(valueKey); - }; - Dataset.extractDatum = function extractDatum(el) { - return $(el).data(datumKey); - }; - _.mixin(Dataset.prototype, EventEmitter, { - _render: function render(query, suggestions) { - if (!this.$el) { - return; - } - var that = this, hasSuggestions; - this.$el.empty(); - hasSuggestions = suggestions && suggestions.length; - if (!hasSuggestions && this.templates.empty) { - this.$el.html(getEmptyHtml()).prepend(that.templates.header ? getHeaderHtml() : null).append(that.templates.footer ? getFooterHtml() : null); - } else if (hasSuggestions) { - this.$el.html(getSuggestionsHtml()).prepend(that.templates.header ? getHeaderHtml() : null).append(that.templates.footer ? getFooterHtml() : null); - } - this.trigger("rendered"); - function getEmptyHtml() { - return that.templates.empty({ - query: query - }); - } - function getSuggestionsHtml() { - var $suggestions; - $suggestions = $(html.suggestions).css(css.suggestions).append(_.map(suggestions, getSuggestionNode)); - that.highlight && highlight({ - node: $suggestions[0], - pattern: query - }); - return $suggestions; - function getSuggestionNode(suggestion) { - var $el, innerHtml, outerHtml; - innerHtml = that.templates.suggestion(suggestion); - outerHtml = html.suggestion.replace("%BODY%", innerHtml); - $el = $(outerHtml).data(datasetKey, that.name).data(valueKey, suggestion[that.valueKey]).data(datumKey, suggestion); - $el.children().each(function() { - $(this).css(css.suggestionChild); - }); - return $el; - } - } - function getHeaderHtml() { - return that.templates.header({ - query: query, - isEmpty: !hasSuggestions - }); - } - function getFooterHtml() { - return that.templates.footer({ - query: query, - isEmpty: !hasSuggestions - }); - } - }, - getRoot: function getRoot() { - return this.$el; - }, - update: function update(query) { - var that = this; - this.query = query; - this.source(query, renderIfQueryIsSame); - function renderIfQueryIsSame(suggestions) { - query === that.query && that._render(query, suggestions); - } - }, - clear: function clear() { - this._render(this.query || ""); - }, - isEmpty: function isEmpty() { - return this.$el.is(":empty"); - }, - destroy: function destroy() { - this.$el = null; - } - }); - return Dataset; - function getTemplates(templates, valueKey) { - return { - empty: templates.empty && _.templatify(templates.empty), - header: templates.header && _.templatify(templates.header), - footer: templates.footer && _.templatify(templates.footer), - suggestion: templates.suggestion || suggestionTemplate - }; - function suggestionTemplate(context) { - return "

" + context[valueKey] + "

"; - } - } - }(); - var Dropdown = function() { - function Dropdown(o) { - var that = this, onMouseEnter, onMouseLeave, onSuggestionClick, onSuggestionMouseEnter, onSuggestionMouseLeave; - o = o || {}; - if (!o.menu) { - $.error("menu is required"); - } - this.isOpen = false; - this.isEmpty = true; - this.isMouseOverDropdown = false; - this.datasets = _.map(o.datasets, initializeDataset); - onMouseEnter = _.bind(this._onMouseEnter, this); - onMouseLeave = _.bind(this._onMouseLeave, this); - onSuggestionClick = _.bind(this._onSuggestionClick, this); - onSuggestionMouseEnter = _.bind(this._onSuggestionMouseEnter, this); - onSuggestionMouseLeave = _.bind(this._onSuggestionMouseLeave, this); - this.$menu = $(o.menu).on("mouseenter.tt", onMouseEnter).on("mouseleave.tt", onMouseLeave).on("click.tt", ".tt-suggestion", onSuggestionClick).on("mouseenter.tt", ".tt-suggestion", onSuggestionMouseEnter).on("mouseleave.tt", ".tt-suggestion", onSuggestionMouseLeave); - _.each(this.datasets, function(dataset) { - that.$menu.append(dataset.getRoot()); - dataset.onSync("rendered", that._onRendered, that); - }); - } - _.mixin(Dropdown.prototype, EventEmitter, { - _onMouseEnter: function onMouseEnter($e) { - this.isMouseOverDropdown = true; - }, - _onMouseLeave: function onMouseLeave($e) { - this.isMouseOverDropdown = false; - }, - _onSuggestionClick: function onSuggestionClick($e) { - this.trigger("suggestionClicked", $($e.currentTarget)); - }, - _onSuggestionMouseEnter: function onSuggestionMouseEnter($e) { - this._removeCursor(); - this._setCursor($($e.currentTarget), true); - }, - _onSuggestionMouseLeave: function onSuggestionMouseLeave($e) { - this._removeCursor(); - }, - _onRendered: function onRendered() { - this.isEmpty = _.every(this.datasets, isDatasetEmpty); - this.isEmpty ? this._hide() : this.isOpen && this._show(); - this.trigger("datasetRendered"); - function isDatasetEmpty(dataset) { - return dataset.isEmpty(); - } - }, - _hide: function() { - this.$menu.hide(); - }, - _show: function() { - this.$menu.css("display", "block"); - }, - _getSuggestions: function getSuggestions() { - return this.$menu.find(".tt-suggestion"); - }, - _getCursor: function getCursor() { - return this.$menu.find(".tt-cursor").first(); - }, - _setCursor: function setCursor($el, silent) { - $el.first().addClass("tt-cursor"); - !silent && this.trigger("cursorMoved"); - }, - _removeCursor: function removeCursor() { - this._getCursor().removeClass("tt-cursor"); - }, - _moveCursor: function moveCursor(increment) { - var $suggestions, $oldCursor, newCursorIndex, $newCursor; - if (!this.isOpen) { - return; - } - $oldCursor = this._getCursor(); - $suggestions = this._getSuggestions(); - this._removeCursor(); - newCursorIndex = $suggestions.index($oldCursor) + increment; - newCursorIndex = (newCursorIndex + 1) % ($suggestions.length + 1) - 1; - if (newCursorIndex === -1) { - this.trigger("cursorRemoved"); - return; - } else if (newCursorIndex < -1) { - newCursorIndex = $suggestions.length - 1; - } - this._setCursor($newCursor = $suggestions.eq(newCursorIndex)); - this._ensureVisible($newCursor); - }, - _ensureVisible: function ensureVisible($el) { - var elTop, elBottom, menuScrollTop, menuHeight; - elTop = $el.position().top; - elBottom = elTop + $el.outerHeight(true); - menuScrollTop = this.$menu.scrollTop(); - menuHeight = this.$menu.height() + parseInt(this.$menu.css("paddingTop"), 10) + parseInt(this.$menu.css("paddingBottom"), 10); - if (elTop < 0) { - this.$menu.scrollTop(menuScrollTop + elTop); - } else if (menuHeight < elBottom) { - this.$menu.scrollTop(menuScrollTop + (elBottom - menuHeight)); - } - }, - close: function close() { - if (this.isOpen) { - this.isOpen = this.isMouseOverDropdown = false; - this._removeCursor(); - this._hide(); - this.trigger("closed"); - } - }, - open: function open() { - if (!this.isOpen) { - this.isOpen = true; - !this.isEmpty && this._show(); - this.trigger("opened"); - } - }, - setLanguageDirection: function setLanguageDirection(dir) { - this.$menu.css(dir === "ltr" ? css.ltr : css.rtl); - }, - moveCursorUp: function moveCursorUp() { - this._moveCursor(-1); - }, - moveCursorDown: function moveCursorDown() { - this._moveCursor(+1); - }, - getDatumForSuggestion: function getDatumForSuggestion($el) { - var datum = null; - if ($el.length) { - datum = { - raw: Dataset.extractDatum($el), - value: Dataset.extractValue($el), - datasetName: Dataset.extractDatasetName($el) - }; - } - return datum; - }, - getDatumForCursor: function getDatumForCursor() { - return this.getDatumForSuggestion(this._getCursor().first()); - }, - getDatumForTopSuggestion: function getDatumForTopSuggestion() { - return this.getDatumForSuggestion(this._getSuggestions().first()); - }, - update: function update(query) { - _.each(this.datasets, updateDataset); - function updateDataset(dataset) { - dataset.update(query); - } - }, - empty: function empty() { - _.each(this.datasets, clearDataset); - function clearDataset(dataset) { - dataset.clear(); - } - }, - isVisible: function isVisible() { - return this.isOpen && !this.isEmpty; - }, - destroy: function destroy() { - this.$menu.off(".tt"); - this.$menu = null; - _.each(this.datasets, destroyDataset); - function destroyDataset(dataset) { - dataset.destroy(); - } - } - }); - return Dropdown; - function initializeDataset(oDataset) { - return new Dataset(oDataset); - } - }(); - var Typeahead = function() { - var attrsKey = "ttAttrs"; - function Typeahead(o) { - var $menu, $input, $hint, datasets; - o = o || {}; - if (!o.input) { - $.error("missing input"); - } - this.autoselect = !!o.autoselect; - this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; - this.$node = buildDomStructure(o.input, o.withHint); - $menu = this.$node.find(".tt-dropdown-menu"); - $input = this.$node.find(".tt-input"); - $hint = this.$node.find(".tt-hint"); - this.eventBus = o.eventBus || new EventBus({ - el: $input - }); - this.dropdown = new Dropdown({ - menu: $menu, - datasets: o.datasets - }).onSync("suggestionClicked", this._onSuggestionClicked, this).onSync("cursorMoved", this._onCursorMoved, this).onSync("cursorRemoved", this._onCursorRemoved, this).onSync("opened", this._onOpened, this).onSync("closed", this._onClosed, this).onAsync("datasetRendered", this._onDatasetRendered, this); - this.input = new Input({ - input: $input, - hint: $hint - }).onSync("focused", this._onFocused, this).onSync("blurred", this._onBlurred, this).onSync("enterKeyed", this._onEnterKeyed, this).onSync("tabKeyed", this._onTabKeyed, this).onSync("escKeyed", this._onEscKeyed, this).onSync("upKeyed", this._onUpKeyed, this).onSync("downKeyed", this._onDownKeyed, this).onSync("leftKeyed", this._onLeftKeyed, this).onSync("rightKeyed", this._onRightKeyed, this).onSync("queryChanged", this._onQueryChanged, this).onSync("whitespaceChanged", this._onWhitespaceChanged, this); - $menu.on("mousedown.tt", function($e) { - if (_.isMsie() && _.isMsie() < 9) { - $input[0].onbeforedeactivate = function() { - window.event.returnValue = false; - $input[0].onbeforedeactivate = null; - }; - } - $e.preventDefault(); - }); - } - _.mixin(Typeahead.prototype, { - _onSuggestionClicked: function onSuggestionClicked(type, $el) { - var datum; - if (datum = this.dropdown.getDatumForSuggestion($el)) { - this._select(datum); - } - }, - _onCursorMoved: function onCursorMoved() { - var datum = this.dropdown.getDatumForCursor(); - this.input.clearHint(); - this.input.setInputValue(datum.value, true); - this.eventBus.trigger("cursorchanged", datum.raw, datum.datasetName); - }, - _onCursorRemoved: function onCursorRemoved() { - this.input.resetInputValue(); - this._updateHint(); - }, - _onDatasetRendered: function onDatasetRendered() { - this._updateHint(); - }, - _onOpened: function onOpened() { - this._updateHint(); - this.eventBus.trigger("opened"); - }, - _onClosed: function onClosed() { - this.input.clearHint(); - this.eventBus.trigger("closed"); - }, - _onFocused: function onFocused() { - this.dropdown.open(); - }, - _onBlurred: function onBlurred() { - !this.dropdown.isMouseOverDropdown && this.dropdown.close(); - }, - _onEnterKeyed: function onEnterKeyed(type, $e) { - var cursorDatum, topSuggestionDatum; - cursorDatum = this.dropdown.getDatumForCursor(); - topSuggestionDatum = this.dropdown.getDatumForTopSuggestion(); - if (cursorDatum) { - this._select(cursorDatum); - $e.preventDefault(); - } else if (this.autoselect && topSuggestionDatum) { - this._select(topSuggestionDatum); - $e.preventDefault(); - } - }, - _onTabKeyed: function onTabKeyed(type, $e) { - var datum; - if (datum = this.dropdown.getDatumForCursor()) { - this._select(datum); - $e.preventDefault(); - } else { - this._autocomplete(); - } - }, - _onEscKeyed: function onEscKeyed() { - this.dropdown.close(); - this.input.resetInputValue(); - }, - _onUpKeyed: function onUpKeyed() { - var query = this.input.getQuery(); - if (!this.dropdown.isOpen && query.length >= this.minLength) { - this.dropdown.update(query); - } - this.dropdown.open(); - this.dropdown.moveCursorUp(); - }, - _onDownKeyed: function onDownKeyed() { - var query = this.input.getQuery(); - if (!this.dropdown.isOpen && query.length >= this.minLength) { - this.dropdown.update(query); - } - this.dropdown.open(); - this.dropdown.moveCursorDown(); - }, - _onLeftKeyed: function onLeftKeyed() { - this.dir === "rtl" && this._autocomplete(); - }, - _onRightKeyed: function onRightKeyed() { - this.dir === "ltr" && this._autocomplete(); - }, - _onQueryChanged: function onQueryChanged(e, query) { - this.input.clearHint(); - this.dropdown.empty(); - query.length >= this.minLength && this.dropdown.update(query); - this.dropdown.open(); - this._setLanguageDirection(); - }, - _onWhitespaceChanged: function onWhitespaceChanged() { - this._updateHint(); - this.dropdown.open(); - }, - _setLanguageDirection: function setLanguageDirection() { - var dir; - if (this.dir !== (dir = this.input.getLanguageDirection())) { - this.dir = dir; - this.$node.css("direction", dir); - this.dropdown.setLanguageDirection(dir); - } - }, - _updateHint: function updateHint() { - var datum, inputValue, query, escapedQuery, frontMatchRegEx, match; - datum = this.dropdown.getDatumForTopSuggestion(); - if (datum && this.dropdown.isVisible() && !this.input.hasOverflow()) { - inputValue = this.input.getInputValue(); - query = Input.normalizeQuery(inputValue); - escapedQuery = _.escapeRegExChars(query); - frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.*$)", "i"); - match = frontMatchRegEx.exec(datum.value); - this.input.setHintValue(inputValue + (match ? match[1] : "")); - } - }, - _autocomplete: function autocomplete() { - var hint, query, datum; - hint = this.input.getHintValue(); - query = this.input.getQuery(); - if (hint && query !== hint && this.input.isCursorAtEnd()) { - datum = this.dropdown.getDatumForTopSuggestion(); - datum && this.input.setInputValue(datum.value); - this.eventBus.trigger("autocompleted", datum.raw, datum.datasetName); - } - }, - _select: function select(datum) { - this.input.clearHint(); - this.input.setQuery(datum.value); - this.input.setInputValue(datum.value, true); - this.dropdown.empty(); - this._setLanguageDirection(); - _.defer(_.bind(this.dropdown.close, this.dropdown)); - this.eventBus.trigger("selected", datum.raw, datum.datasetName); - }, - open: function open() { - this.dropdown.open(); - }, - close: function close() { - this.dropdown.close(); - }, - getQuery: function getQuery() { - return this.input.getQuery(); - }, - setQuery: function setQuery(val) { - this.input.setInputValue(val); - }, - destroy: function destroy() { - this.input.destroy(); - this.dropdown.destroy(); - destroyDomStructure(this.$node); - this.$node = null; - } - }); - return Typeahead; - function buildDomStructure(input, withHint) { - var $input, $wrapper, $dropdown, $hint; - $input = $(input); - $wrapper = $(html.wrapper).css(css.wrapper); - $dropdown = $(html.dropdown).css(css.dropdown); - $hint = $input.clone().css(css.hint).css(getBackgroundStyles($input)); - $hint.removeData().addClass("tt-hint").removeAttr("id name placeholder").prop("disabled", true).attr({ - autocomplete: "off", - spellcheck: "false" - }); - $input.data(attrsKey, { - dir: $input.attr("dir"), - autocomplete: $input.attr("autocomplete"), - spellcheck: $input.attr("spellcheck"), - style: $input.attr("style") - }); - $input.addClass("tt-input").attr({ - autocomplete: "off", - spellcheck: false - }).css(withHint ? css.input : css.inputWithNoHint); - try { - !$input.attr("dir") && $input.attr("dir", "auto"); - } catch (e) {} - return $input.wrap($wrapper).parent().prepend(withHint ? $hint : null).append($dropdown); - } - function getBackgroundStyles($el) { - return { - backgroundAttachment: $el.css("background-attachment"), - backgroundClip: $el.css("background-clip"), - backgroundColor: $el.css("background-color"), - backgroundImage: $el.css("background-image"), - backgroundOrigin: $el.css("background-origin"), - backgroundPosition: $el.css("background-position"), - backgroundRepeat: $el.css("background-repeat"), - backgroundSize: $el.css("background-size") - }; - } - function destroyDomStructure($node) { - var $input = $node.find(".tt-input"); - _.each($input.data(attrsKey), function(val, key) { - _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val); - }); - $input.detach().removeData(attrsKey).removeClass("tt-input").insertAfter($node); - $node.remove(); - } - }(); - (function() { - var typeaheadKey, methods; - typeaheadKey = "ttTypeahead"; - methods = { - initialize: function initialize(o) { - var datasets = [].slice.call(arguments, 1); - o = o || {}; - return this.each(attach); - function attach() { - var $input = $(this), eventBus, typeahead; - _.each(datasets, function(d) { - d.highlight = !!o.highlight; - }); - typeahead = new Typeahead({ - input: $input, - eventBus: eventBus = new EventBus({ - el: $input - }), - withHint: _.isUndefined(o.hint) ? true : !!o.hint, - minLength: o.minLength, - autoselect: o.autoselect, - datasets: datasets - }); - $input.data(typeaheadKey, typeahead); - function trigger(eventName) { - return function() { - _.defer(function() { - eventBus.trigger(eventName); - }); - }; - } - } - }, - open: function open() { - return this.each(openTypeahead); - function openTypeahead() { - var $input = $(this), typeahead; - if (typeahead = $input.data(typeaheadKey)) { - typeahead.open(); - } - } - }, - close: function close() { - return this.each(closeTypeahead); - function closeTypeahead() { - var $input = $(this), typeahead; - if (typeahead = $input.data(typeaheadKey)) { - typeahead.close(); - } - } - }, - val: function val(newVal) { - return _.isString(newVal) ? this.each(setQuery) : this.map(getQuery).get(); - function setQuery() { - var $input = $(this), typeahead; - if (typeahead = $input.data(typeaheadKey)) { - typeahead.setQuery(newVal); - } - } - function getQuery() { - var $input = $(this), typeahead, query; - if (typeahead = $input.data(typeaheadKey)) { - query = typeahead.getQuery(); - } - return query; - } - }, - destroy: function destroy() { - return this.each(unattach); - function unattach() { - var $input = $(this), typeahead; - if (typeahead = $input.data(typeaheadKey)) { - typeahead.destroy(); - $input.removeData(typeaheadKey); - } - } - } - }; - jQuery.fn.typeahead = function(method) { - if (methods[method]) { - return methods[method].apply(this, [].slice.call(arguments, 1)); - } else { - return methods.initialize.apply(this, arguments); - } - }; - })(); -})(window.jQuery); \ No newline at end of file diff --git a/extensions/gii/assets/typeahead.js-bootstrap.css b/extensions/gii/assets/typeahead.js-bootstrap.css deleted file mode 100644 index 987aaf5..0000000 --- a/extensions/gii/assets/typeahead.js-bootstrap.css +++ /dev/null @@ -1,51 +0,0 @@ -/* always keep this link here when updating this file: https://github.com/jharding/typeahead.js-bootstrap.css */ - -.twitter-typeahead .tt-query, -.twitter-typeahead .tt-hint { - margin-bottom: 0; -} - -.tt-dropdown-menu { - min-width: 160px; - margin-top: 2px; - padding: 5px 0; - background-color: #fff; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,.2); - *border-right-width: 2px; - *border-bottom-width: 2px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); - -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2); - box-shadow: 0 5px 10px rgba(0,0,0,.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} - -.tt-suggestion { - display: block; - padding: 3px 20px; -} - -.tt-suggestion.tt-is-under-cursor { - color: #fff; - background-color: #0081c2; - background-image: -moz-linear-gradient(top, #0088cc, #0077b3); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); - background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); - background-image: -o-linear-gradient(top, #0088cc, #0077b3); - background-image: linear-gradient(to bottom, #0088cc, #0077b3); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0) -} - -.tt-suggestion.tt-is-under-cursor a { - color: #fff; -} - -.tt-suggestion p { - margin: 0; -} diff --git a/extensions/gii/components/ActiveField.php b/extensions/gii/components/ActiveField.php index d8d899d..a810338 100644 --- a/extensions/gii/components/ActiveField.php +++ b/extensions/gii/components/ActiveField.php @@ -64,7 +64,7 @@ class ActiveField extends \yii\widgets\ActiveField public function autoComplete($data) { static $counter = 0; - $this->inputOptions['class'] .= ' typeahead-' . (++$counter); + $this->inputOptions['class'] .= ' typeahead typeahead-' . (++$counter); foreach ($data as &$item) { $item = ['word' => $item]; } diff --git a/extensions/gii/views/layouts/main.php b/extensions/gii/views/layouts/main.php index 0fed660..a3d0339 100644 --- a/extensions/gii/views/layouts/main.php +++ b/extensions/gii/views/layouts/main.php @@ -22,7 +22,7 @@ $asset = yii\gii\GiiAsset::register($this); beginBody() ?> Html::img($asset->baseUrl . '/logo.png'), + 'brandLabel' => Html::img('@web/assets/yii2-gii/assets/logo.png'), 'brandUrl' => ['default/index'], 'options' => ['class' => 'navbar-inverse navbar-fixed-top'], ]); diff --git a/framework/assets/jquery.inputmask.bundle.min.js b/framework/assets/jquery.inputmask.bundle.min.js deleted file mode 100644 index cde85cf..0000000 --- a/framework/assets/jquery.inputmask.bundle.min.js +++ /dev/null @@ -1,106 +0,0 @@ -/* - Input Mask plugin for jquery - http://github.com/RobinHerbots/jquery.inputmask - Copyright (c) 2010 - 2014 Robin Herbots - Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) - Version: 3.1.1 -*/ -(function(e){"function"===typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){if(void 0===e.fn.inputmask){var a=function(a){var b=document.createElement("input");a="on"+a;var f=a in b;f||(b.setAttribute(a,"return;"),f="function"==typeof b[a]);return f},b=function(a,c,f){return(a=f.aliases[a])?(a.alias&&b(a.alias,void 0,f),e.extend(!0,f,a),e.extend(!0,f,c),!0):!1},c=function(a,b){function f(b){function f(a,b,e,u){this.matches=[];this.isGroup=a||!1;this.isOptional=b||!1;this.isQuantifier= -e||!1;this.isAlternator=u||!1;this.quantifier={min:1,max:1}}function e(b,f,u){var c=a.definitions[f],d=0==b.matches.length;u=void 0!=u?u:b.matches.length;if(c&&!g){for(var h=c.prevalidator,k=h?h.length:0,s=1;s=s?h[s-1]:[],D=n.validator,n=n.cardinality;b.matches.splice(u++,0,{fn:D?"string"==typeof D?RegExp(D):new function(){this.test=D}:/./,cardinality:n?n:1,optionality:b.isOptional,newBlockMarker:d,casing:c.casing,def:c.definitionSymbol||f,placeholder:c.placeholder,mask:f})}b.matches.splice(u++, -0,{fn:c.validator?"string"==typeof c.validator?RegExp(c.validator):new function(){this.test=c.validator}:/./,cardinality:c.cardinality,optionality:b.isOptional,newBlockMarker:d,casing:c.casing,def:c.definitionSymbol||f,placeholder:c.placeholder,mask:f})}else b.matches.splice(u++,0,{fn:null,cardinality:0,optionality:b.isOptional,newBlockMarker:d,casing:null,def:f,placeholder:void 0,mask:f}),g=!1}for(var c=/(?:[?*+]|\{[0-9\+\*]+(?:,[0-9\+\*]*)?\})\??|[^.?*+^${[]()|\\]+|./g,g=!1,d=new f,u,h=[],l=[], -k,n;u=c.exec(b);)switch(u=u[0],u.charAt(0)){case a.optionalmarker.end:case a.groupmarker.end:u=h.pop();if(0h?M(h,g,h-1)[0]:da(h,g,h-1),r=g.match,g=g.locator.slice(),d.push(null==r.fn?r.def:void 0!=r.placeholder?r.placeholder:f.placeholder.charAt(h%f.placeholder.length));h++}while((void 0==P||h-1=h);d.pop();return d}function g(a){var q= -b;q.buffer=void 0;q.tests={};!0!==a&&(q._buffer=void 0,q.validPositions={},q.p=-1)}function x(a){var q=-1,f=b.validPositions;void 0==a&&(a=-1);var e=q,c;for(c in f){var d=parseInt(c);if(-1==a||null!=f[d].match.fn)d=a&&(q=d)}return 1s.quantifier.min-1,q=0==e.inArray(q,n.matches))if(t>s.quantifier.min-1){p=!0;k=a;break}else return!0;else return!0}else{if(q=g(q,d,B,t))return!0}else k++} -for(var m=0a)break}}var h=b.maskToken,k=c?d:0;d=c||[0];var r=[],p=!1;if(void 0==c){c=a-1;for(var m;void 0==(m=b.validPositions[c])&&-1a);c++);(0==r.length||p)&& -r.push({match:{fn:null,cardinality:0,optionality:!0,casing:null,def:""},locator:[]});b.tests[a]=e.extend(!0,[],r);return b.tests[a]}function I(){void 0==b._buffer&&(b._buffer=c(!1,1));return b._buffer}function s(){void 0==b.buffer&&(b.buffer=c(!0,x(),!0));return b.buffer}function ea(a,c){var d=s().slice();if(!0===a)g(),a=0,c=d.length;else for(var e=a;er;O--)t+=void 0==b.validPositions[a-(O-1)]?Z(a-(O-1)):b.validPositions[a-(O-1)].input;c&&(t+=c);y=null!=p.fn?p.fn.test(t,b,a,d,f):c!=p.def&&c!=f.skipOptionalPartCharacter||""==p.def?!1:{c:p.def,pos:a};if(!1!==y){r=void 0!=y.c?y.c:c;r=r==f.skipOptionalPartCharacter&&null===p.fn?p.def:r;t=a;void 0!=y.remove&& -F(y.remove,y.remove+1);if(y.refreshFromBuffer){t=y.refreshFromBuffer;d=!0;ea(!0===t?t:t.start,t.end);if(void 0==y.pos&&void 0==y.c)return y.pos=x(),!1;t=void 0!=y.pos?y.pos:a;if(t!=a)return y=e.extend(y,N(t,r,!0)),!1}else if(!0!==y&&void 0!=y.pos&&y.pos!=a&&(t=y.pos,ea(a,t),t!=a))return y=e.extend(y,N(t,r,!0)),!1;if(!0!=y&&void 0==y.pos&&void 0==y.c)return!1;0parseInt(h)&&void 0===b.validPositions[p].alternation){var r=b.validPositions[p].locator[B];h=b.validPositions[h].locator[B].split(",");for(var t=0;t=V())return m(a, -c,d,h);a=t(r,c,d,h);if(!d&&!1===a)if((p=b.validPositions[r])&&null==p.match.fn&&(p.match.def==c||c==f.skipOptionalPartCharacter))a={caret:E(r)};else if((f.insertMode||void 0==b.validPositions[E(r)])&&!n(r))for(var p=r+1,l=E(r);p<=l;p++)if(a=t(p,c,d,h),!1!==a){r=p;break}!0===a&&(a={pos:r});return a}function n(a){a=ia(a);return null!=a.fn?a.fn:!1}function V(){var a;P=m.prop("maxLength");-1==P&&(P=void 0);if(!1==f.greedy){var c;c=x();a=b.validPositions[c];var d=void 0!=a?a.locator.slice():void 0;for(c+= -1;void 0==a||null!=a.match.fn||null==a.match.fn&&""!=a.match.def;c++)a=da(c,d,c-1),d=a.locator.slice();a=c}else a=s().length;return void 0==P||a=b)return b;for(;++aa););return a}function Y(a){if(0>=a)return 0;for(;0<--a&&!n(a););return a}function G(a,b,c){a._valueSet(b.join(""));void 0!=c&&w(a,c)}function Z(a,b){b=b||ia(a);return b.placeholder||(null==b.fn?b.def:f.placeholder.charAt(a%f.placeholder.length))}function U(a, -c,d,h,t){h=void 0!=h?h.slice():qa(a._valueGet()).split("");g();c&&a._valueSet("");e.each(h,function(c,f){if(!0===t){var g=x(),q=-1==g?c:E(g);-1==e.inArray(f,I().slice(g+1,q))&&$.call(a,void 0,!0,f.charCodeAt(0),!1,d,c)}else $.call(a,void 0,!0,f.charCodeAt(0),!1,d,c),d=d||0b.p});c&&(c=f.onKeyPress.call(this,void 0,s(),0,f),ba(a,c),G(a,s(),e(a).is(":focus")?E(x(0)):void 0))}function ja(a){return e.inputmask.escapeRegex.call(this,a)}function qa(a){return a.replace(RegExp("("+ja(I().join(""))+")*$"), -"")}function ka(a){if(a.data("_inputmask")&&!a.hasClass("hasDatepicker")){var c=[],d=b.validPositions,g;for(g in d)d[g].match&&null!=d[g].match.fn&&c.push(d[g].input);c=(z?c.reverse():c).join("");d=(z?s().slice().reverse():s()).join("");e.isFunction(f.onUnMask)&&(c=f.onUnMask.call(a,d,c,f));return c}return a[0]._valueGet()}function S(a){!z||"number"!=typeof a||f.greedy&&""==f.placeholder||(a=s().length-a);return a}function w(a,b,c){a=a.jquery&&0g;f--)if(k=h[f].match,(k.optionality|| -k.optionalQuantifier||r&&void 0!=r.alternation&&void 0!=h[f].locator[r.alternation]&&-1!=e.inArray(h[f].locator[r.alternation].toString(),p))&&c[f]==Z(f,k))d--;else break;return a?{l:d,def:h[d]?h[d].match:void 0}:d}function ha(a){var b=s().slice(),c=ga();b.length=c;G(a,b)}function X(a){if(e.isFunction(f.isComplete))return f.isComplete.call(m,a,f);if("*"!=f.repeat){var b=!1,c=ga(!0),d=Y(c.l);if(x()==d&&(void 0==c.def||c.def.newBlockMarker||c.def.optionalQuantifier))for(b=!0,c=0;c<=d;c++){var g=n(c); -if(g&&(void 0==a[c]||a[c]==Z(c))||!g&&a[c]!=Z(c)){b=!1;break}}return b}}function ta(a){a=e._data(a).events;e.each(a,function(a,b){e.each(b,function(a,b){if("inputmask"==b.namespace&&"setvalue"!=b.type){var c=b.handler;b.handler=function(a){if(this.readOnly||this.disabled)a.preventDefault;else return c.apply(this,arguments)}}})})}function ua(a){function b(a){if(void 0==e.valHooks[a]||!0!=e.valHooks[a].inputmaskpatch){var c=e.valHooks[a]&&e.valHooks[a].get?e.valHooks[a].get:function(a){return a.value}, -d=e.valHooks[a]&&e.valHooks[a].set?e.valHooks[a].set:function(a,b){a.value=b;return a};e.valHooks[a]={get:function(a){var b=e(a);if(b.data("_inputmask")){if(b.data("_inputmask").opts.autoUnmask)return b.inputmask("unmaskedvalue");a=c(a);b=(b=b.data("_inputmask").maskset._buffer)?b.join(""):"";return a!=b?a:""}return c(a)},set:function(a,b){var c=e(a),f=c.data("_inputmask");f?(f=d(a,e.isFunction(f.opts.onBeforeMask)?f.opts.onBeforeMask.call(A,b,f.opts):b),c.triggerHandler("setvalue.inputmask")):f= -d(a,b);return f},inputmaskpatch:!0}}}function c(){var a=e(this),b=e(this).data("_inputmask");return b?b.opts.autoUnmask?a.inputmask("unmaskedvalue"):g.call(this)!=I().join("")?g.call(this):"":g.call(this)}function d(a){var b=e(this).data("_inputmask");b?(h.call(this,e.isFunction(b.opts.onBeforeMask)?b.opts.onBeforeMask.call(A,a,b.opts):a),e(this).triggerHandler("setvalue.inputmask")):h.call(this,a)}function f(a){e(a).bind("mouseenter.inputmask",function(a){a=e(this);var b=this._valueGet();""!=b&& -b!=s().join("")&&a.trigger("setvalue")});if(a=e._data(a).events.mouseover){for(var b=a[a.length-1],c=a.length-1;0=d.end-d.begin?d.begin=Y(d.begin):c==f.keyCode.DELETE&&d.begin==d.end&&d.end++;F(d.begin,d.end);c=x(d.begin);b.p=cc.length&&(w(this,c.length), -b=w(this));1!=s().length-c.length||c.charAt(b.begin)==s()[b.begin]||c.charAt(b.begin+1)==s()[b.begin]||n(b.begin)||(a.keyCode=f.keyCode.BACKSPACE,na.call(this,a));a.preventDefault()}function xa(a){if(!0===Q&&"input"==a.type)return Q=!1,!0;var c=w(this),d=this._valueGet();w(this,c.begin-1);var g=e.Event("keypress");g.which=d.charCodeAt(c.begin-1);ca=aa=!1;$.call(this,g,void 0,void 0,!1);c=b.p;G(this,s(),f.numericInput?Y(c):c);a.preventDefault()}function ya(a){Q=!0;var c=this;setTimeout(function(){w(c, -w(c).begin-1);var d=e.Event("keypress");d.which=a.originalEvent.data.charCodeAt(0);ca=aa=!1;$.call(c,d,void 0,void 0,!1);d=b.p;G(c,s(),f.numericInput?Y(d):d)},0);return!1}function za(a){m=e(a);if(m.is(":input")&&"number"!=m.attr("type")){m.data("_inputmask",{maskset:b,opts:f,isRTL:!1});f.showTooltip&&m.prop("title",b.mask);("rtl"==a.dir||f.rightAlign)&&m.css("text-align","right");if("rtl"==a.dir||f.numericInput){a.dir="ltr";m.removeAttr("dir");var c=m.data("_inputmask");c.isRTL=!0;m.data("_inputmask", -c);z=!0}m.unbind(".inputmask");m.removeClass("focus-inputmask");m.closest("form").bind("submit",function(){L!=s().join("")?m.change():m[0]._valueGet()==I().join("")&&m[0]._valueSet("");f.autoUnmask&&f.removeMaskOnSubmit&&m.inputmask("remove")}).bind("reset",function(){setTimeout(function(){m.trigger("setvalue")},0)});m.bind("mouseenter.inputmask",function(){!e(this).hasClass("focus-inputmask")&&f.showMaskOnHover&&this._valueGet()!=s().join("")&&G(this,s())}).bind("blur.inputmask",function(){var a= -e(this);if(a.data("_inputmask")){var b=this._valueGet(),c=s();a.removeClass("focus-inputmask");L!=s().join("")&&a.change();f.clearMaskOnLostFocus&&""!=b&&(b==I().join("")?this._valueSet(""):ha(this));!1===X(c)&&(a.trigger("incomplete"),f.clearIncomplete&&(g(),f.clearMaskOnLostFocus?this._valueSet(""):(c=I().slice(),G(this,c))))}}).bind("focus.inputmask",function(){var a=e(this),b=this._valueGet();f.showMaskOnFocus&&!a.hasClass("focus-inputmask")&&(!f.showMaskOnHover||f.showMaskOnHover&&""==b)&&this._valueGet()!= -s().join("")&&G(this,s(),E(x()));a.addClass("focus-inputmask");L=s().join("")}).bind("mouseleave.inputmask",function(){var a=e(this);f.clearMaskOnLostFocus&&(a.hasClass("focus-inputmask")||this._valueGet()==a.attr("placeholder")||(this._valueGet()==I().join("")||""==this._valueGet()?this._valueSet(""):ha(this)))}).bind("click.inputmask",function(){var a=this;e(a).is(":focus")&&setTimeout(function(){var b=w(a);if(b.begin==b.end){var b=z?S(b.begin):b.begin,c=x(b),c=E(c);bb;b++)a[b]=function(){var a=b;return{validator:function(b,g,e,l,C){if(C.regex["urlpre"+(a+1)]){var v=b;0d)return a;if(bb?a:b}return d},onKeyUp:function(a,b,c,d){b=e(this);a.ctrlKey&&a.keyCode==d.keyCode.RIGHT&&(a=new Date,b.val(a.getDate().toString()+(a.getMonth()+1).toString()+a.getFullYear().toString()))},definitions:{1:{validator:function(a,b,c,d,g){var e=g.regex.val1.test(a);return d||e||a.charAt(1)!=g.separator&&-1=="-./".indexOf(a.charAt(1))||!(e=g.regex.val1.test("0"+a.charAt(0)))?e:(b.buffer[c-1]="0",{refreshFromBuffer:{start:c-1,end:c},pos:c,c:a.charAt(0)})},cardinality:2,prevalidator:[{validator:function(a, -b,c,d,g){isNaN(b.buffer[c+1])||(a+=b.buffer[c+1]);var e=1==a.length?g.regex.val1pre.test(a):g.regex.val1.test(a);return d||e||!(e=g.regex.val1.test("0"+a))?e:(b.buffer[c]="0",c++,{pos:c})},cardinality:1}]},2:{validator:function(a,b,c,d,g){var e=g.mask.indexOf("2")==g.mask.length-1?b.buffer.join("").substr(5,3):b.buffer.join("").substr(0,3);-1!=e.indexOf(g.placeholder[0])&&(e="01"+g.separator);var l=g.regex.val2(g.separator).test(e+a);if(!(d||l||a.charAt(1)!=g.separator&&-1=="-./".indexOf(a.charAt(1)))&& -(l=g.regex.val2(g.separator).test(e+"0"+a.charAt(0))))return b.buffer[c-1]="0",{refreshFromBuffer:{start:c-1,end:c},pos:c,c:a.charAt(0)};if(g.mask.indexOf("2")==g.mask.length-1&&l){if(b.buffer.join("").substr(4,4)+a!=g.leapday)return!0;a=parseInt(b.buffer.join("").substr(0,4),10);return 0===a%4?0===a%100?0===a%400?!0:!1:!0:!1}return l},cardinality:2,prevalidator:[{validator:function(a,b,c,d,g){isNaN(b.buffer[c+1])||(a+=b.buffer[c+1]);var e=g.mask.indexOf("2")==g.mask.length-1?b.buffer.join("").substr(5, -3):b.buffer.join("").substr(0,3);-1!=e.indexOf(g.placeholder[0])&&(e="01"+g.separator);var l=1==a.length?g.regex.val2pre(g.separator).test(e+a):g.regex.val2(g.separator).test(e+a);return d||l||!(l=g.regex.val2(g.separator).test(e+"0"+a))?l:(b.buffer[c]="0",c++,{pos:c})},cardinality:1}]},y:{validator:function(a,b,c,d,g){if(g.isInYearRange(a,g.yearrange.minyear,g.yearrange.maxyear)){if(b.buffer.join("").substr(0,6)!=g.leapday)return!0;a=parseInt(a,10);return 0===a%4?0===a%100?0===a%400?!0:!1:!0:!1}return!1}, -cardinality:4,prevalidator:[{validator:function(a,b,c,d,g){var e=g.isInYearRange(a,g.yearrange.minyear,g.yearrange.maxyear);if(!d&&!e){d=g.determinebaseyear(g.yearrange.minyear,g.yearrange.maxyear,a+"0").toString().slice(0,1);if(e=g.isInYearRange(d+a,g.yearrange.minyear,g.yearrange.maxyear))return b.buffer[c++]=d.charAt(0),{pos:c};d=g.determinebaseyear(g.yearrange.minyear,g.yearrange.maxyear,a+"0").toString().slice(0,2);if(e=g.isInYearRange(d+a,g.yearrange.minyear,g.yearrange.maxyear))return b.buffer[c++]= -d.charAt(0),b.buffer[c++]=d.charAt(1),{pos:c}}return e},cardinality:1},{validator:function(a,b,c,d,e){var h=e.isInYearRange(a,e.yearrange.minyear,e.yearrange.maxyear);if(!d&&!h){d=e.determinebaseyear(e.yearrange.minyear,e.yearrange.maxyear,a).toString().slice(0,2);if(h=e.isInYearRange(a[0]+d[1]+a[1],e.yearrange.minyear,e.yearrange.maxyear))return b.buffer[c++]=d.charAt(1),{pos:c};d=e.determinebaseyear(e.yearrange.minyear,e.yearrange.maxyear,a).toString().slice(0,2);e.isInYearRange(d+a,e.yearrange.minyear, -e.yearrange.maxyear)?b.buffer.join("").substr(0,6)!=e.leapday?h=!0:(e=parseInt(a,10),h=0===e%4?0===e%100?0===e%400?!0:!1:!0:!1):h=!1;if(h)return b.buffer[c-1]=d.charAt(0),b.buffer[c++]=d.charAt(1),b.buffer[c++]=a.charAt(0),{refreshFromBuffer:{start:c-3,end:c},pos:c}}return h},cardinality:2},{validator:function(a,b,c,d,e){return e.isInYearRange(a,e.yearrange.minyear,e.yearrange.maxyear)},cardinality:3}]}},insertMode:!1,autoUnmask:!1},"mm/dd/yyyy":{placeholder:"mm/dd/yyyy",alias:"dd/mm/yyyy",regex:{val2pre:function(a){a= -e.inputmask.escapeRegex.call(this,a);return RegExp("((0[13-9]|1[012])"+a+"[0-3])|(02"+a+"[0-2])")},val2:function(a){a=e.inputmask.escapeRegex.call(this,a);return RegExp("((0[1-9]|1[012])"+a+"(0[1-9]|[12][0-9]))|((0[13-9]|1[012])"+a+"30)|((0[13578]|1[02])"+a+"31)")},val1pre:/[01]/,val1:/0[1-9]|1[012]/},leapday:"02/29/",onKeyUp:function(a,b,c,d){b=e(this);a.ctrlKey&&a.keyCode==d.keyCode.RIGHT&&(a=new Date,b.val((a.getMonth()+1).toString()+a.getDate().toString()+a.getFullYear().toString()))}},"yyyy/mm/dd":{mask:"y/1/2", -placeholder:"yyyy/mm/dd",alias:"mm/dd/yyyy",leapday:"/02/29",onKeyUp:function(a,b,c,d){b=e(this);a.ctrlKey&&a.keyCode==d.keyCode.RIGHT&&(a=new Date,b.val(a.getFullYear().toString()+(a.getMonth()+1).toString()+a.getDate().toString()))}},"dd.mm.yyyy":{mask:"1.2.y",placeholder:"dd.mm.yyyy",leapday:"29.02.",separator:".",alias:"dd/mm/yyyy"},"dd-mm-yyyy":{mask:"1-2-y",placeholder:"dd-mm-yyyy",leapday:"29-02-",separator:"-",alias:"dd/mm/yyyy"},"mm.dd.yyyy":{mask:"1.2.y",placeholder:"mm.dd.yyyy",leapday:"02.29.", -separator:".",alias:"mm/dd/yyyy"},"mm-dd-yyyy":{mask:"1-2-y",placeholder:"mm-dd-yyyy",leapday:"02-29-",separator:"-",alias:"mm/dd/yyyy"},"yyyy.mm.dd":{mask:"y.1.2",placeholder:"yyyy.mm.dd",leapday:".02.29",separator:".",alias:"yyyy/mm/dd"},"yyyy-mm-dd":{mask:"y-1-2",placeholder:"yyyy-mm-dd",leapday:"-02-29",separator:"-",alias:"yyyy/mm/dd"},datetime:{mask:"1/2/y h:s",placeholder:"dd/mm/yyyy hh:mm",alias:"dd/mm/yyyy",regex:{hrspre:/[012]/,hrs24:/2[0-4]|1[3-9]/,hrs:/[01][0-9]|2[0-4]/,ampm:/^[a|p|A|P][m|M]/, -mspre:/[0-5]/,ms:/[0-5][0-9]/},timeseparator:":",hourFormat:"24",definitions:{h:{validator:function(a,b,c,d,e){if("24"==e.hourFormat&&24==parseInt(a,10))return b.buffer[c-1]="0",b.buffer[c]="0",{refreshFromBuffer:{start:c-1,end:c},c:"0"};var h=e.regex.hrs.test(a);return d||h||a.charAt(1)!=e.timeseparator&&-1=="-.:".indexOf(a.charAt(1))||!(h=e.regex.hrs.test("0"+a.charAt(0)))?h&&"24"!==e.hourFormat&&e.regex.hrs24.test(a)?(a=parseInt(a,10),b.buffer[c+5]=24==a?"a":"p",b.buffer[c+6]="m",a-=12,10>a?(b.buffer[c]= -a.toString(),b.buffer[c-1]="0"):(b.buffer[c]=a.toString().charAt(1),b.buffer[c-1]=a.toString().charAt(0)),{refreshFromBuffer:{start:c-1,end:c+6},c:b.buffer[c]}):h:(b.buffer[c-1]="0",b.buffer[c]=a.charAt(0),c++,{refreshFromBuffer:{start:c-2,end:c},pos:c,c:e.timeseparator})},cardinality:2,prevalidator:[{validator:function(a,b,c,d,e){var h=e.regex.hrspre.test(a);return d||h||!(h=e.regex.hrs.test("0"+a))?h:(b.buffer[c]="0",c++,{pos:c})},cardinality:1}]},s:{validator:"[0-5][0-9]",cardinality:2,prevalidator:[{validator:function(a, -b,c,d,e){var h=e.regex.mspre.test(a);return d||h||!(h=e.regex.ms.test("0"+a))?h:(b.buffer[c]="0",c++,{pos:c})},cardinality:1}]},t:{validator:function(a,b,c,d,e){return e.regex.ampm.test(a+"m")},casing:"lower",cardinality:1}},insertMode:!1,autoUnmask:!1},datetime12:{mask:"1/2/y h:s t\\m",placeholder:"dd/mm/yyyy hh:mm xm",alias:"datetime",hourFormat:"12"},"hh:mm t":{mask:"h:s t\\m",placeholder:"hh:mm xm",alias:"datetime",hourFormat:"12"},"h:s t":{mask:"h:s t\\m",placeholder:"hh:mm xm",alias:"datetime", -hourFormat:"12"},"hh:mm:ss":{mask:"h:s:s",placeholder:"hh:mm:ss",alias:"datetime",autoUnmask:!1},"hh:mm":{mask:"h:s",placeholder:"hh:mm",alias:"datetime",autoUnmask:!1},date:{alias:"dd/mm/yyyy"},"mm/yyyy":{mask:"1/y",placeholder:"mm/yyyy",leapday:"donotuse",separator:"/",alias:"mm/dd/yyyy"}});return e.fn.inputmask}); -(function(e){"function"===typeof define&&define.amd?define(["jquery","./jquery.inputmask"],e):e(jQuery)})(function(e){e.extend(e.inputmask.defaults.aliases,{numeric:{mask:function(a){0!==a.repeat&&isNaN(a.integerDigits)&&(a.integerDigits=a.repeat);a.repeat=0;a.autoGroup=a.autoGroup&&""!=a.groupSeparator;if(a.autoGroup&&isFinite(a.integerDigits)){var b=Math.floor(a.integerDigits/a.groupSize);a.integerDigits+=0==a.integerDigits%a.groupSize?b-1:b}a.definitions[":"].placeholder=a.radixPoint;b=a.prefix; -b=b+"[+]"+("~{1,"+a.integerDigits+"}");void 0!=a.digits&&(isNaN(a.digits)||0=e.inArray(d.radixPoint, -a)||/[-+]/.test(h))return{pos:b};var l=a.slice();h==d.groupSeparator&&(l.splice(b--,1),h=l[b]);c?l[b]="?":l.splice(b,0,"?");b=l.join("");if(d.autoGroup||c&&-1!=b.indexOf(d.groupSeparator)){l=e.inputmask.escapeRegex.call(this,d.groupSeparator);g=0==b.indexOf(d.groupSeparator);b=b.replace(RegExp(l,"g"),"");l=b.split(d.radixPoint);b=l[0];if(b!=d.prefix+"?0"&&b.length>=d.groupSize+d.prefix.length)for(var g=!0,C=RegExp("([-+]?[\\d?]+)([\\d?]{"+d.groupSize+"})");C.test(b);)b=b.replace(C,"$1"+d.groupSeparator+ -"$2"),b=b.replace(d.groupSeparator+d.groupSeparator,d.groupSeparator);1=g.prefix.length)-1==l||c<=l&&void 0==b.validPositions[l]?(b.buffer.splice(d.index,1),c= -c>d.index?c-1:d.index,e.extend(h,{pos:c,remove:d.index})):c>d.index&&c<=l&&(b.buffer.splice(d.index,1),c=c>d.index?c-1:d.index,e.extend(h,{pos:c,remove:d.index}));else if("0"==a&&c<=d.index)return!1;if(!1===g.digitsOptional&&c>l)return{pos:c,remove:c}}return h},cardinality:1,prevalidator:null},"+":{validator:function(a,b,c,d,e){b="[";!0===e.allowMinus&&(b+="-");!0===e.allowPlus&&(b+="+");return RegExp(b+"]").test(a)},cardinality:1,prevalidator:null,placeholder:""},":":{validator:function(a,b,c,d, -g){d=g.negationhandler(a,b.buffer,c,d,g);d||(d="["+e.inputmask.escapeRegex.call(this,g.radixPoint)+"]",(d=RegExp(d).test(a))&&b.validPositions[c]&&b.validPositions[c].match.placeholder==g.radixPoint&&(d={pos:c,remove:c}));return d},cardinality:1,prevalidator:null,placeholder:""}},insertMode:!0,autoUnmask:!1,onUnMask:function(a,b,c){a=a.replace(c.prefix,"");a=a.replace(c.suffix,"");return a=a.replace(RegExp(e.inputmask.escapeRegex.call(this,c.groupSeparator),"g"),"")},isComplete:function(a,b){var c= -a.join(""),d=a.slice();b.postFormat(d,0,!0,b);if(d.join("")!=c)return!1;c=c.replace(b.prefix,"");c=c.replace(b.suffix,"");c=c.replace(RegExp(e.inputmask.escapeRegex.call(this,b.groupSeparator),"g"),"");c=c.replace(e.inputmask.escapeRegex.call(this,b.radixPoint),".");return isFinite(c)},onBeforeMask:function(a,b){if(isFinite(a))return a.toString().replace(".",b.radixPoint);var c=a.match(/,/g),d=a.match(/\./g);d&&c?d.length>c.length?(a=a.replace(/\./g,""),a=a.replace(",",b.radixPoint)):c.length>d.length&& -(a=a.replace(/,/g,""),a=a.replace(".",b.radixPoint)):a=a.replace(RegExp(e.inputmask.escapeRegex.call(this,b.groupSeparator),"g"),"");return a}},decimal:{alias:"numeric"},integer:{alias:"numeric",digits:"0"}});return e.fn.inputmask}); -(function(e){"function"===typeof define&&define.amd?define(["jquery","./jquery.inputmask"],e):e(jQuery)})(function(e){e.extend(e.inputmask.defaults.aliases,{Regex:{mask:"r",greedy:!1,repeat:"*",regex:null,regexTokens:null,tokenizer:/\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g,quantifierFilter:/[0-9]+[^,]/,isComplete:function(a,b){return RegExp(b.regex).test(a.join(""))}, -definitions:{r:{validator:function(a,b,c,d,g){function h(a,b){this.matches=[];this.isGroup=a||!1;this.isQuantifier=b||!1;this.quantifier={min:1,max:1};this.repeaterPart=void 0}function l(){var a=new h,b,c=[];for(g.regexTokens=[];b=g.tokenizer.exec(g.regex);)switch(b=b[0],b.charAt(0)){case "(":c.push(new h(!0));break;case ")":var d=c.pop();0v.length&&!(c=C(h,!0)););(c=c||C(h,!0))&&(g.repeaterPart=v);v=l+g.quantifier.max}else{for(var k=0,pa=g.quantifier.max-1;k - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/framework/assets/punycode/punycode.js b/framework/assets/punycode/punycode.js deleted file mode 100644 index 6242382..0000000 --- a/framework/assets/punycode/punycode.js +++ /dev/null @@ -1,502 +0,0 @@ -/*! http://mths.be/punycode v1.2.1 by @mathias */ -;(function(root) { - - /** Detect free variables */ - var freeExports = typeof exports == 'object' && exports; - var freeModule = typeof module == 'object' && module && - module.exports == freeExports && module; - var freeGlobal = typeof global == 'object' && global; - if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { - root = freeGlobal; - } - - /** - * The `punycode` object. - * @name punycode - * @type Object - */ - var punycode, - - /** Highest positive signed 32-bit float value */ - maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 - - /** Bootstring parameters */ - base = 36, - tMin = 1, - tMax = 26, - skew = 38, - damp = 700, - initialBias = 72, - initialN = 128, // 0x80 - delimiter = '-', // '\x2D' - - /** Regular expressions */ - regexPunycode = /^xn--/, - regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars - regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators - - /** Error messages */ - errors = { - 'overflow': 'Overflow: input needs wider integers to process', - 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', - 'invalid-input': 'Invalid input' - }, - - /** Convenience shortcuts */ - baseMinusTMin = base - tMin, - floor = Math.floor, - stringFromCharCode = String.fromCharCode, - - /** Temporary variable */ - key; - - /*--------------------------------------------------------------------------*/ - - /** - * A generic error utility function. - * @private - * @param {String} type The error type. - * @returns {Error} Throws a `RangeError` with the applicable error message. - */ - function error(type) { - throw RangeError(errors[type]); - } - - /** - * A generic `Array#map` utility function. - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function that gets called for every array - * item. - * @returns {Array} A new array of values returned by the callback function. - */ - function map(array, fn) { - var length = array.length; - while (length--) { - array[length] = fn(array[length]); - } - return array; - } - - /** - * A simple `Array#map`-like wrapper to work with domain name strings. - * @private - * @param {String} domain The domain name. - * @param {Function} callback The function that gets called for every - * character. - * @returns {Array} A new string of characters returned by the callback - * function. - */ - function mapDomain(string, fn) { - return map(string.split(regexSeparators), fn).join('.'); - } - - /** - * Creates an array containing the decimal code points of each Unicode - * character in the string. While JavaScript uses UCS-2 internally, - * this function will convert a pair of surrogate halves (each of which - * UCS-2 exposes as separate characters) into a single code point, - * matching UTF-16. - * @see `punycode.ucs2.encode` - * @see - * @memberOf punycode.ucs2 - * @name decode - * @param {String} string The Unicode input string (UCS-2). - * @returns {Array} The new array of code points. - */ - function ucs2decode(string) { - var output = [], - counter = 0, - length = string.length, - value, - extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if ((value & 0xF800) == 0xD800 && counter < length) { - // high surrogate, and there is a next character - extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // low surrogate - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - output.push(value, extra); - } - } else { - output.push(value); - } - } - return output; - } - - /** - * Creates a string based on an array of decimal code points. - * @see `punycode.ucs2.decode` - * @memberOf punycode.ucs2 - * @name encode - * @param {Array} codePoints The array of decimal code points. - * @returns {String} The new Unicode string (UCS-2). - */ - function ucs2encode(array) { - return map(array, function(value) { - var output = ''; - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - return output; - }).join(''); - } - - /** - * Converts a basic code point into a digit/integer. - * @see `digitToBasic()` - * @private - * @param {Number} codePoint The basic (decimal) code point. - * @returns {Number} The numeric value of a basic code point (for use in - * representing integers) in the range `0` to `base - 1`, or `base` if - * the code point does not represent a value. - */ - function basicToDigit(codePoint) { - return codePoint - 48 < 10 - ? codePoint - 22 - : codePoint - 65 < 26 - ? codePoint - 65 - : codePoint - 97 < 26 - ? codePoint - 97 - : base; - } - - /** - * Converts a digit/integer into a basic code point. - * @see `basicToDigit()` - * @private - * @param {Number} digit The numeric value of a basic code point. - * @returns {Number} The basic code point whose value (when used for - * representing integers) is `digit`, which needs to be in the range - * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is - * used; else, the lowercase form is used. The behavior is undefined - * if flag is non-zero and `digit` has no uppercase form. - */ - function digitToBasic(digit, flag) { - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); - } - - /** - * Bias adaptation function as per section 3.4 of RFC 3492. - * http://tools.ietf.org/html/rfc3492#section-3.4 - * @private - */ - function adapt(delta, numPoints, firstTime) { - var k = 0; - delta = firstTime ? floor(delta / damp) : delta >> 1; - delta += floor(delta / numPoints); - for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = floor(delta / baseMinusTMin); - } - return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); - } - - /** - * Converts a Punycode string of ASCII code points to a string of Unicode - * code points. - * @memberOf punycode - * @param {String} input The Punycode string of ASCII code points. - * @returns {String} The resulting string of Unicode code points. - */ - function decode(input) { - // Don't use UCS-2 - var output = [], - inputLength = input.length, - out, - i = 0, - n = initialN, - bias = initialBias, - basic, - j, - index, - oldi, - w, - k, - digit, - t, - length, - /** Cached calculation results */ - baseMinusT; - - // Handle the basic code points: let `basic` be the number of input code - // points before the last delimiter, or `0` if there is none, then copy - // the first basic code points to the output. - - basic = input.lastIndexOf(delimiter); - if (basic < 0) { - basic = 0; - } - - for (j = 0; j < basic; ++j) { - // if it's not a basic code point - if (input.charCodeAt(j) >= 0x80) { - error('not-basic'); - } - output.push(input.charCodeAt(j)); - } - - // Main decoding loop: start just after the last delimiter if any basic code - // points were copied; start at the beginning otherwise. - - for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { - - // `index` is the index of the next character to be consumed. - // Decode a generalized variable-length integer into `delta`, - // which gets added to `i`. The overflow checking is easier - // if we increase `i` as we go, then subtract off its starting - // value at the end to obtain `delta`. - for (oldi = i, w = 1, k = base; /* no condition */; k += base) { - - if (index >= inputLength) { - error('invalid-input'); - } - - digit = basicToDigit(input.charCodeAt(index++)); - - if (digit >= base || digit > floor((maxInt - i) / w)) { - error('overflow'); - } - - i += digit * w; - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - - if (digit < t) { - break; - } - - baseMinusT = base - t; - if (w > floor(maxInt / baseMinusT)) { - error('overflow'); - } - - w *= baseMinusT; - - } - - out = output.length + 1; - bias = adapt(i - oldi, out, oldi == 0); - - // `i` was supposed to wrap around from `out` to `0`, - // incrementing `n` each time, so we'll fix that now: - if (floor(i / out) > maxInt - n) { - error('overflow'); - } - - n += floor(i / out); - i %= out; - - // Insert `n` at position `i` of the output - output.splice(i++, 0, n); - - } - - return ucs2encode(output); - } - - /** - * Converts a string of Unicode code points to a Punycode string of ASCII - * code points. - * @memberOf punycode - * @param {String} input The string of Unicode code points. - * @returns {String} The resulting Punycode string of ASCII code points. - */ - function encode(input) { - var n, - delta, - handledCPCount, - basicLength, - bias, - j, - m, - q, - k, - t, - currentValue, - output = [], - /** `inputLength` will hold the number of code points in `input`. */ - inputLength, - /** Cached calculation results */ - handledCPCountPlusOne, - baseMinusT, - qMinusT; - - // Convert the input in UCS-2 to Unicode - input = ucs2decode(input); - - // Cache the length - inputLength = input.length; - - // Initialize the state - n = initialN; - delta = 0; - bias = initialBias; - - // Handle the basic code points - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue < 0x80) { - output.push(stringFromCharCode(currentValue)); - } - } - - handledCPCount = basicLength = output.length; - - // `handledCPCount` is the number of code points that have been handled; - // `basicLength` is the number of basic code points. - - // Finish the basic string - if it is not empty - with a delimiter - if (basicLength) { - output.push(delimiter); - } - - // Main encoding loop: - while (handledCPCount < inputLength) { - - // All non-basic code points < n have been handled already. Find the next - // larger one: - for (m = maxInt, j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue >= n && currentValue < m) { - m = currentValue; - } - } - - // Increase `delta` enough to advance the decoder's state to , - // but guard against overflow - handledCPCountPlusOne = handledCPCount + 1; - if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { - error('overflow'); - } - - delta += (m - n) * handledCPCountPlusOne; - n = m; - - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - - if (currentValue < n && ++delta > maxInt) { - error('overflow'); - } - - if (currentValue == n) { - // Represent delta as a generalized variable-length integer - for (q = delta, k = base; /* no condition */; k += base) { - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - if (q < t) { - break; - } - qMinusT = q - t; - baseMinusT = base - t; - output.push( - stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) - ); - q = floor(qMinusT / baseMinusT); - } - - output.push(stringFromCharCode(digitToBasic(q, 0))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); - delta = 0; - ++handledCPCount; - } - } - - ++delta; - ++n; - - } - return output.join(''); - } - - /** - * Converts a Punycode string representing a domain name to Unicode. Only the - * Punycoded parts of the domain name will be converted, i.e. it doesn't - * matter if you call it on a string that has already been converted to - * Unicode. - * @memberOf punycode - * @param {String} domain The Punycode domain name to convert to Unicode. - * @returns {String} The Unicode representation of the given Punycode - * string. - */ - function toUnicode(domain) { - return mapDomain(domain, function(string) { - return regexPunycode.test(string) - ? decode(string.slice(4).toLowerCase()) - : string; - }); - } - - /** - * Converts a Unicode string representing a domain name to Punycode. Only the - * non-ASCII parts of the domain name will be converted, i.e. it doesn't - * matter if you call it with a domain that's already in ASCII. - * @memberOf punycode - * @param {String} domain The domain name to convert, as a Unicode string. - * @returns {String} The Punycode representation of the given domain name. - */ - function toASCII(domain) { - return mapDomain(domain, function(string) { - return regexNonASCII.test(string) - ? 'xn--' + encode(string) - : string; - }); - } - - /*--------------------------------------------------------------------------*/ - - /** Define the public API */ - punycode = { - /** - * A string representing the current Punycode.js version number. - * @memberOf punycode - * @type String - */ - 'version': '1.2.1', - /** - * An object of methods to convert from JavaScript's internal character - * representation (UCS-2) to decimal Unicode code points, and back. - * @see - * @memberOf punycode - * @type Object - */ - 'ucs2': { - 'decode': ucs2decode, - 'encode': ucs2encode - }, - 'decode': decode, - 'encode': encode, - 'toASCII': toASCII, - 'toUnicode': toUnicode - }; - - /** Expose `punycode` */ - // Some AMD build optimizers, like r.js, check for specific condition patterns - // like the following: - if ( - typeof define == 'function' && - typeof define.amd == 'object' && - define.amd - ) { - define(function() { - return punycode; - }); - } else if (freeExports && !freeExports.nodeType) { - if (freeModule) { // in Node.js or RingoJS v0.8.0+ - freeModule.exports = punycode; - } else { // in Narwhal or RingoJS v0.7.0- - for (key in punycode) { - punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); - } - } - } else { // in Rhino or a web browser - root.punycode = punycode; - } - -}(this)); diff --git a/framework/assets/punycode/punycode.min.js b/framework/assets/punycode/punycode.min.js deleted file mode 100644 index a61badf..0000000 --- a/framework/assets/punycode/punycode.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! http://mths.be/punycode v1.2.1 by @mathias */ -(function(o){function e(o){throw RangeError(L[o])}function n(o,e){for(var n=o.length;n--;)o[n]=e(o[n]);return o}function t(o,e){return n(o.split(S),e).join(".")}function r(o){for(var e,n,t=[],r=0,u=o.length;u>r;)e=o.charCodeAt(r++),55296==(63488&e)&&u>r?(n=o.charCodeAt(r++),56320==(64512&n)?t.push(((1023&e)<<10)+(1023&n)+65536):t.push(e,n)):t.push(e);return t}function u(o){return n(o,function(o){var e="";return o>65535&&(o-=65536,e+=R(55296|1023&o>>>10),o=56320|1023&o),e+=R(o)}).join("")}function i(o){return 10>o-48?o-22:26>o-65?o-65:26>o-97?o-97:x}function f(o,e){return o+22+75*(26>o)-((0!=e)<<5)}function c(o,e,n){var t=0;for(o=n?P(o/m):o>>1,o+=P(o/e);o>M*y>>1;t+=x)o=P(o/M);return P(t+(M+1)*o/(o+j))}function l(o){var n,t,r,f,l,d,s,a,p,h,v=[],g=o.length,w=0,j=I,m=A;for(t=o.lastIndexOf(F),0>t&&(t=0),r=0;t>r;++r)o.charCodeAt(r)>=128&&e("not-basic"),v.push(o.charCodeAt(r));for(f=t>0?t+1:0;g>f;){for(l=w,d=1,s=x;f>=g&&e("invalid-input"),a=i(o.charCodeAt(f++)),(a>=x||a>P((b-w)/d))&&e("overflow"),w+=a*d,p=m>=s?C:s>=m+y?y:s-m,!(p>a);s+=x)h=x-p,d>P(b/h)&&e("overflow"),d*=h;n=v.length+1,m=c(w-l,n,0==l),P(w/n)>b-j&&e("overflow"),j+=P(w/n),w%=n,v.splice(w++,0,j)}return u(v)}function d(o){var n,t,u,i,l,d,s,a,p,h,v,g,w,j,m,E=[];for(o=r(o),g=o.length,n=I,t=0,l=A,d=0;g>d;++d)v=o[d],128>v&&E.push(R(v));for(u=i=E.length,i&&E.push(F);g>u;){for(s=b,d=0;g>d;++d)v=o[d],v>=n&&s>v&&(s=v);for(w=u+1,s-n>P((b-t)/w)&&e("overflow"),t+=(s-n)*w,n=s,d=0;g>d;++d)if(v=o[d],n>v&&++t>b&&e("overflow"),v==n){for(a=t,p=x;h=l>=p?C:p>=l+y?y:p-l,!(h>a);p+=x)m=a-h,j=x-h,E.push(R(f(h+m%j,0))),a=P(m/j);E.push(R(f(a,0))),l=c(t,w,u==i),t=0,++u}++t,++n}return E.join("")}function s(o){return t(o,function(o){return E.test(o)?l(o.slice(4).toLowerCase()):o})}function a(o){return t(o,function(o){return O.test(o)?"xn--"+d(o):o})}var p="object"==typeof exports&&exports,h="object"==typeof module&&module&&module.exports==p&&module,v="object"==typeof global&&global;(v.global===v||v.window===v)&&(o=v);var g,w,b=2147483647,x=36,C=1,y=26,j=38,m=700,A=72,I=128,F="-",E=/^xn--/,O=/[^ -~]/,S=/\x2E|\u3002|\uFF0E|\uFF61/g,L={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},M=x-C,P=Math.floor,R=String.fromCharCode;if(g={version:"1.2.1",ucs2:{decode:r,encode:u},decode:l,encode:d,toASCII:a,toUnicode:s},"function"==typeof define&&"object"==typeof define.amd&&define.amd)define(function(){return g});else if(p&&!p.nodeType)if(h)h.exports=g;else for(w in g)g.hasOwnProperty(w)&&(p[w]=g[w]);else o.punycode=g})(this); \ No newline at end of file diff --git a/framework/composer.json b/framework/composer.json index d839d64..eb4cba9 100644 --- a/framework/composer.json +++ b/framework/composer.json @@ -53,8 +53,6 @@ "ext-mbstring": "*", "lib-pcre": "*", "yiisoft/yii2-composer": "*", - "yiisoft/jquery": "~2.0 | ~1.10", - "yiisoft/jquery-pjax": "*", "ezyang/htmlpurifier": "4.6.*", "cebe/markdown": "0.9.*" }, From f6e1d5726ae151b2f4a2815effd39f743ecff38a Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 30 Aug 2014 00:37:57 -0400 Subject: [PATCH 06/12] new asset WIP --- extensions/jui/Accordion.php | 2 +- extensions/jui/AccordionAsset.php | 26 - extensions/jui/AutoComplete.php | 2 +- extensions/jui/AutoCompleteAsset.php | 26 - extensions/jui/ButtonAsset.php | 3 +- extensions/jui/CoreAsset.php | 9 +- extensions/jui/DatePicker.php | 6 +- extensions/jui/DatePickerAsset.php | 26 - extensions/jui/DatePickerLanguageAsset.php | 24 + extensions/jui/DatePickerRegionalAsset.php | 25 - extensions/jui/Dialog.php | 2 +- extensions/jui/DialogAsset.php | 28 - extensions/jui/Draggable.php | 2 +- extensions/jui/DraggableAsset.php | 25 - extensions/jui/Droppable.php | 2 +- extensions/jui/DroppableAsset.php | 25 - extensions/jui/EffectAsset.php | 25 - extensions/jui/JuiAsset.php | 27 + extensions/jui/Menu.php | 5 +- extensions/jui/MenuAsset.php | 25 - extensions/jui/ProgressBar.php | 2 +- extensions/jui/ProgressBarAsset.php | 25 - extensions/jui/Resizable.php | 2 +- extensions/jui/ResizableAsset.php | 25 - extensions/jui/Selectable.php | 2 +- extensions/jui/SelectableAsset.php | 25 - extensions/jui/Slider.php | 2 +- extensions/jui/SliderAsset.php | 25 - extensions/jui/SliderInput.php | 2 +- extensions/jui/Sortable.php | 2 +- extensions/jui/SortableAsset.php | 25 - extensions/jui/Spinner.php | 2 +- extensions/jui/SpinnerAsset.php | 26 - extensions/jui/Tabs.php | 2 +- extensions/jui/TabsAsset.php | 26 - extensions/jui/ThemeAsset.php | 22 - extensions/jui/TooltipAsset.php | 26 - extensions/jui/Widget.php | 23 +- extensions/jui/assets/UPGRADE.md | 14 - extensions/jui/assets/jquery.ui.accordion.js | 572 ----- extensions/jui/assets/jquery.ui.autocomplete.js | 610 ------ extensions/jui/assets/jquery.ui.button.js | 419 ---- extensions/jui/assets/jquery.ui.core.js | 320 --- extensions/jui/assets/jquery.ui.datepicker-i18n.js | 1793 ---------------- extensions/jui/assets/jquery.ui.datepicker.js | 2038 ------------------ extensions/jui/assets/jquery.ui.dialog.js | 808 ------- extensions/jui/assets/jquery.ui.draggable.js | 958 --------- extensions/jui/assets/jquery.ui.droppable.js | 372 ---- extensions/jui/assets/jquery.ui.effect-all.js | 2261 -------------------- extensions/jui/assets/jquery.ui.menu.js | 621 ------ extensions/jui/assets/jquery.ui.mouse.js | 169 -- extensions/jui/assets/jquery.ui.position.js | 497 ----- extensions/jui/assets/jquery.ui.progressbar.js | 145 -- extensions/jui/assets/jquery.ui.resizable.js | 968 --------- extensions/jui/assets/jquery.ui.selectable.js | 277 --- extensions/jui/assets/jquery.ui.slider.js | 672 ------ extensions/jui/assets/jquery.ui.sortable.js | 1285 ----------- extensions/jui/assets/jquery.ui.spinner.js | 493 ----- extensions/jui/assets/jquery.ui.tabs.js | 846 -------- extensions/jui/assets/jquery.ui.tooltip.js | 402 ---- extensions/jui/assets/jquery.ui.widget.js | 521 ----- .../jui/assets/theme/images/animated-overlay.gif | Bin 1738 -> 0 bytes .../theme/images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 212 -> 0 bytes .../theme/images/ui-bg_flat_75_ffffff_40x100.png | Bin 208 -> 0 bytes .../theme/images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 335 -> 0 bytes .../theme/images/ui-bg_glass_65_ffffff_1x400.png | Bin 207 -> 0 bytes .../theme/images/ui-bg_glass_75_dadada_1x400.png | Bin 262 -> 0 bytes .../theme/images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 262 -> 0 bytes .../theme/images/ui-bg_glass_95_fef1ec_1x400.png | Bin 332 -> 0 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 280 -> 0 bytes .../theme/images/ui-icons_222222_256x240.png | Bin 6922 -> 0 bytes .../theme/images/ui-icons_2e83ff_256x240.png | Bin 4549 -> 0 bytes .../theme/images/ui-icons_454545_256x240.png | Bin 6992 -> 0 bytes .../theme/images/ui-icons_888888_256x240.png | Bin 6999 -> 0 bytes .../theme/images/ui-icons_cd0a0a_256x240.png | Bin 4549 -> 0 bytes extensions/jui/assets/theme/jquery.ui.css | 1177 ---------- 76 files changed, 75 insertions(+), 18742 deletions(-) delete mode 100644 extensions/jui/AccordionAsset.php delete mode 100644 extensions/jui/AutoCompleteAsset.php delete mode 100644 extensions/jui/DatePickerAsset.php create mode 100644 extensions/jui/DatePickerLanguageAsset.php delete mode 100644 extensions/jui/DatePickerRegionalAsset.php delete mode 100644 extensions/jui/DialogAsset.php delete mode 100644 extensions/jui/DraggableAsset.php delete mode 100644 extensions/jui/DroppableAsset.php delete mode 100644 extensions/jui/EffectAsset.php create mode 100644 extensions/jui/JuiAsset.php delete mode 100644 extensions/jui/MenuAsset.php delete mode 100644 extensions/jui/ProgressBarAsset.php delete mode 100644 extensions/jui/ResizableAsset.php delete mode 100644 extensions/jui/SelectableAsset.php delete mode 100644 extensions/jui/SliderAsset.php delete mode 100644 extensions/jui/SortableAsset.php delete mode 100644 extensions/jui/SpinnerAsset.php delete mode 100644 extensions/jui/TabsAsset.php delete mode 100644 extensions/jui/ThemeAsset.php delete mode 100644 extensions/jui/TooltipAsset.php delete mode 100644 extensions/jui/assets/UPGRADE.md delete mode 100644 extensions/jui/assets/jquery.ui.accordion.js delete mode 100644 extensions/jui/assets/jquery.ui.autocomplete.js delete mode 100644 extensions/jui/assets/jquery.ui.button.js delete mode 100644 extensions/jui/assets/jquery.ui.core.js delete mode 100644 extensions/jui/assets/jquery.ui.datepicker-i18n.js delete mode 100644 extensions/jui/assets/jquery.ui.datepicker.js delete mode 100644 extensions/jui/assets/jquery.ui.dialog.js delete mode 100644 extensions/jui/assets/jquery.ui.draggable.js delete mode 100644 extensions/jui/assets/jquery.ui.droppable.js delete mode 100644 extensions/jui/assets/jquery.ui.effect-all.js delete mode 100644 extensions/jui/assets/jquery.ui.menu.js delete mode 100644 extensions/jui/assets/jquery.ui.mouse.js delete mode 100644 extensions/jui/assets/jquery.ui.position.js delete mode 100644 extensions/jui/assets/jquery.ui.progressbar.js delete mode 100644 extensions/jui/assets/jquery.ui.resizable.js delete mode 100644 extensions/jui/assets/jquery.ui.selectable.js delete mode 100644 extensions/jui/assets/jquery.ui.slider.js delete mode 100644 extensions/jui/assets/jquery.ui.sortable.js delete mode 100644 extensions/jui/assets/jquery.ui.spinner.js delete mode 100644 extensions/jui/assets/jquery.ui.tabs.js delete mode 100644 extensions/jui/assets/jquery.ui.tooltip.js delete mode 100644 extensions/jui/assets/jquery.ui.widget.js delete mode 100644 extensions/jui/assets/theme/images/animated-overlay.gif delete mode 100644 extensions/jui/assets/theme/images/ui-bg_flat_0_aaaaaa_40x100.png delete mode 100644 extensions/jui/assets/theme/images/ui-bg_flat_75_ffffff_40x100.png delete mode 100644 extensions/jui/assets/theme/images/ui-bg_glass_55_fbf9ee_1x400.png delete mode 100644 extensions/jui/assets/theme/images/ui-bg_glass_65_ffffff_1x400.png delete mode 100644 extensions/jui/assets/theme/images/ui-bg_glass_75_dadada_1x400.png delete mode 100644 extensions/jui/assets/theme/images/ui-bg_glass_75_e6e6e6_1x400.png delete mode 100644 extensions/jui/assets/theme/images/ui-bg_glass_95_fef1ec_1x400.png delete mode 100644 extensions/jui/assets/theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png delete mode 100644 extensions/jui/assets/theme/images/ui-icons_222222_256x240.png delete mode 100644 extensions/jui/assets/theme/images/ui-icons_2e83ff_256x240.png delete mode 100644 extensions/jui/assets/theme/images/ui-icons_454545_256x240.png delete mode 100644 extensions/jui/assets/theme/images/ui-icons_888888_256x240.png delete mode 100644 extensions/jui/assets/theme/images/ui-icons_cd0a0a_256x240.png delete mode 100644 extensions/jui/assets/theme/jquery.ui.css diff --git a/extensions/jui/Accordion.php b/extensions/jui/Accordion.php index b7c7c1e..9ffd322 100644 --- a/extensions/jui/Accordion.php +++ b/extensions/jui/Accordion.php @@ -96,7 +96,7 @@ class Accordion extends Widget echo Html::beginTag($tag, $options) . "\n"; echo $this->renderItems() . "\n"; echo Html::endTag($tag) . "\n"; - $this->registerWidget('accordion', AccordionAsset::className()); + $this->registerWidget('accordion'); } /** diff --git a/extensions/jui/AccordionAsset.php b/extensions/jui/AccordionAsset.php deleted file mode 100644 index 3a71a70..0000000 --- a/extensions/jui/AccordionAsset.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @since 2.0 - */ -class AccordionAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.accordion.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - 'yii\jui\EffectAsset', - ]; -} diff --git a/extensions/jui/AutoComplete.php b/extensions/jui/AutoComplete.php index 8baa544..0712350 100644 --- a/extensions/jui/AutoComplete.php +++ b/extensions/jui/AutoComplete.php @@ -47,7 +47,7 @@ class AutoComplete extends InputWidget public function run() { echo $this->renderWidget(); - $this->registerWidget('autocomplete', AutoCompleteAsset::className()); + $this->registerWidget('autocomplete'); } /** diff --git a/extensions/jui/AutoCompleteAsset.php b/extensions/jui/AutoCompleteAsset.php deleted file mode 100644 index 4a92c93..0000000 --- a/extensions/jui/AutoCompleteAsset.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @since 2.0 - */ -class AutoCompleteAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.autocomplete.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - 'yii\jui\MenuAsset', - ]; -} diff --git a/extensions/jui/ButtonAsset.php b/extensions/jui/ButtonAsset.php index fb66255..0975171 100644 --- a/extensions/jui/ButtonAsset.php +++ b/extensions/jui/ButtonAsset.php @@ -15,9 +15,8 @@ use yii\web\AssetBundle; */ class ButtonAsset extends AssetBundle { - public $sourcePath = '@yii/jui/assets'; public $js = [ - 'jquery.ui.button.js', + 'jquery.ui/ui/button.js', ]; public $depends = [ 'yii\jui\CoreAsset', diff --git a/extensions/jui/CoreAsset.php b/extensions/jui/CoreAsset.php index 7a95d59..fe15e7a 100644 --- a/extensions/jui/CoreAsset.php +++ b/extensions/jui/CoreAsset.php @@ -15,12 +15,11 @@ use yii\web\AssetBundle; */ class CoreAsset extends AssetBundle { - public $sourcePath = '@yii/jui/assets'; public $js = [ - 'jquery.ui.core.js', - 'jquery.ui.widget.js', - 'jquery.ui.position.js', - 'jquery.ui.mouse.js', + 'jquery.ui/ui/core.js', + 'jquery.ui/ui/widget.js', + 'jquery.ui/ui/position.js', + 'jquery.ui/ui/mouse.js', ]; public $depends = [ 'yii\web\JqueryAsset', diff --git a/extensions/jui/DatePicker.php b/extensions/jui/DatePicker.php index dafd3fa..fbdd836 100644 --- a/extensions/jui/DatePicker.php +++ b/extensions/jui/DatePicker.php @@ -82,17 +82,17 @@ class DatePicker extends InputWidget $language = $this->language ? $this->language : Yii::$app->language; if ($language != 'en-US') { $view = $this->getView(); - DatePickerRegionalAsset::register($view); + DatePickerLanguageAsset::register($view); $options = Json::encode($this->clientOptions); $view->registerJs("$('#{$containerID}').datepicker($.extend({}, $.datepicker.regional['{$language}'], $options));"); $options = $this->clientOptions; $this->clientOptions = false; // the datepicker js widget is already registered - $this->registerWidget('datepicker', DatePickerAsset::className(), $containerID); + $this->registerWidget('datepicker', $containerID); $this->clientOptions = $options; } else { - $this->registerWidget('datepicker', DatePickerAsset::className(), $containerID); + $this->registerWidget('datepicker', $containerID); } } diff --git a/extensions/jui/DatePickerAsset.php b/extensions/jui/DatePickerAsset.php deleted file mode 100644 index 48ff0e7..0000000 --- a/extensions/jui/DatePickerAsset.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @since 2.0 - */ -class DatePickerAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.datepicker.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - 'yii\jui\EffectAsset', - ]; -} diff --git a/extensions/jui/DatePickerLanguageAsset.php b/extensions/jui/DatePickerLanguageAsset.php new file mode 100644 index 0000000..0c1ecf0 --- /dev/null +++ b/extensions/jui/DatePickerLanguageAsset.php @@ -0,0 +1,24 @@ + + * @since 2.0 + */ +class DatePickerLanguageAsset extends AssetBundle +{ + public $js = [ + 'jquery.ui.datepicker-i18n.js', + ]; + public $depends = [ + 'yii\jui\JuiAsset', + ]; +} diff --git a/extensions/jui/DatePickerRegionalAsset.php b/extensions/jui/DatePickerRegionalAsset.php deleted file mode 100644 index 31dfe6e..0000000 --- a/extensions/jui/DatePickerRegionalAsset.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @since 2.0 - */ -class DatePickerRegionalAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.datepicker-i18n.js', - ]; - public $depends = [ - 'yii\jui\DatePickerAsset', - ]; -} diff --git a/extensions/jui/Dialog.php b/extensions/jui/Dialog.php index f7e49a8..082e4fd 100644 --- a/extensions/jui/Dialog.php +++ b/extensions/jui/Dialog.php @@ -47,6 +47,6 @@ class Dialog extends Widget public function run() { echo Html::endTag('div') . "\n"; - $this->registerWidget('dialog', DialogAsset::className()); + $this->registerWidget('dialog'); } } diff --git a/extensions/jui/DialogAsset.php b/extensions/jui/DialogAsset.php deleted file mode 100644 index f14a096..0000000 --- a/extensions/jui/DialogAsset.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @since 2.0 - */ -class DialogAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.dialog.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - 'yii\jui\ButtonAsset', - 'yii\jui\DraggableAsset', - 'yii\jui\ResizableAsset', - ]; -} diff --git a/extensions/jui/Draggable.php b/extensions/jui/Draggable.php index f54971a..a759ee8 100644 --- a/extensions/jui/Draggable.php +++ b/extensions/jui/Draggable.php @@ -45,6 +45,6 @@ class Draggable extends Widget public function run() { echo Html::endTag('div') . "\n"; - $this->registerWidget('draggable', DraggableAsset::className()); + $this->registerWidget('draggable'); } } diff --git a/extensions/jui/DraggableAsset.php b/extensions/jui/DraggableAsset.php deleted file mode 100644 index 742ab04..0000000 --- a/extensions/jui/DraggableAsset.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @since 2.0 - */ -class DraggableAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.draggable.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - ]; -} diff --git a/extensions/jui/Droppable.php b/extensions/jui/Droppable.php index d0c247d..8676f30 100644 --- a/extensions/jui/Droppable.php +++ b/extensions/jui/Droppable.php @@ -45,6 +45,6 @@ class Droppable extends Widget public function run() { echo Html::endTag('div') . "\n"; - $this->registerWidget('droppable', DroppableAsset::className()); + $this->registerWidget('droppable'); } } diff --git a/extensions/jui/DroppableAsset.php b/extensions/jui/DroppableAsset.php deleted file mode 100644 index 377f9da..0000000 --- a/extensions/jui/DroppableAsset.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @since 2.0 - */ -class DroppableAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.droppable.js', - ]; - public $depends = [ - 'yii\jui\DraggableAsset', - ]; -} diff --git a/extensions/jui/EffectAsset.php b/extensions/jui/EffectAsset.php deleted file mode 100644 index b8cade0..0000000 --- a/extensions/jui/EffectAsset.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @since 2.0 - */ -class EffectAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.effect-all.js', - ]; - public $depends = [ - 'yii\web\JqueryAsset', - ]; -} diff --git a/extensions/jui/JuiAsset.php b/extensions/jui/JuiAsset.php new file mode 100644 index 0000000..0a6066b --- /dev/null +++ b/extensions/jui/JuiAsset.php @@ -0,0 +1,27 @@ + + * @since 2.0 + */ +class JuiAsset extends AssetBundle +{ + public $js = [ + 'jquery-ui/jquery-ui.js', + ]; + public $css = [ + 'jquery-ui/themes/smoothness/jquery-ui.css', + ]; + public $depends = [ + 'yii\web\JqueryAsset', + ]; +} diff --git a/extensions/jui/Menu.php b/extensions/jui/Menu.php index 140906f..754c162 100644 --- a/extensions/jui/Menu.php +++ b/extensions/jui/Menu.php @@ -54,10 +54,7 @@ class Menu extends \yii\widgets\Menu parent::run(); $view = $this->getView(); - MenuAsset::register($view); - /* @var $themeAsset \yii\web\AssetBundle */ - $themeAsset = Widget::$theme; - $themeAsset::register($view); + JuiAsset::register($view); $id = $this->options['id']; if ($this->clientOptions !== false) { diff --git a/extensions/jui/MenuAsset.php b/extensions/jui/MenuAsset.php deleted file mode 100644 index fab40d7..0000000 --- a/extensions/jui/MenuAsset.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @since 2.0 - */ -class MenuAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.menu.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - ]; -} diff --git a/extensions/jui/ProgressBar.php b/extensions/jui/ProgressBar.php index d35fc9b..f161ed3 100644 --- a/extensions/jui/ProgressBar.php +++ b/extensions/jui/ProgressBar.php @@ -55,6 +55,6 @@ class ProgressBar extends Widget public function run() { echo Html::endTag('div') . "\n"; - $this->registerWidget('progressbar', ProgressBarAsset::className()); + $this->registerWidget('progressbar'); } } diff --git a/extensions/jui/ProgressBarAsset.php b/extensions/jui/ProgressBarAsset.php deleted file mode 100644 index c607dc1..0000000 --- a/extensions/jui/ProgressBarAsset.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @since 2.0 - */ -class ProgressBarAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.progressbar.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - ]; -} diff --git a/extensions/jui/Resizable.php b/extensions/jui/Resizable.php index 22e0ed5..aedc613 100644 --- a/extensions/jui/Resizable.php +++ b/extensions/jui/Resizable.php @@ -47,6 +47,6 @@ class Resizable extends Widget public function run() { echo Html::endTag('div') . "\n"; - $this->registerWidget('resizable', ResizableAsset::className()); + $this->registerWidget('resizable'); } } diff --git a/extensions/jui/ResizableAsset.php b/extensions/jui/ResizableAsset.php deleted file mode 100644 index a4e1d83..0000000 --- a/extensions/jui/ResizableAsset.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @since 2.0 - */ -class ResizableAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.resizable.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - ]; -} diff --git a/extensions/jui/Selectable.php b/extensions/jui/Selectable.php index 1cf9aec..64e3639 100644 --- a/extensions/jui/Selectable.php +++ b/extensions/jui/Selectable.php @@ -90,7 +90,7 @@ class Selectable extends Widget echo Html::beginTag($tag, $options) . "\n"; echo $this->renderItems() . "\n"; echo Html::endTag($tag) . "\n"; - $this->registerWidget('selectable', SelectableAsset::className()); + $this->registerWidget('selectable'); } /** diff --git a/extensions/jui/SelectableAsset.php b/extensions/jui/SelectableAsset.php deleted file mode 100644 index 073be52..0000000 --- a/extensions/jui/SelectableAsset.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @since 2.0 - */ -class SelectableAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.selectable.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - ]; -} diff --git a/extensions/jui/Slider.php b/extensions/jui/Slider.php index 740a85f..5fcc642 100644 --- a/extensions/jui/Slider.php +++ b/extensions/jui/Slider.php @@ -44,6 +44,6 @@ class Slider extends Widget public function run() { echo Html::tag('div', '', $this->options); - $this->registerWidget('slider', SliderAsset::className()); + $this->registerWidget('slider'); } } diff --git a/extensions/jui/SliderAsset.php b/extensions/jui/SliderAsset.php deleted file mode 100644 index 96794a5..0000000 --- a/extensions/jui/SliderAsset.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @since 2.0 - */ -class SliderAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.slider.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - ]; -} diff --git a/extensions/jui/SliderInput.php b/extensions/jui/SliderInput.php index 760dfb3..fce66a2 100644 --- a/extensions/jui/SliderInput.php +++ b/extensions/jui/SliderInput.php @@ -93,6 +93,6 @@ class SliderInput extends InputWidget }'; } - $this->registerWidget('slider', SliderAsset::className(), $this->containerOptions['id']); + $this->registerWidget('slider', $this->containerOptions['id']); } } diff --git a/extensions/jui/Sortable.php b/extensions/jui/Sortable.php index 97a7691..0dc7af6 100644 --- a/extensions/jui/Sortable.php +++ b/extensions/jui/Sortable.php @@ -99,7 +99,7 @@ class Sortable extends Widget echo Html::beginTag($tag, $options) . "\n"; echo $this->renderItems() . "\n"; echo Html::endTag($tag) . "\n"; - $this->registerWidget('sortable', SortableAsset::className()); + $this->registerWidget('sortable'); } /** diff --git a/extensions/jui/SortableAsset.php b/extensions/jui/SortableAsset.php deleted file mode 100644 index f7de366..0000000 --- a/extensions/jui/SortableAsset.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @since 2.0 - */ -class SortableAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.sortable.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - ]; -} diff --git a/extensions/jui/Spinner.php b/extensions/jui/Spinner.php index eb6ad04..83f804e 100644 --- a/extensions/jui/Spinner.php +++ b/extensions/jui/Spinner.php @@ -51,7 +51,7 @@ class Spinner extends InputWidget public function run() { echo $this->renderWidget(); - $this->registerWidget('spinner', SpinnerAsset::className()); + $this->registerWidget('spinner'); } /** diff --git a/extensions/jui/SpinnerAsset.php b/extensions/jui/SpinnerAsset.php deleted file mode 100644 index 8c36ef4..0000000 --- a/extensions/jui/SpinnerAsset.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @since 2.0 - */ -class SpinnerAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.spinner.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - 'yii\jui\ButtonAsset', - ]; -} diff --git a/extensions/jui/Tabs.php b/extensions/jui/Tabs.php index 017d028..dd72d76 100644 --- a/extensions/jui/Tabs.php +++ b/extensions/jui/Tabs.php @@ -109,7 +109,7 @@ class Tabs extends Widget echo Html::beginTag($tag, $options) . "\n"; echo $this->renderItems() . "\n"; echo Html::endTag($tag) . "\n"; - $this->registerWidget('tabs', TabsAsset::className()); + $this->registerWidget('tabs'); } /** diff --git a/extensions/jui/TabsAsset.php b/extensions/jui/TabsAsset.php deleted file mode 100644 index 0ae7f87..0000000 --- a/extensions/jui/TabsAsset.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @since 2.0 - */ -class TabsAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.tabs.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - 'yii\jui\EffectAsset', - ]; -} diff --git a/extensions/jui/ThemeAsset.php b/extensions/jui/ThemeAsset.php deleted file mode 100644 index bfb3abf..0000000 --- a/extensions/jui/ThemeAsset.php +++ /dev/null @@ -1,22 +0,0 @@ - - * @since 2.0 - */ -class ThemeAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $css = [ - 'theme/jquery.ui.css', - ]; -} diff --git a/extensions/jui/TooltipAsset.php b/extensions/jui/TooltipAsset.php deleted file mode 100644 index 6e2778a..0000000 --- a/extensions/jui/TooltipAsset.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @since 2.0 - */ -class TooltipAsset extends AssetBundle -{ - public $sourcePath = '@yii/jui/assets'; - public $js = [ - 'jquery.ui.tooltip.js', - ]; - public $depends = [ - 'yii\jui\CoreAsset', - 'yii\jui\EffectAsset', - ]; -} diff --git a/extensions/jui/Widget.php b/extensions/jui/Widget.php index a99bd8c..0676db6 100644 --- a/extensions/jui/Widget.php +++ b/extensions/jui/Widget.php @@ -18,11 +18,6 @@ use yii\helpers\Json; class Widget extends \yii\base\Widget { /** - * @var string the jQuery UI theme. This refers to an asset bundle class - * representing the JUI theme. The default theme is the official "Smoothness" theme. - */ - public static $theme = 'yii\jui\ThemeAsset'; - /** * @var array the HTML attributes for the widget container tag. * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. */ @@ -72,19 +67,6 @@ class Widget extends \yii\base\Widget } /** - * Registers a specific jQuery UI widget assets - * @param string $assetBundle the asset bundle for the widget - */ - protected function registerAssets($assetBundle) - { - /* @var $assetBundle \yii\web\AssetBundle */ - $assetBundle::register($this->getView()); - /* @var $themeAsset \yii\web\AssetBundle */ - $themeAsset = static::$theme; - $themeAsset::register($this->getView()); - } - - /** * Registers a specific jQuery UI widget options * @param string $name the name of the jQuery UI widget * @param string $id the ID of the widget @@ -122,15 +104,14 @@ class Widget extends \yii\base\Widget /** * Registers a specific jQuery UI widget asset bundle, initializes it with client options and registers related events * @param string $name the name of the jQuery UI widget - * @param string $assetBundle the asset bundle for the widget * @param string $id the ID of the widget. If null, it will use the `id` value of [[options]]. */ - protected function registerWidget($name, $assetBundle, $id = null) + protected function registerWidget($name, $id = null) { if ($id === null) { $id = $this->options['id']; } - $this->registerAssets($assetBundle); + JuiAsset::register($this->getView()); $this->registerClientOptions($name, $id); $this->registerClientEvents($name, $id); } diff --git a/extensions/jui/assets/UPGRADE.md b/extensions/jui/assets/UPGRADE.md deleted file mode 100644 index 5cd32d2..0000000 --- a/extensions/jui/assets/UPGRADE.md +++ /dev/null @@ -1,14 +0,0 @@ -How to Upgrade JQuery UI -======================== - -To upgrade JQuery UI, use [JUI Download Builder](http://jqueryui.com/download/) and toggle all options. -Choose the `Smoothness` theme, download and unpack. - -The following files are needed: - -* UI Core: all JS files -* Interactions: all JS files -* Widgets: all JS files -* DatePicker I18N: only the combined file is needed, and it should be renamed as `jquery.ui.datepicker-i18n.js` -* Effects: only the combined file is needed, and it should be renamed as `jquery.ui.effect-all.js` -* Theme: Only the combined CSS file and the image files are needed. Rename the CSS file as `jquery.ui.css`. diff --git a/extensions/jui/assets/jquery.ui.accordion.js b/extensions/jui/assets/jquery.ui.accordion.js deleted file mode 100644 index bdd2d53..0000000 --- a/extensions/jui/assets/jquery.ui.accordion.js +++ /dev/null @@ -1,572 +0,0 @@ -/*! - * jQuery UI Accordion 1.10.3 - * http://jqueryui.com - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/accordion/ - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -var uid = 0, - hideProps = {}, - showProps = {}; - -hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = - hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; -showProps.height = showProps.paddingTop = showProps.paddingBottom = - showProps.borderTopWidth = showProps.borderBottomWidth = "show"; - -$.widget( "ui.accordion", { - version: "1.10.3", - options: { - active: 0, - animate: {}, - collapsible: false, - event: "click", - header: "> li > :first-child,> :not(li):even", - heightStyle: "auto", - icons: { - activeHeader: "ui-icon-triangle-1-s", - header: "ui-icon-triangle-1-e" - }, - - // callbacks - activate: null, - beforeActivate: null - }, - - _create: function() { - var options = this.options; - this.prevShow = this.prevHide = $(); - this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) - // ARIA - .attr( "role", "tablist" ); - - // don't allow collapsible: false and active: false / null - if ( !options.collapsible && (options.active === false || options.active == null) ) { - options.active = 0; - } - - this._processPanels(); - // handle negative values - if ( options.active < 0 ) { - options.active += this.headers.length; - } - this._refresh(); - }, - - _getCreateEventData: function() { - return { - header: this.active, - panel: !this.active.length ? $() : this.active.next(), - content: !this.active.length ? $() : this.active.next() - }; - }, - - _createIcons: function() { - var icons = this.options.icons; - if ( icons ) { - $( "" ) - .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) - .prependTo( this.headers ); - this.active.children( ".ui-accordion-header-icon" ) - .removeClass( icons.header ) - .addClass( icons.activeHeader ); - this.headers.addClass( "ui-accordion-icons" ); - } - }, - - _destroyIcons: function() { - this.headers - .removeClass( "ui-accordion-icons" ) - .children( ".ui-accordion-header-icon" ) - .remove(); - }, - - _destroy: function() { - var contents; - - // clean up main element - this.element - .removeClass( "ui-accordion ui-widget ui-helper-reset" ) - .removeAttr( "role" ); - - // clean up headers - this.headers - .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) - .removeAttr( "role" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-controls" ) - .removeAttr( "tabIndex" ) - .each(function() { - if ( /^ui-accordion/.test( this.id ) ) { - this.removeAttribute( "id" ); - } - }); - this._destroyIcons(); - - // clean up content panels - contents = this.headers.next() - .css( "display", "" ) - .removeAttr( "role" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-labelledby" ) - .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) - .each(function() { - if ( /^ui-accordion/.test( this.id ) ) { - this.removeAttribute( "id" ); - } - }); - if ( this.options.heightStyle !== "content" ) { - contents.css( "height", "" ); - } - }, - - _setOption: function( key, value ) { - if ( key === "active" ) { - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; - } - - if ( key === "event" ) { - if ( this.options.event ) { - this._off( this.headers, this.options.event ); - } - this._setupEvents( value ); - } - - this._super( key, value ); - - // setting collapsible: false while collapsed; open first panel - if ( key === "collapsible" && !value && this.options.active === false ) { - this._activate( 0 ); - } - - if ( key === "icons" ) { - this._destroyIcons(); - if ( value ) { - this._createIcons(); - } - } - - // #5332 - opacity doesn't cascade to positioned elements in IE - // so we need to add the disabled class to the headers and panels - if ( key === "disabled" ) { - this.headers.add( this.headers.next() ) - .toggleClass( "ui-state-disabled", !!value ); - } - }, - - _keydown: function( event ) { - /*jshint maxcomplexity:15*/ - if ( event.altKey || event.ctrlKey ) { - return; - } - - var keyCode = $.ui.keyCode, - length = this.headers.length, - currentIndex = this.headers.index( event.target ), - toFocus = false; - - switch ( event.keyCode ) { - case keyCode.RIGHT: - case keyCode.DOWN: - toFocus = this.headers[ ( currentIndex + 1 ) % length ]; - break; - case keyCode.LEFT: - case keyCode.UP: - toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; - break; - case keyCode.SPACE: - case keyCode.ENTER: - this._eventHandler( event ); - break; - case keyCode.HOME: - toFocus = this.headers[ 0 ]; - break; - case keyCode.END: - toFocus = this.headers[ length - 1 ]; - break; - } - - if ( toFocus ) { - $( event.target ).attr( "tabIndex", -1 ); - $( toFocus ).attr( "tabIndex", 0 ); - toFocus.focus(); - event.preventDefault(); - } - }, - - _panelKeyDown : function( event ) { - if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { - $( event.currentTarget ).prev().focus(); - } - }, - - refresh: function() { - var options = this.options; - this._processPanels(); - - // was collapsed or no panel - if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { - options.active = false; - this.active = $(); - // active false only when collapsible is true - } else if ( options.active === false ) { - this._activate( 0 ); - // was active, but active panel is gone - } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { - // all remaining panel are disabled - if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { - options.active = false; - this.active = $(); - // activate previous panel - } else { - this._activate( Math.max( 0, options.active - 1 ) ); - } - // was active, active panel still exists - } else { - // make sure active index is correct - options.active = this.headers.index( this.active ); - } - - this._destroyIcons(); - - this._refresh(); - }, - - _processPanels: function() { - this.headers = this.element.find( this.options.header ) - .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); - - this.headers.next() - .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) - .filter(":not(.ui-accordion-content-active)") - .hide(); - }, - - _refresh: function() { - var maxHeight, - options = this.options, - heightStyle = options.heightStyle, - parent = this.element.parent(), - accordionId = this.accordionId = "ui-accordion-" + - (this.element.attr( "id" ) || ++uid); - - this.active = this._findActive( options.active ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) - .removeClass( "ui-corner-all" ); - this.active.next() - .addClass( "ui-accordion-content-active" ) - .show(); - - this.headers - .attr( "role", "tab" ) - .each(function( i ) { - var header = $( this ), - headerId = header.attr( "id" ), - panel = header.next(), - panelId = panel.attr( "id" ); - if ( !headerId ) { - headerId = accordionId + "-header-" + i; - header.attr( "id", headerId ); - } - if ( !panelId ) { - panelId = accordionId + "-panel-" + i; - panel.attr( "id", panelId ); - } - header.attr( "aria-controls", panelId ); - panel.attr( "aria-labelledby", headerId ); - }) - .next() - .attr( "role", "tabpanel" ); - - this.headers - .not( this.active ) - .attr({ - "aria-selected": "false", - tabIndex: -1 - }) - .next() - .attr({ - "aria-expanded": "false", - "aria-hidden": "true" - }) - .hide(); - - // make sure at least one header is in the tab order - if ( !this.active.length ) { - this.headers.eq( 0 ).attr( "tabIndex", 0 ); - } else { - this.active.attr({ - "aria-selected": "true", - tabIndex: 0 - }) - .next() - .attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }); - } - - this._createIcons(); - - this._setupEvents( options.event ); - - if ( heightStyle === "fill" ) { - maxHeight = parent.height(); - this.element.siblings( ":visible" ).each(function() { - var elem = $( this ), - position = elem.css( "position" ); - - if ( position === "absolute" || position === "fixed" ) { - return; - } - maxHeight -= elem.outerHeight( true ); - }); - - this.headers.each(function() { - maxHeight -= $( this ).outerHeight( true ); - }); - - this.headers.next() - .each(function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - }) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.headers.next() - .each(function() { - maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); - }) - .height( maxHeight ); - } - }, - - _activate: function( index ) { - var active = this._findActive( index )[ 0 ]; - - // trying to activate the already active panel - if ( active === this.active[ 0 ] ) { - return; - } - - // trying to collapse, simulate a click on the currently active header - active = active || this.active[ 0 ]; - - this._eventHandler({ - target: active, - currentTarget: active, - preventDefault: $.noop - }); - }, - - _findActive: function( selector ) { - return typeof selector === "number" ? this.headers.eq( selector ) : $(); - }, - - _setupEvents: function( event ) { - var events = { - keydown: "_keydown" - }; - if ( event ) { - $.each( event.split(" "), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - }); - } - - this._off( this.headers.add( this.headers.next() ) ); - this._on( this.headers, events ); - this._on( this.headers.next(), { keydown: "_panelKeyDown" }); - this._hoverable( this.headers ); - this._focusable( this.headers ); - }, - - _eventHandler: function( event ) { - var options = this.options, - active = this.active, - clicked = $( event.currentTarget ), - clickedIsActive = clicked[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : clicked.next(), - toHide = active.next(), - eventData = { - oldHeader: active, - oldPanel: toHide, - newHeader: collapsing ? $() : clicked, - newPanel: toShow - }; - - event.preventDefault(); - - if ( - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; - } - - options.active = collapsing ? false : this.headers.index( clicked ); - - // when the call to ._toggle() comes after the class changes - // it causes a very odd bug in IE 8 (see #6720) - this.active = clickedIsActive ? $() : clicked; - this._toggle( eventData ); - - // switch classes - // corner classes on the previously active header stay after the animation - active.removeClass( "ui-accordion-header-active ui-state-active" ); - if ( options.icons ) { - active.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.activeHeader ) - .addClass( options.icons.header ); - } - - if ( !clickedIsActive ) { - clicked - .removeClass( "ui-corner-all" ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); - if ( options.icons ) { - clicked.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.header ) - .addClass( options.icons.activeHeader ); - } - - clicked - .next() - .addClass( "ui-accordion-content-active" ); - } - }, - - _toggle: function( data ) { - var toShow = data.newPanel, - toHide = this.prevShow.length ? this.prevShow : data.oldPanel; - - // handle activating a panel during the animation for another activation - this.prevShow.add( this.prevHide ).stop( true, true ); - this.prevShow = toShow; - this.prevHide = toHide; - - if ( this.options.animate ) { - this._animate( toShow, toHide, data ); - } else { - toHide.hide(); - toShow.show(); - this._toggleComplete( data ); - } - - toHide.attr({ - "aria-expanded": "false", - "aria-hidden": "true" - }); - toHide.prev().attr( "aria-selected", "false" ); - // if we're switching panels, remove the old header from the tab order - // if we're opening from collapsed state, remove the previous header from the tab order - // if we're collapsing, then keep the collapsing header in the tab order - if ( toShow.length && toHide.length ) { - toHide.prev().attr( "tabIndex", -1 ); - } else if ( toShow.length ) { - this.headers.filter(function() { - return $( this ).attr( "tabIndex" ) === 0; - }) - .attr( "tabIndex", -1 ); - } - - toShow - .attr({ - "aria-expanded": "true", - "aria-hidden": "false" - }) - .prev() - .attr({ - "aria-selected": "true", - tabIndex: 0 - }); - }, - - _animate: function( toShow, toHide, data ) { - var total, easing, duration, - that = this, - adjust = 0, - down = toShow.length && - ( !toHide.length || ( toShow.index() < toHide.index() ) ), - animate = this.options.animate || {}, - options = down && animate.down || animate, - complete = function() { - that._toggleComplete( data ); - }; - - if ( typeof options === "number" ) { - duration = options; - } - if ( typeof options === "string" ) { - easing = options; - } - // fall back from options to animation in case of partial down settings - easing = easing || options.easing || animate.easing; - duration = duration || options.duration || animate.duration; - - if ( !toHide.length ) { - return toShow.animate( showProps, duration, easing, complete ); - } - if ( !toShow.length ) { - return toHide.animate( hideProps, duration, easing, complete ); - } - - total = toShow.show().outerHeight(); - toHide.animate( hideProps, { - duration: duration, - easing: easing, - step: function( now, fx ) { - fx.now = Math.round( now ); - } - }); - toShow - .hide() - .animate( showProps, { - duration: duration, - easing: easing, - complete: complete, - step: function( now, fx ) { - fx.now = Math.round( now ); - if ( fx.prop !== "height" ) { - adjust += fx.now; - } else if ( that.options.heightStyle !== "content" ) { - fx.now = Math.round( total - toHide.outerHeight() - adjust ); - adjust = 0; - } - } - }); - }, - - _toggleComplete: function( data ) { - var toHide = data.oldPanel; - - toHide - .removeClass( "ui-accordion-content-active" ) - .prev() - .removeClass( "ui-corner-top" ) - .addClass( "ui-corner-all" ); - - // Work around for rendering bug in IE (#5421) - if ( toHide.length ) { - toHide.parent()[0].className = toHide.parent()[0].className; - } - - this._trigger( "activate", null, data ); - } -}); - -})( jQuery ); diff --git a/extensions/jui/assets/jquery.ui.autocomplete.js b/extensions/jui/assets/jquery.ui.autocomplete.js deleted file mode 100644 index ca53d2c..0000000 --- a/extensions/jui/assets/jquery.ui.autocomplete.js +++ /dev/null @@ -1,610 +0,0 @@ -/*! - * jQuery UI Autocomplete 1.10.3 - * http://jqueryui.com - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/autocomplete/ - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - * jquery.ui.position.js - * jquery.ui.menu.js - */ -(function( $, undefined ) { - -// used to prevent race conditions with remote data sources -var requestIndex = 0; - -$.widget( "ui.autocomplete", { - version: "1.10.3", - defaultElement: "", - options: { - appendTo: null, - autoFocus: false, - delay: 300, - minLength: 1, - position: { - my: "left top", - at: "left bottom", - collision: "none" - }, - source: null, - - // callbacks - change: null, - close: null, - focus: null, - open: null, - response: null, - search: null, - select: null - }, - - pending: 0, - - _create: function() { - // Some browsers only repeat keydown events, not keypress events, - // so we use the suppressKeyPress flag to determine if we've already - // handled the keydown event. #7269 - // Unfortunately the code for & in keypress is the same as the up arrow, - // so we use the suppressKeyPressRepeat flag to avoid handling keypress - // events when we know the keydown event was used to modify the - // search term. #7799 - var suppressKeyPress, suppressKeyPressRepeat, suppressInput, - nodeName = this.element[0].nodeName.toLowerCase(), - isTextarea = nodeName === "textarea", - isInput = nodeName === "input"; - - this.isMultiLine = - // Textareas are always multi-line - isTextarea ? true : - // Inputs are always single-line, even if inside a contentEditable element - // IE also treats inputs as contentEditable - isInput ? false : - // All other element types are determined by whether or not they're contentEditable - this.element.prop( "isContentEditable" ); - - this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; - this.isNewMenu = true; - - this.element - .addClass( "ui-autocomplete-input" ) - .attr( "autocomplete", "off" ); - - this._on( this.element, { - keydown: function( event ) { - /*jshint maxcomplexity:15*/ - if ( this.element.prop( "readOnly" ) ) { - suppressKeyPress = true; - suppressInput = true; - suppressKeyPressRepeat = true; - return; - } - - suppressKeyPress = false; - suppressInput = false; - suppressKeyPressRepeat = false; - var keyCode = $.ui.keyCode; - switch( event.keyCode ) { - case keyCode.PAGE_UP: - suppressKeyPress = true; - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - suppressKeyPress = true; - this._move( "nextPage", event ); - break; - case keyCode.UP: - suppressKeyPress = true; - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - suppressKeyPress = true; - this._keyEvent( "next", event ); - break; - case keyCode.ENTER: - case keyCode.NUMPAD_ENTER: - // when menu is open and has focus - if ( this.menu.active ) { - // #6055 - Opera still allows the keypress to occur - // which causes forms to submit - suppressKeyPress = true; - event.preventDefault(); - this.menu.select( event ); - } - break; - case keyCode.TAB: - if ( this.menu.active ) { - this.menu.select( event ); - } - break; - case keyCode.ESCAPE: - if ( this.menu.element.is( ":visible" ) ) { - this._value( this.term ); - this.close( event ); - // Different browsers have different default behavior for escape - // Single press can mean undo or clear - // Double press in IE means clear the whole form - event.preventDefault(); - } - break; - default: - suppressKeyPressRepeat = true; - // search timeout should be triggered before the input value is changed - this._searchTimeout( event ); - break; - } - }, - keypress: function( event ) { - if ( suppressKeyPress ) { - suppressKeyPress = false; - if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { - event.preventDefault(); - } - return; - } - if ( suppressKeyPressRepeat ) { - return; - } - - // replicate some key handlers to allow them to repeat in Firefox and Opera - var keyCode = $.ui.keyCode; - switch( event.keyCode ) { - case keyCode.PAGE_UP: - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - this._move( "nextPage", event ); - break; - case keyCode.UP: - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - this._keyEvent( "next", event ); - break; - } - }, - input: function( event ) { - if ( suppressInput ) { - suppressInput = false; - event.preventDefault(); - return; - } - this._searchTimeout( event ); - }, - focus: function() { - this.selectedItem = null; - this.previous = this._value(); - }, - blur: function( event ) { - if ( this.cancelBlur ) { - delete this.cancelBlur; - return; - } - - clearTimeout( this.searching ); - this.close( event ); - this._change( event ); - } - }); - - this._initSource(); - this.menu = $( "