Blame view

public/vendor/sabberworm/php-css-parser/src/Value/CalcFunction.php 4.08 KB
86143e36f   Андрей Ларионов   Коммит вторник
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  <?php
  
  namespace Sabberworm\CSS\Value;
  
  use Sabberworm\CSS\Parsing\ParserState;
  use Sabberworm\CSS\Parsing\UnexpectedEOFException;
  use Sabberworm\CSS\Parsing\UnexpectedTokenException;
  
  class CalcFunction extends CSSFunction
  {
      /**
       * @var int
       */
      const T_OPERAND = 1;
  
      /**
       * @var int
       */
      const T_OPERATOR = 2;
  
      /**
       * @param ParserState $oParserState
       * @param bool $bIgnoreCase
       *
       * @return CalcFunction
       *
       * @throws UnexpectedTokenException
       * @throws UnexpectedEOFException
       */
      public static function parse(ParserState $oParserState, $bIgnoreCase = false)
      {
          $aOperators = ['+', '-', '*', '/'];
          $sFunction = $oParserState->parseIdentifier();
          if ($oParserState->peek() != '(') {
              // Found ; or end of line before an opening bracket
              throw new UnexpectedTokenException('(', $oParserState->peek(), 'literal', $oParserState->currentLine());
          } elseif (!in_array($sFunction, ['calc', '-moz-calc', '-webkit-calc'])) {
              // Found invalid calc definition. Example calc (...
              throw new UnexpectedTokenException('calc', $sFunction, 'literal', $oParserState->currentLine());
          }
          $oParserState->consume('(');
          $oCalcList = new CalcRuleValueList($oParserState->currentLine());
          $oList = new RuleValueList(',', $oParserState->currentLine());
          $iNestingLevel = 0;
          $iLastComponentType = null;
          while (!$oParserState->comes(')') || $iNestingLevel > 0) {
              if ($oParserState->isEnd() && $iNestingLevel === 0) {
                  break;
              }
  
              $oParserState->consumeWhiteSpace();
              if ($oParserState->comes('(')) {
                  $iNestingLevel++;
                  $oCalcList->addListComponent($oParserState->consume(1));
                  $oParserState->consumeWhiteSpace();
                  continue;
              } elseif ($oParserState->comes(')')) {
                  $iNestingLevel--;
                  $oCalcList->addListComponent($oParserState->consume(1));
                  $oParserState->consumeWhiteSpace();
                  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()
                      );
                  }
              }
              $oParserState->consumeWhiteSpace();
          }
          $oList->addListComponent($oCalcList);
          if (!$oParserState->isEnd()) {
              $oParserState->consume(')');
          }
          return new CalcFunction($sFunction, $oList, ',', $oParserState->currentLine());
      }
  }