Fixed JS assets that don't have ; at the end for pipeline. Also PSR fixes

This commit is contained in:
Andy Miller
2014-11-18 17:22:03 -07:00
parent 50cdf01fae
commit d3265baa4e

View File

@@ -20,7 +20,6 @@ define('JS_ASSET', false);
* @author RocketTheme
* @license MIT
*/
class Assets
{
use GravTrait;
@@ -86,8 +85,9 @@ class Assets
public function __construct(array $options = array())
{
// Forward config options
if($options)
if ($options) {
$this->config((array)$options);
}
}
/**
@@ -98,7 +98,7 @@ class Assets
/** @var Config $config */
$config = self::$grav['config'];
$base_url = self::$grav['base_url'];
$asset_config = (array) $config->get('system.assets');
$asset_config = (array)$config->get('system.assets');
$this->config($asset_config);
$this->base_url = $base_url . '/';
@@ -118,43 +118,50 @@ class Assets
public function config(array $config)
{
// Set pipeline modes
if(isset($config['css_pipeline']))
if (isset($config['css_pipeline'])) {
$this->css_pipeline = $config['css_pipeline'];
}
if(isset($config['js_pipeline']))
if (isset($config['js_pipeline'])) {
$this->js_pipeline = $config['js_pipeline'];
}
// Pipeline requires public dir
if(($this->js_pipeline || $this->css_pipeline) && ! is_dir(ASSETS_DIR))
if (($this->js_pipeline || $this->css_pipeline) && !is_dir(ASSETS_DIR)) {
throw new \Exception('Assets: Public dir not found');
}
// Set custom pipeline fetch command
if(isset($config['fetch_command']) and ($config['fetch_command'] instanceof Closure))
if (isset($config['fetch_command']) and ($config['fetch_command'] instanceof Closure)) {
$this->fetch_command = $config['fetch_command'];
}
// Set CSS Minify state
if(isset($config['css_minify']))
if (isset($config['css_minify'])) {
$this->css_minify = $config['css_minify'];
}
if(isset($config['css_minify_windows']))
if (isset($config['css_minify_windows'])) {
$this->css_minify_windows = $config['css_minify_windows'];
}
if(isset($config['css_rewrite']))
if (isset($config['css_rewrite'])) {
$this->css_rewrite = $config['css_rewrite'];
}
// Set JS Minify state
if(isset($config['js_minify']))
if (isset($config['js_minify'])) {
$this->js_minify = $config['js_minify'];
}
// Set collections
if(isset($config['collections']) and is_array($config['collections']))
if (isset($config['collections']) and is_array($config['collections'])) {
$this->collections = $config['collections'];
}
// Autoload assets
if(isset($config['autoload']) and is_array($config['autoload']))
{
foreach($config['autoload'] as $asset)
{
if (isset($config['autoload']) and is_array($config['autoload'])) {
foreach ($config['autoload'] as $asset) {
$this->add($asset);
}
}
@@ -168,35 +175,30 @@ class Assets
* It automatically detects the asset type (JavaScript, CSS or collection).
* You may add more than one asset passing an array as argument.
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @return $this
*/
public function add($asset, $priority = 10, $pipeline = true)
{
// More than one asset
if(is_array($asset))
{
foreach($asset as $a)
if (is_array($asset)) {
foreach ($asset as $a) {
$this->add($a, $priority, $pipeline);
}
// Collection
elseif(isset($this->collections[$asset]))
{
}
} elseif (isset($this->collections[$asset])) {
$this->add($this->collections[$asset], $priority, $pipeline);
}
else
{
} else {
// JavaScript or CSS
$info = pathinfo($asset);
if(isset($info['extension']))
{
if (isset($info['extension'])) {
$ext = strtolower($info['extension']);
if($ext === 'css')
if ($ext === 'css') {
$this->addCss($asset, $priority, $pipeline);
elseif($ext === 'js')
} elseif ($ext === 'js') {
$this->addJs($asset, $priority, $pipeline);
}
}
}
@@ -209,11 +211,12 @@ class Assets
* It checks for duplicates.
* For adding chunks of string-based inline CSS
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @return $this
*/
public function addInlineCss($asset, $priority = 10) {
public function addInlineCss($asset, $priority = 10)
{
if (is_string($asset) && !in_array($asset, $this->inline_css)) {
$this->inline_css[] = $asset;
@@ -228,27 +231,32 @@ class Assets
* It checks for duplicates.
* You may add more than one asset passing an array as argument.
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @return $this
*/
public function addCss($asset, $priority = 10, $pipeline = true)
{
if(is_array($asset))
{
foreach($asset as $a)
if (is_array($asset)) {
foreach ($asset as $a) {
$this->addCss($a, $priority, $pipeline);
}
return $this;
}
if( !$this->isRemoteLink($asset)) {
if (!$this->isRemoteLink($asset)) {
$asset = $this->buildLocalLink($asset);
}
if( !array_key_exists($asset, $this->css)) {
$this->css[$asset] = ['asset'=>$asset, 'priority'=>$priority, 'order' => count($this->css), 'pipeline'=>$pipeline];
if (!array_key_exists($asset, $this->css)) {
$this->css[$asset] = [
'asset' => $asset,
'priority' => $priority,
'order' => count($this->css),
'pipeline' => $pipeline
];
}
return $this;
@@ -260,11 +268,12 @@ class Assets
* It checks for duplicates.
* For adding chunks of string-based inline JS
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @return $this
*/
public function addInlineJs($asset) {
public function addInlineJs($asset)
{
if (is_string($asset) && !in_array($asset, $this->inline_js)) {
$this->inline_js[] = $asset;
@@ -279,28 +288,33 @@ class Assets
* It checks for duplicates.
* You may add more than one asset passing an array as argument.
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @return $this
*/
public function addJs($asset, $priority = 10, $pipeline = true)
{
if(is_array($asset))
{
foreach($asset as $a)
if (is_array($asset)) {
foreach ($asset as $a) {
$this->addJs($a, $priority, $pipeline);
}
return $this;
}
if( !$this->isRemoteLink($asset)) {
if (!$this->isRemoteLink($asset)) {
$asset = $this->buildLocalLink($asset);
}
if( !array_key_exists($asset, $this->js)) {
if (!array_key_exists($asset, $this->js)) {
$this->js[$asset] = ['asset' => $asset, 'priority' => $priority, 'order' => count($this->js), 'pipeline' => $pipeline];
$this->js[$asset] = [
'asset' => $asset,
'priority' => $priority,
'order' => count($this->js),
'pipeline' => $pipeline
];
}
return $this;
@@ -309,36 +323,37 @@ class Assets
/**
* Build the CSS link tags.
*
* @param array $attributes
* @param array $attributes
* @return string
*/
public function css($attributes = [])
{
if( ! $this->css)
if (!$this->css) {
return null;
if (self::$grav)
}
// Sort array by priorities (larger priority first)
usort($this->css, function ($a, $b) {
if ($a['priority'] == $b['priority']) {
return $b['order'] - $a['order'];
}
return $a['priority'] - $b['priority'];
});
if (self::$grav) {
usort($this->css, function ($a, $b) {
if ($a['priority'] == $b['priority']) {
return $b['order'] - $a['order'];
}
return $a['priority'] - $b['priority'];
});
}
$this->css = array_reverse($this->css);
$attributes = $this->attributes(array_merge([ 'type' => 'text/css', 'rel' => 'stylesheet' ], $attributes));
$attributes = $this->attributes(array_merge(['type' => 'text/css', 'rel' => 'stylesheet'], $attributes));
$output = '';
if($this->css_pipeline) {
$output .= '<link href="'.$this->pipeline(CSS_ASSET).'"'.$attributes.' />'."\n";
if ($this->css_pipeline) {
$output .= '<link href="' . $this->pipeline(CSS_ASSET) . '"' . $attributes . ' />' . "\n";
foreach ($this->css_no_pipeline as $file) {
$output .= '<link href="'.$file['asset'].'"'.$attributes.' />'."\n";
$output .= '<link href="' . $file['asset'] . '"' . $attributes . ' />' . "\n";
}
} else {
foreach($this->css as $file) {
foreach ($this->css as $file) {
$output .= '<link href="' . $file['asset'] . '"' . $attributes . ' />' . "\n";
}
}
@@ -346,7 +361,7 @@ class Assets
// Render Inline CSS
if (count($this->inline_css) > 0) {
$output .= "<style>\n";
foreach($this->inline_css as $inline) {
foreach ($this->inline_css as $inline) {
$output .= $inline . "\n";
}
$output .= "</style>\n";
@@ -359,13 +374,14 @@ class Assets
/**
* Build the JavaScript script tags.
*
* @param array $attributes
* @param array $attributes
* @return string
*/
public function js($attributes = [])
{
if( ! $this->js)
if (!$this->js) {
return null;
}
// Sort array by priorities (larger priority first)
usort($this->js, function ($a, $b) {
@@ -376,16 +392,16 @@ class Assets
});
$this->js = array_reverse($this->js);
$attributes = $this->attributes(array_merge([ 'type' => 'text/javascript' ], $attributes));
$attributes = $this->attributes(array_merge(['type' => 'text/javascript'], $attributes));
$output = '';
if($this->js_pipeline) {
$output .= '<script src="'.$this->pipeline(JS_ASSET).'"'.$attributes.' ></script>'."\n";
if ($this->js_pipeline) {
$output .= '<script src="' . $this->pipeline(JS_ASSET) . '"' . $attributes . ' ></script>' . "\n";
foreach ($this->js_no_pipeline as $file) {
$output .= '<script src="'.$file['asset'].'"'.$attributes.' ></script>'."\n";
$output .= '<script src="' . $file['asset'] . '"' . $attributes . ' ></script>' . "\n";
}
} else {
foreach($this->js as $file) {
foreach ($this->js as $file) {
$output .= '<script src="' . $file['asset'] . '"' . $attributes . ' ></script>' . "\n";
}
}
@@ -393,7 +409,7 @@ class Assets
// Render Inline JS
if (count($this->inline_js) > 0) {
$output .= "<script>\n";
foreach($this->inline_js as $inline) {
foreach ($this->inline_js as $inline) {
$output .= $inline . "\n";
}
$output .= "</script>\n";
@@ -405,22 +421,26 @@ class Assets
/**
* Build an HTML attribute string from an array.
*
* @param array $attributes
* @param array $attributes
* @return string
*/
protected function attributes(array $attributes){
protected function attributes(array $attributes)
{
$html = '';
foreach ( $attributes as $key => $value)
{
foreach ($attributes as $key => $value) {
// For numeric keys we will assume that the key and the value are the same
// as this will convert HTML attributes such as "required" to a correct
// form like required="required" instead of using incorrect numerics.
if (is_numeric($key)) $key = $value;
if (is_array($value)) $value = implode(' ', $value);
if (is_numeric($key)) {
$key = $value;
}
if (is_array($value)) {
$value = implode(' ', $value);
}
$element = $key.'="'.htmlentities($value, ENT_QUOTES, 'UTF-8', false).'"';
$html .= ' '.$element;
$element = $key . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"';
$html .= ' ' . $element;
}
return $html;
@@ -429,8 +449,8 @@ class Assets
/**
* Add/replace collection.
*
* @param string $collectionName
* @param array $assets
* @param string $collectionName
* @param array $assets
* @return $this
*/
public function registerCollection($collectionName, Array $assets)
@@ -483,7 +503,7 @@ class Assets
{
/** @var Cache $cache */
$cache = self::$grav['cache'];
$key = '?'.$cache->getKey();
$key = '?' . $cache->getKey();
if ($css) {
$file = md5(json_encode($this->css) . $this->js_minify . $this->css_minify . $this->css_rewrite) . '.css';
@@ -503,12 +523,13 @@ class Assets
}
}
$relative_path = "{$this->base_url}".basename(ASSETS_DIR)."/{$file}";
$absolute_path = ASSETS_DIR.$file;
$relative_path = "{$this->base_url}" . basename(ASSETS_DIR) . "/{$file}";
$absolute_path = ASSETS_DIR . $file;
// If pipeline exist return it
if(file_exists($absolute_path))
if (file_exists($absolute_path)) {
return $relative_path . $key;
}
$css_minify = $this->css_minify;
@@ -542,7 +563,7 @@ class Assets
/**
* Download and concatenate the content of several links.
*
* @param array $links
* @param array $links
* @return string
*/
protected function gatherLinks(array $links, $css = true)
@@ -552,27 +573,32 @@ class Assets
$buffer = '';
$local = true;
foreach($links as $asset)
{
foreach ($links as $asset) {
$link = $asset['asset'];
$relative_path = $link;
if($this->isRemoteLink($link)) {
if ($this->isRemoteLink($link)) {
$local = false;
if('//' === substr($link, 0, 2))
if ('//' === substr($link, 0, 2)) {
$link = 'http:' . $link;
}
} else {
// Fix to remove relative dir if grav is in one
if (($this->base_url != '/') && (strpos($this->base_url, $link) == 0)) {
$relative_path = str_replace($this->base_url, '/', $link);
}
$relative_dir = dirname ($relative_path);
$relative_dir = dirname($relative_path);
$link = ROOT_DIR . $relative_path;
}
$file = ($this->fetch_command instanceof Closure) ? $this->fetch_command->__invoke($link) : file_get_contents($link);
// Double check last character being
if (!$css) {
$file = rtrim($file, ' ;') . ';';
}
// If this is CSS + the file is local + rewrite enabled
if ($css && $local && $this->css_rewrite) {
$file = $this->cssRewrite($file, $relative_dir);
@@ -600,7 +626,7 @@ class Assets
$this->imports = array();
$file = preg_replace_callback(self::CSS_IMPORT_REGEX,
function($matches) {
function ($matches) {
$this->imports[] = $matches[0];
return '';
},
@@ -612,7 +638,7 @@ class Assets
/**
* Finds relative CSS urls() and rewrites the URL with an absolute one
* @param string $file the css source file
* @param string $file the css source file
* @param string $relative_path relative path to the css file
* @return [type] [description]
*/
@@ -624,29 +650,31 @@ class Assets
// Find any css url() elements, grab the URLs and calculate an absolute path
// Then replace the old url with the new one
$file = preg_replace_callback(self::CSS_URL_REGEX,
function($matches) use ($relative_path) {
function ($matches) use ($relative_path) {
$old_url = $matches[1];
$old_url = $matches[1];
// ensure this is not a data url
if (strpos($old_url, 'data:') === 0) return $matches[0];
// ensure this is not a data url
if (strpos($old_url, 'data:') === 0) {
return $matches[0];
}
$newpath = array();
$paths = explode('/', $old_url);
$newpath = array();
$paths = explode('/', $old_url);
foreach ($paths as $path) {
if ($path == '..') {
$relative_path = dirname($relative_path);
} else {
$newpath[] = $path;
}
foreach ($paths as $path) {
if ($path == '..') {
$relative_path = dirname($relative_path);
} else {
$newpath[] = $path;
}
}
$new_url = rtrim($this->base_url,'/') . $relative_path . '/' . implode('/', $newpath);
$new_url = rtrim($this->base_url, '/') . $relative_path . '/' . implode('/', $newpath);
return str_replace($old_url, $new_url, $matches[0]);
},
$file
return str_replace($old_url, $new_url, $matches[0]);
},
$file
);
return $file;
@@ -662,7 +690,8 @@ class Assets
{
try {
$asset = self::$grav['locator']->findResource($asset, false);
} catch (\Exception $e) {}
} catch (\Exception $e) {
}
return $this->base_url . ltrim($asset, '/');
}
@@ -678,7 +707,8 @@ class Assets
*/
protected function isRemoteLink($link)
{
return ('http://' === substr($link, 0, 7) or 'https://' === substr($link, 0, 8) or '//' === substr($link, 0, 2));
return ('http://' === substr($link, 0, 7) or 'https://' === substr($link, 0, 8)
or '//' === substr($link, 0, 2));
}
/**
@@ -712,41 +742,40 @@ class Assets
public function addDir($directory, $pattern = self::DEFAULT_REGEX)
{
// Check if public_dir exists
if( ! is_dir(ASSETS_DIR))
if (!is_dir(ASSETS_DIR)) {
throw new Exception('Assets: Public dir not found');
}
// Get files
$files = $this->rglob(ASSETS_DIR . DIRECTORY_SEPARATOR . $directory, $pattern, ASSETS_DIR);
// No luck? Nothing to do
if( ! $files)
if (!$files) {
return $this;
}
// Add CSS files
if($pattern === self::CSS_REGEX)
{
if ($pattern === self::CSS_REGEX) {
$this->css = array_unique(array_merge($this->css, $files));
return $this;
}
// Add JavaScript files
if($pattern === self::JS_REGEX)
{
if ($pattern === self::JS_REGEX) {
$this->js = array_unique(array_merge($this->js, $files));
return $this;
}
// Unknown pattern. We must poll to know the extension :(
foreach($files as $asset)
{
foreach ($files as $asset) {
$info = pathinfo($asset);
if(isset($info['extension']))
{
if (isset($info['extension'])) {
$ext = strtolower($info['extension']);
if($ext === 'css' and ! in_array($asset, $this->css))
if ($ext === 'css' and !in_array($asset, $this->css)) {
$this->css[] = $asset;
elseif($ext === 'js' and ! in_array($asset, $this->js))
} elseif ($ext === 'js' and !in_array($asset, $this->js)) {
$this->js[] = $asset;
}
}
}
@@ -785,12 +814,14 @@ class Assets
*/
protected function rglob($directory, $pattern, $ltrim = null)
{
$iterator = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS)), $pattern);
$iterator = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory,
FilesystemIterator::SKIP_DOTS)), $pattern);
$offset = strlen($ltrim);
$files = array();
foreach($iterator as $file)
foreach ($iterator as $file) {
$files[] = substr($file->getPathname(), $offset);
}
return $files;
}
@@ -805,7 +836,8 @@ class Assets
return $a ['priority'] - $b ['priority'];
}
public function __toString() {
public function __toString()
{
return '';
}