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