From 883ef7080abbd28c6dcec0725bfe19dc811105ed Mon Sep 17 00:00:00 2001 From: Maxim Zemskov Date: Fri, 17 Aug 2012 17:36:36 +0600 Subject: [PATCH 01/10] Added ability to rewrite url relative to imported files (enabled by default). --- lessc.inc.php | 61 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/lessc.inc.php b/lessc.inc.php index 47d24323..bbd93f22 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -52,6 +52,8 @@ class lessc { public $importDisabled = false; public $importDir = ''; + + public $allowUrlRewrite = true; // rewrite urls relative to imported files protected $numberPrecision = null; @@ -112,7 +114,7 @@ protected function tryImport($importPath, $parentBlock, $out) { $this->addParsedFile($realPath); $parser = $this->makeParser($realPath); $root = $parser->parse(file_get_contents($realPath)); - + // copy mixins into scope, set their parents // bring blocks from import into current block // TODO: need to mark the source parser these came from this file @@ -607,8 +609,13 @@ protected function compileProp($prop, $block, $out) { if ($name[0] == $this->vPrefix) { $this->set($name, $value); } else { - $out->lines[] = $this->formatter->property($name, - $this->compileValue($this->reduce($value))); + $_value = $this->compileValue($this->reduce($value)); + if ($this->allowUrlRewrite) { + preg_match_all('#url\(("|\')?([^)"\']+)("|\')?\)#ims', $_value, $matches); + if (count($matches[2]) > 0) + $_value = $this->rewriteUrls($_value, $matches[2][0]); + } + $out->lines[] = $this->formatter->property($name, $_value); } break; case 'block': @@ -706,6 +713,26 @@ protected function compileProp($prop, $block, $out) { } } + protected function rewriteUrls($value, $url) { + $baseImportDir = realpath(end($this->importDir)); + $lastImportDir = realpath(reset($this->importDir)); + + $urlPath = realpath($lastImportDir.DIRECTORY_SEPARATOR.$url); + if ($urlPath === false) + return $value; + + $baseArray = explode(DIRECTORY_SEPARATOR, $baseImportDir); + $urlArray = explode(DIRECTORY_SEPARATOR, $urlPath); + + $baseArrayDiff = array_diff($baseArray, $urlArray); + $urlArrayDiff = array_diff($urlArray, $baseArray); + + $newUrl = implode('/', $urlArrayDiff); + for ($i=0,$l=count($baseArrayDiff); $i<$l; $i++) + $newUrl = '../'.$newUrl; + + return str_replace($url, $newUrl, $value); + } /** * Compiles a primitive value into a CSS property value. @@ -1169,7 +1196,7 @@ protected function funcToColor($func) { return false; } - protected function reduce($value, $forExpression = false) { + protected function reduce($value) { switch ($value[0]) { case "variable": $key = $value[1]; @@ -1190,7 +1217,7 @@ protected function reduce($value, $forExpression = false) { return $out; case "list": foreach ($value[2] as &$item) { - $item = $this->reduce($item, $forExpression); + $item = $this->reduce($item); } return $value; case "expression": @@ -1220,7 +1247,7 @@ protected function reduce($value, $forExpression = false) { if ($args[0] == 'list') $args = self::compressList($args[2], $args[1]); - $ret = call_user_func($f, $this->reduce($args, true), $this); + $ret = call_user_func($f, $this->reduce($args), $this); if (is_null($ret)) { return array("string", "", array( @@ -1252,21 +1279,9 @@ protected function reduce($value, $forExpression = false) { } } return array("string", "", array($op, $exp)); + default: + return $value; } - - if ($forExpression) { - switch ($value[0]) { - case "keyword": - if ($color = $this->coerceColor($value)) { - return $color; - } - break; - case "raw_color": - return $this->coerceColor($value); - } - } - - return $value; } @@ -1326,8 +1341,8 @@ protected function toBool($a) { protected function evaluate($exp) { list(, $op, $left, $right, $whiteBefore, $whiteAfter) = $exp; - $left = $this->reduce($left, true); - $right = $this->reduce($right, true); + $left = $this->reduce($left); + $right = $this->reduce($right); if ($leftColor = $this->coerceColor($left)) { $left = $leftColor; @@ -1754,7 +1769,7 @@ public function unsetVariable($name) { } public function setImportDir($dirs) { - $this->importDir = (array)$dirs; + $this->importDir = (array)$dir; } public function addImportDir($dir) { From 7b55905f92ac565bd51b464d96659cddc9593a8e Mon Sep 17 00:00:00 2001 From: Maxim Zemskov Date: Fri, 17 Aug 2012 22:19:36 +0600 Subject: [PATCH 02/10] Added ability to change relative paths according to path to root .less file. (#119) --- lessc.inc.php | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/lessc.inc.php b/lessc.inc.php index 47d24323..dadc13ed 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -53,6 +53,8 @@ class lessc { public $importDisabled = false; public $importDir = ''; + public $allowUrlRewrite = true; // rewrite urls relative to imported files + protected $numberPrecision = null; // set to the parser that generated the current line when compiling @@ -607,8 +609,11 @@ protected function compileProp($prop, $block, $out) { if ($name[0] == $this->vPrefix) { $this->set($name, $value); } else { - $out->lines[] = $this->formatter->property($name, - $this->compileValue($this->reduce($value))); + $compiledValue = $this->compileValue($this->reduce($value)); + if ($this->allowUrlRewrite) { + $compiledValue = $this->rewriteUrls($compiledValue); + } + $out->lines[] = $this->formatter->property($name, $compiledValue); } break; case 'block': @@ -706,6 +711,34 @@ protected function compileProp($prop, $block, $out) { } } + /** + * Change relative paths according to path to root .less file. + */ + protected function rewriteUrls($value) { + if (preg_match('#url\(("|\')?([^)"\']+)("|\')?\)#ims', $value, $matches)) + $url = $matches[2]; + else + return $value; + + $baseImportDir = realpath(end($this->importDir)); + $lastImportDir = realpath(reset($this->importDir)); + + $urlPath = realpath($lastImportDir.DIRECTORY_SEPARATOR.$url); + if ($urlPath === false) + return $value; + + $baseArray = explode(DIRECTORY_SEPARATOR, $baseImportDir); + $urlArray = explode(DIRECTORY_SEPARATOR, $urlPath); + + $baseArrayDiff = array_diff($baseArray, $urlArray); + $urlArrayDiff = array_diff($urlArray, $baseArray); + + $newUrl = implode('/', $urlArrayDiff); + for ($i=0,$l=count($baseArrayDiff); $i<$l; $i++) + $newUrl = '../'.$newUrl; + + return str_replace($url, $newUrl, $value); + } /** * Compiles a primitive value into a CSS property value. From bb34b9ef2abee0be062867fb0783fcc3fe51896a Mon Sep 17 00:00:00 2001 From: Maxim Zemskov Date: Sat, 18 Aug 2012 00:15:05 +0600 Subject: [PATCH 03/10] Use parsed urls in compileValue() instead of re-parsing. (#119) --- lessc.inc.php | 74 +++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/lessc.inc.php b/lessc.inc.php index dadc13ed..41caa659 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -609,11 +609,8 @@ protected function compileProp($prop, $block, $out) { if ($name[0] == $this->vPrefix) { $this->set($name, $value); } else { - $compiledValue = $this->compileValue($this->reduce($value)); - if ($this->allowUrlRewrite) { - $compiledValue = $this->rewriteUrls($compiledValue); - } - $out->lines[] = $this->formatter->property($name, $compiledValue); + $out->lines[] = $this->formatter->property($name, + $this->compileValue($this->reduce($value))); } break; case 'block': @@ -711,34 +708,6 @@ protected function compileProp($prop, $block, $out) { } } - /** - * Change relative paths according to path to root .less file. - */ - protected function rewriteUrls($value) { - if (preg_match('#url\(("|\')?([^)"\']+)("|\')?\)#ims', $value, $matches)) - $url = $matches[2]; - else - return $value; - - $baseImportDir = realpath(end($this->importDir)); - $lastImportDir = realpath(reset($this->importDir)); - - $urlPath = realpath($lastImportDir.DIRECTORY_SEPARATOR.$url); - if ($urlPath === false) - return $value; - - $baseArray = explode(DIRECTORY_SEPARATOR, $baseImportDir); - $urlArray = explode(DIRECTORY_SEPARATOR, $urlPath); - - $baseArrayDiff = array_diff($baseArray, $urlArray); - $urlArrayDiff = array_diff($urlArray, $baseArray); - - $newUrl = implode('/', $urlArrayDiff); - for ($i=0,$l=count($baseArrayDiff); $i<$l; $i++) - $newUrl = '../'.$newUrl; - - return str_replace($url, $newUrl, $value); - } /** * Compiles a primitive value into a CSS property value. @@ -751,12 +720,16 @@ protected function rewriteUrls($value) { * The input is expected to be reduced. This function will not work on * things like expressions and variables. */ - protected function compileValue($value) { + protected function compileValue($value, $inUrl = false) { switch ($value[0]) { case 'list': // [1] - delimiter // [2] - array of values - return implode($value[1], array_map(array($this, 'compileValue'), $value[2])); + $values = array(); + foreach ($value[2] as $item) { + $values[] = $this->compileValue($item, $inUrl); + } + return implode($value[1], $values); case 'raw_color'; case 'keyword': // [1] - the keyword @@ -774,7 +747,10 @@ protected function compileValue($value) { list(, $delim, $content) = $value; foreach ($content as &$part) { if (is_array($part)) { - $part = $this->compileValue($part); + $part = $this->compileValue($part, $inUrl); + } + if ($inUrl && $this->allowUrlRewrite) { + $part = $this->rewriteUrls($part); } } return $delim . implode($content) . $delim; @@ -805,12 +781,36 @@ protected function compileValue($value) { case 'function': list(, $name, $args) = $value; - return $name.'('.$this->compileValue($args).')'; + return $name.'('.$this->compileValue($args, $name === 'url').')'; default: // assumed to be unit $this->throwError("unknown value type: $value[0]"); } } + /** + * Change relative paths according to path to root .less file. + */ + protected function rewriteUrls($url) { + $baseImportDir = realpath(end($this->importDir)); + $lastImportDir = realpath(reset($this->importDir)); + + $urlPath = realpath($lastImportDir.DIRECTORY_SEPARATOR.$url); + if ($urlPath === false) + return $url; + + $baseArray = explode(DIRECTORY_SEPARATOR, $baseImportDir); + $urlArray = explode(DIRECTORY_SEPARATOR, $urlPath); + + $baseArrayDiff = array_diff($baseArray, $urlArray); + $urlArrayDiff = array_diff($urlArray, $baseArray); + + $newUrl = implode('/', $urlArrayDiff); + for ($i=0,$l=count($baseArrayDiff); $i<$l; $i++) + $newUrl = '../'.$newUrl; + + return $newUrl; + } + protected function lib_isnumber($value) { return $this->toBool($value[0] == "number"); } From 020d220f1612f2e3126a4ca401472bc16b5269b3 Mon Sep 17 00:00:00 2001 From: Maxim Zemskov Date: Sat, 18 Aug 2012 17:23:56 +0600 Subject: [PATCH 04/10] Calculate the first difference of the paths instead of using array_diff in rewriteUrls(). (#119) --- lessc.inc.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lessc.inc.php b/lessc.inc.php index 41caa659..b699bccf 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -790,7 +790,7 @@ protected function compileValue($value, $inUrl = false) { /** * Change relative paths according to path to root .less file. */ - protected function rewriteUrls($url) { + protected function rewriteUrls($url) { $baseImportDir = realpath(end($this->importDir)); $lastImportDir = realpath(reset($this->importDir)); @@ -801,12 +801,14 @@ protected function rewriteUrls($url) { $baseArray = explode(DIRECTORY_SEPARATOR, $baseImportDir); $urlArray = explode(DIRECTORY_SEPARATOR, $urlPath); - $baseArrayDiff = array_diff($baseArray, $urlArray); - $urlArrayDiff = array_diff($urlArray, $baseArray); + $i = 0; + foreach ($baseArray as $i => $segment) { + if ($baseArray[$i] !== $urlArray[$i]) + break; + } - $newUrl = implode('/', $urlArrayDiff); - for ($i=0,$l=count($baseArrayDiff); $i<$l; $i++) - $newUrl = '../'.$newUrl; + $newUrl = str_repeat('../', count($baseArray) - $i); + $newUrl .= implode('/', array_slice($urlArray, $i)); return $newUrl; } From d3161a06a1abcf20efb143ee7139cbf0b66d4cf3 Mon Sep 17 00:00:00 2001 From: Maxim Zemskov Date: Sat, 18 Aug 2012 18:24:30 +0600 Subject: [PATCH 05/10] Fixed bugs in rewriteUrls(). (#119) --- lessc.inc.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lessc.inc.php b/lessc.inc.php index b699bccf..343af55e 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -747,13 +747,14 @@ protected function compileValue($value, $inUrl = false) { list(, $delim, $content) = $value; foreach ($content as &$part) { if (is_array($part)) { - $part = $this->compileValue($part, $inUrl); - } - if ($inUrl && $this->allowUrlRewrite) { - $part = $this->rewriteUrls($part); + $part = $this->compileValue($part, false); } } - return $delim . implode($content) . $delim; + $content = implode($content); + if ($inUrl && $this->allowUrlRewrite) { + $content = $this->rewriteUrls($content); + } + return $delim . $content . $delim; case 'color': // [1] - red component (either number or a %) // [2] - green component @@ -794,6 +795,9 @@ protected function rewriteUrls($url) { $baseImportDir = realpath(end($this->importDir)); $lastImportDir = realpath(reset($this->importDir)); + if ($baseImportDir === $lastImportDir) + return $url; + $urlPath = realpath($lastImportDir.DIRECTORY_SEPARATOR.$url); if ($urlPath === false) return $url; @@ -803,7 +807,7 @@ protected function rewriteUrls($url) { $i = 0; foreach ($baseArray as $i => $segment) { - if ($baseArray[$i] !== $urlArray[$i]) + if (!isset($baseArray[$i], $urlArray[$i]) || $baseArray[$i] !== $urlArray[$i]) break; } From c360c6f96d1b37b7f34c14a39219b6865373f128 Mon Sep 17 00:00:00 2001 From: Maxim Zemskov Date: Wed, 7 Nov 2012 23:51:10 +0600 Subject: [PATCH 06/10] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index cb4bff1a..775d73f3 100644 --- a/README.md +++ b/README.md @@ -94,3 +94,9 @@ output run this: For more help, run `plessc --help` +### This fork ([nodge/lessphp][5]) + +The only change in this fork is the ability to change relative paths according to path to root .less file. (Fixes [#119][6]). + + [5]: https://github.com/Nodge/lessphp/ + [6]: https://github.com/leafo/lessphp/issues/119 \ No newline at end of file From 6d99f34da76846d08170ac257a8cff16b612f56c Mon Sep 17 00:00:00 2001 From: neilime Date: Thu, 24 Jan 2013 18:41:06 +0100 Subject: [PATCH 07/10] Improving the ability to change relative paths according to path to root : allows url with params (file.css?param=sample) --- lessc.inc.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lessc.inc.php b/lessc.inc.php index 15467c5c..964ff97d 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -52,7 +52,7 @@ class lessc { public $importDisabled = false; public $importDir = ''; - + public $allowUrlRewrite = true; // rewrite urls relative to imported files protected $numberPrecision = null; @@ -803,26 +803,30 @@ protected function rewriteUrls($url) { if ($baseImportDir === $lastImportDir) return $url; - + + $arguments = null; + if(strpos($url,'?') !== false) + list($url, $arguments) = explode('?', $url); + $urlPath = realpath($lastImportDir.DIRECTORY_SEPARATOR.$url); if ($urlPath === false) - return $url; + return $arguments ? $url.'?'.$arguments : $url; $baseArray = explode(DIRECTORY_SEPARATOR, $baseImportDir); $urlArray = explode(DIRECTORY_SEPARATOR, $urlPath); - + $i = 0; foreach ($baseArray as $i => $segment) { if (!isset($baseArray[$i], $urlArray[$i]) || $baseArray[$i] !== $urlArray[$i]) break; } - + $newUrl = str_repeat('../', count($baseArray) - $i); $newUrl .= implode('/', array_slice($urlArray, $i)); - - return $newUrl; + + return $arguments ? $newUrl.'?'.$arguments : $newUrl; } - + protected function lib_isnumber($value) { return $this->toBool($value[0] == "number"); } From ad26c2c6b8424b205f727c48685f13c41b182d50 Mon Sep 17 00:00:00 2001 From: Maxim Zemskov Date: Sun, 27 Jan 2013 14:36:42 +0600 Subject: [PATCH 08/10] Improving the ability to change relative paths according to path to root: Allow to manually set base url path (useful for generating css on the fly) --- lessc.inc.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lessc.inc.php b/lessc.inc.php index 15467c5c..1703f629 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -54,6 +54,7 @@ class lessc { public $importDir = ''; public $allowUrlRewrite = true; // rewrite urls relative to imported files + public $baseUrlPath = null; protected $numberPrecision = null; @@ -798,7 +799,7 @@ protected function compileValue($value, $inUrl = false) { * Change relative paths according to path to root .less file. */ protected function rewriteUrls($url) { - $baseImportDir = realpath(end($this->importDir)); + $baseImportDir = realpath(isset($this->baseUrlPath) ? $this->baseUrlPath : end($this->importDir)); $lastImportDir = realpath(reset($this->importDir)); if ($baseImportDir === $lastImportDir) @@ -810,16 +811,18 @@ protected function rewriteUrls($url) { $baseArray = explode(DIRECTORY_SEPARATOR, $baseImportDir); $urlArray = explode(DIRECTORY_SEPARATOR, $urlPath); - + $i = 0; foreach ($baseArray as $i => $segment) { if (!isset($baseArray[$i], $urlArray[$i]) || $baseArray[$i] !== $urlArray[$i]) break; + else + $i++; // if the above condition is not satisfied, `i` must be equal to count($baseArray) } - + $newUrl = str_repeat('../', count($baseArray) - $i); $newUrl .= implode('/', array_slice($urlArray, $i)); - + return $newUrl; } From df7c34c23fcd8f6c4c8c834b7d7f20bccfc40627 Mon Sep 17 00:00:00 2001 From: neilime Date: Fri, 22 Feb 2013 15:14:51 +0100 Subject: [PATCH 09/10] Set allowUrlRewrite default to false to be consistent with the behavior of latest less.js Add setter to define allowUrlRewrite --- lessc.inc.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lessc.inc.php b/lessc.inc.php index 04414328..9b693601 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -53,7 +53,7 @@ class lessc { public $importDisabled = false; public $importDir = ''; - public $allowUrlRewrite = true; // rewrite urls relative to imported files + public $allowUrlRewrite = false; // rewrite urls relative to imported files public $baseUrlPath = null; protected $numberPrecision = null; @@ -1814,6 +1814,10 @@ public function addImportDir($dir) { $this->importDir[] = $dir; } + public function setAllowUrlRewrite($allowUrlRewrite){ + $this->allowUrlRewrite = (bool)$allowUrlRewrite; + } + public function allParsedFiles() { return $this->allParsedFiles; } From c191e862cc2513948b3976a36e0306b5e4bcce5c Mon Sep 17 00:00:00 2001 From: Nodge Date: Thu, 21 Nov 2013 19:42:14 +0600 Subject: [PATCH 10/10] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0f06ba09..4073c622 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "leafo/lessphp", + "name": "nodge/lessphp", "type": "library", "description": "lessphp is a compiler for LESS written in PHP.", "homepage": "http://leafo.net/lessphp/",