Index of /wp-content/plugins/ditty-news-ticker/vendor/sabberworm/php-css-parser/
Name | Last Modified | Size |
---|---|---|
2025-07-22 17:33 | - | |
2025-07-22 17:33 | 9k | |
2025-07-22 17:33 | 3k | |
2025-07-22 17:33 | 2k |
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta charset="utf-8"/>
</head>
<body>
<h1 id="phpcssparser">PHP CSS Parser</h1>
<p><a href="https://github.com/sabberworm/PHP-CSS-Parser/actions/"><img src="https://github.com/sabberworm/PHP-CSS-Parser/workflows/CI/badge.svg?branch=master" alt="Build Status" /></a></p>
<p>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.</p>
<h2 id="usage">Usage</h2>
<h3 id="installationusingcomposer">Installation using Composer</h3>
<pre><code class="bash">composer require sabberworm/php-css-parser
</code></pre>
<h3 id="extraction">Extraction</h3>
<p>To use the CSS Parser, create a new instance. The constructor takes the following form:</p>
<pre><code class="php">new \Sabberworm\CSS\Parser($css);
</code></pre>
<p>To read a file, for example, you’d do the following:</p>
<pre><code class="php">$parser = new \Sabberworm\CSS\Parser(file_get_contents('somefile.css'));
$cssDocument = $parser->parse();
</code></pre>
<p>The resulting CSS document structure can be manipulated prior to being output.</p>
<h3 id="options">Options</h3>
<h4 id="charset">Charset</h4>
<p>The charset option is used only if no <code>@charset</code> declaration is found in the CSS file. 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.</p>
<pre><code class="php">$settings = \Sabberworm\CSS\Settings::create()
->withDefaultCharset('windows-1252');
$parser = new \Sabberworm\CSS\Parser($css, $settings);
</code></pre>
<h4 id="strictparsing">Strict parsing</h4>
<p>To have the parser choke on invalid rules, supply a thusly configured <code>\Sabberworm\CSS\Settings</code> object:</p>
<pre><code class="php">$parser = new \Sabberworm\CSS\Parser(
file_get_contents('somefile.css'),
\Sabberworm\CSS\Settings::create()->beStrict()
);
</code></pre>
<h4 id="disablemultibytefunctions">Disable multibyte functions</h4>
<p>To achieve faster parsing, you can choose to have PHP-CSS-Parser use regular string functions instead of <code>mb_*</code> 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.</p>
<pre><code class="php">$settings = \Sabberworm\CSS\Settings::create()->withMultibyteSupport(false);
$parser = new \Sabberworm\CSS\Parser($css, $settings);
</code></pre>
<h3 id="manipulation">Manipulation</h3>
<p>The resulting data structure consists mainly of five basic types: <code>CSSList</code>, <code>RuleSet</code>, <code>Rule</code>, <code>Selector</code> and <code>Value</code>. There are two additional types used: <code>Import</code> and <code>Charset</code>, which you won’t use often.</p>
<h4 id="csslist">CSSList</h4>
<p><code>CSSList</code> 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. <code>CSSList</code> has the following concrete subtypes:</p>
<ul>
<li><code>Document</code> – representing the root of a CSS file.</li>
<li><code>MediaQuery</code> – represents a subsection of a <code>CSSList</code> that only applies to an output device matching the contained media query.</li>
</ul>
<p>To access the items stored in a <code>CSSList</code> – like the document you got back when calling <code>$parser->parse()</code> –, use <code>getContents()</code>, then iterate over that collection and use instanceof to check whether you’re dealing with another <code>CSSList</code>, a <code>RuleSet</code>, a <code>Import</code> or a <code>Charset</code>.</p>
<p>To append a new item (selector, media query, etc.) to an existing <code>CSSList</code>, construct it using the constructor for this class and use the <code>append($oItem)</code> method.</p>
<h4 id="ruleset">RuleSet</h4>
<p><code>RuleSet</code> 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:</p>
<ul>
<li><code>AtRuleSet</code> – for generic at-rules which do not match the ones specifically mentioned like <code>@import</code>, <code>@charset</code> or <code>@media</code>. A common example for this is <code>@font-face</code>.</li>
<li><code>DeclarationBlock</code> – a <code>RuleSet</code> constrained by a <code>Selector</code>; contains an array of selector objects (comma-separated in the CSS) as well as the rules to be applied to the matching elements.</li>
</ul>
<p>Note: A <code>CSSList</code> can contain other <code>CSSList</code>s (and <code>Import</code>s as well as a <code>Charset</code>), while a <code>RuleSet</code> can only contain <code>Rule</code>s.</p>
<p>If you want to manipulate a <code>RuleSet</code>, use the methods <code>addRule(Rule $rule)</code>, <code>getRules()</code> and <code>removeRule($rule)</code> (which accepts either a <code>Rule</code> instance or a rule name; optionally suffixed by a dash to remove all related rules).</p>
<h4 id="rule">Rule</h4>
<p><code>Rule</code>s just have a key (the rule) and a value. These values are all instances of a <code>Value</code>.</p>
<h4 id="value">Value</h4>
<p><code>Value</code> is an abstract class that only defines the <code>render</code> method. The concrete subclasses for atomic value types are:</p>
<ul>
<li><code>Size</code> – consists of a numeric <code>size</code> value and a unit.</li>
<li><code>Color</code> – 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.</li>
<li><code>CSSString</code> – this is just a wrapper for quoted strings to distinguish them from keywords; always output with double quotes.</li>
<li><code>URL</code> – URLs in CSS; always output in URL(“”) notation.</li>
</ul>
<p>There is another abstract subclass of <code>Value</code>, <code>ValueList</code>. A <code>ValueList</code> represents a lists of <code>Value</code>s, separated by some separation character (mostly <code>,</code>, whitespace, or <code>/</code>). There are two types of <code>ValueList</code>s:</p>
<ul>
<li><code>RuleValueList</code> – The default type, used to represent all multi-valued rules like <code>font: bold 12px/3 Helvetica, Verdana, sans-serif;</code> (where the value would be a whitespace-separated list of the primitive value <code>bold</code>, a slash-separated list and a comma-separated list).</li>
<li><code>CSSFunction</code> – 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 <code>filter: alpha(opacity=90);</code>.</li>
</ul>
<h4 id="conveniencemethods">Convenience methods</h4>
<p>There are a few convenience methods on Document to ease finding, manipulating and deleting rules:</p>
<ul>
<li><code>getAllDeclarationBlocks()</code> – does what it says; no matter how deeply nested your selectors are. Aliased as <code>getAllSelectors()</code>.</li>
<li><code>getAllRuleSets()</code> – does what it says; no matter how deeply nested your rule sets are.</li>
<li><code>getAllValues()</code> – finds all <code>Value</code> objects inside <code>Rule</code>s.</li>
</ul>
<h2 id="to-do">To-Do</h2>
<ul>
<li>More convenience methods (like <code>selectorsWithElement($sId/Class/TagName)</code>, <code>attributesOfType($type)</code>, <code>removeAttributesOfType($type)</code>)</li>
<li>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).</li>
<li>Named color support (using <code>Color</code> instead of an anonymous string literal)</li>
</ul>
<h2 id="usecases">Use cases</h2>
<h3 id="useparsertoprependanidtoallselectors">Use <code>Parser</code> to prepend an ID to all selectors</h3>
<pre><code class="php">$myId = "#my_id";
$parser = new \Sabberworm\CSS\Parser($css);
$cssDocument = $parser->parse();
foreach ($cssDocument->getAllDeclarationBlocks() as $block) {
foreach ($block->getSelectors() as $selector) {
// Loop over all selector parts (the comma-separated strings in a
// selector) and prepend the ID.
$selector->setSelector($myId.' '.$selector->getSelector());
}
}
</code></pre>
<h3 id="shrinkallabsolutesizestohalf">Shrink all absolute sizes to half</h3>
<pre><code class="php">$parser = new \Sabberworm\CSS\Parser($css);
$cssDocument = $parser->parse();
foreach ($cssDocument->getAllValues() as $value) {
if ($value instanceof CSSSize && !$value->isRelative()) {
$value->setSize($value->getSize() / 2);
}
}
</code></pre>
<h3 id="removeunwantedrules">Remove unwanted rules</h3>
<pre><code class="php">$parser = new \Sabberworm\CSS\Parser($css);
$cssDocument = $parser->parse();
foreach($cssDocument->getAllRuleSets() as $oRuleSet) {
// Note that the added dash will make this remove all rules starting with
// `font-` (like `font-size`, `font-weight`, etc.) as well as a potential
// `font-rule`.
$oRuleSet->removeRule('font-');
$oRuleSet->removeRule('cursor');
}
</code></pre>
<h3 id="output">Output</h3>
<p>To output the entire CSS document into a variable, just use <code>->render()</code>:</p>
<pre><code class="php">$parser = new \Sabberworm\CSS\Parser(file_get_contents('somefile.css'));
$cssDocument = $parser->parse();
print $cssDocument->render();
</code></pre>
<p>If you want to format the output, pass an instance of type <code>\Sabberworm\CSS\OutputFormat</code>:</p>
<pre><code class="php">$format = \Sabberworm\CSS\OutputFormat::create()
->indentWithSpaces(4)->setSpaceBetweenRules("\n");
print $cssDocument->render($format);
</code></pre>
<p>Or use one of the predefined formats:</p>
<pre><code class="php">print $cssDocument->render(Sabberworm\CSS\OutputFormat::createPretty());
print $cssDocument->render(Sabberworm\CSS\OutputFormat::createCompact());
</code></pre>
<p>To see what you can do with output formatting, look at the tests in <code>tests/OutputFormatTest.php</code>.</p>
<h2 id="examples">Examples</h2>
<h3 id="example1at-rules">Example 1 (At-Rules)</h3>
<h4 id="input">Input</h4>
<pre><code class="css">@charset "utf-8";
@font-face {
font-family: "CrassRoots";
src: url("../media/cr.ttf");
}
html, body {
font-size: 1.6em;
}
@keyframes mymove {
from { top: 0px; }
to { top: 200px; }
}
</code></pre>
<h4 id="structurevar_dump">Structure (<code>var_dump()</code>)</h4>
<pre><code class="php">class Sabberworm\CSS\CSSList\Document#4 (2) {
protected $aContents =>
array(4) {
[0] =>
class Sabberworm\CSS\Property\Charset#6 (2) {
private $sCharset =>
class Sabberworm\CSS\Value\CSSString#5 (2) {
private $sString =>
string(5) "utf-8"
protected $iLineNo =>
int(1)
}
protected $iLineNo =>
int(1)
}
[1] =>
class Sabberworm\CSS\RuleSet\AtRuleSet#7 (4) {
private $sType =>
string(9) "font-face"
private $sArgs =>
string(0) ""
private $aRules =>
array(2) {
'font-family' =>
array(1) {
[0] =>
class Sabberworm\CSS\Rule\Rule#8 (4) {
private $sRule =>
string(11) "font-family"
private $mValue =>
class Sabberworm\CSS\Value\CSSString#9 (2) {
private $sString =>
string(10) "CrassRoots"
protected $iLineNo =>
int(4)
}
private $bIsImportant =>
bool(false)
protected $iLineNo =>
int(4)
}
}
'src' =>
array(1) {
[0] =>
class Sabberworm\CSS\Rule\Rule#10 (4) {
private $sRule =>
string(3) "src"
private $mValue =>
class Sabberworm\CSS\Value\URL#11 (2) {
private $oURL =>
class Sabberworm\CSS\Value\CSSString#12 (2) {
private $sString =>
string(15) "../media/cr.ttf"
protected $iLineNo =>
int(5)
}
protected $iLineNo =>
int(5)
}
private $bIsImportant =>
bool(false)
protected $iLineNo =>
int(5)
}
}
}
protected $iLineNo =>
int(3)
}
[2] =>
class Sabberworm\CSS\RuleSet\DeclarationBlock#13 (3) {
private $aSelectors =>
array(2) {
[0] =>
class Sabberworm\CSS\Property\Selector#14 (2) {
private $sSelector =>
string(4) "html"
private $iSpecificity =>
NULL
}
[1] =>
class Sabberworm\CSS\Property\Selector#15 (2) {
private $sSelector =>
string(4) "body"
private $iSpecificity =>
NULL
}
}
private $aRules =>
array(1) {
'font-size' =>
array(1) {
[0] =>
class Sabberworm\CSS\Rule\Rule#16 (4) {
private $sRule =>
string(9) "font-size"
private $mValue =>
class Sabberworm\CSS\Value\Size#17 (4) {
private $fSize =>
double(1.6)
private $sUnit =>
string(2) "em"
private $bIsColorComponent =>
bool(false)
protected $iLineNo =>
int(9)
}
private $bIsImportant =>
bool(false)
protected $iLineNo =>
int(9)
}
}
}
protected $iLineNo =>
int(8)
}
[3] =>
class Sabberworm\CSS\CSSList\KeyFrame#18 (4) {
private $vendorKeyFrame =>
string(9) "keyframes"
private $animationName =>
string(6) "mymove"
protected $aContents =>
array(2) {
[0] =>
class Sabberworm\CSS\RuleSet\DeclarationBlock#19 (3) {
private $aSelectors =>
array(1) {
[0] =>
class Sabberworm\CSS\Property\Selector#20 (2) {
private $sSelector =>
string(4) "from"
private $iSpecificity =>
NULL
}
}
private $aRules =>
array(1) {
'top' =>
array(1) {
[0] =>
class Sabberworm\CSS\Rule\Rule#21 (4) {
private $sRule =>
string(3) "top"
private $mValue =>
class Sabberworm\CSS\Value\Size#22 (4) {
private $fSize =>
double(0)
private $sUnit =>
string(2) "px"
private $bIsColorComponent =>
bool(false)
protected $iLineNo =>
int(13)
}
private $bIsImportant =>
bool(false)
protected $iLineNo =>
int(13)
}
}
}
protected $iLineNo =>
int(13)
}
[1] =>
class Sabberworm\CSS\RuleSet\DeclarationBlock#23 (3) {
private $aSelectors =>
array(1) {
[0] =>
class Sabberworm\CSS\Property\Selector#24 (2) {
private $sSelector =>
string(2) "to"
private $iSpecificity =>
NULL
}
}
private $aRules =>
array(1) {
'top' =>
array(1) {
[0] =>
class Sabberworm\CSS\Rule\Rule#25 (4) {
private $sRule =>
string(3) "top"
private $mValue =>
class Sabberworm\CSS\Value\Size#26 (4) {
private $fSize =>
double(200)
private $sUnit =>
string(2) "px"
private $bIsColorComponent =>
bool(false)
protected $iLineNo =>
int(14)
}
private $bIsImportant =>
bool(false)
protected $iLineNo =>
int(14)
}
}
}
protected $iLineNo =>
int(14)
}
}
protected $iLineNo =>
int(12)
}
}
protected $iLineNo =>
int(1)
}
</code></pre>
<h4 id="outputrender">Output (<code>render()</code>)</h4>
<pre><code class="css">@charset "utf-8";
@font-face {font-family: "CrassRoots";src: url("../media/cr.ttf");}
html, body {font-size: 1.6em;}
@keyframes mymove {from {top: 0px;} to {top: 200px;}}
</code></pre>
<h3 id="example2values">Example 2 (Values)</h3>
<h4 id="input">Input</h4>
<pre><code class="css">#header {
margin: 10px 2em 1cm 2%;
font-family: Verdana, Helvetica, "Gill Sans", sans-serif;
color: red !important;
}
</code></pre>
<h4 id="structurevar_dump">Structure (<code>var_dump()</code>)</h4>
<pre><code class="php">class Sabberworm\CSS\CSSList\Document#4 (2) {
protected $aContents =>
array(1) {
[0] =>
class Sabberworm\CSS\RuleSet\DeclarationBlock#5 (3) {
private $aSelectors =>
array(1) {
[0] =>
class Sabberworm\CSS\Property\Selector#6 (2) {
private $sSelector =>
string(7) "#header"
private $iSpecificity =>
NULL
}
}
private $aRules =>
array(3) {
'margin' =>
array(1) {
[0] =>
class Sabberworm\CSS\Rule\Rule#7 (4) {
private $sRule =>
string(6) "margin"
private $mValue =>
class Sabberworm\CSS\Value\RuleValueList#12 (3) {
protected $aComponents =>
array(4) {
[0] =>
class Sabberworm\CSS\Value\Size#8 (4) {
private $fSize =>
double(10)
private $sUnit =>
string(2) "px"
private $bIsColorComponent =>
bool(false)
protected $iLineNo =>
int(2)
}
[1] =>
class Sabberworm\CSS\Value\Size#9 (4) {
private $fSize =>
double(2)
private $sUnit =>
string(2) "em"
private $bIsColorComponent =>
bool(false)
protected $iLineNo =>
int(2)
}
[2] =>
class Sabberworm\CSS\Value\Size#10 (4) {
private $fSize =>
double(1)
private $sUnit =>
string(2) "cm"
private $bIsColorComponent =>
bool(false)
protected $iLineNo =>
int(2)
}
[3] =>
class Sabberworm\CSS\Value\Size#11 (4) {
private $fSize =>
double(2)
private $sUnit =>
string(1) "%"
private $bIsColorComponent =>
bool(false)
protected $iLineNo =>
int(2)
}
}
protected $sSeparator =>
string(1) " "
protected $iLineNo =>
int(2)
}
private $bIsImportant =>
bool(false)
protected $iLineNo =>
int(2)
}
}
'font-family' =>
array(1) {
[0] =>
class Sabberworm\CSS\Rule\Rule#13 (4) {
private $sRule =>
string(11) "font-family"
private $mValue =>
class Sabberworm\CSS\Value\RuleValueList#15 (3) {
protected $aComponents =>
array(4) {
[0] =>
string(7) "Verdana"
[1] =>
string(9) "Helvetica"
[2] =>
class Sabberworm\CSS\Value\CSSString#14 (2) {
private $sString =>
string(9) "Gill Sans"
protected $iLineNo =>
int(3)
}
[3] =>
string(10) "sans-serif"
}
protected $sSeparator =>
string(1) ","
protected $iLineNo =>
int(3)
}
private $bIsImportant =>
bool(false)
protected $iLineNo =>
int(3)
}
}
'color' =>
array(1) {
[0] =>
class Sabberworm\CSS\Rule\Rule#16 (4) {
private $sRule =>
string(5) "color"
private $mValue =>
string(3) "red"
private $bIsImportant =>
bool(true)
protected $iLineNo =>
int(4)
}
}
}
protected $iLineNo =>
int(1)
}
}
protected $iLineNo =>
int(1)
}
</code></pre>
<h4 id="outputrender">Output (<code>render()</code>)</h4>
<pre><code class="css">#header {margin: 10px 2em 1cm 2%;font-family: Verdana,Helvetica,"Gill Sans",sans-serif;color: red !important;}
</code></pre>
<h2 id="contributorsthanksto">Contributors/Thanks to</h2>
<ul>
<li><a href="https://github.com/oliverklee">oliverklee</a> for lots of refactorings, code modernizations and CI integrations</li>
<li><a href="https://github.com/raxbg">raxbg</a> for contributions to parse <code>calc</code>, grid lines, and various bugfixes.</li>
<li><a href="https://github.com/westonruter">westonruter</a> for bugfixes and improvements.</li>
<li><a href="https://github.com/FMCorz">FMCorz</a> for many patches and suggestions, for being able to parse comments and IE hacks (in lenient mode).</li>
<li><a href="https://github.com/Lullabot">Lullabot</a> for a patch that allows to know the line number for each parsed token.</li>
<li><a href="https://github.com/ju1ius">ju1ius</a> for the specificity parsing code and the ability to expand/compact shorthand properties.</li>
<li><a href="https://github.com/ossinkine">ossinkine</a> for a 150 time performance boost.</li>
<li><a href="https://github.com/GaryJones">GaryJones</a> for lots of input and <a href="https://css-specificity.info/">https://css-specificity.info/</a>.</li>
<li><a href="https://github.com/docteurklein">docteurklein</a> for output formatting and <code>CSSList->remove()</code> inspiration.</li>
<li><a href="https://github.com/nicolopignatelli">nicolopignatelli</a> for PSR-0 compatibility.</li>
<li><a href="https://github.com/diegoembarcadero">diegoembarcadero</a> for keyframe at-rule parsing.</li>
<li><a href="https://github.com/goetas">goetas</a> for @namespace at-rule support.</li>
<li><a href="https://github.com/sabberworm/PHP-CSS-Parser/contributors">View full list</a></li>
</ul>
<h2 id="misc">Misc</h2>
<ul>
<li>Legacy Support: The latest pre-PSR-0 version of this project can be checked with the <code>0.9.0</code> tag.</li>
<li>Running Tests: To run all unit tests for this project, run <code>composer install</code> to install phpunit and use <code>./vendor/bin/phpunit</code>.</li>
</ul>
</body>
</html>
Proudly Served by LiteSpeed Web Server at www.internationalairportreview.com Port 443