PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.4
Booking for Appointments and Events Calendar – Amelia v2.4.4
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / vendor / sabberworm / php-css-parser / README.md
ameliabooking / vendor / sabberworm / php-css-parser Last commit date
src 6 months ago CHANGELOG.md 6 months ago LICENSE 1 year ago README.md 1 year ago composer.json 6 months ago
README.md
638 lines
1 # PHP CSS Parser
2
3 [](https://github.com/sabberworm/PHP-CSS-Parser/actions/![Build Status](https://github.com/sabberworm/PHP-CSS-Parser/workflows/CI/badge.svg?branch=master)](https://github.com/sabberworm/PHP-CSS-Parser/actions/](https://github.com/sabberworm/PHP-CSS-Parser/actions/)
4
5 A Parser for CSS Files written in PHP. Allows extraction of CSS files into a data structure, manipulation of said structure and output as (optimized) CSS.
6
7 ## Usage
8
9 ### Installation using Composer
10
11 ```bash
12 composer require sabberworm/php-css-parser
13 ```
14
15 ### Extraction
16
17 To use the CSS Parser, create a new instance. The constructor takes the following form:
18
19 ```php
20 new \Sabberworm\CSS\Parser($css);
21 ```
22
23 To read a file, for example, you’d do the following:
24
25 ```php
26 $parser = new \Sabberworm\CSS\Parser(file_get_contents('somefile.css'));
27 $cssDocument = $parser->parse();
28 ```
29
30 The resulting CSS document structure can be manipulated prior to being output.
31
32 ### Options
33
34 #### Charset
35
36 The charset option will only be used if the CSS file does not contain an `@charset` declaration. UTF-8 is the default, so you won’t have to create a settings object at all if you don’t intend to change that.
37
38 ```php
39 $settings = \Sabberworm\CSS\Settings::create()
40 ->withDefaultCharset('windows-1252');
41 $parser = new \Sabberworm\CSS\Parser($css, $settings);
42 ```
43
44 #### Strict parsing
45
46 To have the parser throw an exception when encountering invalid/unknown constructs (as opposed to trying to ignore them and carry on parsing), supply a thusly configured `\Sabberworm\CSS\Settings` object:
47
48 ```php
49 $parser = new \Sabberworm\CSS\Parser(
50 file_get_contents('somefile.css'),
51 \Sabberworm\CSS\Settings::create()->beStrict()
52 );
53 ```
54
55 Note that this will also disable a workaround for parsing the unquoted variant of the legacy IE-specific `filter` rule.
56
57 #### Disable multibyte functions
58
59 To achieve faster parsing, you can choose to have PHP-CSS-Parser use regular string functions instead of `mb_*` functions. This should work fine in most cases, even for UTF-8 files, as all the multibyte characters are in string literals. Still it’s not recommended using this with input you have no control over as it’s not thoroughly covered by test cases.
60
61 ```php
62 $settings = \Sabberworm\CSS\Settings::create()->withMultibyteSupport(false);
63 $parser = new \Sabberworm\CSS\Parser($css, $settings);
64 ```
65
66 ### Manipulation
67
68 The resulting data structure consists mainly of five basic types: `CSSList`, `RuleSet`, `Rule`, `Selector` and `Value`. There are two additional types used: `Import` and `Charset`, which you won’t use often.
69
70 #### CSSList
71
72 `CSSList` represents a generic CSS container, most likely containing declaration blocks (rule sets with a selector), but it may also contain at-rules, charset declarations, etc.
73
74 To access the items stored in a `CSSList` – like the document you got back when calling `$parser->parse()` –, use `getContents()`, then iterate over that collection and use `instanceof` to check whether you’re dealing with another `CSSList`, a `RuleSet`, a `Import` or a `Charset`.
75
76 To append a new item (selector, media query, etc.) to an existing `CSSList`, construct it using the constructor for this class and use the `append($oItem)` method.
77
78 #### RuleSet
79
80 `RuleSet` is a container for individual rules. The most common form of a rule set is one constrained by a selector. The following concrete subtypes exist:
81
82 * `AtRuleSet` – for generic at-rules for generic at-rules which are not covered by specific classes, i.e., not `@import`, `@charset` or `@media`. A common example for this is `@font-face`.
83 * `DeclarationBlock` – a `RuleSet` constrained by a `Selector`; contains an array of selector objects (comma-separated in the CSS) as well as the rules to be applied to the matching elements.
84
85 Note: A `CSSList` can contain other `CSSList`s (and `Import`s as well as a `Charset`), while a `RuleSet` can only contain `Rule`s.
86
87 If you want to manipulate a `RuleSet`, use the methods `addRule(Rule $rule)`, `getRules()` and `removeRule($rule)` (which accepts either a `Rule` or a rule name; optionally suffixed by a dash to remove all related rules).
88
89 #### Rule
90
91 `Rule`s just have a string key (the rule) and a `Value`.
92
93 #### Value
94
95 `Value` is an abstract class that only defines the `render` method. The concrete subclasses for atomic value types are:
96
97 * `Size` – consists of a numeric `size` value and a unit.
98 * `Color` – colors can be input in the form #rrggbb, #rgb or schema(val1, val2, …) but are always stored as an array of ('s' => val1, 'c' => val2, 'h' => val3, …) and output in the second form.
99 * `CSSString` – this is just a wrapper for quoted strings to distinguish them from keywords; always output with double quotes.
100 * `URL` – URLs in CSS; always output in `URL("")` notation.
101
102 There is another abstract subclass of `Value`, `ValueList`: A `ValueList` represents a lists of `Value`s, separated by some separation character (mostly `,`, whitespace, or `/`).
103
104 There are two types of `ValueList`s:
105
106 * `RuleValueList` – The default type, used to represent all multivalued rules like `font: bold 12px/3 Helvetica, Verdana, sans-serif;` (where the value would be a whitespace-separated list of the primitive value `bold`, a slash-separated list and a comma-separated list).
107 * `CSSFunction` – A special kind of value that also contains a function name and where the values are the function’s arguments. Also handles equals-sign-separated argument lists like `filter: alpha(opacity=90);`.
108
109 #### Convenience methods
110
111 There are a few convenience methods on `Document` to ease finding, manipulating and deleting rules:
112
113 * `getAllDeclarationBlocks()` – does what it says; no matter how deeply nested the selectors are. Aliased as `getAllSelectors()`.
114 * `getAllRuleSets()` – does what it says; no matter how deeply nested the rule sets are.
115 * `getAllValues()` – finds all `Value` objects inside `Rule`s.
116
117 ## To-Do
118
119 * More convenience methods (like `selectorsWithElement($sId/Class/TagName)`, `attributesOfType($type)`, `removeAttributesOfType($type)`)
120 * Real multibyte support. Currently, only multibyte charsets whose first 255 code points take up only one byte and are identical with ASCII are supported (yes, UTF-8 fits this description).
121 * Named color support (using `Color` instead of an anonymous string literal)
122
123 ## Use cases
124
125 ### Use `Parser` to prepend an ID to all selectors
126
127 ```php
128 $myId = "#my_id";
129 $parser = new \Sabberworm\CSS\Parser($css);
130 $cssDocument = $parser->parse();
131 foreach ($cssDocument->getAllDeclarationBlocks() as $block) {
132 foreach ($block->getSelectors() as $selector) {
133 // Loop over all selector parts (the comma-separated strings in a
134 // selector) and prepend the ID.
135 $selector->setSelector($myId.' '.$selector->getSelector());
136 }
137 }
138 ```
139
140 ### Shrink all absolute sizes to half
141
142 ```php
143 $parser = new \Sabberworm\CSS\Parser($css);
144 $cssDocument = $parser->parse();
145 foreach ($cssDocument->getAllValues() as $value) {
146 if ($value instanceof CSSSize && !$value->isRelative()) {
147 $value->setSize($value->getSize() / 2);
148 }
149 }
150 ```
151
152 ### Remove unwanted rules
153
154 ```php
155 $parser = new \Sabberworm\CSS\Parser($css);
156 $cssDocument = $parser->parse();
157 foreach($cssDocument->getAllRuleSets() as $oRuleSet) {
158 // Note that the added dash will make this remove all rules starting with
159 // `font-` (like `font-size`, `font-weight`, etc.) as well as a potential
160 // `font` rule.
161 $oRuleSet->removeRule('font-');
162 $oRuleSet->removeRule('cursor');
163 }
164 ```
165
166 ### Output
167
168 To output the entire CSS document into a variable, just use `->render()`:
169
170 ```php
171 $parser = new \Sabberworm\CSS\Parser(file_get_contents('somefile.css'));
172 $cssDocument = $parser->parse();
173 print $cssDocument->render();
174 ```
175
176 If you want to format the output, pass an instance of type `\Sabberworm\CSS\OutputFormat`:
177
178 ```php
179 $format = \Sabberworm\CSS\OutputFormat::create()
180 ->indentWithSpaces(4)->setSpaceBetweenRules("\n");
181 print $cssDocument->render($format);
182 ```
183
184 Or use one of the predefined formats:
185
186 ```php
187 print $cssDocument->render(Sabberworm\CSS\OutputFormat::createPretty());
188 print $cssDocument->render(Sabberworm\CSS\OutputFormat::createCompact());
189 ```
190
191 To see what you can do with output formatting, look at the tests in `tests/OutputFormatTest.php`.
192
193 ## Examples
194
195 ### Example 1 (At-Rules)
196
197 #### Input
198
199 ```css
200 @charset "utf-8";
201
202 @font-face {
203 font-family: "CrassRoots";
204 src: url("../media/cr.ttf");
205 }
206
207 html, body {
208 font-size: 1.6em;
209 }
210
211 @keyframes mymove {
212 from { top: 0px; }
213 to { top: 200px; }
214 }
215
216 ```
217
218 <details>
219 <summary><b>Structure (<code>var_dump()</code>)</b></summary>
220
221 ```php
222 class Sabberworm\CSS\CSSList\Document#4 (2) {
223 protected $aContents =>
224 array(4) {
225 [0] =>
226 class Sabberworm\CSS\Property\Charset#6 (2) {
227 private $sCharset =>
228 class Sabberworm\CSS\Value\CSSString#5 (2) {
229 private $sString =>
230 string(5) "utf-8"
231 protected $iLineNo =>
232 int(1)
233 }
234 protected $iLineNo =>
235 int(1)
236 }
237 [1] =>
238 class Sabberworm\CSS\RuleSet\AtRuleSet#7 (4) {
239 private $sType =>
240 string(9) "font-face"
241 private $sArgs =>
242 string(0) ""
243 private $aRules =>
244 array(2) {
245 'font-family' =>
246 array(1) {
247 [0] =>
248 class Sabberworm\CSS\Rule\Rule#8 (4) {
249 private $sRule =>
250 string(11) "font-family"
251 private $mValue =>
252 class Sabberworm\CSS\Value\CSSString#9 (2) {
253 private $sString =>
254 string(10) "CrassRoots"
255 protected $iLineNo =>
256 int(4)
257 }
258 private $bIsImportant =>
259 bool(false)
260 protected $iLineNo =>
261 int(4)
262 }
263 }
264 'src' =>
265 array(1) {
266 [0] =>
267 class Sabberworm\CSS\Rule\Rule#10 (4) {
268 private $sRule =>
269 string(3) "src"
270 private $mValue =>
271 class Sabberworm\CSS\Value\URL#11 (2) {
272 private $oURL =>
273 class Sabberworm\CSS\Value\CSSString#12 (2) {
274 private $sString =>
275 string(15) "../media/cr.ttf"
276 protected $iLineNo =>
277 int(5)
278 }
279 protected $iLineNo =>
280 int(5)
281 }
282 private $bIsImportant =>
283 bool(false)
284 protected $iLineNo =>
285 int(5)
286 }
287 }
288 }
289 protected $iLineNo =>
290 int(3)
291 }
292 [2] =>
293 class Sabberworm\CSS\RuleSet\DeclarationBlock#13 (3) {
294 private $aSelectors =>
295 array(2) {
296 [0] =>
297 class Sabberworm\CSS\Property\Selector#14 (2) {
298 private $sSelector =>
299 string(4) "html"
300 private $iSpecificity =>
301 NULL
302 }
303 [1] =>
304 class Sabberworm\CSS\Property\Selector#15 (2) {
305 private $sSelector =>
306 string(4) "body"
307 private $iSpecificity =>
308 NULL
309 }
310 }
311 private $aRules =>
312 array(1) {
313 'font-size' =>
314 array(1) {
315 [0] =>
316 class Sabberworm\CSS\Rule\Rule#16 (4) {
317 private $sRule =>
318 string(9) "font-size"
319 private $mValue =>
320 class Sabberworm\CSS\Value\Size#17 (4) {
321 private $fSize =>
322 double(1.6)
323 private $sUnit =>
324 string(2) "em"
325 private $bIsColorComponent =>
326 bool(false)
327 protected $iLineNo =>
328 int(9)
329 }
330 private $bIsImportant =>
331 bool(false)
332 protected $iLineNo =>
333 int(9)
334 }
335 }
336 }
337 protected $iLineNo =>
338 int(8)
339 }
340 [3] =>
341 class Sabberworm\CSS\CSSList\KeyFrame#18 (4) {
342 private $vendorKeyFrame =>
343 string(9) "keyframes"
344 private $animationName =>
345 string(6) "mymove"
346 protected $aContents =>
347 array(2) {
348 [0] =>
349 class Sabberworm\CSS\RuleSet\DeclarationBlock#19 (3) {
350 private $aSelectors =>
351 array(1) {
352 [0] =>
353 class Sabberworm\CSS\Property\Selector#20 (2) {
354 private $sSelector =>
355 string(4) "from"
356 private $iSpecificity =>
357 NULL
358 }
359 }
360 private $aRules =>
361 array(1) {
362 'top' =>
363 array(1) {
364 [0] =>
365 class Sabberworm\CSS\Rule\Rule#21 (4) {
366 private $sRule =>
367 string(3) "top"
368 private $mValue =>
369 class Sabberworm\CSS\Value\Size#22 (4) {
370 private $fSize =>
371 double(0)
372 private $sUnit =>
373 string(2) "px"
374 private $bIsColorComponent =>
375 bool(false)
376 protected $iLineNo =>
377 int(13)
378 }
379 private $bIsImportant =>
380 bool(false)
381 protected $iLineNo =>
382 int(13)
383 }
384 }
385 }
386 protected $iLineNo =>
387 int(13)
388 }
389 [1] =>
390 class Sabberworm\CSS\RuleSet\DeclarationBlock#23 (3) {
391 private $aSelectors =>
392 array(1) {
393 [0] =>
394 class Sabberworm\CSS\Property\Selector#24 (2) {
395 private $sSelector =>
396 string(2) "to"
397 private $iSpecificity =>
398 NULL
399 }
400 }
401 private $aRules =>
402 array(1) {
403 'top' =>
404 array(1) {
405 [0] =>
406 class Sabberworm\CSS\Rule\Rule#25 (4) {
407 private $sRule =>
408 string(3) "top"
409 private $mValue =>
410 class Sabberworm\CSS\Value\Size#26 (4) {
411 private $fSize =>
412 double(200)
413 private $sUnit =>
414 string(2) "px"
415 private $bIsColorComponent =>
416 bool(false)
417 protected $iLineNo =>
418 int(14)
419 }
420 private $bIsImportant =>
421 bool(false)
422 protected $iLineNo =>
423 int(14)
424 }
425 }
426 }
427 protected $iLineNo =>
428 int(14)
429 }
430 }
431 protected $iLineNo =>
432 int(12)
433 }
434 }
435 protected $iLineNo =>
436 int(1)
437 }
438
439 ```
440 </details>
441
442 #### Output (`render()`)
443
444 ```css
445 @charset "utf-8";
446 @font-face {font-family: "CrassRoots";src: url("../media/cr.ttf");}
447 html, body {font-size: 1.6em;}
448 @keyframes mymove {from {top: 0px;} to {top: 200px;}}
449 ```
450
451 ### Example 2 (Values)
452
453 #### Input
454
455 ```css
456 #header {
457 margin: 10px 2em 1cm 2%;
458 font-family: Verdana, Helvetica, "Gill Sans", sans-serif;
459 color: red !important;
460 }
461
462 ```
463
464 <details>
465 <summary><b>Structure (<code>var_dump()</code>)</b></summary>
466
467 ```php
468 class Sabberworm\CSS\CSSList\Document#4 (2) {
469 protected $aContents =>
470 array(1) {
471 [0] =>
472 class Sabberworm\CSS\RuleSet\DeclarationBlock#5 (3) {
473 private $aSelectors =>
474 array(1) {
475 [0] =>
476 class Sabberworm\CSS\Property\Selector#6 (2) {
477 private $sSelector =>
478 string(7) "#header"
479 private $iSpecificity =>
480 NULL
481 }
482 }
483 private $aRules =>
484 array(3) {
485 'margin' =>
486 array(1) {
487 [0] =>
488 class Sabberworm\CSS\Rule\Rule#7 (4) {
489 private $sRule =>
490 string(6) "margin"
491 private $mValue =>
492 class Sabberworm\CSS\Value\RuleValueList#12 (3) {
493 protected $aComponents =>
494 array(4) {
495 [0] =>
496 class Sabberworm\CSS\Value\Size#8 (4) {
497 private $fSize =>
498 double(10)
499 private $sUnit =>
500 string(2) "px"
501 private $bIsColorComponent =>
502 bool(false)
503 protected $iLineNo =>
504 int(2)
505 }
506 [1] =>
507 class Sabberworm\CSS\Value\Size#9 (4) {
508 private $fSize =>
509 double(2)
510 private $sUnit =>
511 string(2) "em"
512 private $bIsColorComponent =>
513 bool(false)
514 protected $iLineNo =>
515 int(2)
516 }
517 [2] =>
518 class Sabberworm\CSS\Value\Size#10 (4) {
519 private $fSize =>
520 double(1)
521 private $sUnit =>
522 string(2) "cm"
523 private $bIsColorComponent =>
524 bool(false)
525 protected $iLineNo =>
526 int(2)
527 }
528 [3] =>
529 class Sabberworm\CSS\Value\Size#11 (4) {
530 private $fSize =>
531 double(2)
532 private $sUnit =>
533 string(1) "%"
534 private $bIsColorComponent =>
535 bool(false)
536 protected $iLineNo =>
537 int(2)
538 }
539 }
540 protected $sSeparator =>
541 string(1) " "
542 protected $iLineNo =>
543 int(2)
544 }
545 private $bIsImportant =>
546 bool(false)
547 protected $iLineNo =>
548 int(2)
549 }
550 }
551 'font-family' =>
552 array(1) {
553 [0] =>
554 class Sabberworm\CSS\Rule\Rule#13 (4) {
555 private $sRule =>
556 string(11) "font-family"
557 private $mValue =>
558 class Sabberworm\CSS\Value\RuleValueList#15 (3) {
559 protected $aComponents =>
560 array(4) {
561 [0] =>
562 string(7) "Verdana"
563 [1] =>
564 string(9) "Helvetica"
565 [2] =>
566 class Sabberworm\CSS\Value\CSSString#14 (2) {
567 private $sString =>
568 string(9) "Gill Sans"
569 protected $iLineNo =>
570 int(3)
571 }
572 [3] =>
573 string(10) "sans-serif"
574 }
575 protected $sSeparator =>
576 string(1) ","
577 protected $iLineNo =>
578 int(3)
579 }
580 private $bIsImportant =>
581 bool(false)
582 protected $iLineNo =>
583 int(3)
584 }
585 }
586 'color' =>
587 array(1) {
588 [0] =>
589 class Sabberworm\CSS\Rule\Rule#16 (4) {
590 private $sRule =>
591 string(5) "color"
592 private $mValue =>
593 string(3) "red"
594 private $bIsImportant =>
595 bool(true)
596 protected $iLineNo =>
597 int(4)
598 }
599 }
600 }
601 protected $iLineNo =>
602 int(1)
603 }
604 }
605 protected $iLineNo =>
606 int(1)
607 }
608
609 ```
610 </details>
611
612 #### Output (`render()`)
613
614 ```css
615 #header {margin: 10px 2em 1cm 2%;font-family: Verdana,Helvetica,"Gill Sans",sans-serif;color: red !important;}
616 ```
617
618 ## Contributors/Thanks to
619
620 * [](https://github.com/oliverkleeoliverklee](https://github.com/oliverklee](https://github.com/oliverklee) for lots of refactorings, code modernizations and CI integrations
621 * [](https://github.com/raxbgraxbg](https://github.com/raxbg](https://github.com/raxbg) for contributions to parse `calc`, grid lines, and various bugfixes.
622 * [](https://github.com/westonruterwestonruter](https://github.com/westonruter](https://github.com/westonruter) for bugfixes and improvements.
623 * [](https://github.com/FMCorzFMCorz](https://github.com/FMCorz](https://github.com/FMCorz) for many patches and suggestions, for being able to parse comments and IE hacks (in lenient mode).
624 * [](https://github.com/LullabotLullabot](https://github.com/Lullabot](https://github.com/Lullabot) for a patch that allows to know the line number for each parsed token.
625 * [](https://github.com/ju1iusju1ius](https://github.com/ju1ius](https://github.com/ju1ius) for the specificity parsing code and the ability to expand/compact shorthand properties.
626 * [](https://github.com/ossinkineossinkine](https://github.com/ossinkine](https://github.com/ossinkine) for a 150 time performance boost.
627 * [](https://github.com/GaryJonesGaryJones](https://github.com/GaryJones](https://github.com/GaryJones) for lots of input and [](https://css-specificity.info/https://css-specificity.info/](https://css-specificity.info/](https://css-specificity.info/).
628 * [](https://github.com/docteurkleindocteurklein](https://github.com/docteurklein](https://github.com/docteurklein) for output formatting and `CSSList->remove()` inspiration.
629 * [](https://github.com/nicolopignatellinicolopignatelli](https://github.com/nicolopignatelli](https://github.com/nicolopignatelli) for PSR-0 compatibility.
630 * [](https://github.com/diegoembarcaderodiegoembarcadero](https://github.com/diegoembarcadero](https://github.com/diegoembarcadero) for keyframe at-rule parsing.
631 * [](https://github.com/goetasgoetas](https://github.com/goetas](https://github.com/goetas) for @namespace at-rule support.
632 * [](https://github.com/sabberworm/PHP-CSS-Parser/contributorsView full list](https://github.com/sabberworm/PHP-CSS-Parser/contributors](https://github.com/sabberworm/PHP-CSS-Parser/contributors)
633
634 ## Misc
635
636 * Legacy Support: The latest pre-PSR-0 version of this project can be checked with the `0.9.0` tag.
637 * Running Tests: To run all unit tests for this project, run `composer install` to install phpunit and use `./vendor/bin/phpunit`.
638