Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 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
     * @internal
15
     */
16
    const T_OPERAND = 1;
17
 
18
    /**
19
     * @var int
20
     *
21
     * @internal
22
     */
23
    const T_OPERATOR = 2;
24
 
25
    /**
26
     * @param ParserState $oParserState
27
     * @param bool $bIgnoreCase
28
     *
29
     * @return CalcFunction
30
     *
31
     * @throws UnexpectedTokenException
32
     * @throws UnexpectedEOFException
33
     */
34
    public static function parse(ParserState $oParserState, $bIgnoreCase = false)
35
    {
36
        $aOperators = ['+', '-', '*', '/'];
37
        $sFunction = $oParserState->parseIdentifier();
38
        if ($oParserState->peek() != '(') {
39
            // Found ; or end of line before an opening bracket
40
            throw new UnexpectedTokenException('(', $oParserState->peek(), 'literal', $oParserState->currentLine());
41
        } elseif (!in_array($sFunction, ['calc', '-moz-calc', '-webkit-calc'])) {
42
            // Found invalid calc definition. Example calc (...
43
            throw new UnexpectedTokenException('calc', $sFunction, 'literal', $oParserState->currentLine());
44
        }
45
        $oParserState->consume('(');
46
        $oCalcList = new CalcRuleValueList($oParserState->currentLine());
47
        $oList = new RuleValueList(',', $oParserState->currentLine());
48
        $iNestingLevel = 0;
49
        $iLastComponentType = null;
50
        while (!$oParserState->comes(')') || $iNestingLevel > 0) {
51
            if ($oParserState->isEnd() && $iNestingLevel === 0) {
52
                break;
53
            }
54
 
55
            $oParserState->consumeWhiteSpace();
56
            if ($oParserState->comes('(')) {
57
                $iNestingLevel++;
58
                $oCalcList->addListComponent($oParserState->consume(1));
59
                $oParserState->consumeWhiteSpace();
60
                continue;
61
            } elseif ($oParserState->comes(')')) {
62
                $iNestingLevel--;
63
                $oCalcList->addListComponent($oParserState->consume(1));
64
                $oParserState->consumeWhiteSpace();
65
                continue;
66
            }
67
            if ($iLastComponentType != CalcFunction::T_OPERAND) {
68
                $oVal = Value::parsePrimitiveValue($oParserState);
69
                $oCalcList->addListComponent($oVal);
70
                $iLastComponentType = CalcFunction::T_OPERAND;
71
            } else {
72
                if (in_array($oParserState->peek(), $aOperators)) {
73
                    if (($oParserState->comes('-') || $oParserState->comes('+'))) {
74
                        if (
75
                            $oParserState->peek(1, -1) != ' '
76
                            || !($oParserState->comes('- ')
77
                                || $oParserState->comes('+ '))
78
                        ) {
79
                            throw new UnexpectedTokenException(
80
                                " {$oParserState->peek()} ",
81
                                $oParserState->peek(1, -1) . $oParserState->peek(2),
82
                                'literal',
83
                                $oParserState->currentLine()
84
                            );
85
                        }
86
                    }
87
                    $oCalcList->addListComponent($oParserState->consume(1));
88
                    $iLastComponentType = CalcFunction::T_OPERATOR;
89
                } else {
90
                    throw new UnexpectedTokenException(
91
                        sprintf(
92
                            'Next token was expected to be an operand of type %s. Instead "%s" was found.',
93
                            implode(', ', $aOperators),
94
                            $oParserState->peek()
95
                        ),
96
                        '',
97
                        'custom',
98
                        $oParserState->currentLine()
99
                    );
100
                }
101
            }
102
            $oParserState->consumeWhiteSpace();
103
        }
104
        $oList->addListComponent($oCalcList);
105
        if (!$oParserState->isEnd()) {
106
            $oParserState->consume(')');
107
        }
108
        return new CalcFunction($sFunction, $oList, ',', $oParserState->currentLine());
109
    }
110
}