PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.3
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.3
2.4.3 2.4.4 2.4.2 2.4.0 2.4.1 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.2.0 2.1.21 2.1.20 2.1.19 2.1.18 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 All 60 releases
easy-invoice / vendor / sabberworm / php-css-parser / src / Rule / Rule.php

Rule.php in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.4.3, at vendor/sabberworm/php-css-parser/src/Rule/Rule.php

384 lines 10.4 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\Rule;
4
5 use Sabberworm\CSS\Comment\Comment;
6 use Sabberworm\CSS\Comment\Commentable;
7 use Sabberworm\CSS\CSSElement;
8 use Sabberworm\CSS\OutputFormat;
9 use Sabberworm\CSS\Parsing\ParserState;
10 use Sabberworm\CSS\Parsing\UnexpectedEOFException;
11 use Sabberworm\CSS\Parsing\UnexpectedTokenException;
12 use Sabberworm\CSS\Position\Position;
13 use Sabberworm\CSS\Position\Positionable;
14 use Sabberworm\CSS\Value\RuleValueList;
15 use Sabberworm\CSS\Value\Value;
16
17 /**
18 * `Rule`s just have a string key (the rule) and a 'Value'.
19 *
20 * In CSS, `Rule`s are expressed as follows: “key: value[0][0] value[0][1], value[1][0] value[1][1];”
21 */
22 class Rule implements Commentable, CSSElement, Positionable
23 {
24 use Position;
25
26 /**
27 * @var string
28 */
29 private $sRule;
30
31 /**
32 * @var RuleValueList|string|null
33 */
34 private $mValue;
35
36 /**
37 * @var bool
38 */
39 private $bIsImportant;
40
41 /**
42 * @var array<int, int>
43 */
44 private $aIeHack;
45
46 /**
47 * @var array<array-key, Comment>
48 *
49 * @internal since 8.8.0
50 */
51 protected $aComments;
52
53 /**
54 * @param string $sRule
55 * @param int $iLineNo
56 * @param int $iColNo
57 */
58 public function __construct($sRule, $iLineNo = 0, $iColNo = 0)
59 {
60 $this->sRule = $sRule;
61 $this->mValue = null;
62 $this->bIsImportant = false;
63 $this->aIeHack = [];
64 $this->setPosition($iLineNo, $iColNo);
65 $this->aComments = [];
66 }
67
68 /**
69 * @param array<int, Comment> $commentsBeforeRule
70 *
71 * @return Rule
72 *
73 * @throws UnexpectedEOFException
74 * @throws UnexpectedTokenException
75 *
76 * @internal since V8.8.0
77 */
78 public static function parse(ParserState $oParserState, $commentsBeforeRule = [])
79 {
80 $aComments = \array_merge($commentsBeforeRule, $oParserState->consumeWhiteSpace());
81 $oRule = new Rule(
82 $oParserState->parseIdentifier(!$oParserState->comes("--")),
83 $oParserState->currentLine(),
84 $oParserState->currentColumn()
85 );
86 $oRule->setComments($aComments);
87 $oRule->addComments($oParserState->consumeWhiteSpace());
88 $oParserState->consume(':');
89 $oValue = Value::parseValue($oParserState, self::listDelimiterForRule($oRule->getRule()));
90 $oRule->setValue($oValue);
91 if ($oParserState->getSettings()->bLenientParsing) {
92 while ($oParserState->comes('\\')) {
93 $oParserState->consume('\\');
94 $oRule->addIeHack($oParserState->consume());
95 $oParserState->consumeWhiteSpace();
96 }
97 }
98 $oParserState->consumeWhiteSpace();
99 if ($oParserState->comes('!')) {
100 $oParserState->consume('!');
101 $oParserState->consumeWhiteSpace();
102 $oParserState->consume('important');
103 $oRule->setIsImportant(true);
104 }
105 $oParserState->consumeWhiteSpace();
106 while ($oParserState->comes(';')) {
107 $oParserState->consume(';');
108 }
109
110 return $oRule;
111 }
112
113 /**
114 * Returns a list of delimiters (or separators).
115 * The first item is the innermost separator (or, put another way, the highest-precedence operator).
116 * The sequence continues to the outermost separator (or lowest-precedence operator).
117 *
118 * @param string $sRule
119 *
120 * @return list<non-empty-string>
121 */
122 private static function listDelimiterForRule($sRule)
123 {
124 if (preg_match('/^font($|-)/', $sRule)) {
125 return [',', '/', ' '];
126 }
127
128 switch ($sRule) {
129 case 'src':
130 return [' ', ','];
131 default:
132 return [',', ' ', '/'];
133 }
134 }
135
136 /**
137 * @param string $sRule
138 *
139 * @return void
140 */
141 public function setRule($sRule)
142 {
143 $this->sRule = $sRule;
144 }
145
146 /**
147 * @return string
148 */
149 public function getRule()
150 {
151 return $this->sRule;
152 }
153
154 /**
155 * @return RuleValueList|string|null
156 */
157 public function getValue()
158 {
159 return $this->mValue;
160 }
161
162 /**
163 * @param RuleValueList|string|null $mValue
164 *
165 * @return void
166 */
167 public function setValue($mValue)
168 {
169 $this->mValue = $mValue;
170 }
171
172 /**
173 * @param array<array-key, array<array-key, RuleValueList>> $aSpaceSeparatedValues
174 *
175 * @return RuleValueList
176 *
177 * @deprecated will be removed in version 9.0
178 * Old-Style 2-dimensional array given. Retained for (some) backwards-compatibility.
179 * Use `setValue()` instead and wrap the value inside a RuleValueList if necessary.
180 */
181 public function setValues(array $aSpaceSeparatedValues)
182 {
183 $oSpaceSeparatedList = null;
184 if (count($aSpaceSeparatedValues) > 1) {
185 $oSpaceSeparatedList = new RuleValueList(' ', $this->iLineNo);
186 }
187 foreach ($aSpaceSeparatedValues as $aCommaSeparatedValues) {
188 $oCommaSeparatedList = null;
189 if (count($aCommaSeparatedValues) > 1) {
190 $oCommaSeparatedList = new RuleValueList(',', $this->iLineNo);
191 }
192 foreach ($aCommaSeparatedValues as $mValue) {
193 if (!$oSpaceSeparatedList && !$oCommaSeparatedList) {
194 $this->mValue = $mValue;
195 return $mValue;
196 }
197 if ($oCommaSeparatedList) {
198 $oCommaSeparatedList->addListComponent($mValue);
199 } else {
200 $oSpaceSeparatedList->addListComponent($mValue);
201 }
202 }
203 if (!$oSpaceSeparatedList) {
204 $this->mValue = $oCommaSeparatedList;
205 return $oCommaSeparatedList;
206 } else {
207 $oSpaceSeparatedList->addListComponent($oCommaSeparatedList);
208 }
209 }
210 $this->mValue = $oSpaceSeparatedList;
211 return $oSpaceSeparatedList;
212 }
213
214 /**
215 * @return array<int, array<int, RuleValueList>>
216 *
217 * @deprecated will be removed in version 9.0
218 * Old-Style 2-dimensional array returned. Retained for (some) backwards-compatibility.
219 * Use `getValue()` instead and check for the existence of a (nested set of) ValueList object(s).
220 */
221 public function getValues()
222 {
223 if (!$this->mValue instanceof RuleValueList) {
224 return [[$this->mValue]];
225 }
226 if ($this->mValue->getListSeparator() === ',') {
227 return [$this->mValue->getListComponents()];
228 }
229 $aResult = [];
230 foreach ($this->mValue->getListComponents() as $mValue) {
231 if (!$mValue instanceof RuleValueList || $mValue->getListSeparator() !== ',') {
232 $aResult[] = [$mValue];
233 continue;
234 }
235 if ($this->mValue->getListSeparator() === ' ' || count($aResult) === 0) {
236 $aResult[] = [];
237 }
238 foreach ($mValue->getListComponents() as $mValue) {
239 $aResult[count($aResult) - 1][] = $mValue;
240 }
241 }
242 return $aResult;
243 }
244
245 /**
246 * Adds a value to the existing value. Value will be appended if a `RuleValueList` exists of the given type.
247 * Otherwise, the existing value will be wrapped by one.
248 *
249 * @param RuleValueList|array<int, RuleValueList> $mValue
250 * @param string $sType
251 *
252 * @return void
253 */
254 public function addValue($mValue, $sType = ' ')
255 {
256 if (!is_array($mValue)) {
257 $mValue = [$mValue];
258 }
259 if (!$this->mValue instanceof RuleValueList || $this->mValue->getListSeparator() !== $sType) {
260 $mCurrentValue = $this->mValue;
261 $this->mValue = new RuleValueList($sType, $this->getLineNumber());
262 if ($mCurrentValue) {
263 $this->mValue->addListComponent($mCurrentValue);
264 }
265 }
266 foreach ($mValue as $mValueItem) {
267 $this->mValue->addListComponent($mValueItem);
268 }
269 }
270
271 /**
272 * @param int $iModifier
273 *
274 * @return void
275 *
276 * @deprecated since V8.8.0, will be removed in V9.0
277 */
278 public function addIeHack($iModifier)
279 {
280 $this->aIeHack[] = $iModifier;
281 }
282
283 /**
284 * @param array<int, int> $aModifiers
285 *
286 * @return void
287 *
288 * @deprecated since V8.8.0, will be removed in V9.0
289 */
290 public function setIeHack(array $aModifiers)
291 {
292 $this->aIeHack = $aModifiers;
293 }
294
295 /**
296 * @return array<int, int>
297 *
298 * @deprecated since V8.8.0, will be removed in V9.0
299 */
300 public function getIeHack()
301 {
302 return $this->aIeHack;
303 }
304
305 /**
306 * @param bool $bIsImportant
307 *
308 * @return void
309 */
310 public function setIsImportant($bIsImportant)
311 {
312 $this->bIsImportant = $bIsImportant;
313 }
314
315 /**
316 * @return bool
317 */
318 public function getIsImportant()
319 {
320 return $this->bIsImportant;
321 }
322
323 /**
324 * @return string
325 *
326 * @deprecated in V8.8.0, will be removed in V9.0.0. Use `render` instead.
327 */
328 public function __toString()
329 {
330 return $this->render(new OutputFormat());
331 }
332
333 /**
334 * @param OutputFormat|null $oOutputFormat
335 *
336 * @return string
337 */
338 public function render($oOutputFormat)
339 {
340 $sResult = "{$oOutputFormat->comments($this)}{$this->sRule}:{$oOutputFormat->spaceAfterRuleName()}";
341 if ($this->mValue instanceof Value) { // Can also be a ValueList
342 $sResult .= $this->mValue->render($oOutputFormat);
343 } else {
344 $sResult .= $this->mValue;
345 }
346 if (!empty($this->aIeHack)) {
347 $sResult .= ' \\' . implode('\\', $this->aIeHack);
348 }
349 if ($this->bIsImportant) {
350 $sResult .= ' !important';
351 }
352 $sResult .= ';';
353 return $sResult;
354 }
355
356 /**
357 * @param array<array-key, Comment> $aComments
358 *
359 * @return void
360 */
361 public function addComments(array $aComments)
362 {
363 $this->aComments = array_merge($this->aComments, $aComments);
364 }
365
366 /**
367 * @return array<array-key, Comment>
368 */
369 public function getComments()
370 {
371 return $this->aComments;
372 }
373
374 /**
375 * @param array<array-key, Comment> $aComments
376 *
377 * @return void
378 */
379 public function setComments(array $aComments)
380 {
381 $this->aComments = $aComments;
382 }
383 }
384