vendor: Update lessphp to version 0.5.0

refs #3785
This commit is contained in:
Johannes Meyer 2019-06-27 09:21:13 +02:00
parent cdaef76faf
commit 3f7b317ced
3 changed files with 159 additions and 61 deletions

View File

@ -1,4 +1,4 @@
For ease of distribution, lessphp 0.2.0 is under a dual license.
For ease of distribution, lessphp 0.4.0 is under a dual license.
You are free to pick which one suits your needs.
@ -9,8 +9,8 @@ MIT LICENSE
Copyright (c) 2010 Leaf Corcoran, http://leafo.net/lessphp
Copyright (c) 2013 Leaf Corcoran, http://leafo.net/lessphp
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
@ -18,10 +18,10 @@ 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

View File

@ -1,2 +1,7 @@
http://leafo.net/lessphp/src/lessphp-0.4.0.tar.gz
tar xfz lessphp-0.4.0.tar.gz lessphp/lessc.inc.php lessphp/LICENSE
#!/bin/bash
set -eux
VERSION=0.5.0
curl -LsS https://github.com/leafo/lessphp/archive/v"$VERSION".tar.gz -o /tmp/lessphp.tar.gz
tar xfz /tmp/lessphp.tar.gz --strip-components 1 lessphp-$VERSION/lessc.inc.php lessphp-$VERSION/LICENSE
rm /tmp/lessphp.tar.gz

View File

@ -1,18 +1,18 @@
<?php
/**
* lessphp v0.4.0
* lessphp v0.5.0
* http://leafo.net/lessphp
*
* LESS css compiler, adapted from http://lesscss.org
* LESS CSS compiler, adapted from http://lesscss.org
*
* Copyright 2012, Leaf Corcoran <leafot@gmail.com>
* Copyright 2013, Leaf Corcoran <leafot@gmail.com>
* Licensed under MIT or GPLv3, see LICENSE
*/
/**
* The less compiler and parser.
* The LESS compiler and parser.
*
* Converting LESS to CSS is a three stage process. The incoming file is parsed
* by `lessc_parser` into a syntax tree, then it is compiled into another tree
@ -27,7 +27,7 @@
*
* In summary:
*
* The `lessc` class creates an intstance of the parser, feeds it LESS code,
* The `lessc` class creates an instance of the parser, feeds it LESS code,
* then transforms the resulting tree to a CSS tree. This class also holds the
* evaluation context, such as all available mixins and variables at any given
* time.
@ -38,9 +38,10 @@
* handling things like indentation.
*/
class lessc {
static public $VERSION = "v0.4.0";
static protected $TRUE = array("keyword", "true");
static protected $FALSE = array("keyword", "false");
static public $VERSION = "v0.5.0";
static public $TRUE = array("keyword", "true");
static public $FALSE = array("keyword", "false");
protected $libFunctions = array();
protected $registeredVars = array();
@ -62,8 +63,6 @@ class lessc {
protected $sourceParser = null;
protected $sourceLoc = null;
static public $defaultValue = array("keyword", "");
static protected $nextImportId = 0; // uniquely identify imports
// attempts to find the path of an import url, returns null for css files
@ -283,39 +282,73 @@ class lessc {
foreach ($this->sortProps($block->props) as $prop) {
$this->compileProp($prop, $block, $out);
}
$out->lines = $this->deduplicate($out->lines);
}
$out->lines = array_values(array_unique($out->lines));
/**
* Deduplicate lines in a block. Comments are not deduplicated. If a
* duplicate rule is detected, the comments immediately preceding each
* occurence are consolidated.
*/
protected function deduplicate($lines) {
$unique = array();
$comments = array();
foreach($lines as $line) {
if (strpos($line, '/*') === 0) {
$comments[] = $line;
continue;
}
if (!in_array($line, $unique)) {
$unique[] = $line;
}
array_splice($unique, array_search($line, $unique), 0, $comments);
$comments = array();
}
return array_merge($unique, $comments);
}
protected function sortProps($props, $split = false) {
$vars = array();
$imports = array();
$other = array();
$stack = array();
foreach ($props as $prop) {
switch ($prop[0]) {
case "comment":
$stack[] = $prop;
break;
case "assign":
$stack[] = $prop;
if (isset($prop[1][0]) && $prop[1][0] == $this->vPrefix) {
$vars[] = $prop;
$vars = array_merge($vars, $stack);
} else {
$other[] = $prop;
$other = array_merge($other, $stack);
}
$stack = array();
break;
case "import":
$id = self::$nextImportId++;
$prop[] = $id;
$imports[] = $prop;
$stack[] = $prop;
$imports = array_merge($imports, $stack);
$other[] = array("import_mixin", $id);
$stack = array();
break;
default:
$other[] = $prop;
$stack[] = $prop;
$other = array_merge($other, $stack);
$stack = array();
break;
}
}
$other = array_merge($other, $stack);
if ($split) {
return array(array_merge($vars, $imports), $other);
return array(array_merge($imports, $vars), $other);
} else {
return array_merge($vars, $imports, $other);
return array_merge($imports, $vars, $other);
}
}
@ -684,8 +717,7 @@ class lessc {
$mixins = $this->findBlocks($block, $path, $orderedArgs, $keywordArgs);
if ($mixins === null) {
// fwrite(STDERR,"failed to find block: ".implode(" > ", $path)."\n");
break; // throw error here??
$this->throwError("{$prop[1][0]} is undefined");
}
foreach ($mixins as $mixin) {
@ -787,7 +819,7 @@ class lessc {
* The input is expected to be reduced. This function will not work on
* things like expressions and variables.
*/
protected function compileValue($value) {
public function compileValue($value) {
switch ($value[0]) {
case 'list':
// [1] - delimiter
@ -951,6 +983,39 @@ class lessc {
return $this->lib_rgbahex($color);
}
/**
* Given an url, decide whether to output a regular link or the base64-encoded contents of the file
*
* @param array $value either an argument list (two strings) or a single string
* @return string formatted url(), either as a link or base64-encoded
*/
protected function lib_data_uri($value) {
$mime = ($value[0] === 'list') ? $value[2][0][2] : null;
$url = ($value[0] === 'list') ? $value[2][1][2][0] : $value[2][0];
$fullpath = $this->findImport($url);
if($fullpath && ($fsize = filesize($fullpath)) !== false) {
// IE8 can't handle data uris larger than 32KB
if($fsize/1024 < 32) {
if(is_null($mime)) {
if(class_exists('finfo')) { // php 5.3+
$finfo = new finfo(FILEINFO_MIME);
$mime = explode('; ', $finfo->file($fullpath));
$mime = $mime[0];
} elseif(function_exists('mime_content_type')) { // PHP 5.2
$mime = mime_content_type($fullpath);
}
}
if(!is_null($mime)) // fallback if the mime type is still unknown
$url = sprintf('data:%s;base64,%s', $mime, base64_encode(file_get_contents($fullpath)));
}
}
return 'url("'.$url.'")';
}
// utility func to unquote a string
protected function lib_e($arg) {
switch ($arg[0]) {
@ -959,7 +1024,7 @@ class lessc {
if (isset($items[0])) {
return $this->lib_e($items[0]);
}
return self::$defaultValue;
$this->throwError("unrecognised input");
case "string":
$arg[1] = "";
return $arg;
@ -1009,8 +1074,14 @@ class lessc {
}
protected function lib_round($arg) {
$value = $this->assertNumber($arg);
return array("number", round($value), $arg[2]);
if($arg[0] != "list") {
$value = $this->assertNumber($arg);
return array("number", round($value), $arg[2]);
} else {
$value = $this->assertNumber($arg[2][0]);
$precision = $this->assertNumber($arg[2][1]);
return array("number", round($value, $precision), $arg[2][0][2]);
}
}
protected function lib_unit($arg) {
@ -1027,7 +1098,7 @@ class lessc {
* Helper function to get arguments for color manipulation functions.
* takes a list that contains a color like thing and a percentage
*/
protected function colorArgs($args) {
public function colorArgs($args) {
if ($args[0] != 'list' || count($args[2]) < 2) {
return array(array('color', 0, 0, 0), 0);
}
@ -1168,36 +1239,56 @@ class lessc {
}
protected function lib_contrast($args) {
if ($args[0] != 'list' || count($args[2]) < 3) {
return array(array('color', 0, 0, 0), 0);
}
$darkColor = array('color', 0, 0, 0);
$lightColor = array('color', 255, 255, 255);
$threshold = 0.43;
list($inputColor, $darkColor, $lightColor) = $args[2];
if ( $args[0] == 'list' ) {
$inputColor = ( isset($args[2][0]) ) ? $this->assertColor($args[2][0]) : $lightColor;
$darkColor = ( isset($args[2][1]) ) ? $this->assertColor($args[2][1]) : $darkColor;
$lightColor = ( isset($args[2][2]) ) ? $this->assertColor($args[2][2]) : $lightColor;
$threshold = ( isset($args[2][3]) ) ? $this->assertNumber($args[2][3]) : $threshold;
}
else {
$inputColor = $this->assertColor($args);
}
$inputColor = $this->assertColor($inputColor);
$darkColor = $this->assertColor($darkColor);
$lightColor = $this->assertColor($lightColor);
$hsl = $this->toHSL($inputColor);
$inputColor = $this->coerceColor($inputColor);
$darkColor = $this->coerceColor($darkColor);
$lightColor = $this->coerceColor($lightColor);
if ($hsl[3] > 50) {
return $darkColor;
}
//Figure out which is actually light and dark!
if ( $this->lib_luma($darkColor) > $this->lib_luma($lightColor) ) {
$t = $lightColor;
$lightColor = $darkColor;
$darkColor = $t;
}
return $lightColor;
$inputColor_alpha = $this->lib_alpha($inputColor);
if ( ( $this->lib_luma($inputColor) * $inputColor_alpha) < $threshold) {
return $lightColor;
}
return $darkColor;
}
protected function assertColor($value, $error = "expected color value") {
protected function lib_luma($color) {
$color = $this->coerceColor($color);
return (0.2126 * $color[0] / 255) + (0.7152 * $color[1] / 255) + (0.0722 * $color[2] / 255);
}
public function assertColor($value, $error = "expected color value") {
$color = $this->coerceColor($value);
if (is_null($color)) $this->throwError($error);
return $color;
}
protected function assertNumber($value, $error = "expecting number") {
public function assertNumber($value, $error = "expecting number") {
if ($value[0] == "number") return $value[1];
$this->throwError($error);
}
protected function assertArgs($value, $expectedArgs, $name="") {
public function assertArgs($value, $expectedArgs, $name="") {
if ($expectedArgs == 1) {
return $value;
} else {
@ -1381,7 +1472,7 @@ class lessc {
}
$seen[$key] = true;
$out = $this->reduce($this->get($key, self::$defaultValue));
$out = $this->reduce($this->get($key));
$seen[$key] = false;
return $out;
case "list":
@ -1409,8 +1500,9 @@ class lessc {
list(, $name, $args) = $value;
if ($name == "%") $name = "_sprintf";
$f = isset($this->libFunctions[$name]) ?
$this->libFunctions[$name] : array($this, 'lib_'.$name);
$this->libFunctions[$name] : array($this, 'lib_'.str_replace('-', '_', $name));
if (is_callable($f)) {
if ($args[0] == 'list')
@ -1517,7 +1609,7 @@ class lessc {
return $value;
}
protected function toBool($a) {
public function toBool($a) {
if ($a) return self::$TRUE;
else return self::$FALSE;
}
@ -1740,7 +1832,7 @@ class lessc {
// get the highest occurrence entry for a name
protected function get($name, $default=null) {
protected function get($name) {
$current = $this->env;
$isArguments = $name == $this->vPrefix . 'arguments';
@ -1757,7 +1849,7 @@ class lessc {
}
}
return $default;
$this->throwError("variable $name is undefined");
}
// inject array of unparsed strings into environment as variables
@ -1993,14 +2085,14 @@ class lessc {
return $this->allParsedFiles;
}
protected function addParsedFile($file) {
public function addParsedFile($file) {
$this->allParsedFiles[realpath($file)] = filemtime($file);
}
/**
* Uses the current value of $this->count to show line and line number
*/
protected function throwError($msg = null) {
public function throwError($msg = null) {
if ($this->sourceLoc >= 0) {
$this->sourceParser->throwError($msg, $this->sourceLoc);
}
@ -2266,14 +2358,13 @@ class lessc_parser {
$this->whitespace();
// parse the entire file
$lastCount = $this->count;
while (false !== $this->parseChunk());
if ($this->count != strlen($this->buffer))
$this->throwError();
// TODO report where the block was opened
if (!is_null($this->env->parent))
if ( !property_exists($this->env, 'parent') || !is_null($this->env->parent) )
throw new exception('parse error: unclosed block');
return $this->env;
@ -2319,6 +2410,10 @@ class lessc_parser {
if (empty($this->buffer)) return false;
$s = $this->seek();
if ($this->whitespace()) {
return true;
}
// setting a property
if ($this->keyword($key) && $this->assign() &&
$this->propertyValue($value, $key) && $this->end())
@ -2399,7 +2494,7 @@ class lessc_parser {
}
// opening a simple block
if ($this->tags($tags) && $this->literal('{')) {
if ($this->tags($tags) && $this->literal('{', false)) {
$tags = $this->fixTags($tags);
$this->pushBlock($tags);
return true;
@ -2674,7 +2769,6 @@ class lessc_parser {
// an import statement
protected function import(&$out) {
$s = $this->seek();
if (!$this->literal('@import')) return false;
// @import "something.css" media;
@ -3034,7 +3128,6 @@ class lessc_parser {
// list of tags of specifying mixin path
// optionally separated by > (lazy, accepts extra >)
protected function mixinTags(&$tags) {
$s = $this->seek();
$tags = array();
while ($this->tag($tt, true)) {
$tags[] = $tt;
@ -3262,7 +3355,7 @@ class lessc_parser {
// consume an end of statement delimiter
protected function end() {
if ($this->literal(';')) {
if ($this->literal(';', false)) {
return true;
} elseif ($this->count == strlen($this->buffer) || $this->buffer[$this->count] == '}') {
// if there is end of file or a closing block next then we don't need a ;
@ -3411,9 +3504,9 @@ class lessc_parser {
if ($this->writeComments) {
$gotWhite = false;
while (preg_match(self::$whitePattern, $this->buffer, $m, null, $this->count)) {
if (isset($m[1]) && empty($this->commentsSeen[$this->count])) {
if (isset($m[1]) && empty($this->seenComments[$this->count])) {
$this->append(array("comment", $m[1]));
$this->commentsSeen[$this->count] = true;
$this->seenComments[$this->count] = true;
}
$this->count += strlen($m[0]);
$gotWhite = true;