mirror of
https://github.com/mrclay/minify.git
synced 2025-08-09 15:46:34 +02:00
Merge pull request #124 from glensc/WIP_lessphp
WIP lesscss integration. #112
This commit is contained in:
@@ -16,11 +16,21 @@
|
|||||||
"issues": "http://code.google.com/p/minify/issues/list",
|
"issues": "http://code.google.com/p/minify/issues/list",
|
||||||
"wiki": "http://code.google.com/p/minify/w/list"
|
"wiki": "http://code.google.com/p/minify/w/list"
|
||||||
},
|
},
|
||||||
|
"autoload": {
|
||||||
|
"classmap": ["min/lib/"]
|
||||||
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.2.1",
|
"php": ">=5.2.1",
|
||||||
"ext-pcre": "*"
|
"ext-pcre": "*"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"require-dev": {
|
||||||
"classmap": ["min/lib/"]
|
"leafo/lessphp": "~0.4.0",
|
||||||
|
"meenie/javascript-packer": "~1.1",
|
||||||
|
"tubalmartin/cssmin": "~2.4.8"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"leafo/lessphp": "LESS support",
|
||||||
|
"meenie/javascript-packer": "Keep track of the Packer PHP port using Composer",
|
||||||
|
"tubalmartin/cssmin": "Support minify with CSSMin (YUI PHP port)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -94,7 +94,7 @@ if ($env->get('f') || null !== $env->get('g')) {
|
|||||||
if (isset($min_serveOptions['minApp']['noMinPattern'])) {
|
if (isset($min_serveOptions['minApp']['noMinPattern'])) {
|
||||||
$sourceFactoryOptions['noMinPattern'] = $min_serveOptions['minApp']['noMinPattern'];
|
$sourceFactoryOptions['noMinPattern'] = $min_serveOptions['minApp']['noMinPattern'];
|
||||||
}
|
}
|
||||||
$sourceFactory = new Minify_Source_Factory($env, $sourceFactoryOptions);
|
$sourceFactory = new Minify_Source_Factory($env, $sourceFactoryOptions, $cache);
|
||||||
|
|
||||||
$min_serveController = new Minify_Controller_MinApp($env, $sourceFactory);
|
$min_serveController = new Minify_Controller_MinApp($env, $sourceFactory);
|
||||||
}
|
}
|
||||||
|
@@ -93,7 +93,7 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
|
|||||||
// respond to.
|
// respond to.
|
||||||
if (// verify at least one file, files are single comma separated,
|
if (// verify at least one file, files are single comma separated,
|
||||||
// and are all same extension
|
// and are all same extension
|
||||||
! preg_match('/^[^,]+\\.(css|js)(?:,[^,]+\\.\\1)*$/', $get['f'], $m)
|
! preg_match('/^[^,]+\\.(css|less|js)(?:,[^,]+\\.\\1)*$/', $get['f'], $m)
|
||||||
// no "//"
|
// no "//"
|
||||||
|| strpos($get['f'], '//') !== false
|
|| strpos($get['f'], '//') !== false
|
||||||
// no "\"
|
// no "\"
|
||||||
|
107
min/lib/Minify/LessCssSource.php
Normal file
107
min/lib/Minify/LessCssSource.php
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Minify_LessCssSource extends Minify_Source {
|
||||||
|
/**
|
||||||
|
* @var Minify_CacheInterface
|
||||||
|
*/
|
||||||
|
private $cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parsed lessphp cache object
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $parsed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function __construct(array $spec, Minify_CacheInterface $cache) {
|
||||||
|
parent::__construct($spec);
|
||||||
|
|
||||||
|
$this->cache = $cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get last modified of all parsed files
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getLastModified() {
|
||||||
|
$cache = $this->getCache();
|
||||||
|
|
||||||
|
$lastModified = 0;
|
||||||
|
foreach ($cache['files'] as $mtime) {
|
||||||
|
$lastModified = max($lastModified, $mtime);
|
||||||
|
|
||||||
|
}
|
||||||
|
return $lastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get content
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getContent() {
|
||||||
|
$cache = $this->getCache();
|
||||||
|
|
||||||
|
return $cache['compiled'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get lessphp cache object
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getCache() {
|
||||||
|
// cache for single run
|
||||||
|
// so that getLastModified and getContent in single request do not add additional cache roundtrips (i.e memcache)
|
||||||
|
if (isset($this->parsed)) {
|
||||||
|
return $this->parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check from cache first
|
||||||
|
$cache = null;
|
||||||
|
$cacheId = $this->getCacheId();
|
||||||
|
if ($this->cache->isValid($cacheId, 0)) {
|
||||||
|
if ($cache = $this->cache->fetch($cacheId)) {
|
||||||
|
$cache = unserialize($cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$less = $this->getCompiler();
|
||||||
|
$input = $cache ? $cache : $this->filepath;
|
||||||
|
$cache = $less->cachedCompile($input);
|
||||||
|
|
||||||
|
if (!is_array($input) || $cache['updated'] > $input['updated']) {
|
||||||
|
$this->cache->store($cacheId, serialize($cache));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parsed = $cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a unique cache id for for this source.
|
||||||
|
*
|
||||||
|
* @param string $prefix
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getCacheId($prefix = 'minify') {
|
||||||
|
$md5 = md5($this->filepath);
|
||||||
|
return "{$prefix}_less_{$md5}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get instance of less compiler
|
||||||
|
*
|
||||||
|
* @return lessc
|
||||||
|
*/
|
||||||
|
private function getCompiler() {
|
||||||
|
$less = new lessc();
|
||||||
|
// do not spend CPU time letting less doing minify
|
||||||
|
$less->setPreserveComments(true);
|
||||||
|
return $less;
|
||||||
|
}
|
||||||
|
}
|
@@ -72,6 +72,7 @@ class Minify_Source implements Minify_SourceInterface {
|
|||||||
switch ($ext) {
|
switch ($ext) {
|
||||||
case 'js' : $this->contentType = Minify::TYPE_JS;
|
case 'js' : $this->contentType = Minify::TYPE_JS;
|
||||||
break;
|
break;
|
||||||
|
case 'less' : // fallthrough
|
||||||
case 'css' : $this->contentType = Minify::TYPE_CSS;
|
case 'css' : $this->contentType = Minify::TYPE_CSS;
|
||||||
break;
|
break;
|
||||||
case 'htm' : // fallthrough
|
case 'htm' : // fallthrough
|
||||||
|
@@ -41,7 +41,7 @@ class Minify_Source_Factory {
|
|||||||
* moves back, this should not be needed.
|
* moves back, this should not be needed.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function __construct(Minify_Env $env, array $options = array())
|
public function __construct(Minify_Env $env, array $options = array(), Minify_CacheInterface $cache = null)
|
||||||
{
|
{
|
||||||
$this->env = $env;
|
$this->env = $env;
|
||||||
$this->options = array_merge(array(
|
$this->options = array_merge(array(
|
||||||
@@ -63,6 +63,10 @@ class Minify_Source_Factory {
|
|||||||
throw new InvalidArgumentException("fileChecker option is not callable");
|
throw new InvalidArgumentException("fileChecker option is not callable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->setHandler('~\.less$~i', function ($spec) use ($cache) {
|
||||||
|
return new Minify_LessCssSource($spec, $cache);
|
||||||
|
});
|
||||||
|
|
||||||
$this->setHandler('~\.(js|css)$~i', function ($spec) {
|
$this->setHandler('~\.(js|css)$~i', function ($spec) {
|
||||||
return new Minify_Source($spec);
|
return new Minify_Source($spec);
|
||||||
});
|
});
|
||||||
@@ -142,7 +146,7 @@ class Minify_Source_Factory {
|
|||||||
$basename = basename($spec['filepath']);
|
$basename = basename($spec['filepath']);
|
||||||
|
|
||||||
if ($this->options['noMinPattern'] && preg_match($this->options['noMinPattern'], $basename)) {
|
if ($this->options['noMinPattern'] && preg_match($this->options['noMinPattern'], $basename)) {
|
||||||
if (preg_match('~\.css$~i', $basename)) {
|
if (preg_match('~\.(css|less)$~i', $basename)) {
|
||||||
$spec['minifyOptions']['compress'] = false;
|
$spec['minifyOptions']['compress'] = false;
|
||||||
// we still want URI rewriting to work for CSS
|
// we still want URI rewriting to work for CSS
|
||||||
} else {
|
} else {
|
||||||
|
12
min/quick-test.less
Normal file
12
min/quick-test.less
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/*! This file exists only for testing a Minify installation. It's content is not used.
|
||||||
|
*
|
||||||
|
* http://example.org/min/f=min/quick-test.less
|
||||||
|
*/
|
||||||
|
|
||||||
|
// LESS import statement shares syntax with the CSS import statement.
|
||||||
|
// If the file being imported ends in a .less extension, or no extension, then it is treated as a LESS
|
||||||
|
// import. Otherwise it is left alone and outputted directly.
|
||||||
|
// http://leafo.net/lessphp/docs/#import
|
||||||
|
@import "quick-test.css";
|
||||||
|
|
||||||
|
@import "quick-testinc.less";
|
20
min/quick-testinc.less
Normal file
20
min/quick-testinc.less
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
@base: 24px;
|
||||||
|
@border-color: #B2B;
|
||||||
|
|
||||||
|
.underline { border-bottom: 1px solid green }
|
||||||
|
|
||||||
|
#header {
|
||||||
|
color: black;
|
||||||
|
border: 1px solid @border-color + #222222;
|
||||||
|
|
||||||
|
.navigation {
|
||||||
|
font-size: @base / 2;
|
||||||
|
a {
|
||||||
|
.underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
width: 300px;
|
||||||
|
:hover { text-decoration: none }
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user