See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
1 <?php 2 3 namespace Sabberworm\CSS\Value; 4 5 use Sabberworm\CSS\Parsing\ParserState; 6 use Sabberworm\CSS\Parsing\UnexpectedEOFException; 7 use Sabberworm\CSS\Parsing\UnexpectedTokenException; 8 9 class CalcFunction extends CSSFunction 10 { 11 /** 12 * @var int 13 */ 14 const T_OPERAND = 1; 15 16 /** 17 * @var int 18 */ 19 const T_OPERATOR = 2; 20 21 /** 22 * @return CalcFunction 23 * 24 * @throws UnexpectedTokenException 25 * @throws UnexpectedEOFException 26 */ 27 public static function parse(ParserState $oParserState) 28 { 29 $aOperators = ['+', '-', '*', '/']; 30 $sFunction = trim($oParserState->consumeUntil('(', false, true)); 31 $oCalcList = new CalcRuleValueList($oParserState->currentLine()); 32 $oList = new RuleValueList(',', $oParserState->currentLine()); 33 $iNestingLevel = 0; 34 $iLastComponentType = null; 35 while (!$oParserState->comes(')') || $iNestingLevel > 0) { 36 $oParserState->consumeWhiteSpace(); 37 if ($oParserState->comes('(')) { 38 $iNestingLevel++; 39 $oCalcList->addListComponent($oParserState->consume(1)); 40 $oParserState->consumeWhiteSpace(); 41 continue; 42 } elseif ($oParserState->comes(')')) { 43 $iNestingLevel--; 44 $oCalcList->addListComponent($oParserState->consume(1)); 45 $oParserState->consumeWhiteSpace(); 46 continue; 47 } 48 if ($iLastComponentType != CalcFunction::T_OPERAND) { 49 $oVal = Value::parsePrimitiveValue($oParserState); 50 $oCalcList->addListComponent($oVal); 51 $iLastComponentType = CalcFunction::T_OPERAND; 52 } else { 53 if (in_array($oParserState->peek(), $aOperators)) { 54 if (($oParserState->comes('-') || $oParserState->comes('+'))) { 55 if ( 56 $oParserState->peek(1, -1) != ' ' 57 || !($oParserState->comes('- ') 58 || $oParserState->comes('+ ')) 59 ) { 60 throw new UnexpectedTokenException( 61 " {$oParserState->peek()} ", 62 $oParserState->peek(1, -1) . $oParserState->peek(2), 63 'literal', 64 $oParserState->currentLine() 65 ); 66 } 67 } 68 $oCalcList->addListComponent($oParserState->consume(1)); 69 $iLastComponentType = CalcFunction::T_OPERATOR; 70 } else { 71 throw new UnexpectedTokenException( 72 sprintf( 73 'Next token was expected to be an operand of type %s. Instead "%s" was found.', 74 implode(', ', $aOperators), 75 $oVal 76 ), 77 '', 78 'custom', 79 $oParserState->currentLine() 80 ); 81 } 82 } 83 $oParserState->consumeWhiteSpace(); 84 } 85 $oList->addListComponent($oCalcList); 86 $oParserState->consume(')'); 87 return new CalcFunction($sFunction, $oList, ',', $oParserState->currentLine()); 88 } 89 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body