PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.0.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.0.1
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 / Rule / Rule.php

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

393 lines 9.9 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\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;
14
15 /**
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];”
18 */
19 class Rule implements Renderable, Commentable
20 {
21 /**
22 * @var string
23 */
24 private $sRule;
25
26 /**
27 * @var RuleValueList|null
28 */
29 private $mValue;
30
31 /**
32 * @var bool
33 */
34 private $bIsImportant;
35
36 /**
37 * @var array<int, int>
38 */
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)
62 {
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 = [];
70 }
71
72 /**
73 * @return Rule
74 *
75 * @throws UnexpectedEOFException
76 * @throws UnexpectedTokenException
77 */
78 public static function parse(ParserState $oParserState)
79 {
80 $aComments = $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 $oParserState->consumeWhiteSpace();
110
111 return $oRule;
112 }
113
114 /**
115 * @param string $sRule
116 *
117 * @return array<int, string>
118 */
119 private static function listDelimiterForRule($sRule)
120 {
121 if (preg_match('/^font($|-)/', $sRule)) {
122 return [',', '/', ' '];
123 }
124 return [',', ' ', '/'];
125 }
126
127 /**
128 * @return int
129 */
130 public function getLineNo()
131 {
132 return $this->iLineNo;
133 }
134
135 /**
136 * @return int
137 */
138 public function getColNo()
139 {
140 return $this->iColNo;
141 }
142
143 /**
144 * @param int $iLine
145 * @param int $iColumn
146 *
147 * @return void
148 */
149 public function setPosition($iLine, $iColumn)
150 {
151 $this->iColNo = $iColumn;
152 $this->iLineNo = $iLine;
153 }
154
155 /**
156 * @param string $sRule
157 *
158 * @return void
159 */
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 public function getValue()
177 {
178 return $this->mValue;
179 }
180
181 /**
182 * @param RuleValueList|null $mValue
183 *
184 * @return void
185 */
186 public function setValue($mValue)
187 {
188 $this->mValue = $mValue;
189 }
190
191 /**
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 * Adds a value to the existing value. Value will be appended if a `RuleValueList` exists of the given type.
266 * Otherwise, the existing value will be wrapped by one.
267 *
268 * @param RuleValueList|array<int, RuleValueList> $mValue
269 * @param string $sType
270 *
271 * @return void
272 */
273 public function addValue($mValue, $sType = ' ')
274 {
275 if (!is_array($mValue)) {
276 $mValue = [$mValue];
277 }
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);
283 }
284 }
285 foreach ($mValue as $mValueItem) {
286 $this->mValue->addListComponent($mValueItem);
287 }
288 }
289
290 /**
291 * @param int $iModifier
292 *
293 * @return void
294 */
295 public function addIeHack($iModifier)
296 {
297 $this->aIeHack[] = $iModifier;
298 }
299
300 /**
301 * @param array<int, int> $aModifiers
302 *
303 * @return void
304 */
305 public function setIeHack(array $aModifiers)
306 {
307 $this->aIeHack = $aModifiers;
308 }
309
310 /**
311 * @return array<int, int>
312 */
313 public function getIeHack()
314 {
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);
352 } else {
353 $sResult .= $this->mValue;
354 }
355 if (!empty($this->aIeHack)) {
356 $sResult .= ' \\' . implode('\\', $this->aIeHack);
357 }
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;
391 }
392 }
393