PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.1.4
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.1.4
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
acymailing / back / Libraries / Sabberworm / CSS / src / Value / Value.php

Value.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 10.1.4, at back/Libraries/Sabberworm/CSS/src/Value/Value.php

199 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Sabberworm\CSS\Value;
4
5 use Sabberworm\CSS\Parsing\ParserState;
6 use Sabberworm\CSS\Parsing\SourceException;
7 use Sabberworm\CSS\Parsing\UnexpectedEOFException;
8 use Sabberworm\CSS\Parsing\UnexpectedTokenException;
9 use Sabberworm\CSS\Renderable;
10
11 abstract class Value implements Renderable
12 {
13 /**
14 * @var int
15 */
16 protected $iLineNo;
17
18 /**
19 * @param int $iLineNo
20 */
21 public function __construct($iLineNo = 0)
22 {
23 $this->iLineNo = $iLineNo;
24 }
25
26 /**
27 * @param array<array-key, string> $aListDelimiters
28 *
29 * @return RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string
30 *
31 * @throws UnexpectedTokenException
32 * @throws UnexpectedEOFException
33 */
34 public static function parseValue(ParserState $oParserState, array $aListDelimiters = [])
35 {
36 /** @var array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string> $aStack */
37 $aStack = [];
38 $oParserState->consumeWhiteSpace();
39 //Build a list of delimiters and parsed values
40 while (
41 !($oParserState->comes('}') || $oParserState->comes(';') || $oParserState->comes('!')
42 || $oParserState->comes(')')
43 || $oParserState->comes('\\'))
44 ) {
45 if (count($aStack) > 0) {
46 $bFoundDelimiter = false;
47 foreach ($aListDelimiters as $sDelimiter) {
48 if ($oParserState->comes($sDelimiter)) {
49 array_push($aStack, $oParserState->consume($sDelimiter));
50 $oParserState->consumeWhiteSpace();
51 $bFoundDelimiter = true;
52 break;
53 }
54 }
55 if (!$bFoundDelimiter) {
56 //Whitespace was the list delimiter
57 array_push($aStack, ' ');
58 }
59 }
60 array_push($aStack, self::parsePrimitiveValue($oParserState));
61 $oParserState->consumeWhiteSpace();
62 }
63 // Convert the list to list objects
64 foreach ($aListDelimiters as $sDelimiter) {
65 if (count($aStack) === 1) {
66 return $aStack[0];
67 }
68 $iStartPosition = null;
69 while (($iStartPosition = array_search($sDelimiter, $aStack, true)) !== false) {
70 $iLength = 2; //Number of elements to be joined
71 for ($i = $iStartPosition + 2; $i < count($aStack); $i += 2, ++$iLength) {
72 if ($sDelimiter !== $aStack[$i]) {
73 break;
74 }
75 }
76 $oList = new RuleValueList($sDelimiter, $oParserState->currentLine());
77 for ($i = $iStartPosition - 1; $i - $iStartPosition + 1 < $iLength * 2; $i += 2) {
78 $oList->addListComponent($aStack[$i]);
79 }
80 array_splice($aStack, $iStartPosition - 1, $iLength * 2 - 1, [$oList]);
81 }
82 }
83 if (!isset($aStack[0])) {
84 throw new UnexpectedTokenException(
85 " {$oParserState->peek()} ",
86 $oParserState->peek(1, -1) . $oParserState->peek(2),
87 'literal',
88 $oParserState->currentLine()
89 );
90 }
91 return $aStack[0];
92 }
93
94 /**
95 * @param bool $bIgnoreCase
96 *
97 * @return CSSFunction|string
98 *
99 * @throws UnexpectedEOFException
100 * @throws UnexpectedTokenException
101 */
102 public static function parseIdentifierOrFunction(ParserState $oParserState, $bIgnoreCase = false)
103 {
104 $sResult = $oParserState->parseIdentifier($bIgnoreCase);
105
106 if ($oParserState->comes('(')) {
107 $oParserState->consume('(');
108 $aArguments = Value::parseValue($oParserState, ['=', ' ', ',']);
109 $sResult = new CSSFunction($sResult, $aArguments, ',', $oParserState->currentLine());
110 $oParserState->consume(')');
111 }
112
113 return $sResult;
114 }
115
116 /**
117 * @return CSSFunction|CSSString|LineName|Size|URL|string
118 *
119 * @throws UnexpectedEOFException
120 * @throws UnexpectedTokenException
121 * @throws SourceException
122 */
123 public static function parsePrimitiveValue(ParserState $oParserState)
124 {
125 $oValue = null;
126 $oParserState->consumeWhiteSpace();
127 if (
128 is_numeric($oParserState->peek())
129 || ($oParserState->comes('-.')
130 && is_numeric($oParserState->peek(1, 2)))
131 || (($oParserState->comes('-') || $oParserState->comes('.')) && is_numeric($oParserState->peek(1, 1)))
132 ) {
133 $oValue = Size::parse($oParserState);
134 } elseif ($oParserState->comes('#') || $oParserState->comes('rgb', true) || $oParserState->comes('hsl', true)) {
135 $oValue = Color::parse($oParserState);
136 } elseif ($oParserState->comes('url', true)) {
137 $oValue = URL::parse($oParserState);
138 } elseif (
139 $oParserState->comes('calc', true) || $oParserState->comes('-webkit-calc', true)
140 || $oParserState->comes('-moz-calc', true)
141 ) {
142 $oValue = CalcFunction::parse($oParserState);
143 } elseif ($oParserState->comes("'") || $oParserState->comes('"')) {
144 $oValue = CSSString::parse($oParserState);
145 } elseif ($oParserState->comes("progid:") && $oParserState->getSettings()->bLenientParsing) {
146 $oValue = self::parseMicrosoftFilter($oParserState);
147 } elseif ($oParserState->comes("[")) {
148 $oValue = LineName::parse($oParserState);
149 } elseif ($oParserState->comes("U+")) {
150 $oValue = self::parseUnicodeRangeValue($oParserState);
151 } else {
152 $oValue = self::parseIdentifierOrFunction($oParserState);
153 }
154 $oParserState->consumeWhiteSpace();
155 return $oValue;
156 }
157
158 /**
159 * @return CSSFunction
160 *
161 * @throws UnexpectedEOFException
162 * @throws UnexpectedTokenException
163 */
164 private static function parseMicrosoftFilter(ParserState $oParserState)
165 {
166 $sFunction = $oParserState->consumeUntil('(', false, true);
167 $aArguments = Value::parseValue($oParserState, [',', '=']);
168 return new CSSFunction($sFunction, $aArguments, ',', $oParserState->currentLine());
169 }
170
171 /**
172 * @return string
173 *
174 * @throws UnexpectedEOFException
175 * @throws UnexpectedTokenException
176 */
177 private static function parseUnicodeRangeValue(ParserState $oParserState)
178 {
179 $iCodepointMaxLength = 6; // Code points outside BMP can use up to six digits
180 $sRange = "";
181 $oParserState->consume("U+");
182 do {
183 if ($oParserState->comes('-')) {
184 $iCodepointMaxLength = 13; // Max length is 2 six digit code points + the dash(-) between them
185 }
186 $sRange .= $oParserState->consume(1);
187 } while (strlen($sRange) < $iCodepointMaxLength && preg_match("/[A-Fa-f0-9\?-]/", $oParserState->peek()));
188 return "U+{$sRange}";
189 }
190
191 /**
192 * @return int
193 */
194 public function getLineNo()
195 {
196 return $this->iLineNo;
197 }
198 }
199