First commit
This commit is contained in:
commit
c6e2478c40
13918 changed files with 2303184 additions and 0 deletions
9
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/.travis.yml
vendored
Normal file
9
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/.travis.yml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
language: php
|
||||
php:
|
||||
- "5.4"
|
||||
- "5.3"
|
||||
- "5.5"
|
||||
- "5.6"
|
||||
- hhvm
|
||||
script: phpunit .
|
||||
|
154
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/CHANGELOG.md
vendored
Normal file
154
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
# Revision History
|
||||
|
||||
## 6.0
|
||||
|
||||
### 6.0.0 (2014-07-03)
|
||||
|
||||
* Format output using Sabberworm\CSS\OutputFormat
|
||||
* *No backwards-incompatible changes*
|
||||
|
||||
#### Deprecations
|
||||
|
||||
* The parse() method replaces __toString with an optional argument (instance of the OutputFormat class)
|
||||
|
||||
### 6.0.1 (2014-08-24)
|
||||
|
||||
* Remove some declarations in interfaces incompatible with PHP 5.3 (< 5.3.9)
|
||||
* *No deprecations*
|
||||
|
||||
## 5.0
|
||||
|
||||
### 5.0.0 (2013-03-20)
|
||||
|
||||
* Correctly parse all known CSS 3 units (including Hz and kHz).
|
||||
* Output RGB colors in short (#aaa or #ababab) notation
|
||||
* Be case-insensitive when parsing identifiers.
|
||||
* *No deprecations*
|
||||
|
||||
#### Backwards-incompatible changes
|
||||
|
||||
* `Sabberworm\CSS\Value\Color`’s `__toString` method overrides `CSSList`’s to maybe return something other than `type(value, …)` (see above).
|
||||
|
||||
### 5.0.1 (2013-03-20)
|
||||
|
||||
* Internal cleanup
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.0.2 (2013-03-21)
|
||||
|
||||
* CHANGELOG.md file added to distribution
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.0.3 (2013-03-21)
|
||||
|
||||
* More size units recognized
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.0.4 (2013-03-21)
|
||||
|
||||
* Don’t output floats with locale-aware separator chars
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.0.5 (2013-04-17)
|
||||
|
||||
* Initial support for lenient parsing (setting this parser option will catch some exceptions internally and recover the parser’s state as neatly as possible).
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.0.6 (2013-05-31)
|
||||
|
||||
* Fix broken unit test
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.0.7 (2013-08-04)
|
||||
|
||||
* Fix broken decimal point output optimization
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.0.8 (2013-08-15)
|
||||
|
||||
* Make default settings’ multibyte parsing option dependent on whether or not the mbstring extension is actually installed.
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.1.0 (2013-10-24)
|
||||
|
||||
* Performance enhancements by Michael M Slusarz
|
||||
* More rescue entry points for lenient parsing (unexpected tokens between declaration blocks and unclosed comments)
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.1.1 (2013-10-28)
|
||||
|
||||
* Updated CHANGELOG.md to reflect changes since 5.0.4
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.1.2 (2013-10-30)
|
||||
|
||||
* Remove the use of consumeUntil in comment parsing. This makes it possible to parse comments such as “/** Perfectly valid **/”
|
||||
* *No backwards-incompatible changes*
|
||||
* *No deprecations*
|
||||
|
||||
### 5.2.0 (2014-06-30)
|
||||
|
||||
* Support removing a selector from a declaration block using `$oBlock->removeSelector($mSelector)`
|
||||
* Introduce a specialized exception (Sabberworm\CSS\Parsing\OuputException) for exceptions during output rendering
|
||||
|
||||
* *No deprecations*
|
||||
|
||||
#### Backwards-incompatible changes
|
||||
|
||||
* Outputting a declaration block that has no selectors throws an OuputException instead of outputting an invalid ` {…}` into the CSS document.
|
||||
|
||||
## 4.0
|
||||
|
||||
### 4.0.0 (2013-03-19)
|
||||
|
||||
* Support for more @-rules
|
||||
* Generic interface `Sabberworm\CSS\Property\AtRule`, implemented by all @-rule classes
|
||||
* *No deprecations*
|
||||
|
||||
#### Backwards-incompatible changes
|
||||
|
||||
* `Sabberworm\CSS\RuleSet\AtRule` renamed to `Sabberworm\CSS\RuleSet\AtRuleSet`
|
||||
* `Sabberworm\CSS\CSSList\MediaQuery` renamed to `Sabberworm\CSS\RuleSet\CSSList\AtRuleBlockList` with differing semantics and API (which also works for other block-list-based @-rules like `@supports`).
|
||||
|
||||
## 3.0
|
||||
|
||||
### 3.0.0 (2013-03-06)
|
||||
|
||||
* Support for lenient parsing (on by default)
|
||||
* *No deprecations*
|
||||
|
||||
#### Backwards-incompatible changes
|
||||
|
||||
* All properties (like whether or not to use `mb_`-functions, which default charset to use and – new – whether or not to be forgiving when parsing) are now encapsulated in an instance of `Sabberworm\CSS\Settings` which can be passed as the second argument to `Sabberworm\CSS\Parser->__construct()`.
|
||||
* Specifying a charset as the second argument to `Sabberworm\CSS\Parser->__construct()` is no longer supported. Use `Sabberworm\CSS\Settings::create()->withDefaultCharset('some-charset')` instead.
|
||||
* Setting `Sabberworm\CSS\Parser->bUseMbFunctions` has no effect. Use `Sabberworm\CSS\Settings::create()->withMultibyteSupport(true/false)` instead.
|
||||
* `Sabberworm\CSS\Parser->parse()` may throw a `Sabberworm\CSS\Parsing\UnexpectedTokenException` when in strict parsing mode.
|
||||
|
||||
## 2.0
|
||||
|
||||
### 2.0.0 (2013-01-29)
|
||||
|
||||
* Allow multiple rules of the same type per rule set
|
||||
|
||||
#### Backwards-incompatible changes
|
||||
|
||||
* `Sabberworm\CSS\RuleSet->getRules()` returns an index-based array instead of an associative array. Use `Sabberworm\CSS\RuleSet->getRulesAssoc()` (which eliminates duplicate rules and lets the later rule of the same name win).
|
||||
* `Sabberworm\CSS\RuleSet->removeRule()` works as it did before except when passed an instance of `Sabberworm\CSS\Rule\Rule`, in which case it would only remove the exact rule given instead of all the rules of the same type. To get the old behaviour, use `Sabberworm\CSS\RuleSet->removeRule($oRule->getRule()`;
|
||||
|
||||
## 1.0
|
||||
|
||||
Initial release of a stable public API.
|
||||
|
||||
## 0.9
|
||||
|
||||
Last version not to use PSR-0 project organization semantics.
|
2310
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/Doxyfile
vendored
Normal file
2310
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/Doxyfile
vendored
Normal file
File diff suppressed because it is too large
Load diff
532
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/README.md
vendored
Normal file
532
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/README.md
vendored
Normal file
|
@ -0,0 +1,532 @@
|
|||
PHP CSS Parser
|
||||
--------------
|
||||
|
||||
[](https://travis-ci.org/sabberworm/PHP-CSS-Parser) [](http://hhvm.h4cc.de/package/sabberworm/php-css-parser)
|
||||
|
||||
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.
|
||||
|
||||
## Usage
|
||||
|
||||
### Installation using composer
|
||||
|
||||
Add php-css-parser to your composer.json
|
||||
|
||||
{
|
||||
"require": {
|
||||
"sabberworm/php-css-parser": "*"
|
||||
}
|
||||
}
|
||||
|
||||
### Extraction
|
||||
|
||||
To use the CSS Parser, create a new instance. The constructor takes the following form:
|
||||
|
||||
new Sabberworm\CSS\Parser($sText);
|
||||
|
||||
To read a file, for example, you’d do the following:
|
||||
|
||||
$oCssParser = new Sabberworm\CSS\Parser(file_get_contents('somefile.css'));
|
||||
$oCssDocument = $oCssParser->parse();
|
||||
|
||||
The resulting CSS document structure can be manipulated prior to being output.
|
||||
|
||||
### Options
|
||||
|
||||
#### Charset
|
||||
|
||||
The charset option is used only if no @charset 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.
|
||||
|
||||
$oSettings = Sabberworm\CSS\Settings::create()->withDefaultCharset('windows-1252');
|
||||
new Sabberworm\CSS\Parser($sText, $oSettings);
|
||||
|
||||
#### Strict parsing
|
||||
|
||||
To have the parser choke on invalid rules, supply a thusly configured Sabberworm\CSS\Settings object:
|
||||
|
||||
$oCssParser = new Sabberworm\CSS\Parser(file_get_contents('somefile.css'), Sabberworm\CSS\Settings::create()->beStrict());
|
||||
|
||||
#### Disable multibyte functions
|
||||
|
||||
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 to use this with input you have no control over as it’s not thoroughly covered by test cases.
|
||||
|
||||
$oSettings = Sabberworm\CSS\Settings::create()->withMultibyteSupport(false);
|
||||
new Sabberworm\CSS\Parser($sText, $oSettings);
|
||||
|
||||
### Manipulation
|
||||
|
||||
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.
|
||||
|
||||
#### CSSList
|
||||
|
||||
`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. `CSSList` has the following concrete subtypes:
|
||||
|
||||
* `Document` – representing the root of a CSS file.
|
||||
* `MediaQuery` – represents a subsection of a CSSList that only applies to a output device matching the contained media query.
|
||||
|
||||
To access the items stored in a `CSSList` – like the document you got back when calling `$oCssParser->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`.
|
||||
|
||||
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.
|
||||
|
||||
#### RuleSet
|
||||
|
||||
`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:
|
||||
|
||||
* `AtRuleSet` – for generic at-rules which do not match the ones specifically mentioned like @import, @charset or @media. A common example for this is @font-face.
|
||||
* `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.
|
||||
|
||||
Note: A `CSSList` can contain other `CSSList`s (and `Import`s as well as a `Charset`) while a `RuleSet` can only contain `Rule`s.
|
||||
|
||||
If you want to manipulate a `RuleSet`, use the methods `addRule(Rule $oRule)`, `getRules()` and `removeRule($mRule)` (which accepts either a Rule instance or a rule name; optionally suffixed by a dash to remove all related rules).
|
||||
|
||||
#### Rule
|
||||
|
||||
`Rule`s just have a key (the rule) and a value. These values are all instances of a `Value`.
|
||||
|
||||
#### Value
|
||||
|
||||
`Value` is an abstract class that only defines the `render` method. The concrete subclasses for atomic value types are:
|
||||
|
||||
* `Size` – consists of a numeric `size` value and a unit.
|
||||
* `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.
|
||||
* `String` – this is just a wrapper for quoted strings to distinguish them from keywords; always output with double quotes.
|
||||
* `URL` – URLs in CSS; always output in URL("") notation.
|
||||
|
||||
There is another abstract subclass of `Value`, `ValueList`. A `ValueList` represents a lists of `Value`s, separated by some separation character (mostly `,`, whitespace, or `/`). There are two types of `ValueList`s:
|
||||
|
||||
* `RuleValueList` – The default type, used to represent all multi-valued 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).
|
||||
* `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);`.
|
||||
|
||||
#### Convenience methods
|
||||
|
||||
There are a few convenience methods on Document to ease finding, manipulating and deleting rules:
|
||||
|
||||
* `getAllDeclarationBlocks()` – does what it says; no matter how deeply nested your selectors are. Aliased as `getAllSelectors()`.
|
||||
* `getAllRuleSets()` – does what it says; no matter how deeply nested your rule sets are.
|
||||
* `getAllValues()` – finds all `Value` objects inside `Rule`s.
|
||||
|
||||
## To-Do
|
||||
|
||||
* More convenience methods [like `selectorsWithElement($sId/Class/TagName)`, `attributesOfType($sType)`, `removeAttributesOfType($sType)`]
|
||||
* 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).
|
||||
* Named color support (using `Color` instead of an anonymous string literal)
|
||||
|
||||
## Use cases
|
||||
|
||||
### Use `Parser` to prepend an id to all selectors
|
||||
|
||||
$sMyId = "#my_id";
|
||||
$oParser = new Sabberworm\CSS\Parser($sText);
|
||||
$oCss = $oParser->parse();
|
||||
foreach($oCss->getAllDeclarationBlocks() as $oBlock) {
|
||||
foreach($oBlock->getSelectors() as $oSelector) {
|
||||
//Loop over all selector parts (the comma-separated strings in a selector) and prepend the id
|
||||
$oSelector->setSelector($sMyId.' '.$oSelector->getSelector());
|
||||
}
|
||||
}
|
||||
|
||||
### Shrink all absolute sizes to half
|
||||
|
||||
$oParser = new Sabberworm\CSS\Parser($sText);
|
||||
$oCss = $oParser->parse();
|
||||
foreach($oCss->getAllValues() as $mValue) {
|
||||
if($mValue instanceof CSSSize && !$mValue->isRelative()) {
|
||||
$mValue->setSize($mValue->getSize()/2);
|
||||
}
|
||||
}
|
||||
|
||||
### Remove unwanted rules
|
||||
|
||||
$oParser = new Sabberworm\CSS\Parser($sText);
|
||||
$oCss = $oParser->parse();
|
||||
foreach($oCss->getAllRuleSets() as $oRuleSet) {
|
||||
$oRuleSet->removeRule('font-'); //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('cursor');
|
||||
}
|
||||
|
||||
### Output
|
||||
|
||||
To output the entire CSS document into a variable, just use `->render()`:
|
||||
|
||||
$oCssParser = new Sabberworm\CSS\Parser(file_get_contents('somefile.css'));
|
||||
$oCssDocument = $oCssParser->parse();
|
||||
print $oCssDocument->render();
|
||||
|
||||
If you want to format the output, pass an instance of type `Sabberworm\CSS\OutputFormat`:
|
||||
|
||||
$oFormat = Sabberworm\CSS\OutputFormat::create()->indentWithSpaces(4)->setSpaceBetweenRules("\n");
|
||||
print $oCssDocument->render($oFormat);
|
||||
|
||||
Or use one of the predefined formats:
|
||||
|
||||
print $oCssDocument->render(Sabberworm\CSS\OutputFormat::createPretty());
|
||||
print $oCssDocument->render(Sabberworm\CSS\OutputFormat::createCompact());
|
||||
|
||||
To see what you can do with output formatting, look at the tests in `tests/Sabberworm/CSS/OutputFormatTest.php`.
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1 (At-Rules)
|
||||
|
||||
#### Input
|
||||
|
||||
@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; }
|
||||
}
|
||||
|
||||
#### Structure (`var_dump()`)
|
||||
|
||||
object(Sabberworm\CSS\CSSList\Document)#4 (1) {
|
||||
["aContents":protected]=>
|
||||
array(4) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Property\Charset)#6 (1) {
|
||||
["sCharset":"Sabberworm\CSS\Property\Charset":private]=>
|
||||
object(Sabberworm\CSS\Value\String)#5 (1) {
|
||||
["sString":"Sabberworm\CSS\Value\String":private]=>
|
||||
string(5) "utf-8"
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
object(Sabberworm\CSS\RuleSet\AtRuleSet)#7 (2) {
|
||||
["sType":"Sabberworm\CSS\RuleSet\AtRuleSet":private]=>
|
||||
string(9) "font-face"
|
||||
["aRules":"Sabberworm\CSS\RuleSet\RuleSet":private]=>
|
||||
array(2) {
|
||||
["font-family"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Rule\Rule)#8 (3) {
|
||||
["sRule":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
string(11) "font-family"
|
||||
["mValue":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
object(Sabberworm\CSS\Value\String)#9 (1) {
|
||||
["sString":"Sabberworm\CSS\Value\String":private]=>
|
||||
string(10) "CrassRoots"
|
||||
}
|
||||
["bIsImportant":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
bool(false)
|
||||
}
|
||||
}
|
||||
["src"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Rule\Rule)#10 (3) {
|
||||
["sRule":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
string(3) "src"
|
||||
["mValue":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
object(Sabberworm\CSS\Value\URL)#11 (1) {
|
||||
["oURL":"Sabberworm\CSS\Value\URL":private]=>
|
||||
object(Sabberworm\CSS\Value\String)#12 (1) {
|
||||
["sString":"Sabberworm\CSS\Value\String":private]=>
|
||||
string(15) "../media/cr.ttf"
|
||||
}
|
||||
}
|
||||
["bIsImportant":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[2]=>
|
||||
object(Sabberworm\CSS\RuleSet\DeclarationBlock)#13 (2) {
|
||||
["aSelectors":"Sabberworm\CSS\RuleSet\DeclarationBlock":private]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Property\Selector)#14 (2) {
|
||||
["sSelector":"Sabberworm\CSS\Property\Selector":private]=>
|
||||
string(4) "html"
|
||||
["iSpecificity":"Sabberworm\CSS\Property\Selector":private]=>
|
||||
NULL
|
||||
}
|
||||
[1]=>
|
||||
object(Sabberworm\CSS\Property\Selector)#15 (2) {
|
||||
["sSelector":"Sabberworm\CSS\Property\Selector":private]=>
|
||||
string(4) "body"
|
||||
["iSpecificity":"Sabberworm\CSS\Property\Selector":private]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
["aRules":"Sabberworm\CSS\RuleSet\RuleSet":private]=>
|
||||
array(1) {
|
||||
["font-size"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Rule\Rule)#16 (3) {
|
||||
["sRule":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
string(9) "font-size"
|
||||
["mValue":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
object(Sabberworm\CSS\Value\Size)#17 (3) {
|
||||
["fSize":"Sabberworm\CSS\Value\Size":private]=>
|
||||
float(1.6)
|
||||
["sUnit":"Sabberworm\CSS\Value\Size":private]=>
|
||||
string(2) "em"
|
||||
["bIsColorComponent":"Sabberworm\CSS\Value\Size":private]=>
|
||||
bool(false)
|
||||
}
|
||||
["bIsImportant":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[3]=>
|
||||
object(Sabberworm\CSS\CSSList\KeyFrame)#18 (3) {
|
||||
["vendorKeyFrame":"Sabberworm\CSS\CSSList\KeyFrame":private]=>
|
||||
string(9) "keyframes"
|
||||
["animationName":"Sabberworm\CSS\CSSList\KeyFrame":private]=>
|
||||
string(6) "mymove"
|
||||
["aContents":protected]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\RuleSet\DeclarationBlock)#19 (2) {
|
||||
["aSelectors":"Sabberworm\CSS\RuleSet\DeclarationBlock":private]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Property\Selector)#20 (2) {
|
||||
["sSelector":"Sabberworm\CSS\Property\Selector":private]=>
|
||||
string(4) "from"
|
||||
["iSpecificity":"Sabberworm\CSS\Property\Selector":private]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
["aRules":"Sabberworm\CSS\RuleSet\RuleSet":private]=>
|
||||
array(1) {
|
||||
["top"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Rule\Rule)#21 (3) {
|
||||
["sRule":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
string(3) "top"
|
||||
["mValue":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
object(Sabberworm\CSS\Value\Size)#22 (3) {
|
||||
["fSize":"Sabberworm\CSS\Value\Size":private]=>
|
||||
float(0)
|
||||
["sUnit":"Sabberworm\CSS\Value\Size":private]=>
|
||||
string(2) "px"
|
||||
["bIsColorComponent":"Sabberworm\CSS\Value\Size":private]=>
|
||||
bool(false)
|
||||
}
|
||||
["bIsImportant":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
object(Sabberworm\CSS\RuleSet\DeclarationBlock)#23 (2) {
|
||||
["aSelectors":"Sabberworm\CSS\RuleSet\DeclarationBlock":private]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Property\Selector)#24 (2) {
|
||||
["sSelector":"Sabberworm\CSS\Property\Selector":private]=>
|
||||
string(2) "to"
|
||||
["iSpecificity":"Sabberworm\CSS\Property\Selector":private]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
["aRules":"Sabberworm\CSS\RuleSet\RuleSet":private]=>
|
||||
array(1) {
|
||||
["top"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Rule\Rule)#25 (3) {
|
||||
["sRule":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
string(3) "top"
|
||||
["mValue":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
object(Sabberworm\CSS\Value\Size)#26 (3) {
|
||||
["fSize":"Sabberworm\CSS\Value\Size":private]=>
|
||||
float(200)
|
||||
["sUnit":"Sabberworm\CSS\Value\Size":private]=>
|
||||
string(2) "px"
|
||||
["bIsColorComponent":"Sabberworm\CSS\Value\Size":private]=>
|
||||
bool(false)
|
||||
}
|
||||
["bIsImportant":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#### Output (`render()`)
|
||||
|
||||
@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;}
|
||||
}
|
||||
|
||||
### Example 2 (Values)
|
||||
|
||||
#### Input
|
||||
|
||||
#header {
|
||||
margin: 10px 2em 1cm 2%;
|
||||
font-family: Verdana, Helvetica, "Gill Sans", sans-serif;
|
||||
color: red !important;
|
||||
}
|
||||
|
||||
#### Structure (`var_dump()`)
|
||||
|
||||
object(Sabberworm\CSS\CSSList\Document)#4 (1) {
|
||||
["aContents":protected]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\RuleSet\DeclarationBlock)#5 (2) {
|
||||
["aSelectors":"Sabberworm\CSS\RuleSet\DeclarationBlock":private]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Property\Selector)#6 (2) {
|
||||
["sSelector":"Sabberworm\CSS\Property\Selector":private]=>
|
||||
string(7) "#header"
|
||||
["iSpecificity":"Sabberworm\CSS\Property\Selector":private]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
["aRules":"Sabberworm\CSS\RuleSet\RuleSet":private]=>
|
||||
array(3) {
|
||||
["margin"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Rule\Rule)#7 (3) {
|
||||
["sRule":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
string(6) "margin"
|
||||
["mValue":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
object(Sabberworm\CSS\Value\RuleValueList)#12 (2) {
|
||||
["aComponents":protected]=>
|
||||
array(4) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Value\Size)#8 (3) {
|
||||
["fSize":"Sabberworm\CSS\Value\Size":private]=>
|
||||
float(10)
|
||||
["sUnit":"Sabberworm\CSS\Value\Size":private]=>
|
||||
string(2) "px"
|
||||
["bIsColorComponent":"Sabberworm\CSS\Value\Size":private]=>
|
||||
bool(false)
|
||||
}
|
||||
[1]=>
|
||||
object(Sabberworm\CSS\Value\Size)#9 (3) {
|
||||
["fSize":"Sabberworm\CSS\Value\Size":private]=>
|
||||
float(2)
|
||||
["sUnit":"Sabberworm\CSS\Value\Size":private]=>
|
||||
string(2) "em"
|
||||
["bIsColorComponent":"Sabberworm\CSS\Value\Size":private]=>
|
||||
bool(false)
|
||||
}
|
||||
[2]=>
|
||||
object(Sabberworm\CSS\Value\Size)#10 (3) {
|
||||
["fSize":"Sabberworm\CSS\Value\Size":private]=>
|
||||
float(1)
|
||||
["sUnit":"Sabberworm\CSS\Value\Size":private]=>
|
||||
string(2) "cm"
|
||||
["bIsColorComponent":"Sabberworm\CSS\Value\Size":private]=>
|
||||
bool(false)
|
||||
}
|
||||
[3]=>
|
||||
object(Sabberworm\CSS\Value\Size)#11 (3) {
|
||||
["fSize":"Sabberworm\CSS\Value\Size":private]=>
|
||||
float(2)
|
||||
["sUnit":"Sabberworm\CSS\Value\Size":private]=>
|
||||
string(1) "%"
|
||||
["bIsColorComponent":"Sabberworm\CSS\Value\Size":private]=>
|
||||
bool(false)
|
||||
}
|
||||
}
|
||||
["sSeparator":protected]=>
|
||||
string(1) " "
|
||||
}
|
||||
["bIsImportant":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
bool(false)
|
||||
}
|
||||
}
|
||||
["font-family"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Rule\Rule)#13 (3) {
|
||||
["sRule":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
string(11) "font-family"
|
||||
["mValue":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
object(Sabberworm\CSS\Value\RuleValueList)#15 (2) {
|
||||
["aComponents":protected]=>
|
||||
array(4) {
|
||||
[0]=>
|
||||
string(7) "Verdana"
|
||||
[1]=>
|
||||
string(9) "Helvetica"
|
||||
[2]=>
|
||||
object(Sabberworm\CSS\Value\String)#14 (1) {
|
||||
["sString":"Sabberworm\CSS\Value\String":private]=>
|
||||
string(9) "Gill Sans"
|
||||
}
|
||||
[3]=>
|
||||
string(10) "sans-serif"
|
||||
}
|
||||
["sSeparator":protected]=>
|
||||
string(1) ","
|
||||
}
|
||||
["bIsImportant":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
bool(false)
|
||||
}
|
||||
}
|
||||
["color"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(Sabberworm\CSS\Rule\Rule)#16 (3) {
|
||||
["sRule":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
string(5) "color"
|
||||
["mValue":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
string(3) "red"
|
||||
["bIsImportant":"Sabberworm\CSS\Rule\Rule":private]=>
|
||||
bool(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#### Output (`render()`)
|
||||
|
||||
#header {margin: 10px 2em 1cm 2%;font-family: Verdana,Helvetica,"Gill Sans",sans-serif;color: red !important;}
|
||||
|
||||
## Contributors/Thanks to
|
||||
|
||||
* [ju1ius](https://github.com/ju1ius) for the specificity parsing code and the ability to expand/compact shorthand properties.
|
||||
* [GaryJones](https://github.com/GaryJones) for lots of input and [http://css-specificity.info/](http://css-specificity.info/).
|
||||
* [docteurklein](https://github.com/docteurklein) for output formatting and `CSSList->remove()` inspiration.
|
||||
* [nicolopignatelli](https://github.com/nicolopignatelli) for PSR-0 compatibility.
|
||||
* [diegoembarcadero](https://github.com/diegoembarcadero) for keyframe at-rule parsing.
|
||||
* [goetas](https://github.com/goetas) for @namespace at-rule support.
|
||||
* [View full list](https://github.com/sabberworm/PHP-CSS-Parser/contributors)
|
||||
|
||||
## Misc
|
||||
|
||||
* Legacy Support: The latest pre-PSR-0 version of this project can be checked with the `0.9.0` tag.
|
||||
* Running Tests: To run all unit tests for this project, have `phpunit` installed and run `phpunit .`.
|
||||
|
||||
## License
|
||||
|
||||
PHP-CSS-Parser is freely distributable under the terms of an MIT-style license.
|
||||
|
||||
Copyright (c) 2011 Raphael Schweikert, http://sabberworm.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/composer.json
vendored
Normal file
17
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/composer.json
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "sabberworm/php-css-parser",
|
||||
"type": "library",
|
||||
"description": "Parser for CSS Files written in PHP",
|
||||
"keywords": ["parser", "css", "stylesheet"],
|
||||
"homepage": "http://www.sabberworm.com/blog/2010/6/10/php-css-parser",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{"name": "Raphael Schweikert"}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Sabberworm\\CSS": "lib/" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\CSSList;
|
||||
|
||||
use Sabberworm\CSS\Property\AtRule;
|
||||
|
||||
/**
|
||||
* A BlockList constructed by an unknown @-rule. @media rules are rendered into AtRuleBlockList objects.
|
||||
*/
|
||||
class AtRuleBlockList extends CSSBlockList implements AtRule {
|
||||
|
||||
private $sType;
|
||||
private $sArgs;
|
||||
|
||||
public function __construct($sType, $sArgs = '') {
|
||||
parent::__construct();
|
||||
$this->sType = $sType;
|
||||
$this->sArgs = $sArgs;
|
||||
}
|
||||
|
||||
public function atRuleName() {
|
||||
return $this->sType;
|
||||
}
|
||||
|
||||
public function atRuleArgs() {
|
||||
return $this->sArgs;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
$sArgs = $this->sArgs;
|
||||
if($sArgs) {
|
||||
$sArgs = ' ' . $sArgs;
|
||||
}
|
||||
$sResult = "@{$this->sType}$sArgs{$oOutputFormat->spaceBeforeOpeningBrace()}{";
|
||||
$sResult .= parent::render($oOutputFormat);
|
||||
$sResult .= '}';
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
public function isRootList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\CSSList;
|
||||
|
||||
use Sabberworm\CSS\RuleSet\DeclarationBlock;
|
||||
use Sabberworm\CSS\RuleSet\RuleSet;
|
||||
use Sabberworm\CSS\Property\Selector;
|
||||
use Sabberworm\CSS\Rule\Rule;
|
||||
use Sabberworm\CSS\Value\ValueList;
|
||||
use Sabberworm\CSS\Value\CSSFunction;
|
||||
|
||||
/**
|
||||
* A CSSBlockList is a CSSList whose DeclarationBlocks are guaranteed to contain valid declaration blocks or at-rules.
|
||||
* Most CSSLists conform to this category but some at-rules (such as @keyframes) do not.
|
||||
*/
|
||||
abstract class CSSBlockList extends CSSList {
|
||||
protected function allDeclarationBlocks(&$aResult) {
|
||||
foreach ($this->aContents as $mContent) {
|
||||
if ($mContent instanceof DeclarationBlock) {
|
||||
$aResult[] = $mContent;
|
||||
} else if ($mContent instanceof CSSBlockList) {
|
||||
$mContent->allDeclarationBlocks($aResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function allRuleSets(&$aResult) {
|
||||
foreach ($this->aContents as $mContent) {
|
||||
if ($mContent instanceof RuleSet) {
|
||||
$aResult[] = $mContent;
|
||||
} else if ($mContent instanceof CSSBlockList) {
|
||||
$mContent->allRuleSets($aResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function allValues($oElement, &$aResult, $sSearchString = null, $bSearchInFunctionArguments = false) {
|
||||
if ($oElement instanceof CSSBlockList) {
|
||||
foreach ($oElement->getContents() as $oContent) {
|
||||
$this->allValues($oContent, $aResult, $sSearchString, $bSearchInFunctionArguments);
|
||||
}
|
||||
} else if ($oElement instanceof RuleSet) {
|
||||
foreach ($oElement->getRules($sSearchString) as $oRule) {
|
||||
$this->allValues($oRule, $aResult, $sSearchString, $bSearchInFunctionArguments);
|
||||
}
|
||||
} else if ($oElement instanceof Rule) {
|
||||
$this->allValues($oElement->getValue(), $aResult, $sSearchString, $bSearchInFunctionArguments);
|
||||
} else if ($oElement instanceof ValueList) {
|
||||
if ($bSearchInFunctionArguments || !($oElement instanceof CSSFunction)) {
|
||||
foreach ($oElement->getListComponents() as $mComponent) {
|
||||
$this->allValues($mComponent, $aResult, $sSearchString, $bSearchInFunctionArguments);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Non-List Value or String (CSS identifier)
|
||||
$aResult[] = $oElement;
|
||||
}
|
||||
}
|
||||
|
||||
protected function allSelectors(&$aResult, $sSpecificitySearch = null) {
|
||||
$aDeclarationBlocks = array();
|
||||
$this->allDeclarationBlocks($aDeclarationBlocks);
|
||||
foreach ($aDeclarationBlocks as $oBlock) {
|
||||
foreach ($oBlock->getSelectors() as $oSelector) {
|
||||
if ($sSpecificitySearch === null) {
|
||||
$aResult[] = $oSelector;
|
||||
} else {
|
||||
$sComparison = "\$bRes = {$oSelector->getSpecificity()} $sSpecificitySearch;";
|
||||
eval($sComparison);
|
||||
if ($bRes) {
|
||||
$aResult[] = $oSelector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
114
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSList.php
vendored
Normal file
114
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSList.php
vendored
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\CSSList;
|
||||
|
||||
use Sabberworm\CSS\RuleSet\DeclarationBlock;
|
||||
use Sabberworm\CSS\RuleSet\RuleSet;
|
||||
use Sabberworm\CSS\Property\Selector;
|
||||
use Sabberworm\CSS\Rule\Rule;
|
||||
use Sabberworm\CSS\Value\ValueList;
|
||||
use Sabberworm\CSS\Value\CSSFunction;
|
||||
|
||||
/**
|
||||
* A CSSList is the most generic container available. Its contents include RuleSet as well as other CSSList objects.
|
||||
* Also, it may contain Import and Charset objects stemming from @-rules.
|
||||
*/
|
||||
abstract class CSSList {
|
||||
|
||||
protected $aContents;
|
||||
|
||||
public function __construct() {
|
||||
$this->aContents = array();
|
||||
}
|
||||
|
||||
public function append($oItem) {
|
||||
$this->aContents[] = $oItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an item from the CSS list.
|
||||
* @param RuleSet|Import|Charset|CSSList $oItemToRemove May be a RuleSet (most likely a DeclarationBlock), a Import, a Charset or another CSSList (most likely a MediaQuery)
|
||||
*/
|
||||
public function remove($oItemToRemove) {
|
||||
$iKey = array_search($oItemToRemove, $this->aContents, true);
|
||||
if ($iKey !== false) {
|
||||
unset($this->aContents[$iKey]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a declaration block from the CSS list if it matches all given selectors.
|
||||
* @param array|string $mSelector The selectors to match.
|
||||
* @param boolean $bRemoveAll Whether to stop at the first declaration block found or remove all blocks
|
||||
*/
|
||||
public function removeDeclarationBlockBySelector($mSelector, $bRemoveAll = false) {
|
||||
if ($mSelector instanceof DeclarationBlock) {
|
||||
$mSelector = $mSelector->getSelectors();
|
||||
}
|
||||
if (!is_array($mSelector)) {
|
||||
$mSelector = explode(',', $mSelector);
|
||||
}
|
||||
foreach ($mSelector as $iKey => &$mSel) {
|
||||
if (!($mSel instanceof Selector)) {
|
||||
$mSel = new Selector($mSel);
|
||||
}
|
||||
}
|
||||
foreach ($this->aContents as $iKey => $mItem) {
|
||||
if (!($mItem instanceof DeclarationBlock)) {
|
||||
continue;
|
||||
}
|
||||
if ($mItem->getSelectors() == $mSelector) {
|
||||
unset($this->aContents[$iKey]);
|
||||
if (!$bRemoveAll) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
$sResult = '';
|
||||
$bIsFirst = true;
|
||||
$oNextLevel = $oOutputFormat;
|
||||
if(!$this->isRootList()) {
|
||||
$oNextLevel = $oOutputFormat->nextLevel();
|
||||
}
|
||||
foreach ($this->aContents as $oContent) {
|
||||
$sRendered = $oOutputFormat->safely(function() use ($oNextLevel, $oContent) {
|
||||
return $oContent->render($oNextLevel);
|
||||
});
|
||||
if($sRendered === null) {
|
||||
continue;
|
||||
}
|
||||
if($bIsFirst) {
|
||||
$bIsFirst = false;
|
||||
$sResult .= $oNextLevel->spaceBeforeBlocks();
|
||||
} else {
|
||||
$sResult .= $oNextLevel->spaceBetweenBlocks();
|
||||
}
|
||||
$sResult .= $sRendered;
|
||||
}
|
||||
|
||||
if(!$bIsFirst) {
|
||||
// Had some output
|
||||
$sResult .= $oOutputFormat->spaceAfterBlocks();
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the list can not be further outdented. Only important when rendering.
|
||||
*/
|
||||
public abstract function isRootList();
|
||||
|
||||
public function getContents() {
|
||||
return $this->aContents;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\CSSList;
|
||||
|
||||
/**
|
||||
* The root CSSList of a parsed file. Contains all top-level css contents, mostly declaration blocks, but also any @-rules encountered.
|
||||
*/
|
||||
class Document extends CSSBlockList {
|
||||
|
||||
/**
|
||||
* Gets all DeclarationBlock objects recursively.
|
||||
*/
|
||||
public function getAllDeclarationBlocks() {
|
||||
$aResult = array();
|
||||
$this->allDeclarationBlocks($aResult);
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use getAllDeclarationBlocks()
|
||||
*/
|
||||
public function getAllSelectors() {
|
||||
return $this->getAllDeclarationBlocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all RuleSet objects found recursively in the tree.
|
||||
*/
|
||||
public function getAllRuleSets() {
|
||||
$aResult = array();
|
||||
$this->allRuleSets($aResult);
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Value objects found recursively in the tree.
|
||||
* @param (object|string) $mElement the CSSList or RuleSet to start the search from (defaults to the whole document). If a string is given, it is used as rule name filter (@see{RuleSet->getRules()}).
|
||||
* @param (bool) $bSearchInFunctionArguments whether to also return Value objects used as Function arguments.
|
||||
*/
|
||||
public function getAllValues($mElement = null, $bSearchInFunctionArguments = false) {
|
||||
$sSearchString = null;
|
||||
if ($mElement === null) {
|
||||
$mElement = $this;
|
||||
} else if (is_string($mElement)) {
|
||||
$sSearchString = $mElement;
|
||||
$mElement = $this;
|
||||
}
|
||||
$aResult = array();
|
||||
$this->allValues($mElement, $aResult, $sSearchString, $bSearchInFunctionArguments);
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Selector objects found recursively in the tree.
|
||||
* Note that this does not yield the full DeclarationBlock that the selector belongs to (and, currently, there is no way to get to that).
|
||||
* @param $sSpecificitySearch An optional filter by specificity. May contain a comparison operator and a number or just a number (defaults to "==").
|
||||
* @example getSelectorsBySpecificity('>= 100')
|
||||
*/
|
||||
public function getSelectorsBySpecificity($sSpecificitySearch = null) {
|
||||
if (is_numeric($sSpecificitySearch) || is_numeric($sSpecificitySearch[0])) {
|
||||
$sSpecificitySearch = "== $sSpecificitySearch";
|
||||
}
|
||||
$aResult = array();
|
||||
$this->allSelectors($aResult, $sSpecificitySearch);
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands all shorthand properties to their long value
|
||||
*/
|
||||
public function expandShorthands() {
|
||||
foreach ($this->getAllDeclarationBlocks() as $oDeclaration) {
|
||||
$oDeclaration->expandShorthands();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create shorthands properties whenever possible
|
||||
*/
|
||||
public function createShorthands() {
|
||||
foreach ($this->getAllDeclarationBlocks() as $oDeclaration) {
|
||||
$oDeclaration->createShorthands();
|
||||
}
|
||||
}
|
||||
|
||||
// Override render() to make format argument optional
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat = null) {
|
||||
if($oOutputFormat === null) {
|
||||
$oOutputFormat = new \Sabberworm\CSS\OutputFormat();
|
||||
}
|
||||
return parent::render($oOutputFormat);
|
||||
}
|
||||
|
||||
public function isRootList() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\CSSList;
|
||||
|
||||
use Sabberworm\CSS\Property\AtRule;
|
||||
|
||||
class KeyFrame extends CSSList implements AtRule {
|
||||
|
||||
private $vendorKeyFrame;
|
||||
private $animationName;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->vendorKeyFrame = null;
|
||||
$this->animationName = null;
|
||||
}
|
||||
|
||||
public function setVendorKeyFrame($vendorKeyFrame) {
|
||||
$this->vendorKeyFrame = $vendorKeyFrame;
|
||||
}
|
||||
|
||||
public function getVendorKeyFrame() {
|
||||
return $this->vendorKeyFrame;
|
||||
}
|
||||
|
||||
public function setAnimationName($animationName) {
|
||||
$this->animationName = $animationName;
|
||||
}
|
||||
|
||||
public function getAnimationName() {
|
||||
return $this->animationName;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
$sResult = "@{$this->vendorKeyFrame} {$this->animationName}{$oOutputFormat->spaceBeforeOpeningBrace()}{";
|
||||
$sResult .= parent::render($oOutputFormat);
|
||||
$sResult .= '}';
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
public function isRootList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function atRuleName() {
|
||||
return $this->vendorKeyFrame;
|
||||
}
|
||||
|
||||
public function atRuleArgs() {
|
||||
return $this->animationName;
|
||||
}
|
||||
}
|
289
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/OutputFormat.php
vendored
Normal file
289
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/OutputFormat.php
vendored
Normal file
|
@ -0,0 +1,289 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS;
|
||||
|
||||
use Sabberworm\CSS\Parsing\OutputException;
|
||||
|
||||
class OutputFormat {
|
||||
/**
|
||||
* Value format
|
||||
*/
|
||||
// " means double-quote, ' means single-quote
|
||||
public $sStringQuotingType = '"';
|
||||
// Output RGB colors in hash notation if possible
|
||||
public $bRGBHashNotation = true;
|
||||
|
||||
/**
|
||||
* Declaration format
|
||||
*/
|
||||
// Semicolon after the last rule of a declaration block can be omitted. To do that, set this false.
|
||||
public $bSemicolonAfterLastRule = true;
|
||||
|
||||
/**
|
||||
* Spacing
|
||||
* Note that these strings are not sanity-checked: the value should only consist of whitespace
|
||||
* Any newline character will be indented according to the current level.
|
||||
* The triples (After, Before, Between) can be set using a wildcard (e.g. `$oFormat->set('Space*Rules', "\n");`)
|
||||
*/
|
||||
public $sSpaceAfterRuleName = ' ';
|
||||
|
||||
public $sSpaceBeforeRules = '';
|
||||
public $sSpaceAfterRules = '';
|
||||
public $sSpaceBetweenRules = '';
|
||||
|
||||
public $sSpaceBeforeBlocks = '';
|
||||
public $sSpaceAfterBlocks = '';
|
||||
public $sSpaceBetweenBlocks = "\n";
|
||||
|
||||
// This is what’s printed before and after the comma if a declaration block contains multiple selectors.
|
||||
public $sSpaceBeforeSelectorSeparator = '';
|
||||
public $sSpaceAfterSelectorSeparator = ' ';
|
||||
// This is what’s printed after the comma of value lists
|
||||
public $sSpaceBeforeListArgumentSeparator = '';
|
||||
public $sSpaceAfterListArgumentSeparator = '';
|
||||
|
||||
public $sSpaceBeforeOpeningBrace = ' ';
|
||||
|
||||
/**
|
||||
* Indentation
|
||||
*/
|
||||
// Indentation character(s) per level. Only applicable if newlines are used in any of the spacing settings.
|
||||
public $sIndentation = "\t";
|
||||
|
||||
/**
|
||||
* Output exceptions.
|
||||
*/
|
||||
public $bIgnoreExceptions = false;
|
||||
|
||||
|
||||
private $oFormatter = null;
|
||||
private $oNextLevelFormat = null;
|
||||
private $iIndentationLevel = 0;
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
public function get($sName) {
|
||||
$aVarPrefixes = array('a', 's', 'm', 'b', 'f', 'o', 'c', 'i');
|
||||
foreach($aVarPrefixes as $sPrefix) {
|
||||
$sFieldName = $sPrefix.ucfirst($sName);
|
||||
if(isset($this->$sFieldName)) {
|
||||
return $this->$sFieldName;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function set($aNames, $mValue) {
|
||||
$aVarPrefixes = array('a', 's', 'm', 'b', 'f', 'o', 'c', 'i');
|
||||
if(is_string($aNames) && strpos($aNames, '*') !== false) {
|
||||
$aNames = array(str_replace('*', 'Before', $aNames), str_replace('*', 'Between', $aNames), str_replace('*', 'After', $aNames));
|
||||
} else if(!is_array($aNames)) {
|
||||
$aNames = array($aNames);
|
||||
}
|
||||
foreach($aVarPrefixes as $sPrefix) {
|
||||
$bDidReplace = false;
|
||||
foreach($aNames as $sName) {
|
||||
$sFieldName = $sPrefix.ucfirst($sName);
|
||||
if(isset($this->$sFieldName)) {
|
||||
$this->$sFieldName = $mValue;
|
||||
$bDidReplace = true;
|
||||
}
|
||||
}
|
||||
if($bDidReplace) {
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
// Break the chain so the user knows this option is invalid
|
||||
return false;
|
||||
}
|
||||
|
||||
public function __call($sMethodName, $aArguments) {
|
||||
if(strpos($sMethodName, 'set') === 0) {
|
||||
return $this->set(substr($sMethodName, 3), $aArguments[0]);
|
||||
} else if(strpos($sMethodName, 'get') === 0) {
|
||||
return $this->get(substr($sMethodName, 3));
|
||||
} else if(method_exists('\\Sabberworm\\CSS\\OutputFormatter', $sMethodName)) {
|
||||
return call_user_func_array(array($this->getFormatter(), $sMethodName), $aArguments);
|
||||
} else {
|
||||
throw new \Exception('Unknown OutputFormat method called: '.$sMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
public function indentWithTabs($iNumber = 1) {
|
||||
return $this->setIndentation(str_repeat("\t", $iNumber));
|
||||
}
|
||||
|
||||
public function indentWithSpaces($iNumber = 2) {
|
||||
return $this->setIndentation(str_repeat(" ", $iNumber));
|
||||
}
|
||||
|
||||
public function nextLevel() {
|
||||
if($this->oNextLevelFormat === null) {
|
||||
$this->oNextLevelFormat = clone $this;
|
||||
$this->oNextLevelFormat->iIndentationLevel++;
|
||||
$this->oNextLevelFormat->oFormatter = null;
|
||||
}
|
||||
return $this->oNextLevelFormat;
|
||||
}
|
||||
|
||||
public function beLenient() {
|
||||
$this->bIgnoreExceptions = true;
|
||||
}
|
||||
|
||||
public function getFormatter() {
|
||||
if($this->oFormatter === null) {
|
||||
$this->oFormatter = new OutputFormatter($this);
|
||||
}
|
||||
return $this->oFormatter;
|
||||
}
|
||||
|
||||
public function level() {
|
||||
return $this->iIndentationLevel;
|
||||
}
|
||||
|
||||
public static function create() {
|
||||
return new OutputFormat();
|
||||
}
|
||||
|
||||
public static function createCompact() {
|
||||
return self::create()->set('Space*Rules', "")->set('Space*Blocks', "")->setSpaceAfterRuleName('')->setSpaceBeforeOpeningBrace('')->setSpaceAfterSelectorSeparator('');
|
||||
}
|
||||
|
||||
public static function createPretty() {
|
||||
return self::create()->set('Space*Rules', "\n")->set('Space*Blocks', "\n")->setSpaceBetweenBlocks("\n\n")->set('SpaceAfterListArgumentSeparator', array('default' => '', ',' => ' '));
|
||||
}
|
||||
}
|
||||
|
||||
class OutputFormatter {
|
||||
private $oFormat;
|
||||
|
||||
public function __construct(OutputFormat $oFormat) {
|
||||
$this->oFormat = $oFormat;
|
||||
}
|
||||
|
||||
public function space($sName, $sType = null) {
|
||||
$sSpaceString = $this->oFormat->get("Space$sName");
|
||||
// If $sSpaceString is an array, we have multple values configured depending on the type of object the space applies to
|
||||
if(is_array($sSpaceString)) {
|
||||
if($sType !== null && isset($sSpaceString[$sType])) {
|
||||
$sSpaceString = $sSpaceString[$sType];
|
||||
} else {
|
||||
$sSpaceString = reset($sSpaceString);
|
||||
}
|
||||
}
|
||||
return $this->prepareSpace($sSpaceString);
|
||||
}
|
||||
|
||||
public function spaceAfterRuleName() {
|
||||
return $this->space('AfterRuleName');
|
||||
}
|
||||
|
||||
public function spaceBeforeRules() {
|
||||
return $this->space('BeforeRules');
|
||||
}
|
||||
|
||||
public function spaceAfterRules() {
|
||||
return $this->space('AfterRules');
|
||||
}
|
||||
|
||||
public function spaceBetweenRules() {
|
||||
return $this->space('BetweenRules');
|
||||
}
|
||||
|
||||
public function spaceBeforeBlocks() {
|
||||
return $this->space('BeforeBlocks');
|
||||
}
|
||||
|
||||
public function spaceAfterBlocks() {
|
||||
return $this->space('AfterBlocks');
|
||||
}
|
||||
|
||||
public function spaceBetweenBlocks() {
|
||||
return $this->space('BetweenBlocks');
|
||||
}
|
||||
|
||||
public function spaceBeforeSelectorSeparator() {
|
||||
return $this->space('BeforeSelectorSeparator');
|
||||
}
|
||||
|
||||
public function spaceAfterSelectorSeparator() {
|
||||
return $this->space('AfterSelectorSeparator');
|
||||
}
|
||||
|
||||
public function spaceBeforeListArgumentSeparator($sSeparator) {
|
||||
return $this->space('BeforeListArgumentSeparator', $sSeparator);
|
||||
}
|
||||
|
||||
public function spaceAfterListArgumentSeparator($sSeparator) {
|
||||
return $this->space('AfterListArgumentSeparator', $sSeparator);
|
||||
}
|
||||
|
||||
public function spaceBeforeOpeningBrace() {
|
||||
return $this->space('BeforeOpeningBrace');
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given code, either swallowing or passing exceptions, depending on the bIgnoreExceptions setting.
|
||||
*/
|
||||
public function safely($cCode) {
|
||||
if($this->oFormat->get('IgnoreExceptions')) {
|
||||
// If output exceptions are ignored, run the code with exception guards
|
||||
try {
|
||||
return $cCode();
|
||||
} catch (OutputException $e) {
|
||||
return null;
|
||||
} //Do nothing
|
||||
} else {
|
||||
// Run the code as-is
|
||||
return $cCode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone of the implode function but calls ->render with the current output format instead of __toString()
|
||||
*/
|
||||
public function implode($sSeparator, $aValues, $bIncreaseLevel = false) {
|
||||
$sResult = '';
|
||||
$oFormat = $this->oFormat;
|
||||
if($bIncreaseLevel) {
|
||||
$oFormat = $oFormat->nextLevel();
|
||||
}
|
||||
$bIsFirst = true;
|
||||
foreach($aValues as $mValue) {
|
||||
if($bIsFirst) {
|
||||
$bIsFirst = false;
|
||||
} else {
|
||||
$sResult .= $sSeparator;
|
||||
}
|
||||
if($mValue instanceof \Sabberworm\CSS\Renderable) {
|
||||
$sResult .= $mValue->render($oFormat);
|
||||
} else {
|
||||
$sResult .= $mValue;
|
||||
}
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
public function removeLastSemicolon($sString) {
|
||||
if($this->oFormat->get('SemicolonAfterLastRule')) {
|
||||
return $sString;
|
||||
}
|
||||
$sString = explode(';', $sString);
|
||||
if(count($sString) < 2) {
|
||||
return $sString[0];
|
||||
}
|
||||
$sLast = array_pop($sString);
|
||||
$sNextToLast = array_pop($sString);
|
||||
array_push($sString, $sNextToLast.$sLast);
|
||||
return implode(';', $sString);
|
||||
}
|
||||
|
||||
private function prepareSpace($sSpaceString) {
|
||||
return str_replace("\n", "\n".$this->indent(), $sSpaceString);
|
||||
}
|
||||
|
||||
private function indent() {
|
||||
return str_repeat($this->oFormat->sIndentation, $this->oFormat->level());
|
||||
}
|
||||
}
|
630
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php
vendored
Normal file
630
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php
vendored
Normal file
|
@ -0,0 +1,630 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS;
|
||||
|
||||
use Sabberworm\CSS\CSSList\CSSList;
|
||||
use Sabberworm\CSS\CSSList\Document;
|
||||
use Sabberworm\CSS\CSSList\KeyFrame;
|
||||
use Sabberworm\CSS\Property\AtRule;
|
||||
use Sabberworm\CSS\Property\Import;
|
||||
use Sabberworm\CSS\Property\Charset;
|
||||
use Sabberworm\CSS\Property\CSSNamespace;
|
||||
use Sabberworm\CSS\RuleSet\AtRuleSet;
|
||||
use Sabberworm\CSS\CSSList\AtRuleBlockList;
|
||||
use Sabberworm\CSS\RuleSet\DeclarationBlock;
|
||||
use Sabberworm\CSS\Value\CSSFunction;
|
||||
use Sabberworm\CSS\Value\RuleValueList;
|
||||
use Sabberworm\CSS\Value\Size;
|
||||
use Sabberworm\CSS\Value\Color;
|
||||
use Sabberworm\CSS\Value\URL;
|
||||
use Sabberworm\CSS\Value\String;
|
||||
use Sabberworm\CSS\Rule\Rule;
|
||||
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
|
||||
|
||||
/**
|
||||
* Parser class parses CSS from text into a data structure.
|
||||
*/
|
||||
class Parser {
|
||||
|
||||
private $sText;
|
||||
private $iCurrentPosition;
|
||||
private $oParserSettings;
|
||||
private $sCharset;
|
||||
private $iLength;
|
||||
private $peekCache = null;
|
||||
private $blockRules;
|
||||
private $aSizeUnits;
|
||||
|
||||
public function __construct($sText, Settings $oParserSettings = null) {
|
||||
$this->sText = $sText;
|
||||
$this->iCurrentPosition = 0;
|
||||
if ($oParserSettings === null) {
|
||||
$oParserSettings = Settings::create();
|
||||
}
|
||||
$this->oParserSettings = $oParserSettings;
|
||||
$this->blockRules = explode('/', AtRule::BLOCK_RULES);
|
||||
|
||||
foreach (explode('/', Size::ABSOLUTE_SIZE_UNITS.'/'.Size::RELATIVE_SIZE_UNITS.'/'.Size::NON_SIZE_UNITS) as $val) {
|
||||
$iSize = strlen($val);
|
||||
if(!isset($this->aSizeUnits[$iSize])) {
|
||||
$this->aSizeUnits[$iSize] = array();
|
||||
}
|
||||
$this->aSizeUnits[$iSize][strtolower($val)] = $val;
|
||||
}
|
||||
ksort($this->aSizeUnits, SORT_NUMERIC);
|
||||
}
|
||||
|
||||
public function setCharset($sCharset) {
|
||||
$this->sCharset = $sCharset;
|
||||
$this->iLength = $this->strlen($this->sText);
|
||||
}
|
||||
|
||||
public function getCharset() {
|
||||
return $this->sCharset;
|
||||
}
|
||||
|
||||
public function parse() {
|
||||
$this->setCharset($this->oParserSettings->sDefaultCharset);
|
||||
$oResult = new Document();
|
||||
$this->parseDocument($oResult);
|
||||
return $oResult;
|
||||
}
|
||||
|
||||
private function parseDocument(Document $oDocument) {
|
||||
$this->consumeWhiteSpace();
|
||||
$this->parseList($oDocument, true);
|
||||
}
|
||||
|
||||
private function parseList(CSSList $oList, $bIsRoot = false) {
|
||||
while (!$this->isEnd()) {
|
||||
if ($this->comes('@')) {
|
||||
$oList->append($this->parseAtRule());
|
||||
} else if ($this->comes('}')) {
|
||||
$this->consume('}');
|
||||
if ($bIsRoot) {
|
||||
throw new \Exception("Unopened {");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if($this->oParserSettings->bLenientParsing) {
|
||||
try {
|
||||
$oList->append($this->parseSelector());
|
||||
} catch (UnexpectedTokenException $e) {}
|
||||
} else {
|
||||
$oList->append($this->parseSelector());
|
||||
}
|
||||
}
|
||||
$this->consumeWhiteSpace();
|
||||
}
|
||||
if (!$bIsRoot) {
|
||||
throw new \Exception("Unexpected end of document");
|
||||
}
|
||||
}
|
||||
|
||||
private function parseAtRule() {
|
||||
$this->consume('@');
|
||||
$sIdentifier = $this->parseIdentifier();
|
||||
$this->consumeWhiteSpace();
|
||||
if ($sIdentifier === 'import') {
|
||||
$oLocation = $this->parseURLValue();
|
||||
$this->consumeWhiteSpace();
|
||||
$sMediaQuery = null;
|
||||
if (!$this->comes(';')) {
|
||||
$sMediaQuery = $this->consumeUntil(';');
|
||||
}
|
||||
$this->consume(';');
|
||||
return new Import($oLocation, $sMediaQuery);
|
||||
} else if ($sIdentifier === 'charset') {
|
||||
$sCharset = $this->parseStringValue();
|
||||
$this->consumeWhiteSpace();
|
||||
$this->consume(';');
|
||||
$this->setCharset($sCharset->getString());
|
||||
return new Charset($sCharset);
|
||||
} else if ($this->identifierIs($sIdentifier, 'keyframes')) {
|
||||
$oResult = new KeyFrame();
|
||||
$oResult->setVendorKeyFrame($sIdentifier);
|
||||
$oResult->setAnimationName(trim($this->consumeUntil('{', false, true)));
|
||||
$this->consumeWhiteSpace();
|
||||
$this->parseList($oResult);
|
||||
return $oResult;
|
||||
} else if ($sIdentifier === 'namespace') {
|
||||
$sPrefix = null;
|
||||
$mUrl = $this->parsePrimitiveValue();
|
||||
if (!$this->comes(';')) {
|
||||
$sPrefix = $mUrl;
|
||||
$mUrl = $this->parsePrimitiveValue();
|
||||
}
|
||||
$this->consume(';');
|
||||
if ($sPrefix !== null && !is_string($sPrefix)) {
|
||||
throw new \Exception('Wrong namespace prefix '.$sPrefix);
|
||||
}
|
||||
if (!($mUrl instanceof String || $mUrl instanceof URL)) {
|
||||
throw new \Exception('Wrong namespace url of invalid type '.$mUrl);
|
||||
}
|
||||
return new CSSNamespace($mUrl, $sPrefix);
|
||||
} else {
|
||||
//Unknown other at rule (font-face or such)
|
||||
$sArgs = trim($this->consumeUntil('{', false, true));
|
||||
$this->consumeWhiteSpace();
|
||||
$bUseRuleSet = true;
|
||||
foreach($this->blockRules as $sBlockRuleName) {
|
||||
if($this->identifierIs($sIdentifier, $sBlockRuleName)) {
|
||||
$bUseRuleSet = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($bUseRuleSet) {
|
||||
$oAtRule = new AtRuleSet($sIdentifier, $sArgs);
|
||||
$this->parseRuleSet($oAtRule);
|
||||
} else {
|
||||
$oAtRule = new AtRuleBlockList($sIdentifier, $sArgs);
|
||||
$this->parseList($oAtRule);
|
||||
}
|
||||
return $oAtRule;
|
||||
}
|
||||
}
|
||||
|
||||
private function parseIdentifier($bAllowFunctions = true, $bIgnoreCase = true) {
|
||||
$sResult = $this->parseCharacter(true);
|
||||
if ($sResult === null) {
|
||||
throw new UnexpectedTokenException($sResult, $this->peek(5), 'identifier');
|
||||
}
|
||||
$sCharacter = null;
|
||||
while (($sCharacter = $this->parseCharacter(true)) !== null) {
|
||||
$sResult .= $sCharacter;
|
||||
}
|
||||
if ($bIgnoreCase) {
|
||||
$sResult = $this->strtolower($sResult);
|
||||
}
|
||||
if ($bAllowFunctions && $this->comes('(')) {
|
||||
$this->consume('(');
|
||||
$aArguments = $this->parseValue(array('=', ' ', ','));
|
||||
$sResult = new CSSFunction($sResult, $aArguments);
|
||||
$this->consume(')');
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
private function parseStringValue() {
|
||||
$sBegin = $this->peek();
|
||||
$sQuote = null;
|
||||
if ($sBegin === "'") {
|
||||
$sQuote = "'";
|
||||
} else if ($sBegin === '"') {
|
||||
$sQuote = '"';
|
||||
}
|
||||
if ($sQuote !== null) {
|
||||
$this->consume($sQuote);
|
||||
}
|
||||
$sResult = "";
|
||||
$sContent = null;
|
||||
if ($sQuote === null) {
|
||||
//Unquoted strings end in whitespace or with braces, brackets, parentheses
|
||||
while (!preg_match('/[\\s{}()<>\\[\\]]/isu', $this->peek())) {
|
||||
$sResult .= $this->parseCharacter(false);
|
||||
}
|
||||
} else {
|
||||
while (!$this->comes($sQuote)) {
|
||||
$sContent = $this->parseCharacter(false);
|
||||
if ($sContent === null) {
|
||||
throw new \Exception("Non-well-formed quoted string {$this->peek(3)}");
|
||||
}
|
||||
$sResult .= $sContent;
|
||||
}
|
||||
$this->consume($sQuote);
|
||||
}
|
||||
return new String($sResult);
|
||||
}
|
||||
|
||||
private function parseCharacter($bIsForIdentifier) {
|
||||
if ($this->peek() === '\\') {
|
||||
$this->consume('\\');
|
||||
if ($this->comes('\n') || $this->comes('\r')) {
|
||||
return '';
|
||||
}
|
||||
if (preg_match('/[0-9a-fA-F]/Su', $this->peek()) === 0) {
|
||||
return $this->consume(1);
|
||||
}
|
||||
$sUnicode = $this->consumeExpression('/^[0-9a-fA-F]{1,6}/u');
|
||||
if ($this->strlen($sUnicode) < 6) {
|
||||
//Consume whitespace after incomplete unicode escape
|
||||
if (preg_match('/\\s/isSu', $this->peek())) {
|
||||
if ($this->comes('\r\n')) {
|
||||
$this->consume(2);
|
||||
} else {
|
||||
$this->consume(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
$iUnicode = intval($sUnicode, 16);
|
||||
$sUtf32 = "";
|
||||
for ($i = 0; $i < 4; ++$i) {
|
||||
$sUtf32 .= chr($iUnicode & 0xff);
|
||||
$iUnicode = $iUnicode >> 8;
|
||||
}
|
||||
return iconv('utf-32le', $this->sCharset, $sUtf32);
|
||||
}
|
||||
if ($bIsForIdentifier) {
|
||||
$peek = ord($this->peek());
|
||||
// Ranges: a-z A-Z 0-9 - _
|
||||
if (($peek >= 97 && $peek <= 122) ||
|
||||
($peek >= 65 && $peek <= 90) ||
|
||||
($peek >= 48 && $peek <= 57) ||
|
||||
($peek === 45) ||
|
||||
($peek === 95) ||
|
||||
($peek > 0xa1)) {
|
||||
return $this->consume(1);
|
||||
}
|
||||
} else {
|
||||
return $this->consume(1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function parseSelector() {
|
||||
$oResult = new DeclarationBlock();
|
||||
$oResult->setSelector($this->consumeUntil('{', false, true));
|
||||
$this->consumeWhiteSpace();
|
||||
$this->parseRuleSet($oResult);
|
||||
return $oResult;
|
||||
}
|
||||
|
||||
private function parseRuleSet($oRuleSet) {
|
||||
while ($this->comes(';')) {
|
||||
$this->consume(';');
|
||||
$this->consumeWhiteSpace();
|
||||
}
|
||||
while (!$this->comes('}')) {
|
||||
$oRule = null;
|
||||
if($this->oParserSettings->bLenientParsing) {
|
||||
try {
|
||||
$oRule = $this->parseRule();
|
||||
} catch (UnexpectedTokenException $e) {
|
||||
try {
|
||||
$sConsume = $this->consumeUntil(array("\n", ";", '}'), true);
|
||||
// We need to “unfind” the matches to the end of the ruleSet as this will be matched later
|
||||
if($this->streql($this->substr($sConsume, $this->strlen($sConsume)-1, 1), '}')) {
|
||||
--$this->iCurrentPosition;
|
||||
$this->peekCache = null;
|
||||
} else {
|
||||
$this->consumeWhiteSpace();
|
||||
while ($this->comes(';')) {
|
||||
$this->consume(';');
|
||||
}
|
||||
}
|
||||
} catch (UnexpectedTokenException $e) {
|
||||
// We’ve reached the end of the document. Just close the RuleSet.
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$oRule = $this->parseRule();
|
||||
}
|
||||
if($oRule) {
|
||||
$oRuleSet->addRule($oRule);
|
||||
}
|
||||
$this->consumeWhiteSpace();
|
||||
}
|
||||
$this->consume('}');
|
||||
}
|
||||
|
||||
private function parseRule() {
|
||||
$oRule = new Rule($this->parseIdentifier());
|
||||
$this->consumeWhiteSpace();
|
||||
$this->consume(':');
|
||||
$oValue = $this->parseValue(self::listDelimiterForRule($oRule->getRule()));
|
||||
$oRule->setValue($oValue);
|
||||
if ($this->comes('!')) {
|
||||
$this->consume('!');
|
||||
$this->consumeWhiteSpace();
|
||||
$this->consume('important');
|
||||
$oRule->setIsImportant(true);
|
||||
}
|
||||
while ($this->comes(';')) {
|
||||
$this->consume(';');
|
||||
$this->consumeWhiteSpace();
|
||||
}
|
||||
return $oRule;
|
||||
}
|
||||
|
||||
private function parseValue($aListDelimiters) {
|
||||
$aStack = array();
|
||||
$this->consumeWhiteSpace();
|
||||
//Build a list of delimiters and parsed values
|
||||
while (!($this->comes('}') || $this->comes(';') || $this->comes('!') || $this->comes(')'))) {
|
||||
if (count($aStack) > 0) {
|
||||
$bFoundDelimiter = false;
|
||||
foreach ($aListDelimiters as $sDelimiter) {
|
||||
if ($this->comes($sDelimiter)) {
|
||||
array_push($aStack, $this->consume($sDelimiter));
|
||||
$this->consumeWhiteSpace();
|
||||
$bFoundDelimiter = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$bFoundDelimiter) {
|
||||
//Whitespace was the list delimiter
|
||||
array_push($aStack, ' ');
|
||||
}
|
||||
}
|
||||
array_push($aStack, $this->parsePrimitiveValue());
|
||||
$this->consumeWhiteSpace();
|
||||
}
|
||||
//Convert the list to list objects
|
||||
foreach ($aListDelimiters as $sDelimiter) {
|
||||
if (count($aStack) === 1) {
|
||||
return $aStack[0];
|
||||
}
|
||||
$iStartPosition = null;
|
||||
while (($iStartPosition = array_search($sDelimiter, $aStack, true)) !== false) {
|
||||
$iLength = 2; //Number of elements to be joined
|
||||
for ($i = $iStartPosition + 2; $i < count($aStack); $i+=2, ++$iLength) {
|
||||
if ($sDelimiter !== $aStack[$i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$oList = new RuleValueList($sDelimiter);
|
||||
for ($i = $iStartPosition - 1; $i - $iStartPosition + 1 < $iLength * 2; $i+=2) {
|
||||
$oList->addListComponent($aStack[$i]);
|
||||
}
|
||||
array_splice($aStack, $iStartPosition - 1, $iLength * 2 - 1, array($oList));
|
||||
}
|
||||
}
|
||||
return $aStack[0];
|
||||
}
|
||||
|
||||
private static function listDelimiterForRule($sRule) {
|
||||
if (preg_match('/^font($|-)/', $sRule)) {
|
||||
return array(',', '/', ' ');
|
||||
}
|
||||
return array(',', ' ', '/');
|
||||
}
|
||||
|
||||
private function parsePrimitiveValue() {
|
||||
$oValue = null;
|
||||
$this->consumeWhiteSpace();
|
||||
if (is_numeric($this->peek()) || ($this->comes('-.') && is_numeric($this->peek(1, 2))) || (($this->comes('-') || $this->comes('.')) && is_numeric($this->peek(1, 1)))) {
|
||||
$oValue = $this->parseNumericValue();
|
||||
} else if ($this->comes('#') || $this->comes('rgb', true) || $this->comes('hsl', true)) {
|
||||
$oValue = $this->parseColorValue();
|
||||
} else if ($this->comes('url', true)) {
|
||||
$oValue = $this->parseURLValue();
|
||||
} else if ($this->comes("'") || $this->comes('"')) {
|
||||
$oValue = $this->parseStringValue();
|
||||
} else {
|
||||
$oValue = $this->parseIdentifier(true, false);
|
||||
}
|
||||
$this->consumeWhiteSpace();
|
||||
return $oValue;
|
||||
}
|
||||
|
||||
private function parseNumericValue($bForColor = false) {
|
||||
$sSize = '';
|
||||
if ($this->comes('-')) {
|
||||
$sSize .= $this->consume('-');
|
||||
}
|
||||
while (is_numeric($this->peek()) || $this->comes('.')) {
|
||||
if ($this->comes('.')) {
|
||||
$sSize .= $this->consume('.');
|
||||
} else {
|
||||
$sSize .= $this->consume(1);
|
||||
}
|
||||
}
|
||||
|
||||
$sUnit = null;
|
||||
foreach ($this->aSizeUnits as $iLength => &$aValues) {
|
||||
if(($sUnit = @$aValues[strtolower($this->peek($iLength))]) !== null) {
|
||||
$this->consume($iLength);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Size(floatval($sSize), $sUnit, $bForColor);
|
||||
}
|
||||
|
||||
private function parseColorValue() {
|
||||
$aColor = array();
|
||||
if ($this->comes('#')) {
|
||||
$this->consume('#');
|
||||
$sValue = $this->parseIdentifier(false);
|
||||
if ($this->strlen($sValue) === 3) {
|
||||
$sValue = $sValue[0] . $sValue[0] . $sValue[1] . $sValue[1] . $sValue[2] . $sValue[2];
|
||||
}
|
||||
$aColor = array('r' => new Size(intval($sValue[0] . $sValue[1], 16), null, true), 'g' => new Size(intval($sValue[2] . $sValue[3], 16), null, true), 'b' => new Size(intval($sValue[4] . $sValue[5], 16), null, true));
|
||||
} else {
|
||||
$sColorMode = $this->parseIdentifier(false);
|
||||
$this->consumeWhiteSpace();
|
||||
$this->consume('(');
|
||||
$iLength = $this->strlen($sColorMode);
|
||||
for ($i = 0; $i < $iLength; ++$i) {
|
||||
$this->consumeWhiteSpace();
|
||||
$aColor[$sColorMode[$i]] = $this->parseNumericValue(true);
|
||||
$this->consumeWhiteSpace();
|
||||
if ($i < ($iLength - 1)) {
|
||||
$this->consume(',');
|
||||
}
|
||||
}
|
||||
$this->consume(')');
|
||||
}
|
||||
return new Color($aColor);
|
||||
}
|
||||
|
||||
private function parseURLValue() {
|
||||
$bUseUrl = $this->comes('url', true);
|
||||
if ($bUseUrl) {
|
||||
$this->consume('url');
|
||||
$this->consumeWhiteSpace();
|
||||
$this->consume('(');
|
||||
}
|
||||
$this->consumeWhiteSpace();
|
||||
$oResult = new URL($this->parseStringValue());
|
||||
if ($bUseUrl) {
|
||||
$this->consumeWhiteSpace();
|
||||
$this->consume(')');
|
||||
}
|
||||
return $oResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests an identifier for a given value. Since identifiers are all keywords, they can be vendor-prefixed. We need to check for these versions too.
|
||||
*/
|
||||
private function identifierIs($sIdentifier, $sMatch) {
|
||||
return (strcasecmp($sIdentifier, $sMatch) === 0)
|
||||
?: preg_match("/^(-\\w+-)?$sMatch$/i", $sIdentifier) === 1;
|
||||
}
|
||||
|
||||
private function comes($sString, $bCaseInsensitive = false) {
|
||||
$sPeek = $this->peek(strlen($sString));
|
||||
return ($sPeek == '')
|
||||
? false
|
||||
: $this->streql($sPeek, $sString, $bCaseInsensitive);
|
||||
}
|
||||
|
||||
private function peek($iLength = 1, $iOffset = 0) {
|
||||
if (($peek = (!$iOffset && ($iLength === 1))) &&
|
||||
!is_null($this->peekCache)) {
|
||||
return $this->peekCache;
|
||||
}
|
||||
$iOffset += $this->iCurrentPosition;
|
||||
if ($iOffset >= $this->iLength) {
|
||||
return '';
|
||||
}
|
||||
$iLength = min($iLength, $this->iLength-$iOffset);
|
||||
$out = $this->substr($this->sText, $iOffset, $iLength);
|
||||
if ($peek) {
|
||||
$this->peekCache = $out;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
private function consume($mValue = 1) {
|
||||
if (is_string($mValue)) {
|
||||
$iLength = $this->strlen($mValue);
|
||||
if (!$this->streql($this->substr($this->sText, $this->iCurrentPosition, $iLength), $mValue)) {
|
||||
throw new UnexpectedTokenException($mValue, $this->peek(max($iLength, 5)));
|
||||
}
|
||||
$this->iCurrentPosition += $this->strlen($mValue);
|
||||
$this->peekCache = null;
|
||||
return $mValue;
|
||||
} else {
|
||||
if ($this->iCurrentPosition + $mValue > $this->iLength) {
|
||||
throw new UnexpectedTokenException($mValue, $this->peek(5), 'count');
|
||||
}
|
||||
$sResult = $this->substr($this->sText, $this->iCurrentPosition, $mValue);
|
||||
$this->iCurrentPosition += $mValue;
|
||||
$this->peekCache = null;
|
||||
return $sResult;
|
||||
}
|
||||
}
|
||||
|
||||
private function consumeExpression($mExpression) {
|
||||
$aMatches = null;
|
||||
if (preg_match($mExpression, $this->inputLeft(), $aMatches, PREG_OFFSET_CAPTURE) === 1) {
|
||||
return $this->consume($aMatches[0][0]);
|
||||
}
|
||||
throw new UnexpectedTokenException($mExpression, $this->peek(5), 'expression');
|
||||
}
|
||||
|
||||
private function consumeWhiteSpace() {
|
||||
do {
|
||||
while (preg_match('/\\s/isSu', $this->peek()) === 1) {
|
||||
$this->consume(1);
|
||||
}
|
||||
if($this->oParserSettings->bLenientParsing) {
|
||||
try {
|
||||
$bHasComment = $this->consumeComment();
|
||||
} catch(UnexpectedTokenException $e) {
|
||||
// When we can’t find the end of a comment, we assume the document is finished.
|
||||
$this->iCurrentPosition = $this->iLength;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$bHasComment = $this->consumeComment();
|
||||
}
|
||||
} while($bHasComment);
|
||||
}
|
||||
|
||||
private function consumeComment() {
|
||||
if ($this->comes('/*')) {
|
||||
$this->consume(1);
|
||||
while ($this->consume(1) !== '') {
|
||||
if ($this->comes('*/')) {
|
||||
$this->consume(2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isEnd() {
|
||||
return $this->iCurrentPosition >= $this->iLength;
|
||||
}
|
||||
|
||||
private function consumeUntil($aEnd, $bIncludeEnd = false, $consumeEnd = false) {
|
||||
$aEnd = is_array($aEnd) ? $aEnd : array($aEnd);
|
||||
$out = '';
|
||||
$start = $this->iCurrentPosition;
|
||||
|
||||
while (($char = $this->consume(1)) !== '') {
|
||||
$this->consumeComment();
|
||||
if (in_array($char, $aEnd)) {
|
||||
if ($bIncludeEnd) {
|
||||
$out .= $char;
|
||||
} elseif (!$consumeEnd) {
|
||||
$this->iCurrentPosition -= $this->strlen($char);
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
$out .= $char;
|
||||
}
|
||||
|
||||
$this->iCurrentPosition = $start;
|
||||
throw new UnexpectedTokenException('One of ("'.implode('","', $aEnd).'")', $this->peek(5), 'search');
|
||||
}
|
||||
|
||||
private function inputLeft() {
|
||||
return $this->substr($this->sText, $this->iCurrentPosition, -1);
|
||||
}
|
||||
|
||||
private function substr($sString, $iStart, $iLength) {
|
||||
if ($this->oParserSettings->bMultibyteSupport) {
|
||||
return mb_substr($sString, $iStart, $iLength, $this->sCharset);
|
||||
} else {
|
||||
return substr($sString, $iStart, $iLength);
|
||||
}
|
||||
}
|
||||
|
||||
private function strlen($sString) {
|
||||
if ($this->oParserSettings->bMultibyteSupport) {
|
||||
return mb_strlen($sString, $this->sCharset);
|
||||
} else {
|
||||
return strlen($sString);
|
||||
}
|
||||
}
|
||||
|
||||
private function streql($sString1, $sString2, $bCaseInsensitive = true) {
|
||||
if($bCaseInsensitive) {
|
||||
return $this->strtolower($sString1) === $this->strtolower($sString2);
|
||||
} else {
|
||||
return $sString1 === $sString2;
|
||||
}
|
||||
}
|
||||
|
||||
private function strtolower($sString) {
|
||||
if ($this->oParserSettings->bMultibyteSupport) {
|
||||
return mb_strtolower($sString, $this->sCharset);
|
||||
} else {
|
||||
return strtolower($sString);
|
||||
}
|
||||
}
|
||||
|
||||
private function strpos($sString, $sNeedle, $iOffset) {
|
||||
if ($this->oParserSettings->bMultibyteSupport) {
|
||||
return mb_strpos($sString, $sNeedle, $iOffset, $this->sCharset);
|
||||
} else {
|
||||
return strpos($sString, $sNeedle, $iOffset);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Parsing;
|
||||
|
||||
/**
|
||||
* Thrown if the CSS parsers attempts to print something invalid
|
||||
*/
|
||||
class OutputException extends \Exception {
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Parsing;
|
||||
|
||||
/**
|
||||
* Thrown if the CSS parsers encounters a token it did not expect
|
||||
*/
|
||||
class UnexpectedTokenException extends \Exception {
|
||||
private $sExpected;
|
||||
private $sFound;
|
||||
// Possible values: literal, identifier, count, expression, search
|
||||
private $sMatchType;
|
||||
|
||||
public function __construct($sExpected, $sFound, $sMatchType = 'literal') {
|
||||
$this->sExpected = $sExpected;
|
||||
$this->sFound = $sFound;
|
||||
$this->sMatchType = $sMatchType;
|
||||
$sMessage = "Token “{$sExpected}” ({$sMatchType}) not found. Got “{$sFound}”.";
|
||||
if($this->sMatchType === 'search') {
|
||||
$sMessage = "Search for “{$sExpected}” returned no results. Context: “{$sFound}”.";
|
||||
} else if($this->sMatchType === 'count') {
|
||||
$sMessage = "Next token was expected to have {$sExpected} chars. Context: “{$sFound}”.";
|
||||
} else if($this->sMatchType === 'identifier') {
|
||||
$sMessage = "Identifier expected. Got “{$sFound}”";
|
||||
}
|
||||
parent::__construct($sMessage);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Property;
|
||||
|
||||
use Sabberworm\CSS\Renderable;
|
||||
|
||||
interface AtRule extends Renderable {
|
||||
const BLOCK_RULES = 'media/document/supports/region-style/font-feature-values';
|
||||
// Since there are more set rules than block rules, we’re whitelisting the block rules and have anything else be treated as a set rule.
|
||||
const SET_RULES = 'font-face/counter-style/page/swash/styleset/annotation'; //…and more font-specific ones (to be used inside font-feature-values)
|
||||
|
||||
public function atRuleName();
|
||||
public function atRuleArgs();
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Property;
|
||||
|
||||
/**
|
||||
* CSSNamespace represents an @namespace rule.
|
||||
*/
|
||||
class CSSNamespace implements AtRule {
|
||||
private $mUrl;
|
||||
private $sPrefix;
|
||||
|
||||
public function __construct($mUrl, $sPrefix = null) {
|
||||
$this->mUrl = $mUrl;
|
||||
$this->sPrefix = $sPrefix;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
return '@namespace '.($this->sPrefix === null ? '' : $this->sPrefix.' ').$this->mUrl->render($oOutputFormat).';';
|
||||
}
|
||||
|
||||
public function getUrl() {
|
||||
return $this->mUrl;
|
||||
}
|
||||
|
||||
public function getPrefix() {
|
||||
return $this->sPrefix;
|
||||
}
|
||||
|
||||
public function setUrl($mUrl) {
|
||||
$this->mUrl = $mUrl;
|
||||
}
|
||||
|
||||
public function setPrefix($sPrefix) {
|
||||
$this->sPrefix = $sPrefix;
|
||||
}
|
||||
|
||||
public function atRuleName() {
|
||||
return 'namespace';
|
||||
}
|
||||
|
||||
public function atRuleArgs() {
|
||||
$aResult = array($this->mUrl);
|
||||
if($this->sPrefix) {
|
||||
array_unshift($aResult, $this->sPrefix);
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Property;
|
||||
|
||||
/**
|
||||
* Class representing an @charset rule.
|
||||
* The following restrictions apply:
|
||||
* • May not be found in any CSSList other than the Document.
|
||||
* • May only appear at the very top of a Document’s contents.
|
||||
* • Must not appear more than once.
|
||||
*/
|
||||
class Charset implements AtRule {
|
||||
|
||||
private $sCharset;
|
||||
|
||||
public function __construct($sCharset) {
|
||||
$this->sCharset = $sCharset;
|
||||
}
|
||||
|
||||
public function setCharset($sCharset) {
|
||||
$this->sCharset = $sCharset;
|
||||
}
|
||||
|
||||
public function getCharset() {
|
||||
return $this->sCharset;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
return "@charset {$this->sCharset->render($oOutputFormat)};";
|
||||
}
|
||||
|
||||
public function atRuleName() {
|
||||
return 'charset';
|
||||
}
|
||||
|
||||
public function atRuleArgs() {
|
||||
return $this->sCharset;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Property;
|
||||
|
||||
use Sabberworm\CSS\Value\URL;
|
||||
|
||||
/**
|
||||
* Class representing an @import rule.
|
||||
*/
|
||||
class Import implements AtRule {
|
||||
private $oLocation;
|
||||
private $sMediaQuery;
|
||||
|
||||
public function __construct(URL $oLocation, $sMediaQuery) {
|
||||
$this->oLocation = $oLocation;
|
||||
$this->sMediaQuery = $sMediaQuery;
|
||||
}
|
||||
|
||||
public function setLocation($oLocation) {
|
||||
$this->oLocation = $oLocation;
|
||||
}
|
||||
|
||||
public function getLocation() {
|
||||
return $this->oLocation;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
return "@import ".$this->oLocation->render($oOutputFormat).($this->sMediaQuery === null ? '' : ' '.$this->sMediaQuery).';';
|
||||
}
|
||||
|
||||
public function atRuleName() {
|
||||
return 'import';
|
||||
}
|
||||
|
||||
public function atRuleArgs() {
|
||||
$aResult = array($this->oLocation);
|
||||
if($this->sMediaQuery) {
|
||||
array_push($aResult, $this->sMediaQuery);
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Property;
|
||||
|
||||
/**
|
||||
* Class representing a single CSS selector. Selectors have to be split by the comma prior to being passed into this class.
|
||||
*/
|
||||
class Selector {
|
||||
|
||||
//Regexes for specificity calculations
|
||||
const NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX = '/
|
||||
(\.[\w]+) # classes
|
||||
|
|
||||
\[(\w+) # attributes
|
||||
|
|
||||
(\:( # pseudo classes
|
||||
link|visited|active
|
||||
|hover|focus
|
||||
|lang
|
||||
|target
|
||||
|enabled|disabled|checked|indeterminate
|
||||
|root
|
||||
|nth-child|nth-last-child|nth-of-type|nth-last-of-type
|
||||
|first-child|last-child|first-of-type|last-of-type
|
||||
|only-child|only-of-type
|
||||
|empty|contains
|
||||
))
|
||||
/ix';
|
||||
|
||||
const ELEMENTS_AND_PSEUDO_ELEMENTS_RX = '/
|
||||
((^|[\s\+\>\~]+)[\w]+ # elements
|
||||
|
|
||||
\:{1,2}( # pseudo-elements
|
||||
after|before|first-letter|first-line|selection
|
||||
))
|
||||
/ix';
|
||||
|
||||
private $sSelector;
|
||||
private $iSpecificity;
|
||||
|
||||
public function __construct($sSelector, $bCalculateSpecificity = false) {
|
||||
$this->setSelector($sSelector);
|
||||
if ($bCalculateSpecificity) {
|
||||
$this->getSpecificity();
|
||||
}
|
||||
}
|
||||
|
||||
public function getSelector() {
|
||||
return $this->sSelector;
|
||||
}
|
||||
|
||||
public function setSelector($sSelector) {
|
||||
$this->sSelector = trim($sSelector);
|
||||
$this->iSpecificity = null;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->getSelector();
|
||||
}
|
||||
|
||||
public function getSpecificity() {
|
||||
if ($this->iSpecificity === null) {
|
||||
$a = 0;
|
||||
/// @todo should exclude \# as well as "#"
|
||||
$aMatches = null;
|
||||
$b = substr_count($this->sSelector, '#');
|
||||
$c = preg_match_all(self::NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX, $this->sSelector, $aMatches);
|
||||
$d = preg_match_all(self::ELEMENTS_AND_PSEUDO_ELEMENTS_RX, $this->sSelector, $aMatches);
|
||||
$this->iSpecificity = ($a * 1000) + ($b * 100) + ($c * 10) + $d;
|
||||
}
|
||||
return $this->iSpecificity;
|
||||
}
|
||||
|
||||
}
|
8
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Renderable.php
vendored
Normal file
8
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Renderable.php
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS;
|
||||
|
||||
interface Renderable {
|
||||
public function __toString();
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat);
|
||||
}
|
146
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php
vendored
Normal file
146
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php
vendored
Normal file
|
@ -0,0 +1,146 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Rule;
|
||||
|
||||
use Sabberworm\CSS\Value\RuleValueList;
|
||||
use Sabberworm\CSS\Value\Value;
|
||||
|
||||
/**
|
||||
* RuleSets contains Rule objects which always have a key and a value.
|
||||
* In CSS, Rules are expressed as follows: “key: value[0][0] value[0][1], value[1][0] value[1][1];”
|
||||
*/
|
||||
class Rule {
|
||||
|
||||
private $sRule;
|
||||
private $mValue;
|
||||
private $bIsImportant;
|
||||
|
||||
public function __construct($sRule) {
|
||||
$this->sRule = $sRule;
|
||||
$this->mValue = null;
|
||||
$this->bIsImportant = false;
|
||||
}
|
||||
|
||||
public function setRule($sRule) {
|
||||
$this->sRule = $sRule;
|
||||
}
|
||||
|
||||
public function getRule() {
|
||||
return $this->sRule;
|
||||
}
|
||||
|
||||
public function getValue() {
|
||||
return $this->mValue;
|
||||
}
|
||||
|
||||
public function setValue($mValue) {
|
||||
$this->mValue = $mValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Old-Style 2-dimensional array given. Retained for (some) backwards-compatibility. Use setValue() instead and wrapp the value inside a RuleValueList if necessary.
|
||||
*/
|
||||
public function setValues($aSpaceSeparatedValues) {
|
||||
$oSpaceSeparatedList = null;
|
||||
if (count($aSpaceSeparatedValues) > 1) {
|
||||
$oSpaceSeparatedList = new RuleValueList(' ');
|
||||
}
|
||||
foreach ($aSpaceSeparatedValues as $aCommaSeparatedValues) {
|
||||
$oCommaSeparatedList = null;
|
||||
if (count($aCommaSeparatedValues) > 1) {
|
||||
$oCommaSeparatedList = new RuleValueList(',');
|
||||
}
|
||||
foreach ($aCommaSeparatedValues as $mValue) {
|
||||
if (!$oSpaceSeparatedList && !$oCommaSeparatedList) {
|
||||
$this->mValue = $mValue;
|
||||
return $mValue;
|
||||
}
|
||||
if ($oCommaSeparatedList) {
|
||||
$oCommaSeparatedList->addListComponent($mValue);
|
||||
} else {
|
||||
$oSpaceSeparatedList->addListComponent($mValue);
|
||||
}
|
||||
}
|
||||
if (!$oSpaceSeparatedList) {
|
||||
$this->mValue = $oCommaSeparatedList;
|
||||
return $oCommaSeparatedList;
|
||||
} else {
|
||||
$oSpaceSeparatedList->addListComponent($oCommaSeparatedList);
|
||||
}
|
||||
}
|
||||
$this->mValue = $oSpaceSeparatedList;
|
||||
return $oSpaceSeparatedList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Old-Style 2-dimensional array returned. Retained for (some) backwards-compatibility. Use getValue() instead and check for the existance of a (nested set of) ValueList object(s).
|
||||
*/
|
||||
public function getValues() {
|
||||
if (!$this->mValue instanceof RuleValueList) {
|
||||
return array(array($this->mValue));
|
||||
}
|
||||
if ($this->mValue->getListSeparator() === ',') {
|
||||
return array($this->mValue->getListComponents());
|
||||
}
|
||||
$aResult = array();
|
||||
foreach ($this->mValue->getListComponents() as $mValue) {
|
||||
if (!$mValue instanceof RuleValueList || $mValue->getListSeparator() !== ',') {
|
||||
$aResult[] = array($mValue);
|
||||
continue;
|
||||
}
|
||||
if ($this->mValue->getListSeparator() === ' ' || count($aResult) === 0) {
|
||||
$aResult[] = array();
|
||||
}
|
||||
foreach ($mValue->getListComponents() as $mValue) {
|
||||
$aResult[count($aResult) - 1][] = $mValue;
|
||||
}
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a value to the existing value. Value will be appended if a RuleValueList exists of the given type. Otherwise, the existing value will be wrapped by one.
|
||||
*/
|
||||
public function addValue($mValue, $sType = ' ') {
|
||||
if (!is_array($mValue)) {
|
||||
$mValue = array($mValue);
|
||||
}
|
||||
if (!$this->mValue instanceof RuleValueList || $this->mValue->getListSeparator() !== $sType) {
|
||||
$mCurrentValue = $this->mValue;
|
||||
$this->mValue = new RuleValueList($sType);
|
||||
if ($mCurrentValue) {
|
||||
$this->mValue->addListComponent($mCurrentValue);
|
||||
}
|
||||
}
|
||||
foreach ($mValue as $mValueItem) {
|
||||
$this->mValue->addListComponent($mValueItem);
|
||||
}
|
||||
}
|
||||
|
||||
public function setIsImportant($bIsImportant) {
|
||||
$this->bIsImportant = $bIsImportant;
|
||||
}
|
||||
|
||||
public function getIsImportant() {
|
||||
return $this->bIsImportant;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
$sResult = "{$this->sRule}:{$oOutputFormat->spaceAfterRuleName()}";
|
||||
if ($this->mValue instanceof Value) { //Can also be a ValueList
|
||||
$sResult .= $this->mValue->render($oOutputFormat);
|
||||
} else {
|
||||
$sResult .= $this->mValue;
|
||||
}
|
||||
if ($this->bIsImportant) {
|
||||
$sResult .= ' !important';
|
||||
}
|
||||
$sResult .= ';';
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\RuleSet;
|
||||
|
||||
use Sabberworm\CSS\Property\AtRule;
|
||||
|
||||
/**
|
||||
* A RuleSet constructed by an unknown @-rule. @font-face rules are rendered into AtRuleSet objects.
|
||||
*/
|
||||
class AtRuleSet extends RuleSet implements AtRule {
|
||||
|
||||
private $sType;
|
||||
private $sArgs;
|
||||
|
||||
public function __construct($sType, $sArgs = '') {
|
||||
parent::__construct();
|
||||
$this->sType = $sType;
|
||||
$this->sArgs = $sArgs;
|
||||
}
|
||||
|
||||
public function atRuleName() {
|
||||
return $this->sType;
|
||||
}
|
||||
|
||||
public function atRuleArgs() {
|
||||
return $this->sArgs;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
$sArgs = $this->sArgs;
|
||||
if($sArgs) {
|
||||
$sArgs = ' ' . $sArgs;
|
||||
}
|
||||
$sResult = "@{$this->sType}$sArgs{$oOutputFormat->spaceBeforeOpeningBrace()}{";
|
||||
$sResult .= parent::render($oOutputFormat);
|
||||
$sResult .= '}';
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,608 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\RuleSet;
|
||||
|
||||
use Sabberworm\CSS\Property\Selector;
|
||||
use Sabberworm\CSS\Rule\Rule;
|
||||
use Sabberworm\CSS\Value\RuleValueList;
|
||||
use Sabberworm\CSS\Value\Value;
|
||||
use Sabberworm\CSS\Value\Size;
|
||||
use Sabberworm\CSS\Value\Color;
|
||||
use Sabberworm\CSS\Value\URL;
|
||||
use Sabberworm\CSS\Parsing\OutputException;
|
||||
|
||||
/**
|
||||
* Declaration blocks are the parts of a css file which denote the rules belonging to a selector.
|
||||
* Declaration blocks usually appear directly inside a Document or another CSSList (mostly a MediaQuery).
|
||||
*/
|
||||
class DeclarationBlock extends RuleSet {
|
||||
|
||||
private $aSelectors;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->aSelectors = array();
|
||||
}
|
||||
|
||||
public function setSelectors($mSelector) {
|
||||
if (is_array($mSelector)) {
|
||||
$this->aSelectors = $mSelector;
|
||||
} else {
|
||||
$this->aSelectors = explode(',', $mSelector);
|
||||
}
|
||||
foreach ($this->aSelectors as $iKey => $mSelector) {
|
||||
if (!($mSelector instanceof Selector)) {
|
||||
$this->aSelectors[$iKey] = new Selector($mSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove one of the selector of the block
|
||||
public function removeSelector($mSelector) {
|
||||
if($mSelector instanceof Selector) {
|
||||
$mSelector = $mSelector->getSelector();
|
||||
}
|
||||
foreach($this->aSelectors as $iKey => $oSelector) {
|
||||
if($oSelector->getSelector() === $mSelector) {
|
||||
unset($this->aSelectors[$iKey]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use getSelectors()
|
||||
*/
|
||||
public function getSelector() {
|
||||
return $this->getSelectors();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use setSelectors()
|
||||
*/
|
||||
public function setSelector($mSelector) {
|
||||
$this->setSelectors($mSelector);
|
||||
}
|
||||
|
||||
public function getSelectors() {
|
||||
return $this->aSelectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split shorthand declarations (e.g. +margin+ or +font+) into their constituent parts.
|
||||
* */
|
||||
public function expandShorthands() {
|
||||
// border must be expanded before dimensions
|
||||
$this->expandBorderShorthand();
|
||||
$this->expandDimensionsShorthand();
|
||||
$this->expandFontShorthand();
|
||||
$this->expandBackgroundShorthand();
|
||||
$this->expandListStyleShorthand();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create shorthand declarations (e.g. +margin+ or +font+) whenever possible.
|
||||
* */
|
||||
public function createShorthands() {
|
||||
$this->createBackgroundShorthand();
|
||||
$this->createDimensionsShorthand();
|
||||
// border must be shortened after dimensions
|
||||
$this->createBorderShorthand();
|
||||
$this->createFontShorthand();
|
||||
$this->createListStyleShorthand();
|
||||
}
|
||||
|
||||
/**
|
||||
* Split shorthand border declarations (e.g. <tt>border: 1px red;</tt>)
|
||||
* Additional splitting happens in expandDimensionsShorthand
|
||||
* Multiple borders are not yet supported as of 3
|
||||
* */
|
||||
public function expandBorderShorthand() {
|
||||
$aBorderRules = array(
|
||||
'border', 'border-left', 'border-right', 'border-top', 'border-bottom'
|
||||
);
|
||||
$aBorderSizes = array(
|
||||
'thin', 'medium', 'thick'
|
||||
);
|
||||
$aRules = $this->getRulesAssoc();
|
||||
foreach ($aBorderRules as $sBorderRule) {
|
||||
if (!isset($aRules[$sBorderRule]))
|
||||
continue;
|
||||
$oRule = $aRules[$sBorderRule];
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
foreach ($aValues as $mValue) {
|
||||
if ($mValue instanceof Value) {
|
||||
$mNewValue = clone $mValue;
|
||||
} else {
|
||||
$mNewValue = $mValue;
|
||||
}
|
||||
if ($mValue instanceof Size) {
|
||||
$sNewRuleName = $sBorderRule . "-width";
|
||||
} else if ($mValue instanceof Color) {
|
||||
$sNewRuleName = $sBorderRule . "-color";
|
||||
} else {
|
||||
if (in_array($mValue, $aBorderSizes)) {
|
||||
$sNewRuleName = $sBorderRule . "-width";
|
||||
} else/* if(in_array($mValue, $aBorderStyles)) */ {
|
||||
$sNewRuleName = $sBorderRule . "-style";
|
||||
}
|
||||
}
|
||||
$oNewRule = new Rule($sNewRuleName);
|
||||
$oNewRule->setIsImportant($oRule->getIsImportant());
|
||||
$oNewRule->addValue(array($mNewValue));
|
||||
$this->addRule($oNewRule);
|
||||
}
|
||||
$this->removeRule($sBorderRule);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Split shorthand dimensional declarations (e.g. <tt>margin: 0px auto;</tt>)
|
||||
* into their constituent parts.
|
||||
* Handles margin, padding, border-color, border-style and border-width.
|
||||
* */
|
||||
public function expandDimensionsShorthand() {
|
||||
$aExpansions = array(
|
||||
'margin' => 'margin-%s',
|
||||
'padding' => 'padding-%s',
|
||||
'border-color' => 'border-%s-color',
|
||||
'border-style' => 'border-%s-style',
|
||||
'border-width' => 'border-%s-width'
|
||||
);
|
||||
$aRules = $this->getRulesAssoc();
|
||||
foreach ($aExpansions as $sProperty => $sExpanded) {
|
||||
if (!isset($aRules[$sProperty]))
|
||||
continue;
|
||||
$oRule = $aRules[$sProperty];
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
$top = $right = $bottom = $left = null;
|
||||
switch (count($aValues)) {
|
||||
case 1:
|
||||
$top = $right = $bottom = $left = $aValues[0];
|
||||
break;
|
||||
case 2:
|
||||
$top = $bottom = $aValues[0];
|
||||
$left = $right = $aValues[1];
|
||||
break;
|
||||
case 3:
|
||||
$top = $aValues[0];
|
||||
$left = $right = $aValues[1];
|
||||
$bottom = $aValues[2];
|
||||
break;
|
||||
case 4:
|
||||
$top = $aValues[0];
|
||||
$right = $aValues[1];
|
||||
$bottom = $aValues[2];
|
||||
$left = $aValues[3];
|
||||
break;
|
||||
}
|
||||
foreach (array('top', 'right', 'bottom', 'left') as $sPosition) {
|
||||
$oNewRule = new Rule(sprintf($sExpanded, $sPosition));
|
||||
$oNewRule->setIsImportant($oRule->getIsImportant());
|
||||
$oNewRule->addValue(${$sPosition});
|
||||
$this->addRule($oNewRule);
|
||||
}
|
||||
$this->removeRule($sProperty);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert shorthand font declarations
|
||||
* (e.g. <tt>font: 300 italic 11px/14px verdana, helvetica, sans-serif;</tt>)
|
||||
* into their constituent parts.
|
||||
* */
|
||||
public function expandFontShorthand() {
|
||||
$aRules = $this->getRulesAssoc();
|
||||
if (!isset($aRules['font']))
|
||||
return;
|
||||
$oRule = $aRules['font'];
|
||||
// reset properties to 'normal' per http://www.w3.org/TR/21/fonts.html#font-shorthand
|
||||
$aFontProperties = array(
|
||||
'font-style' => 'normal',
|
||||
'font-variant' => 'normal',
|
||||
'font-weight' => 'normal',
|
||||
'font-size' => 'normal',
|
||||
'line-height' => 'normal'
|
||||
);
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
foreach ($aValues as $mValue) {
|
||||
if (!$mValue instanceof Value) {
|
||||
$mValue = mb_strtolower($mValue);
|
||||
}
|
||||
if (in_array($mValue, array('normal', 'inherit'))) {
|
||||
foreach (array('font-style', 'font-weight', 'font-variant') as $sProperty) {
|
||||
if (!isset($aFontProperties[$sProperty])) {
|
||||
$aFontProperties[$sProperty] = $mValue;
|
||||
}
|
||||
}
|
||||
} else if (in_array($mValue, array('italic', 'oblique'))) {
|
||||
$aFontProperties['font-style'] = $mValue;
|
||||
} else if ($mValue == 'small-caps') {
|
||||
$aFontProperties['font-variant'] = $mValue;
|
||||
} else if (
|
||||
in_array($mValue, array('bold', 'bolder', 'lighter'))
|
||||
|| ($mValue instanceof Size
|
||||
&& in_array($mValue->getSize(), range(100, 900, 100)))
|
||||
) {
|
||||
$aFontProperties['font-weight'] = $mValue;
|
||||
} else if ($mValue instanceof RuleValueList && $mValue->getListSeparator() == '/') {
|
||||
list($oSize, $oHeight) = $mValue->getListComponents();
|
||||
$aFontProperties['font-size'] = $oSize;
|
||||
$aFontProperties['line-height'] = $oHeight;
|
||||
} else if ($mValue instanceof Size && $mValue->getUnit() !== null) {
|
||||
$aFontProperties['font-size'] = $mValue;
|
||||
} else {
|
||||
$aFontProperties['font-family'] = $mValue;
|
||||
}
|
||||
}
|
||||
foreach ($aFontProperties as $sProperty => $mValue) {
|
||||
$oNewRule = new Rule($sProperty);
|
||||
$oNewRule->addValue($mValue);
|
||||
$oNewRule->setIsImportant($oRule->getIsImportant());
|
||||
$this->addRule($oNewRule);
|
||||
}
|
||||
$this->removeRule('font');
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert shorthand background declarations
|
||||
* (e.g. <tt>background: url("chess.png") gray 50% repeat fixed;</tt>)
|
||||
* into their constituent parts.
|
||||
* @see http://www.w3.org/TR/21/colors.html#propdef-background
|
||||
* */
|
||||
|
||||
public function expandBackgroundShorthand() {
|
||||
$aRules = $this->getRulesAssoc();
|
||||
if (!isset($aRules['background']))
|
||||
return;
|
||||
$oRule = $aRules['background'];
|
||||
$aBgProperties = array(
|
||||
'background-color' => array('transparent'), 'background-image' => array('none'),
|
||||
'background-repeat' => array('repeat'), 'background-attachment' => array('scroll'),
|
||||
'background-position' => array(new Size(0, '%'), new Size(0, '%'))
|
||||
);
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
if (count($aValues) == 1 && $aValues[0] == 'inherit') {
|
||||
foreach ($aBgProperties as $sProperty => $mValue) {
|
||||
$oNewRule = new Rule($sProperty);
|
||||
$oNewRule->addValue('inherit');
|
||||
$oNewRule->setIsImportant($oRule->getIsImportant());
|
||||
$this->addRule($oNewRule);
|
||||
}
|
||||
$this->removeRule('background');
|
||||
return;
|
||||
}
|
||||
$iNumBgPos = 0;
|
||||
foreach ($aValues as $mValue) {
|
||||
if (!$mValue instanceof Value) {
|
||||
$mValue = mb_strtolower($mValue);
|
||||
}
|
||||
if ($mValue instanceof URL) {
|
||||
$aBgProperties['background-image'] = $mValue;
|
||||
} else if ($mValue instanceof Color) {
|
||||
$aBgProperties['background-color'] = $mValue;
|
||||
} else if (in_array($mValue, array('scroll', 'fixed'))) {
|
||||
$aBgProperties['background-attachment'] = $mValue;
|
||||
} else if (in_array($mValue, array('repeat', 'no-repeat', 'repeat-x', 'repeat-y'))) {
|
||||
$aBgProperties['background-repeat'] = $mValue;
|
||||
} else if (in_array($mValue, array('left', 'center', 'right', 'top', 'bottom'))
|
||||
|| $mValue instanceof Size
|
||||
) {
|
||||
if ($iNumBgPos == 0) {
|
||||
$aBgProperties['background-position'][0] = $mValue;
|
||||
$aBgProperties['background-position'][1] = 'center';
|
||||
} else {
|
||||
$aBgProperties['background-position'][$iNumBgPos] = $mValue;
|
||||
}
|
||||
$iNumBgPos++;
|
||||
}
|
||||
}
|
||||
foreach ($aBgProperties as $sProperty => $mValue) {
|
||||
$oNewRule = new Rule($sProperty);
|
||||
$oNewRule->setIsImportant($oRule->getIsImportant());
|
||||
$oNewRule->addValue($mValue);
|
||||
$this->addRule($oNewRule);
|
||||
}
|
||||
$this->removeRule('background');
|
||||
}
|
||||
|
||||
public function expandListStyleShorthand() {
|
||||
$aListProperties = array(
|
||||
'list-style-type' => 'disc',
|
||||
'list-style-position' => 'outside',
|
||||
'list-style-image' => 'none'
|
||||
);
|
||||
$aListStyleTypes = array(
|
||||
'none', 'disc', 'circle', 'square', 'decimal-leading-zero', 'decimal',
|
||||
'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha', 'lower-latin',
|
||||
'upper-alpha', 'upper-latin', 'hebrew', 'armenian', 'georgian', 'cjk-ideographic',
|
||||
'hiragana', 'hira-gana-iroha', 'katakana-iroha', 'katakana'
|
||||
);
|
||||
$aListStylePositions = array(
|
||||
'inside', 'outside'
|
||||
);
|
||||
$aRules = $this->getRulesAssoc();
|
||||
if (!isset($aRules['list-style']))
|
||||
return;
|
||||
$oRule = $aRules['list-style'];
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
if (count($aValues) == 1 && $aValues[0] == 'inherit') {
|
||||
foreach ($aListProperties as $sProperty => $mValue) {
|
||||
$oNewRule = new Rule($sProperty);
|
||||
$oNewRule->addValue('inherit');
|
||||
$oNewRule->setIsImportant($oRule->getIsImportant());
|
||||
$this->addRule($oNewRule);
|
||||
}
|
||||
$this->removeRule('list-style');
|
||||
return;
|
||||
}
|
||||
foreach ($aValues as $mValue) {
|
||||
if (!$mValue instanceof Value) {
|
||||
$mValue = mb_strtolower($mValue);
|
||||
}
|
||||
if ($mValue instanceof Url) {
|
||||
$aListProperties['list-style-image'] = $mValue;
|
||||
} else if (in_array($mValue, $aListStyleTypes)) {
|
||||
$aListProperties['list-style-types'] = $mValue;
|
||||
} else if (in_array($mValue, $aListStylePositions)) {
|
||||
$aListProperties['list-style-position'] = $mValue;
|
||||
}
|
||||
}
|
||||
foreach ($aListProperties as $sProperty => $mValue) {
|
||||
$oNewRule = new Rule($sProperty);
|
||||
$oNewRule->setIsImportant($oRule->getIsImportant());
|
||||
$oNewRule->addValue($mValue);
|
||||
$this->addRule($oNewRule);
|
||||
}
|
||||
$this->removeRule('list-style');
|
||||
}
|
||||
|
||||
public function createShorthandProperties(array $aProperties, $sShorthand) {
|
||||
$aRules = $this->getRulesAssoc();
|
||||
$aNewValues = array();
|
||||
foreach ($aProperties as $sProperty) {
|
||||
if (!isset($aRules[$sProperty]))
|
||||
continue;
|
||||
$oRule = $aRules[$sProperty];
|
||||
if (!$oRule->getIsImportant()) {
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
foreach ($aValues as $mValue) {
|
||||
$aNewValues[] = $mValue;
|
||||
}
|
||||
$this->removeRule($sProperty);
|
||||
}
|
||||
}
|
||||
if (count($aNewValues)) {
|
||||
$oNewRule = new Rule($sShorthand);
|
||||
foreach ($aNewValues as $mValue) {
|
||||
$oNewRule->addValue($mValue);
|
||||
}
|
||||
$this->addRule($oNewRule);
|
||||
}
|
||||
}
|
||||
|
||||
public function createBackgroundShorthand() {
|
||||
$aProperties = array(
|
||||
'background-color', 'background-image', 'background-repeat',
|
||||
'background-position', 'background-attachment'
|
||||
);
|
||||
$this->createShorthandProperties($aProperties, 'background');
|
||||
}
|
||||
|
||||
public function createListStyleShorthand() {
|
||||
$aProperties = array(
|
||||
'list-style-type', 'list-style-position', 'list-style-image'
|
||||
);
|
||||
$this->createShorthandProperties($aProperties, 'list-style');
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine border-color, border-style and border-width into border
|
||||
* Should be run after create_dimensions_shorthand!
|
||||
* */
|
||||
public function createBorderShorthand() {
|
||||
$aProperties = array(
|
||||
'border-width', 'border-style', 'border-color'
|
||||
);
|
||||
$this->createShorthandProperties($aProperties, 'border');
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks for long format CSS dimensional properties
|
||||
* (margin, padding, border-color, border-style and border-width)
|
||||
* and converts them into shorthand CSS properties.
|
||||
* */
|
||||
|
||||
public function createDimensionsShorthand() {
|
||||
$aPositions = array('top', 'right', 'bottom', 'left');
|
||||
$aExpansions = array(
|
||||
'margin' => 'margin-%s',
|
||||
'padding' => 'padding-%s',
|
||||
'border-color' => 'border-%s-color',
|
||||
'border-style' => 'border-%s-style',
|
||||
'border-width' => 'border-%s-width'
|
||||
);
|
||||
$aRules = $this->getRulesAssoc();
|
||||
foreach ($aExpansions as $sProperty => $sExpanded) {
|
||||
$aFoldable = array();
|
||||
foreach ($aRules as $sRuleName => $oRule) {
|
||||
foreach ($aPositions as $sPosition) {
|
||||
if ($sRuleName == sprintf($sExpanded, $sPosition)) {
|
||||
$aFoldable[$sRuleName] = $oRule;
|
||||
}
|
||||
}
|
||||
}
|
||||
// All four dimensions must be present
|
||||
if (count($aFoldable) == 4) {
|
||||
$aValues = array();
|
||||
foreach ($aPositions as $sPosition) {
|
||||
$oRule = $aRules[sprintf($sExpanded, $sPosition)];
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aRuleValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aRuleValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aRuleValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
$aValues[$sPosition] = $aRuleValues;
|
||||
}
|
||||
$oNewRule = new Rule($sProperty);
|
||||
if ((string) $aValues['left'][0] == (string) $aValues['right'][0]) {
|
||||
if ((string) $aValues['top'][0] == (string) $aValues['bottom'][0]) {
|
||||
if ((string) $aValues['top'][0] == (string) $aValues['left'][0]) {
|
||||
// All 4 sides are equal
|
||||
$oNewRule->addValue($aValues['top']);
|
||||
} else {
|
||||
// Top and bottom are equal, left and right are equal
|
||||
$oNewRule->addValue($aValues['top']);
|
||||
$oNewRule->addValue($aValues['left']);
|
||||
}
|
||||
} else {
|
||||
// Only left and right are equal
|
||||
$oNewRule->addValue($aValues['top']);
|
||||
$oNewRule->addValue($aValues['left']);
|
||||
$oNewRule->addValue($aValues['bottom']);
|
||||
}
|
||||
} else {
|
||||
// No sides are equal
|
||||
$oNewRule->addValue($aValues['top']);
|
||||
$oNewRule->addValue($aValues['left']);
|
||||
$oNewRule->addValue($aValues['bottom']);
|
||||
$oNewRule->addValue($aValues['right']);
|
||||
}
|
||||
$this->addRule($oNewRule);
|
||||
foreach ($aPositions as $sPosition) {
|
||||
$this->removeRule(sprintf($sExpanded, $sPosition));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for long format CSS font properties (e.g. <tt>font-weight</tt>) and
|
||||
* tries to convert them into a shorthand CSS <tt>font</tt> property.
|
||||
* At least font-size AND font-family must be present in order to create a shorthand declaration.
|
||||
* */
|
||||
public function createFontShorthand() {
|
||||
$aFontProperties = array(
|
||||
'font-style', 'font-variant', 'font-weight', 'font-size', 'line-height', 'font-family'
|
||||
);
|
||||
$aRules = $this->getRulesAssoc();
|
||||
if (!isset($aRules['font-size']) || !isset($aRules['font-family'])) {
|
||||
return;
|
||||
}
|
||||
$oNewRule = new Rule('font');
|
||||
foreach (array('font-style', 'font-variant', 'font-weight') as $sProperty) {
|
||||
if (isset($aRules[$sProperty])) {
|
||||
$oRule = $aRules[$sProperty];
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
if ($aValues[0] !== 'normal') {
|
||||
$oNewRule->addValue($aValues[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get the font-size value
|
||||
$oRule = $aRules['font-size'];
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aFSValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aFSValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aFSValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
// But wait to know if we have line-height to add it
|
||||
if (isset($aRules['line-height'])) {
|
||||
$oRule = $aRules['line-height'];
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aLHValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aLHValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aLHValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
if ($aLHValues[0] !== 'normal') {
|
||||
$val = new RuleValueList('/');
|
||||
$val->addListComponent($aFSValues[0]);
|
||||
$val->addListComponent($aLHValues[0]);
|
||||
$oNewRule->addValue($val);
|
||||
}
|
||||
} else {
|
||||
$oNewRule->addValue($aFSValues[0]);
|
||||
}
|
||||
$oRule = $aRules['font-family'];
|
||||
$mRuleValue = $oRule->getValue();
|
||||
$aFFValues = array();
|
||||
if (!$mRuleValue instanceof RuleValueList) {
|
||||
$aFFValues[] = $mRuleValue;
|
||||
} else {
|
||||
$aFFValues = $mRuleValue->getListComponents();
|
||||
}
|
||||
$oFFValue = new RuleValueList(',');
|
||||
$oFFValue->setListComponents($aFFValues);
|
||||
$oNewRule->addValue($oFFValue);
|
||||
|
||||
$this->addRule($oNewRule);
|
||||
foreach ($aFontProperties as $sProperty) {
|
||||
$this->removeRule($sProperty);
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
if(count($this->aSelectors) === 0) {
|
||||
// If all the selectors have been removed, this declaration block becomes invalid
|
||||
throw new OutputException("Attempt to print declaration block with missing selector");
|
||||
}
|
||||
$sResult = $oOutputFormat->implode($oOutputFormat->spaceBeforeSelectorSeparator() . ',' . $oOutputFormat->spaceAfterSelectorSeparator(), $this->aSelectors) . $oOutputFormat->spaceBeforeOpeningBrace() . '{';
|
||||
$sResult .= parent::render($oOutputFormat);
|
||||
$sResult .= '}';
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
}
|
119
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/RuleSet.php
vendored
Normal file
119
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/RuleSet.php
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\RuleSet;
|
||||
|
||||
use Sabberworm\CSS\Rule\Rule;
|
||||
use Sabberworm\CSS\Renderable;
|
||||
|
||||
/**
|
||||
* RuleSet is a generic superclass denoting rules. The typical example for rule sets are declaration block.
|
||||
* However, unknown At-Rules (like @font-face) are also rule sets.
|
||||
*/
|
||||
abstract class RuleSet implements Renderable {
|
||||
|
||||
private $aRules;
|
||||
|
||||
public function __construct() {
|
||||
$this->aRules = array();
|
||||
}
|
||||
|
||||
public function addRule(Rule $oRule) {
|
||||
$sRule = $oRule->getRule();
|
||||
if(!isset($this->aRules[$sRule])) {
|
||||
$this->aRules[$sRule] = array();
|
||||
}
|
||||
$this->aRules[$sRule][] = $oRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all rules matching the given rule name
|
||||
* @param (null|string|Rule) $mRule pattern to search for. If null, returns all rules. if the pattern ends with a dash, all rules starting with the pattern are returned as well as one matching the pattern with the dash excluded. passing a Rule behaves like calling getRules($mRule->getRule()).
|
||||
* @example $oRuleSet->getRules('font-') //returns an array of all rules either beginning with font- or matching font.
|
||||
* @example $oRuleSet->getRules('font') //returns array(0 => $oRule, …) or array().
|
||||
*/
|
||||
public function getRules($mRule = null) {
|
||||
if ($mRule instanceof Rule) {
|
||||
$mRule = $mRule->getRule();
|
||||
}
|
||||
$aResult = array();
|
||||
foreach($this->aRules as $sName => $aRules) {
|
||||
// Either no search rule is given or the search rule matches the found rule exactly or the search rule ends in “-” and the found rule starts with the search rule.
|
||||
if(!$mRule || $sName === $mRule || (strrpos($mRule, '-') === strlen($mRule) - strlen('-') && (strpos($sName, $mRule) === 0 || $sName === substr($mRule, 0, -1)))) {
|
||||
$aResult = array_merge($aResult, $aRules);
|
||||
}
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all rules matching the given pattern and returns them in an associative array with the rule’s name as keys. This method exists mainly for backwards-compatibility and is really only partially useful.
|
||||
* @param (string) $mRule pattern to search for. If null, returns all rules. if the pattern ends with a dash, all rules starting with the pattern are returned as well as one matching the pattern with the dash excluded. passing a Rule behaves like calling getRules($mRule->getRule()).
|
||||
* Note: This method loses some information: Calling this (with an argument of 'background-') on a declaration block like { background-color: green; background-color; rgba(0, 127, 0, 0.7); } will only yield an associative array containing the rgba-valued rule while @link{getRules()} would yield an indexed array containing both.
|
||||
*/
|
||||
public function getRulesAssoc($mRule = null) {
|
||||
$aResult = array();
|
||||
foreach($this->getRules($mRule) as $oRule) {
|
||||
$aResult[$oRule->getRule()] = $oRule;
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a rule from this RuleSet. This accepts all the possible values that @link{getRules()} accepts. If given a Rule, it will only remove this particular rule (by identity). If given a name, it will remove all rules by that name. Note: this is different from pre-v.2.0 behaviour of PHP-CSS-Parser, where passing a Rule instance would remove all rules with the same name. To get the old behvaiour, use removeRule($oRule->getRule()).
|
||||
* @param (null|string|Rule) $mRule pattern to remove. If $mRule is null, all rules are removed. If the pattern ends in a dash, all rules starting with the pattern are removed as well as one matching the pattern with the dash excluded. Passing a Rule behaves matches by identity.
|
||||
*/
|
||||
public function removeRule($mRule) {
|
||||
if($mRule instanceof Rule) {
|
||||
$sRule = $mRule->getRule();
|
||||
if(!isset($this->aRules[$sRule])) {
|
||||
return;
|
||||
}
|
||||
foreach($this->aRules[$sRule] as $iKey => $oRule) {
|
||||
if($oRule === $mRule) {
|
||||
unset($this->aRules[$sRule][$iKey]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach($this->aRules as $sName => $aRules) {
|
||||
// Either no search rule is given or the search rule matches the found rule exactly or the search rule ends in “-” and the found rule starts with the search rule or equals it (without the trailing dash).
|
||||
if(!$mRule || $sName === $mRule || (strrpos($mRule, '-') === strlen($mRule) - strlen('-') && (strpos($sName, $mRule) === 0 || $sName === substr($mRule, 0, -1)))) {
|
||||
unset($this->aRules[$sName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
$sResult = '';
|
||||
$bIsFirst = true;
|
||||
foreach ($this->aRules as $aRules) {
|
||||
foreach($aRules as $oRule) {
|
||||
$sRendered = $oOutputFormat->safely(function() use ($oRule, $oOutputFormat) {
|
||||
return $oRule->render($oOutputFormat->nextLevel());
|
||||
});
|
||||
if($sRendered === null) {
|
||||
continue;
|
||||
}
|
||||
if($bIsFirst) {
|
||||
$bIsFirst = false;
|
||||
$sResult .= $oOutputFormat->nextLevel()->spaceBeforeRules();
|
||||
} else {
|
||||
$sResult .= $oOutputFormat->nextLevel()->spaceBetweenRules();
|
||||
}
|
||||
$sResult .= $sRendered;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$bIsFirst) {
|
||||
// Had some output
|
||||
$sResult .= $oOutputFormat->spaceAfterRules();
|
||||
}
|
||||
|
||||
return $oOutputFormat->removeLastSemicolon($sResult);
|
||||
}
|
||||
|
||||
}
|
54
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Settings.php
vendored
Normal file
54
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Settings.php
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS;
|
||||
|
||||
use Sabberworm\CSS\Rule\Rule;
|
||||
|
||||
/**
|
||||
* Parser settings class.
|
||||
*
|
||||
* Configure parser behaviour here.
|
||||
*/
|
||||
class Settings {
|
||||
/**
|
||||
* Multi-byte string support. If true (mbstring extension must be enabled), will use (slower) mb_strlen, mb_convert_case, mb_substr and mb_strpos functions. Otherwise, the normal (ASCII-Only) functions will be used.
|
||||
*/
|
||||
public $bMultibyteSupport;
|
||||
|
||||
/**
|
||||
* The default charset for the CSS if no `@charset` rule is found. Defaults to utf-8.
|
||||
*/
|
||||
public $sDefaultCharset = 'utf-8';
|
||||
|
||||
/**
|
||||
* Lenient parsing. When used (which is true by default), the parser will not choke on unexpected tokens but simply ignore them.
|
||||
*/
|
||||
public $bLenientParsing = true;
|
||||
|
||||
private function __construct() {
|
||||
$this->bMultibyteSupport = extension_loaded('mbstring');
|
||||
}
|
||||
|
||||
public static function create() {
|
||||
return new Settings();
|
||||
}
|
||||
|
||||
public function withMultibyteSupport($bMultibyteSupport = true) {
|
||||
$this->bMultibyteSupport = $bMultibyteSupport;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withDefaultCharset($sDefaultCharset) {
|
||||
$this->sDefaultCharset = $sDefaultCharset;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withLenientParsing($bLenientParsing = true) {
|
||||
$this->bLenientParsing = $bLenientParsing;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function beStrict() {
|
||||
return $this->withLenientParsing(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
class CSSFunction extends ValueList {
|
||||
|
||||
private $sName;
|
||||
|
||||
public function __construct($sName, $aArguments, $sSeparator = ',') {
|
||||
if($aArguments instanceof RuleValueList) {
|
||||
$sSeparator = $aArguments->getListSeparator();
|
||||
$aArguments = $aArguments->getListComponents();
|
||||
}
|
||||
$this->sName = $sName;
|
||||
parent::__construct($aArguments, $sSeparator);
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
public function setName($sName) {
|
||||
$this->sName = $sName;
|
||||
}
|
||||
|
||||
public function getArguments() {
|
||||
return $this->aComponents;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
$aArguments = parent::render($oOutputFormat);
|
||||
return "{$this->sName}({$aArguments})";
|
||||
}
|
||||
|
||||
}
|
41
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Color.php
vendored
Normal file
41
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Color.php
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
class Color extends CSSFunction {
|
||||
|
||||
public function __construct($aColor) {
|
||||
parent::__construct(implode('', array_keys($aColor)), $aColor);
|
||||
}
|
||||
|
||||
public function getColor() {
|
||||
return $this->aComponents;
|
||||
}
|
||||
|
||||
public function setColor($aColor) {
|
||||
$this->setName(implode('', array_keys($aColor)));
|
||||
$this->aComponents = $aColor;
|
||||
}
|
||||
|
||||
public function getColorDescription() {
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
// Shorthand RGB color values
|
||||
if($oOutputFormat->getRGBHashNotation() && implode('', array_keys($this->aComponents)) === 'rgb') {
|
||||
$sResult = sprintf(
|
||||
'%02x%02x%02x',
|
||||
$this->aComponents['r']->getSize(),
|
||||
$this->aComponents['g']->getSize(),
|
||||
$this->aComponents['b']->getSize()
|
||||
);
|
||||
return '#'.(($sResult[0] == $sResult[1]) && ($sResult[2] == $sResult[3]) && ($sResult[4] == $sResult[5]) ? "$sResult[0]$sResult[2]$sResult[4]" : $sResult);
|
||||
}
|
||||
return parent::render($oOutputFormat);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
abstract class PrimitiveValue extends Value {
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
class RuleValueList extends ValueList {
|
||||
|
||||
public function __construct($sSeparator = ',') {
|
||||
parent::__construct(array(), $sSeparator);
|
||||
}
|
||||
|
||||
}
|
72
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Size.php
vendored
Normal file
72
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Size.php
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
class Size extends PrimitiveValue {
|
||||
|
||||
const ABSOLUTE_SIZE_UNITS = 'px/cm/mm/mozmm/in/pt/pc/vh/vw/vm/vmin/vmax/rem'; //vh/vw/vm(ax)/vmin/rem are absolute insofar as they don’t scale to the immediate parent (only the viewport)
|
||||
const RELATIVE_SIZE_UNITS = '%/em/ex/ch/fr';
|
||||
const NON_SIZE_UNITS = 'deg/grad/rad/s/ms/turns/Hz/kHz';
|
||||
|
||||
private $fSize;
|
||||
private $sUnit;
|
||||
private $bIsColorComponent;
|
||||
|
||||
public function __construct($fSize, $sUnit = null, $bIsColorComponent = false) {
|
||||
$this->fSize = floatval($fSize);
|
||||
$this->sUnit = $sUnit;
|
||||
$this->bIsColorComponent = $bIsColorComponent;
|
||||
}
|
||||
|
||||
public function setUnit($sUnit) {
|
||||
$this->sUnit = $sUnit;
|
||||
}
|
||||
|
||||
public function getUnit() {
|
||||
return $this->sUnit;
|
||||
}
|
||||
|
||||
public function setSize($fSize) {
|
||||
$this->fSize = floatval($fSize);
|
||||
}
|
||||
|
||||
public function getSize() {
|
||||
return $this->fSize;
|
||||
}
|
||||
|
||||
public function isColorComponent() {
|
||||
return $this->bIsColorComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the number stored in this Size really represents a size (as in a length of something on screen).
|
||||
* @return false if the unit an angle, a duration, a frequency or the number is a component in a Color object.
|
||||
*/
|
||||
public function isSize() {
|
||||
if (in_array($this->sUnit, explode('/', self::NON_SIZE_UNITS))) {
|
||||
return false;
|
||||
}
|
||||
return !$this->isColorComponent();
|
||||
}
|
||||
|
||||
public function isRelative() {
|
||||
if (in_array($this->sUnit, explode('/', self::RELATIVE_SIZE_UNITS))) {
|
||||
return true;
|
||||
}
|
||||
if ($this->sUnit === null && $this->fSize != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
$l = localeconv();
|
||||
$sPoint = preg_quote($l['decimal_point'], '/');
|
||||
return preg_replace(array("/$sPoint/", "/^(-?)0\./"), array('.', '$1.'), $this->fSize) . ($this->sUnit === null ? '' : $this->sUnit);
|
||||
}
|
||||
|
||||
}
|
31
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/String.php
vendored
Normal file
31
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/String.php
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
class String extends PrimitiveValue {
|
||||
|
||||
private $sString;
|
||||
|
||||
public function __construct($sString) {
|
||||
$this->sString = $sString;
|
||||
}
|
||||
|
||||
public function setString($sString) {
|
||||
$this->sString = $sString;
|
||||
}
|
||||
|
||||
public function getString() {
|
||||
return $this->sString;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
$sString = addslashes($this->sString);
|
||||
$sString = str_replace("\n", '\A', $sString);
|
||||
return $oOutputFormat->getStringQuotingType() . $sString . $oOutputFormat->getStringQuotingType();
|
||||
}
|
||||
|
||||
}
|
30
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/URL.php
vendored
Normal file
30
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/URL.php
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
|
||||
class URL extends PrimitiveValue {
|
||||
|
||||
private $oURL;
|
||||
|
||||
public function __construct(String $oURL) {
|
||||
$this->oURL = $oURL;
|
||||
}
|
||||
|
||||
public function setURL(String $oURL) {
|
||||
$this->oURL = $oURL;
|
||||
}
|
||||
|
||||
public function getURL() {
|
||||
return $this->oURL;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
return "url({$this->oURL->render($oOutputFormat)})";
|
||||
}
|
||||
|
||||
}
|
11
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Value.php
vendored
Normal file
11
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Value.php
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
use Sabberworm\CSS\Renderable;
|
||||
|
||||
abstract class Value implements Renderable {
|
||||
//Methods are commented out because re-declaring them here is a fatal error in PHP < 5.3.9
|
||||
//public abstract function __toString();
|
||||
//public abstract function render(\Sabberworm\CSS\OutputFormat $oOutputFormat);
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Sabberworm\CSS\Value;
|
||||
|
||||
abstract class ValueList extends Value {
|
||||
|
||||
protected $aComponents;
|
||||
protected $sSeparator;
|
||||
|
||||
public function __construct($aComponents = array(), $sSeparator = ',') {
|
||||
if (!is_array($aComponents)) {
|
||||
$aComponents = array($aComponents);
|
||||
}
|
||||
$this->aComponents = $aComponents;
|
||||
$this->sSeparator = $sSeparator;
|
||||
}
|
||||
|
||||
public function addListComponent($mComponent) {
|
||||
$this->aComponents[] = $mComponent;
|
||||
}
|
||||
|
||||
public function getListComponents() {
|
||||
return $this->aComponents;
|
||||
}
|
||||
|
||||
public function setListComponents($aComponents) {
|
||||
$this->aComponents = $aComponents;
|
||||
}
|
||||
|
||||
public function getListSeparator() {
|
||||
return $this->sSeparator;
|
||||
}
|
||||
|
||||
public function setListSeparator($sSeparator) {
|
||||
$this->sSeparator = $sSeparator;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->render(new \Sabberworm\CSS\OutputFormat());
|
||||
}
|
||||
|
||||
public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
|
||||
return $oOutputFormat->implode($oOutputFormat->spaceBeforeListArgumentSeparator($this->sSeparator) . $this->sSeparator . $oOutputFormat->spaceAfterListArgumentSeparator($this->sSeparator), $this->aComponents);
|
||||
}
|
||||
|
||||
}
|
1
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/phpunit.xml
vendored
Normal file
1
sites/all/modules/civicrm/vendor/sabberworm/php-css-parser/phpunit.xml
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<phpunit bootstrap="tests/bootstrap.php"></phpunit>
|
Loading…
Add table
Add a link
Reference in a new issue