Initial support for LESS and SCSS stylesheets

This commit is contained in:
Kijin Sung 2016-05-03 21:23:38 +09:00
parent 0b05de6f80
commit 25965b5d72
3 changed files with 127 additions and 52 deletions

View file

@ -16,7 +16,18 @@ class FileHandler
*/ */
public static function getRealPath($source) public static function getRealPath($source)
{ {
return (strncmp($source, './', 2) === 0) ? (\RX_BASEDIR . substr($source, 2)) : $source; if (strncmp($source, './', 2) === 0)
{
return \RX_BASEDIR . substr($source, 2);
}
elseif (strncmp($source, '/', 1) === 0)
{
return $source;
}
else
{
return \RX_BASEDIR . $source;
}
} }
/** /**

View file

@ -87,7 +87,7 @@ class FrontEndFileHandler extends Handler
* @param array $args Arguments * @param array $args Arguments
* @return void * @return void
* */ * */
function loadFile($args) public function loadFile($args)
{ {
if(!is_array($args)) if(!is_array($args))
{ {
@ -113,7 +113,7 @@ class FrontEndFileHandler extends Handler
$map = &$this->cssMap; $map = &$this->cssMap;
$mapIndex = &$this->cssMapIndex; $mapIndex = &$this->cssMapIndex;
$this->_arrangeCssIndex($pathInfo['dirname'], $file); $this->_arrangeCssIndex($file->fileRealPath, $file);
} }
else if($file->fileExtension == 'js') else if($file->fileExtension == 'js')
{ {
@ -131,7 +131,7 @@ class FrontEndFileHandler extends Handler
if(!isset($mapIndex[$file->key]) || $mapIndex[$file->key] > $file->index) if(!isset($mapIndex[$file->key]) || $mapIndex[$file->key] > $file->index)
{ {
$this->unloadFile($args[0], $args[2], $args[1]); //$this->unloadFile($args[0], $args[2], $args[1]);
$map[$file->index][$file->key] = $file; $map[$file->index][$file->key] = $file;
$mapIndex[$file->key] = $file->index; $mapIndex[$file->key] = $file->index;
} }
@ -146,7 +146,7 @@ class FrontEndFileHandler extends Handler
* @param bool $forceMinify Whether this file should be minified * @param bool $forceMinify Whether this file should be minified
* @return stdClass The file information * @return stdClass The file information
*/ */
private function getFileInfo($fileName, $targetIe = '', $media = 'all', $forceMinify = false) protected function getFileInfo($fileName, $targetIe = '', $media = 'all', $forceMinify = false)
{ {
static $existsInfo = array(); static $existsInfo = array();
@ -165,6 +165,7 @@ class FrontEndFileHandler extends Handler
$file->fileName = $pathInfo['basename']; $file->fileName = $pathInfo['basename'];
$file->filePath = $this->_getAbsFileUrl($pathInfo['dirname']); $file->filePath = $this->_getAbsFileUrl($pathInfo['dirname']);
$file->fileRealPath = FileHandler::getRealPath($pathInfo['dirname']); $file->fileRealPath = FileHandler::getRealPath($pathInfo['dirname']);
$file->fileFullPath = $file->fileRealPath . '/' . $pathInfo['basename'];
$file->fileExtension = strtolower($pathInfo['extension']); $file->fileExtension = strtolower($pathInfo['extension']);
if(preg_match('/^(.+)\.min$/', $pathInfo['filename'], $matches)) if(preg_match('/^(.+)\.min$/', $pathInfo['filename'], $matches))
{ {
@ -180,65 +181,46 @@ class FrontEndFileHandler extends Handler
$file->isCachedScript = !$file->isExternalURL && strpos($file->filePath, 'files/cache/') !== false; $file->isCachedScript = !$file->isExternalURL && strpos($file->filePath, 'files/cache/') !== false;
$file->keyName = $file->fileNameNoExt . '.' . $file->fileExtension; $file->keyName = $file->fileNameNoExt . '.' . $file->fileExtension;
$file->cdnPath = $this->_normalizeFilePath($pathInfo['dirname']); $file->cdnPath = $this->_normalizeFilePath($pathInfo['dirname']);
$originalFilePath = $file->fileRealPath . '/' . $pathInfo['basename'];
// Fix incorrectly minified URL // Fix incorrectly minified URL
if($file->isMinified && !$file->isExternalURL && (!file_exists($originalFilePath) || is_link($originalFilePath) || if($file->isMinified && !$file->isExternalURL && (!file_exists($file->fileFullPath) || is_link($file->fileFullPath) ||
(filesize($originalFilePath) < 32 && trim(file_get_contents($originalFilePath)) === $file->keyName))) (filesize($file->fileFullPath) < 32 && trim(file_get_contents($file->fileFullPath)) === $file->keyName)))
{ {
if(file_exists($file->fileRealPath . '/' . $file->fileNameNoExt . '.' . $file->fileExtension)) if(file_exists($file->fileRealPath . '/' . $file->fileNameNoExt . '.' . $file->fileExtension))
{ {
$file->fileName = $file->fileNameNoExt . '.' . $file->fileExtension; $file->fileName = $file->fileNameNoExt . '.' . $file->fileExtension;
$file->isMinified = false; $file->isMinified = false;
$originalFilePath = $file->fileRealPath . '/' . $file->fileNameNoExt . '.' . $file->fileExtension; $file->fileFullPath = $file->fileRealPath . '/' . $file->fileNameNoExt . '.' . $file->fileExtension;
} }
} }
// Decide whether to minify this file // Decide whether to minify this file
if(self::$minify === 'all') if ($file->isMinified || $file->isExternalURL || $file->isCachedScript || strpos($file->filePath, 'common/js/plugins') !== false || self::$minify === 'none')
{ {
$minify_enabled = true; $minify = false;
} }
elseif(self::$minify === 'none') elseif (self::$minify === 'all')
{ {
$minify_enabled = false; $minify = true;
} }
else else
{ {
$minify_enabled = $forceMinify; $minify = $forceMinify;
} }
// Minify file // Process according to file type
if($minify_enabled && !$file->isMinified && !$file->isExternalURL && !$file->isCachedScript && strpos($file->filePath, 'common/js/plugins') === false) switch ($file->fileExtension)
{ {
if(($file->fileExtension === 'css' || $file->fileExtension === 'js') && file_exists($originalFilePath)) case 'css':
{ case 'js':
$minifiedFileName = $file->fileNameNoExt . '.min.' . $file->fileExtension; $this->proc_CSS_JS($file, $minify);
$minifiedFileHash = ltrim(str_replace(array('/', '\\'), '.', $pathInfo['dirname']), '.'); break;
$minifiedFilePath = _XE_PATH_ . 'files/cache/minify/' . $minifiedFileHash . '.' . $minifiedFileName; case 'less':
case 'scss':
if(!file_exists($minifiedFilePath) || filemtime($minifiedFilePath) < filemtime($originalFilePath)) $this->proc_LESS_SCSS($file, $minify);
{ break;
if($file->fileExtension === 'css') default:
{ break;
$minifier = new MatthiasMullie\Minify\CSS($originalFilePath);
$content = $minifier->execute($minifiedFilePath);
}
else
{
$minifier = new MatthiasMullie\Minify\JS($originalFilePath);
$content = $minifier->execute($minifiedFilePath);
}
FileHandler::writeFile($minifiedFilePath, $content);
}
$file->fileName = $minifiedFileHash . '.' . $minifiedFileName;
$file->filePath = $this->_getAbsFileUrl('./files/cache/minify');
$file->fileRealPath = _XE_PATH_ . 'files/cache/minify';
$file->keyName = $minifiedFileHash . '.' . $file->fileNameNoExt . '.' . $file->fileExtension;
$file->cdnPath = $this->_normalizeFilePath('./files/cache/minify');
$file->isMinified = true;
}
} }
// Process targetIe and media attributes // Process targetIe and media attributes
@ -260,6 +242,82 @@ class FrontEndFileHandler extends Handler
return $file; return $file;
} }
/**
* Process CSS and JS file
*
* @param object $file
* @param bool $minify
* @return void
*/
protected function proc_CSS_JS($file, $minify)
{
if (!$minify || !file_exists($file->fileFullPath))
{
return;
}
$minifiedFileName = $file->fileNameNoExt . '.min.' . $file->fileExtension;
$minifiedFileHash = ltrim(str_replace(array('/', '\\'), '.', substr($file->fileRealPath, strlen(\RX_BASEDIR))), '.');
$minifiedFilePath = \RX_BASEDIR . 'files/cache/minify/' . $minifiedFileHash . '.' . $minifiedFileName;
if (!file_exists($minifiedFilePath) || filemtime($minifiedFilePath) < filemtime($file->fileFullPath))
{
$method_name = 'minify' . $file->fileExtension;
$success = Rhymix\Framework\Formatter::$method_name($file->fileFullPath, $minifiedFilePath);
if ($success === false)
{
return;
}
}
$file->fileName = $minifiedFileHash . '.' . $minifiedFileName;
$file->filePath = $this->_getAbsFileUrl('./files/cache/minify');
$file->fileRealPath = \RX_BASEDIR . 'files/cache/minify';
$file->fileFullPath = $minifiedFilePath;
$file->keyName = $minifiedFileHash . '.' . $file->fileNameNoExt . '.' . $file->fileExtension;
$file->cdnPath = $this->_normalizeFilePath('./files/cache/minify');
$file->isMinified = true;
}
/**
* Process LESS and SCSS file
*
* @param object $file
* @param bool $minify
* @param array $vars
* @return void
*/
protected function proc_LESS_SCSS($file, $minify, $vars = array())
{
if (!file_exists($file->fileFullPath))
{
return;
}
$compiledFileName = $file->fileName . ($minify ? '.min' : '') . '.css';
$compiledFileHash = ltrim(str_replace(array('/', '\\'), '.', substr($file->fileRealPath, strlen(\RX_BASEDIR))), '.');
$compiledFilePath = \RX_BASEDIR . 'files/cache/minify/' . $compiledFileHash . '.' . $compiledFileName;
if (!file_exists($compiledFilePath) || filemtime($compiledFilePath) < filemtime($file->fileFullPath))
{
$method_name = 'compile' . $file->fileExtension;
$success = Rhymix\Framework\Formatter::$method_name($file->fileFullPath, $compiledFilePath, $vars, $minify);
if ($success === false)
{
return;
}
}
$file->fileName = $compiledFileHash . '.' . $compiledFileName;
$file->filePath = $this->_getAbsFileUrl('./files/cache/minify');
$file->fileRealPath = \RX_BASEDIR . 'files/cache/minify';
$file->fileFullPath = $compiledFilePath;
$file->keyName = $compiledFileHash . '.' . $file->fileNameNoExt . '.' . $file->fileExtension;
$file->cdnPath = $this->_normalizeFilePath('./files/cache/minify');
$file->isMinified = true;
$file->fileExtension = 'css';
}
/** /**
* Unload front end file * Unload front end file
* *
@ -268,7 +326,7 @@ class FrontEndFileHandler extends Handler
* @param string $media Media of file to unload. Only use when file is css. * @param string $media Media of file to unload. Only use when file is css.
* @return void * @return void
*/ */
function unloadFile($fileName, $targetIe = '', $media = 'all') public function unloadFile($fileName, $targetIe = '', $media = 'all')
{ {
$file = $this->getFileInfo($fileName, $targetIe, $media); $file = $this->getFileInfo($fileName, $targetIe, $media);
@ -452,19 +510,23 @@ class FrontEndFileHandler extends Handler
/** /**
* Arrage css index * Arrage css index
* *
* @param string $dirName First directory name of css path * @param string $dirname
* @param array $file file info. * @param object $file
* @return void * @return void
*/ */
function _arrangeCssIndex($dirName, &$file) function _arrangeCssIndex($dirname, $file)
{ {
if ($file->index !== 0) if ($file->index !== 0)
{ {
return; return;
} }
$dirName = str_replace('./', '', $dirName); $dirname = substr($dirname, strlen(\RX_BASEDIR));
$tmp = explode('/', $dirName); if (strncmp($dirname, 'files/cache/minify/', 19) === 0)
{
$dirname = substr($dirname, 19);
}
$tmp = array_first(explode('/', strtr($dirname, '\\.', '//')));
$cssSortList = array('common' => -100000, 'layouts' => -90000, 'modules' => -80000, 'widgets' => -70000, 'addons' => -60000); $cssSortList = array('common' => -100000, 'layouts' => -90000, 'modules' => -80000, 'widgets' => -70000, 'addons' => -60000);
$file->index = $cssSortList[$tmp[0]]; $file->index = $cssSortList[$tmp[0]];

View file

@ -688,6 +688,8 @@ class TemplateHandler
} }
break; break;
case 'css': case 'css':
case 'less':
case 'scss':
if($doUnload) if($doUnload)
{ {
$result = "Context::unloadFile('{$attr['target']}','{$attr['targetie']}','{$attr['media']}');"; $result = "Context::unloadFile('{$attr['target']}','{$attr['targetie']}','{$attr['media']}');";