MDL-65759 library: Update php-css-parser to 8.3.0
This commit is contained in:
@@ -4,7 +4,7 @@ namespace Sabberworm\CSS\Value;
|
||||
|
||||
class CSSFunction extends ValueList {
|
||||
|
||||
private $sName;
|
||||
protected $sName;
|
||||
|
||||
public function __construct($sName, $aArguments, $sSeparator = ',', $iLineNo = 0) {
|
||||
if($aArguments instanceof RuleValueList) {
|
||||
@@ -37,4 +37,4 @@ class CSSFunction extends ValueList {
|
||||
return "{$this->sName}({$aArguments})";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
use Sabberworm\CSS\Parsing\ParserState;
|
||||
use Sabberworm\CSS\Parsing\SourceException;
|
||||
|
||||
class CSSString extends PrimitiveValue {
|
||||
|
||||
private $sString;
|
||||
@@ -11,6 +14,37 @@ class CSSString extends PrimitiveValue {
|
||||
parent::__construct($iLineNo);
|
||||
}
|
||||
|
||||
public static function parse(ParserState $oParserState) {
|
||||
$sBegin = $oParserState->peek();
|
||||
$sQuote = null;
|
||||
if ($sBegin === "'") {
|
||||
$sQuote = "'";
|
||||
} else if ($sBegin === '"') {
|
||||
$sQuote = '"';
|
||||
}
|
||||
if ($sQuote !== null) {
|
||||
$oParserState->consume($sQuote);
|
||||
}
|
||||
$sResult = "";
|
||||
$sContent = null;
|
||||
if ($sQuote === null) {
|
||||
// Unquoted strings end in whitespace or with braces, brackets, parentheses
|
||||
while (!preg_match('/[\\s{}()<>\\[\\]]/isu', $oParserState->peek())) {
|
||||
$sResult .= $oParserState->parseCharacter(false);
|
||||
}
|
||||
} else {
|
||||
while (!$oParserState->comes($sQuote)) {
|
||||
$sContent = $oParserState->parseCharacter(false);
|
||||
if ($sContent === null) {
|
||||
throw new SourceException("Non-well-formed quoted string {$oParserState->peek(3)}", $oParserState->currentLine());
|
||||
}
|
||||
$sResult .= $sContent;
|
||||
}
|
||||
$oParserState->consume($sQuote);
|
||||
}
|
||||
return new CSSString($sResult, $oParserState->currentLine());
|
||||
}
|
||||
|
||||
public function setString($sString) {
|
||||
$this->sString = $sString;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
use Sabberworm\CSS\Parsing\ParserState;
|
||||
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
|
||||
|
||||
class CalcFunction extends CSSFunction {
|
||||
const T_OPERAND = 1;
|
||||
const T_OPERATOR = 2;
|
||||
|
||||
public static function parse(ParserState $oParserState) {
|
||||
$aOperators = array('+', '-', '*', '/');
|
||||
$sFunction = trim($oParserState->consumeUntil('(', false, true));
|
||||
$oCalcList = new CalcRuleValueList($oParserState->currentLine());
|
||||
$oList = new RuleValueList(',', $oParserState->currentLine());
|
||||
$iNestingLevel = 0;
|
||||
$iLastComponentType = NULL;
|
||||
while(!$oParserState->comes(')') || $iNestingLevel > 0) {
|
||||
$oParserState->consumeWhiteSpace();
|
||||
if ($oParserState->comes('(')) {
|
||||
$iNestingLevel++;
|
||||
$oCalcList->addListComponent($oParserState->consume(1));
|
||||
continue;
|
||||
} else if ($oParserState->comes(')')) {
|
||||
$iNestingLevel--;
|
||||
$oCalcList->addListComponent($oParserState->consume(1));
|
||||
continue;
|
||||
}
|
||||
if ($iLastComponentType != CalcFunction::T_OPERAND) {
|
||||
$oVal = Value::parsePrimitiveValue($oParserState);
|
||||
$oCalcList->addListComponent($oVal);
|
||||
$iLastComponentType = CalcFunction::T_OPERAND;
|
||||
} else {
|
||||
if (in_array($oParserState->peek(), $aOperators)) {
|
||||
if (($oParserState->comes('-') || $oParserState->comes('+'))) {
|
||||
if ($oParserState->peek(1, -1) != ' ' || !($oParserState->comes('- ') || $oParserState->comes('+ '))) {
|
||||
throw new UnexpectedTokenException(" {$oParserState->peek()} ", $oParserState->peek(1, -1) . $oParserState->peek(2), 'literal', $oParserState->currentLine());
|
||||
}
|
||||
}
|
||||
$oCalcList->addListComponent($oParserState->consume(1));
|
||||
$iLastComponentType = CalcFunction::T_OPERATOR;
|
||||
} else {
|
||||
throw new UnexpectedTokenException(
|
||||
sprintf(
|
||||
'Next token was expected to be an operand of type %s. Instead "%s" was found.',
|
||||
implode(', ', $aOperators),
|
||||
$oVal
|
||||
),
|
||||
'',
|
||||
'custom',
|
||||
$oParserState->currentLine()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$oList->addListComponent($oCalcList);
|
||||
$oParserState->consume(')');
|
||||
return new CalcFunction($sFunction, $oList, ',', $oParserState->currentLine());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
class CalcRuleValueList extends RuleValueList {
|
||||
public function __construct($iLineNo = 0) {
|
||||
parent::__construct(array(), ',', $iLineNo);
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
return $oOutputFormat->implode(' ', $this->aComponents);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,12 +2,66 @@
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
use Sabberworm\CSS\Parsing\ParserState;
|
||||
|
||||
class Color extends CSSFunction {
|
||||
|
||||
public function __construct($aColor, $iLineNo = 0) {
|
||||
parent::__construct(implode('', array_keys($aColor)), $aColor, ',', $iLineNo);
|
||||
}
|
||||
|
||||
public static function parse(ParserState $oParserState) {
|
||||
$aColor = array();
|
||||
if ($oParserState->comes('#')) {
|
||||
$oParserState->consume('#');
|
||||
$sValue = $oParserState->parseIdentifier(false);
|
||||
if ($oParserState->strlen($sValue) === 3) {
|
||||
$sValue = $sValue[0] . $sValue[0] . $sValue[1] . $sValue[1] . $sValue[2] . $sValue[2];
|
||||
} else if ($oParserState->strlen($sValue) === 4) {
|
||||
$sValue = $sValue[0] . $sValue[0] . $sValue[1] . $sValue[1] . $sValue[2] . $sValue[2] . $sValue[3] . $sValue[3];
|
||||
}
|
||||
|
||||
if ($oParserState->strlen($sValue) === 8) {
|
||||
$aColor = array(
|
||||
'r' => new Size(intval($sValue[0] . $sValue[1], 16), null, true, $oParserState->currentLine()),
|
||||
'g' => new Size(intval($sValue[2] . $sValue[3], 16), null, true, $oParserState->currentLine()),
|
||||
'b' => new Size(intval($sValue[4] . $sValue[5], 16), null, true, $oParserState->currentLine()),
|
||||
'a' => new Size(round(self::mapRange(intval($sValue[6] . $sValue[7], 16), 0, 255, 0, 1), 2), null, true, $oParserState->currentLine())
|
||||
);
|
||||
} else {
|
||||
$aColor = array(
|
||||
'r' => new Size(intval($sValue[0] . $sValue[1], 16), null, true, $oParserState->currentLine()),
|
||||
'g' => new Size(intval($sValue[2] . $sValue[3], 16), null, true, $oParserState->currentLine()),
|
||||
'b' => new Size(intval($sValue[4] . $sValue[5], 16), null, true, $oParserState->currentLine())
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$sColorMode = $oParserState->parseIdentifier(true);
|
||||
$oParserState->consumeWhiteSpace();
|
||||
$oParserState->consume('(');
|
||||
$iLength = $oParserState->strlen($sColorMode);
|
||||
for ($i = 0; $i < $iLength; ++$i) {
|
||||
$oParserState->consumeWhiteSpace();
|
||||
$aColor[$sColorMode[$i]] = Size::parse($oParserState, true);
|
||||
$oParserState->consumeWhiteSpace();
|
||||
if ($i < ($iLength - 1)) {
|
||||
$oParserState->consume(',');
|
||||
}
|
||||
}
|
||||
$oParserState->consume(')');
|
||||
}
|
||||
return new Color($aColor, $oParserState->currentLine());
|
||||
}
|
||||
|
||||
private static function mapRange($fVal, $fFromMin, $fFromMax, $fToMin, $fToMax) {
|
||||
$fFromRange = $fFromMax - $fFromMin;
|
||||
$fToRange = $fToMax - $fToMin;
|
||||
$fMultiplier = $fToRange / $fFromRange;
|
||||
$fNewVal = $fVal - $fFromMin;
|
||||
$fNewVal *= $fMultiplier;
|
||||
return $fNewVal + $fToMin;
|
||||
}
|
||||
|
||||
public function getColor() {
|
||||
return $this->aComponents;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
use Sabberworm\CSS\Parsing\ParserState;
|
||||
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
|
||||
|
||||
class LineName extends ValueList {
|
||||
public function __construct($aComponents = array(), $iLineNo = 0) {
|
||||
parent::__construct($aComponents, ' ', $iLineNo);
|
||||
}
|
||||
|
||||
public static function parse(ParserState $oParserState) {
|
||||
$oParserState->consume('[');
|
||||
$oParserState->consumeWhiteSpace();
|
||||
$aNames = array();
|
||||
do {
|
||||
if($oParserState->getSettings()->bLenientParsing) {
|
||||
try {
|
||||
$aNames[] = $oParserState->parseIdentifier();
|
||||
} catch(UnexpectedTokenException $e) {}
|
||||
} else {
|
||||
$aNames[] = $oParserState->parseIdentifier();
|
||||
}
|
||||
$oParserState->consumeWhiteSpace();
|
||||
} while (!$oParserState->comes(']'));
|
||||
$oParserState->consume(']');
|
||||
return new LineName($aNames, $oParserState->currentLine());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
return '[' . parent::render(\Sabberworm\CSS\OutputFormat::createCompact()) . ']';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,12 +2,16 @@
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
use Sabberworm\CSS\Parsing\ParserState;
|
||||
|
||||
class Size extends PrimitiveValue {
|
||||
|
||||
const ABSOLUTE_SIZE_UNITS = 'px/cm/mm/mozmm/in/pt/pc/vh/vw/vm/vmin/vmax/rem'; //vh/vw/vm(ax)/vmin/rem are absolute insofar as they don’t scale to the immediate parent (only the viewport)
|
||||
const RELATIVE_SIZE_UNITS = '%/em/ex/ch/fr';
|
||||
const NON_SIZE_UNITS = 'deg/grad/rad/s/ms/turns/Hz/kHz';
|
||||
|
||||
private static $SIZE_UNITS = null;
|
||||
|
||||
private $fSize;
|
||||
private $sUnit;
|
||||
private $bIsColorComponent;
|
||||
@@ -19,6 +23,51 @@ class Size extends PrimitiveValue {
|
||||
$this->bIsColorComponent = $bIsColorComponent;
|
||||
}
|
||||
|
||||
public static function parse(ParserState $oParserState, $bIsColorComponent = false) {
|
||||
$sSize = '';
|
||||
if ($oParserState->comes('-')) {
|
||||
$sSize .= $oParserState->consume('-');
|
||||
}
|
||||
while (is_numeric($oParserState->peek()) || $oParserState->comes('.')) {
|
||||
if ($oParserState->comes('.')) {
|
||||
$sSize .= $oParserState->consume('.');
|
||||
} else {
|
||||
$sSize .= $oParserState->consume(1);
|
||||
}
|
||||
}
|
||||
|
||||
$sUnit = null;
|
||||
$aSizeUnits = self::getSizeUnits();
|
||||
foreach($aSizeUnits as $iLength => &$aValues) {
|
||||
$sKey = strtolower($oParserState->peek($iLength));
|
||||
if(array_key_exists($sKey, $aValues)) {
|
||||
if (($sUnit = $aValues[$sKey]) !== null) {
|
||||
$oParserState->consume($iLength);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Size(floatval($sSize), $sUnit, $bIsColorComponent, $oParserState->currentLine());
|
||||
}
|
||||
|
||||
private static function getSizeUnits() {
|
||||
if(self::$SIZE_UNITS === null) {
|
||||
self::$SIZE_UNITS = array();
|
||||
foreach (explode('/', Size::ABSOLUTE_SIZE_UNITS.'/'.Size::RELATIVE_SIZE_UNITS.'/'.Size::NON_SIZE_UNITS) as $val) {
|
||||
$iSize = strlen($val);
|
||||
if(!isset(self::$SIZE_UNITS[$iSize])) {
|
||||
self::$SIZE_UNITS[$iSize] = array();
|
||||
}
|
||||
self::$SIZE_UNITS[$iSize][strtolower($val)] = $val;
|
||||
}
|
||||
|
||||
// FIXME: Should we not order the longest units first?
|
||||
ksort(self::$SIZE_UNITS, SORT_NUMERIC);
|
||||
}
|
||||
|
||||
return self::$SIZE_UNITS;
|
||||
}
|
||||
|
||||
public function setUnit($sUnit) {
|
||||
$this->sUnit = $sUnit;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
use Sabberworm\CSS\Parsing\ParserState;
|
||||
|
||||
class URL extends PrimitiveValue {
|
||||
|
||||
@@ -12,6 +13,23 @@ class URL extends PrimitiveValue {
|
||||
$this->oURL = $oURL;
|
||||
}
|
||||
|
||||
public static function parse(ParserState $oParserState) {
|
||||
$bUseUrl = $oParserState->comes('url', true);
|
||||
if ($bUseUrl) {
|
||||
$oParserState->consume('url');
|
||||
$oParserState->consumeWhiteSpace();
|
||||
$oParserState->consume('(');
|
||||
}
|
||||
$oParserState->consumeWhiteSpace();
|
||||
$oResult = new URL(CSSString::parse($oParserState), $oParserState->currentLine());
|
||||
if ($bUseUrl) {
|
||||
$oParserState->consumeWhiteSpace();
|
||||
$oParserState->consume(')');
|
||||
}
|
||||
return $oResult;
|
||||
}
|
||||
|
||||
|
||||
public function setURL(CSSString $oURL) {
|
||||
$this->oURL = $oURL;
|
||||
}
|
||||
|
||||
@@ -2,23 +2,130 @@
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
use Sabberworm\CSS\Parsing\ParserState;
|
||||
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
|
||||
use Sabberworm\CSS\Renderable;
|
||||
|
||||
abstract class Value implements Renderable {
|
||||
protected $iLineNo;
|
||||
protected $iLineNo;
|
||||
|
||||
public function __construct($iLineNo = 0) {
|
||||
$this->iLineNo = $iLineNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLineNo() {
|
||||
return $this->iLineNo;
|
||||
}
|
||||
public function __construct($iLineNo = 0) {
|
||||
$this->iLineNo = $iLineNo;
|
||||
}
|
||||
|
||||
//Methods are commented out because re-declaring them here is a fatal error in PHP < 5.3.9
|
||||
public static function parseValue(ParserState $oParserState, $aListDelimiters = array()) {
|
||||
$aStack = array();
|
||||
$oParserState->consumeWhiteSpace();
|
||||
//Build a list of delimiters and parsed values
|
||||
while (!($oParserState->comes('}') || $oParserState->comes(';') || $oParserState->comes('!') || $oParserState->comes(')') || $oParserState->comes('\\'))) {
|
||||
if (count($aStack) > 0) {
|
||||
$bFoundDelimiter = false;
|
||||
foreach ($aListDelimiters as $sDelimiter) {
|
||||
if ($oParserState->comes($sDelimiter)) {
|
||||
array_push($aStack, $oParserState->consume($sDelimiter));
|
||||
$oParserState->consumeWhiteSpace();
|
||||
$bFoundDelimiter = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$bFoundDelimiter) {
|
||||
//Whitespace was the list delimiter
|
||||
array_push($aStack, ' ');
|
||||
}
|
||||
}
|
||||
array_push($aStack, self::parsePrimitiveValue($oParserState));
|
||||
$oParserState->consumeWhiteSpace();
|
||||
}
|
||||
//Convert the list to list objects
|
||||
foreach ($aListDelimiters as $sDelimiter) {
|
||||
if (count($aStack) === 1) {
|
||||
return $aStack[0];
|
||||
}
|
||||
$iStartPosition = null;
|
||||
while (($iStartPosition = array_search($sDelimiter, $aStack, true)) !== false) {
|
||||
$iLength = 2; //Number of elements to be joined
|
||||
for ($i = $iStartPosition + 2; $i < count($aStack); $i+=2, ++$iLength) {
|
||||
if ($sDelimiter !== $aStack[$i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$oList = new RuleValueList($sDelimiter, $oParserState->currentLine());
|
||||
for ($i = $iStartPosition - 1; $i - $iStartPosition + 1 < $iLength * 2; $i+=2) {
|
||||
$oList->addListComponent($aStack[$i]);
|
||||
}
|
||||
array_splice($aStack, $iStartPosition - 1, $iLength * 2 - 1, array($oList));
|
||||
}
|
||||
}
|
||||
if (!isset($aStack[0])) {
|
||||
throw new UnexpectedTokenException(" {$oParserState->peek()} ", $oParserState->peek(1, -1) . $oParserState->peek(2), 'literal', $oParserState->currentLine());
|
||||
}
|
||||
return $aStack[0];
|
||||
}
|
||||
|
||||
public static function parseIdentifierOrFunction(ParserState $oParserState, $bIgnoreCase = false) {
|
||||
$sResult = $oParserState->parseIdentifier($bIgnoreCase);
|
||||
|
||||
if ($oParserState->comes('(')) {
|
||||
$oParserState->consume('(');
|
||||
$aArguments = Value::parseValue($oParserState, array('=', ' ', ','));
|
||||
$sResult = new CSSFunction($sResult, $aArguments, ',', $oParserState->currentLine());
|
||||
$oParserState->consume(')');
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
public static function parsePrimitiveValue(ParserState $oParserState) {
|
||||
$oValue = null;
|
||||
$oParserState->consumeWhiteSpace();
|
||||
if (is_numeric($oParserState->peek()) || ($oParserState->comes('-.') && is_numeric($oParserState->peek(1, 2))) || (($oParserState->comes('-') || $oParserState->comes('.')) && is_numeric($oParserState->peek(1, 1)))) {
|
||||
$oValue = Size::parse($oParserState);
|
||||
} else if ($oParserState->comes('#') || $oParserState->comes('rgb', true) || $oParserState->comes('hsl', true)) {
|
||||
$oValue = Color::parse($oParserState);
|
||||
} else if ($oParserState->comes('url', true)) {
|
||||
$oValue = URL::parse($oParserState);
|
||||
} else if ($oParserState->comes('calc', true) || $oParserState->comes('-webkit-calc', true) || $oParserState->comes('-moz-calc', true)) {
|
||||
$oValue = CalcFunction::parse($oParserState);
|
||||
} else if ($oParserState->comes("'") || $oParserState->comes('"')) {
|
||||
$oValue = CSSString::parse($oParserState);
|
||||
} else if ($oParserState->comes("progid:") && $oParserState->getSettings()->bLenientParsing) {
|
||||
$oValue = self::parseMicrosoftFilter($oParserState);
|
||||
} else if ($oParserState->comes("[")) {
|
||||
$oValue = LineName::parse($oParserState);
|
||||
} else if ($oParserState->comes("U+")) {
|
||||
$oValue = self::parseUnicodeRangeValue($oParserState);
|
||||
} else {
|
||||
$oValue = self::parseIdentifierOrFunction($oParserState);
|
||||
}
|
||||
$oParserState->consumeWhiteSpace();
|
||||
return $oValue;
|
||||
}
|
||||
|
||||
private static function parseMicrosoftFilter(ParserState $oParserState) {
|
||||
$sFunction = $oParserState->consumeUntil('(', false, true);
|
||||
$aArguments = Value::parseValue($oParserState, array(',', '='));
|
||||
return new CSSFunction($sFunction, $aArguments, ',', $oParserState->currentLine());
|
||||
}
|
||||
|
||||
private static function parseUnicodeRangeValue(ParserState $oParserState) {
|
||||
$iCodepointMaxLenth = 6; // Code points outside BMP can use up to six digits
|
||||
$sRange = "";
|
||||
$oParserState->consume("U+");
|
||||
do {
|
||||
if ($oParserState->comes('-')) $iCodepointMaxLenth = 13; // Max length is 2 six digit code points + the dash(-) between them
|
||||
$sRange .= $oParserState->consume(1);
|
||||
} while (strlen($sRange) < $iCodepointMaxLenth && preg_match("/[A-Fa-f0-9\?-]/", $oParserState->peek()));
|
||||
return "U+{$sRange}";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLineNo() {
|
||||
return $this->iLineNo;
|
||||
}
|
||||
|
||||
//Methods are commented out because re-declaring them here is a fatal error in PHP < 5.3.9
|
||||
//public abstract function __toString();
|
||||
//public abstract function render(\Sabberworm\CSS\OutputFormat $oOutputFormat);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user