From 7ec39fa8fefd1dba42197e099671ea1337bb69f1 Mon Sep 17 00:00:00 2001 From: Ewout Fernhout Date: Mon, 12 Jun 2017 16:26:21 +0200 Subject: [PATCH] update some vendor libraries to resolve PHP 7.0 issues --- composer.json | 3 +- composer.lock | 45 +- vendor/phenx/php-svg-lib/composer.json | 5 +- .../src/Svg/Surface/SurfaceCpdf.php | 10 +- .../src/Svg/Surface/SurfaceGmagick.php | 4 +- .../src/Svg/Surface/SurfacePDFLib.php | 4 +- .../phenx/php-svg-lib/src/Svg/Tag/Shape.php | 6 +- .../phenx/php-svg-lib/tests/Svg/StyleTest.php | 60 +- vendor/sabberworm/php-css-parser/.travis.yml | 3 + vendor/sabberworm/php-css-parser/CHANGELOG.md | 55 +- vendor/sabberworm/php-css-parser/Doxyfile | 4 +- vendor/sabberworm/php-css-parser/README.md | 824 ++++++----- .../sabberworm/php-css-parser/composer.json | 3 + .../sabberworm/php-css-parser/composer.lock | 1317 +++++++++++++++++ .../CSS/CSSList/AtRuleBlockList.php | 4 +- .../Sabberworm/CSS/CSSList/CSSBlockList.php | 6 +- .../lib/Sabberworm/CSS/CSSList/CSSList.php | 53 +- .../lib/Sabberworm/CSS/CSSList/Document.php | 7 + .../lib/Sabberworm/CSS/CSSList/KeyFrame.php | 4 +- .../lib/Sabberworm/CSS/Comment/Comment.php | 51 + .../Sabberworm/CSS/Comment/Commentable.php | 23 + .../lib/Sabberworm/CSS/Parser.php | 277 ++-- .../CSS/Parsing/OutputException.php | 5 +- .../CSS/Parsing/SourceException.php | 18 + .../CSS/Parsing/UnexpectedTokenException.php | 9 +- .../lib/Sabberworm/CSS/Property/AtRule.php | 3 +- .../Sabberworm/CSS/Property/CSSNamespace.php | 27 +- .../lib/Sabberworm/CSS/Property/Charset.php | 25 +- .../lib/Sabberworm/CSS/Property/Import.php | 27 +- .../lib/Sabberworm/CSS/Renderable.php | 1 + .../lib/Sabberworm/CSS/Rule/Rule.php | 61 +- .../lib/Sabberworm/CSS/RuleSet/AtRuleSet.php | 4 +- .../CSS/RuleSet/DeclarationBlock.php | 32 +- .../lib/Sabberworm/CSS/RuleSet/RuleSet.php | 64 +- .../lib/Sabberworm/CSS/Value/CSSFunction.php | 5 +- .../CSS/Value/{String.php => CSSString.php} | 5 +- .../lib/Sabberworm/CSS/Value/Color.php | 4 +- .../Sabberworm/CSS/Value/PrimitiveValue.php | 5 +- .../Sabberworm/CSS/Value/RuleValueList.php | 6 +- .../lib/Sabberworm/CSS/Value/Size.php | 3 +- .../lib/Sabberworm/CSS/Value/URL.php | 5 +- .../lib/Sabberworm/CSS/Value/Value.php | 15 +- .../lib/Sabberworm/CSS/Value/ValueList.php | 3 +- vendor/sabberworm/php-css-parser/phpunit.xml | 11 +- .../CSS/CSSList/AtRuleBlockListTest.php | 27 + .../Sabberworm/CSS/CSSList/DocumentTest.php | 26 + .../tests/Sabberworm/CSS/ParserTest.php | 217 ++- .../CSS/RuleSet/DeclarationBlockTest.php | 59 + .../tests/files/-charset-after-rule.css | 5 + .../tests/files/-charset-in-block.css | 3 + .../php-css-parser/tests/files/-empty.css | 0 .../php-css-parser/tests/files/-tobedone.css | 6 + .../php-css-parser/tests/files/comments.css | 1 + .../php-css-parser/tests/files/ie-hacks.css | 9 + .../tests/files/line-numbers.css | 32 + .../php-css-parser/tests/files/url.css | 4 + .../php-css-parser/tests/quickdump.php | 13 +- 57 files changed, 2922 insertions(+), 586 deletions(-) create mode 100644 vendor/sabberworm/php-css-parser/composer.lock create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Comment/Comment.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Comment/Commentable.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/SourceException.php rename vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/{String.php => CSSString.php} (82%) create mode 100644 vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/CSSList/AtRuleBlockListTest.php create mode 100644 vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/CSSList/DocumentTest.php create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-charset-after-rule.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-charset-in-block.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-empty.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/ie-hacks.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/line-numbers.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/url.css diff --git a/composer.json b/composer.json index 5386e79fa..7e2ad22e7 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,7 @@ { "require": { "php": ">=5.3.0", - "dompdf/dompdf": "*" + "dompdf/dompdf": "*", + "phenx/php-svg-lib": "dev-master as 0.2" } } \ No newline at end of file diff --git a/composer.lock b/composer.lock index 0984f225f..fb0c84757 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "6472a5f257de58c04c8a7c78a08db897", - "content-hash": "7e8e737c6fffa1c43aefc1018cab381f", + "hash": "6d43636f50a06155e4d904151f2d229a", + "content-hash": "e1f5c7e5728bea51e82dd00ecedf7583", "packages": [ { "name": "dompdf/dompdf", @@ -108,20 +108,23 @@ }, { "name": "phenx/php-svg-lib", - "version": "v0.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/PhenX/php-svg-lib.git", - "reference": "de291bec8449b89acfe85691b5c71434797959dc" + "reference": "a85f7fe9fe08d093a4a8583cdd306b553ff918aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PhenX/php-svg-lib/zipball/de291bec8449b89acfe85691b5c71434797959dc", - "reference": "de291bec8449b89acfe85691b5c71434797959dc", + "url": "https://api.github.com/repos/PhenX/php-svg-lib/zipball/a85f7fe9fe08d093a4a8583cdd306b553ff918aa", + "reference": "a85f7fe9fe08d093a4a8583cdd306b553ff918aa", "shasum": "" }, "require": { - "sabberworm/php-css-parser": "6.0.*" + "sabberworm/php-css-parser": "8.1.*" + }, + "require-dev": { + "phpunit/phpunit": "~5.0" }, "type": "library", "autoload": { @@ -141,25 +144,28 @@ ], "description": "A library to read, parse and export to PDF SVG files.", "homepage": "https://github.com/PhenX/php-svg-lib", - "time": "2016-12-13 20:25:45" + "time": "2017-05-24 10:07:27" }, { "name": "sabberworm/php-css-parser", - "version": "6.0.1", + "version": "8.1.0", "source": { "type": "git", "url": "https://github.com/sabberworm/PHP-CSS-Parser.git", - "reference": "9ea4b00c569b19f731d0c2e0e802055877ff40c2" + "reference": "850cbbcbe7fbb155387a151ea562897a67e242ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/9ea4b00c569b19f731d0c2e0e802055877ff40c2", - "reference": "9ea4b00c569b19f731d0c2e0e802055877ff40c2", + "url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/850cbbcbe7fbb155387a151ea562897a67e242ef", + "reference": "850cbbcbe7fbb155387a151ea562897a67e242ef", "shasum": "" }, "require": { "php": ">=5.3.2" }, + "require-dev": { + "phpunit/phpunit": "*" + }, "type": "library", "autoload": { "psr-0": { @@ -182,13 +188,22 @@ "parser", "stylesheet" ], - "time": "2015-08-24 08:48:52" + "time": "2016-07-19 19:14:21" } ], "packages-dev": [], - "aliases": [], + "aliases": [ + { + "alias": "0.2", + "alias_normalized": "0.2.0.0", + "version": "9999999-dev", + "package": "phenx/php-svg-lib" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "phenx/php-svg-lib": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/vendor/phenx/php-svg-lib/composer.json b/vendor/phenx/php-svg-lib/composer.json index 705331613..16f9ec0be 100644 --- a/vendor/phenx/php-svg-lib/composer.json +++ b/vendor/phenx/php-svg-lib/composer.json @@ -16,6 +16,9 @@ } }, "require": { - "sabberworm/php-css-parser": "6.0.*" + "sabberworm/php-css-parser": "8.1.*" + }, + "require-dev": { + "phpunit/phpunit": "~5.0" } } diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php index 9dc7ff65d..2e9130441 100644 --- a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php @@ -376,12 +376,12 @@ public function setStyle(Style $style) $this->style = $style; $canvas = $this->canvas; - if ($stroke = $style->stroke) { - $canvas->setStrokeColor(array($stroke[0]/255, $stroke[1]/255, $stroke[2]/255), true); + if (is_array($style->stroke) && $stroke = $style->stroke) { + $canvas->setStrokeColor(array((float)$stroke[0]/255, (float)$stroke[1]/255, (float)$stroke[2]/255), true); } - if ($fill = $style->fill) { - $canvas->setColor(array($fill[0]/255, $fill[1]/255, $fill[2]/255), true); + if (is_array($style->fill) && $fill = $style->fill) { + $canvas->setColor(array((float)$fill[0]/255, (float)$fill[1]/255, (float)$fill[2]/255), true); } if ($fillRule = strtolower($style->fillRule)) { @@ -483,4 +483,4 @@ public function setFont($family, $style, $weight) $this->canvas->selectFont("$family.afm"); } -} \ No newline at end of file +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceGmagick.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceGmagick.php index 96e05ad5f..c74d60191 100644 --- a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceGmagick.php +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceGmagick.php @@ -256,11 +256,11 @@ public function setStyle(Style $style) $this->style = $style; $canvas = $this->canvas; - if ($stroke = $style->stroke) { + if (is_array($style->stroke) && $stroke = $style->stroke) { $canvas->setcolor("stroke", "rgb", $stroke[0] / 255, $stroke[1] / 255, $stroke[2] / 255, null); } - if ($fill = $style->fill) { + if (is_array($style->fill) && $fill = $style->fill) { // $canvas->setcolor("fill", "rgb", $fill[0] / 255, $fill[1] / 255, $fill[2] / 255, null); } diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php index f355ef780..f31d560a4 100644 --- a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php @@ -315,7 +315,7 @@ public function setStyle(Style $style) $this->style = $style; $canvas = $this->canvas; - if (($stroke = $style->stroke) && $stroke !== "none") { + if ($stroke = $style->stroke && is_array($style->stroke)) { $canvas->setcolor( "stroke", "rgb", @@ -326,7 +326,7 @@ public function setStyle(Style $style) ); } - if (($fill = $style->fill) && $fill !== "none") { + if ($fill = $style->fill && is_array($style->fill)) { $canvas->setcolor( "fill", "rgb", diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php index 28debe2d4..1d7a12725 100644 --- a/vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php @@ -2,7 +2,7 @@ /** * @package php-svg-lib * @link http://github.com/PhenX/php-svg-lib - * @author Fabien Ménager + * @author Fabien MĂ©nager * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ @@ -33,8 +33,8 @@ protected function after() if ($this->hasShape) { $style = $surface->getStyle(); - $fill = $style->fill && $style->fill !== "none"; - $stroke = $style->stroke && $style->stroke !== "none"; + $fill = $style->fill && is_array($style->fill); + $stroke = $style->stroke && is_array($style->stroke); if ($fill) { if ($stroke) { diff --git a/vendor/phenx/php-svg-lib/tests/Svg/StyleTest.php b/vendor/phenx/php-svg-lib/tests/Svg/StyleTest.php index 421e11f14..341e4a988 100644 --- a/vendor/phenx/php-svg-lib/tests/Svg/StyleTest.php +++ b/vendor/phenx/php-svg-lib/tests/Svg/StyleTest.php @@ -8,39 +8,53 @@ namespace Svg\Tests; -include_once __DIR__."/../../src/autoload.php"; +include_once __DIR__ . "/../../src/autoload.php"; use Svg\Style; -class StyleTest extends \PHPUnit_Framework_TestCase { - public function test_parseColor() { - $this->assertEquals("none", Style::parseColor("none")); - $this->assertEquals(array(255, 0, 0), Style::parseColor("RED")); - $this->assertEquals(array(0, 0, 255), Style::parseColor("blue")); - $this->assertEquals(null, Style::parseColor("foo")); - } +class StyleTest extends \PHPUnit_Framework_TestCase +{ + + public function test_parseColor() + { + $this->assertEquals("none", Style::parseColor("none")); + $this->assertEquals(array(255, 0, 0), Style::parseColor("RED")); + $this->assertEquals(array(0, 0, 255), Style::parseColor("blue")); + $this->assertEquals(null, Style::parseColor("foo")); + $this->assertEquals(array(0, 0, 0), Style::parseColor("black")); + $this->assertEquals(array(255, 255, 255), Style::parseColor("white")); + $this->assertEquals(array(0, 0, 0), Style::parseColor("#000000")); + $this->assertEquals(array(255, 255, 255), Style::parseColor("#ffffff")); + $this->assertEquals(array(0, 0, 0), Style::parseColor("rgb(0,0,0)")); + $this->assertEquals(array(255, 255, 255), Style::parseColor("rgb(255,255,255)")); + $this->assertEquals(array(0, 0, 0), Style::parseColor("rgb(0, 0, 0)")); + $this->assertEquals(array(255, 255, 255), Style::parseColor("rgb(255, 255, 255)")); + } - public function test_fromAttributes() { - $style = new Style(); + public function test_fromAttributes() + { + $style = new Style(); - $attributes = array( - "color" => "blue", - "fill" => "#fff", - "stroke" => "none", - ); + $attributes = array( + "color" => "blue", + "fill" => "#fff", + "stroke" => "none", + ); - $style->fromAttributes($attributes); + $style->fromAttributes($attributes); - $this->assertEquals(array(0, 0, 255), $style->color); - $this->assertEquals(array(255, 255, 255), $style->fill); - $this->assertEquals("none", $style->stroke); - } + $this->assertEquals(array(0, 0, 255), $style->color); + $this->assertEquals(array(255, 255, 255), $style->fill); + $this->assertEquals("none", $style->stroke); + } - public function test_convertSize(){ - $this->assertEquals(1, Style::convertSize(1)); + public function test_convertSize() + { + $this->assertEquals(1, Style::convertSize(1)); $this->assertEquals(10, Style::convertSize("10px")); // FIXME $this->assertEquals(10, Style::convertSize("10pt")); - $this->assertEquals(8, Style::convertSize("80%", 10, 72)); + $this->assertEquals(8, Style::convertSize("80%", 10, 72)); } + } \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/.travis.yml b/vendor/sabberworm/php-css-parser/.travis.yml index c6ad6600f..d2aeb0239 100644 --- a/vendor/sabberworm/php-css-parser/.travis.yml +++ b/vendor/sabberworm/php-css-parser/.travis.yml @@ -4,6 +4,9 @@ php: - "5.3" - "5.5" - "5.6" + - "7.0" + - "nightly" - hhvm script: phpunit . +sudo: false diff --git a/vendor/sabberworm/php-css-parser/CHANGELOG.md b/vendor/sabberworm/php-css-parser/CHANGELOG.md index 4737018ed..2c3c5ea5b 100644 --- a/vendor/sabberworm/php-css-parser/CHANGELOG.md +++ b/vendor/sabberworm/php-css-parser/CHANGELOG.md @@ -1,5 +1,54 @@ # Revision History +## 8.0 + +### 8.0.0 (2016-06-30) + +* Store source CSS line numbers in tokens and parsing exceptions. +* *No deprecations* + +#### Backwards-incompatible changes + +* Unrecoverable parser errors throw an exception of type `Sabberworm\CSS\Parsing\SourceException` instead of `\Exception`. + +### 8.1.0 (2016-07-19) + +* Comments are no longer silently ignored but stored with the object with which they appear (no render support, though). Thanks to @FMCorz. +* The IE hacks using `\0` and `\9` can now be parsed (and rendered) in lenient mode. Thanks (again) to @FMCorz. +* Media queries with or without spaces before the query are parsed. Still no *real* parsing support, though. Sorry… +* PHPUnit is now listed as a dev-dependency in composer.json. +* *No backwards-incompatible changes* +* *No deprecations* + +## 7.0 + +### 7.0.0 (2015-08-24) + +* Compatibility with PHP 7. Well timed, eh? +* *No deprecations* + +#### Backwards-incompatible changes + +* The `Sabberworm\CSS\Value\String` class has been renamed to `Sabberworm\CSS\Value\CSSString`. + +### 7.0.1 (2015-12-25) + +* No more suppressed `E_NOTICE` +* *No backwards-incompatible changes* +* *No deprecations* + +### 7.0.2 (2016-02-11) + +* 150 time performance boost thanks to @[ossinkine](https://github.com/ossinkine) +* *No backwards-incompatible changes* +* *No deprecations* + +### 7.0.3 (2016-04-27) + +* Fixed parsing empty CSS when multibyte is off +* *No backwards-incompatible changes* +* *No deprecations* + ## 6.0 ### 6.0.0 (2014-07-03) @@ -11,7 +60,7 @@ * The parse() method replaces __toString with an optional argument (instance of the OutputFormat class) -### 6.0.1 (2014-08-24) +### 6.0.1 (2015-08-24) * Remove some declarations in interfaces incompatible with PHP 5.3 (< 5.3.9) * *No deprecations* @@ -92,7 +141,9 @@ ### 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 **/” +* Remove the use of consumeUntil in comment parsing. This makes it possible to parse comments such as `/** Perfectly valid **/` +* Add fr relative size unit +* Fix some issues with HHVM * *No backwards-incompatible changes* * *No deprecations* diff --git a/vendor/sabberworm/php-css-parser/Doxyfile b/vendor/sabberworm/php-css-parser/Doxyfile index ba7e949c3..acc9d3bde 100644 --- a/vendor/sabberworm/php-css-parser/Doxyfile +++ b/vendor/sabberworm/php-css-parser/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Sabberworm/PHP-CSS-Parser" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "6.0.0" +PROJECT_NUMBER = "7.0.3" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -152,7 +152,7 @@ FULL_PATH_NAMES = YES # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = +STRIP_FROM_PATH = ./lib # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which diff --git a/vendor/sabberworm/php-css-parser/README.md b/vendor/sabberworm/php-css-parser/README.md index 2297e9f20..48a95b217 100644 --- a/vendor/sabberworm/php-css-parser/README.md +++ b/vendor/sabberworm/php-css-parser/README.md @@ -1,7 +1,7 @@ PHP CSS Parser -------------- -[![build status](https://travis-ci.org/sabberworm/PHP-CSS-Parser.png)](https://travis-ci.org/sabberworm/PHP-CSS-Parser) [![HHVM Status](http://hhvm.h4cc.de/badge/sabberworm/php-css-parser.png)](http://hhvm.h4cc.de/package/sabberworm/php-css-parser) +[![build status](https://api.travis-ci.org/sabberworm/PHP-CSS-Parser.svg)](https://travis-ci.org/sabberworm/PHP-CSS-Parser) [![HHVM Status](http://hhvm.h4cc.de/badge/sabberworm/php-css-parser.svg)](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. @@ -11,22 +11,28 @@ A Parser for CSS Files written in PHP. Allows extraction of CSS files into a dat Add php-css-parser to your composer.json - { - "require": { - "sabberworm/php-css-parser": "*" - } - } +```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); +```php +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(); +```php +$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. @@ -36,21 +42,27 @@ The resulting CSS document structure can be manipulated prior to being output. 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); +```php +$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()); +```php +$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); +```php +$oSettings = Sabberworm\CSS\Settings::create()->withMultibyteSupport(false); +new Sabberworm\CSS\Parser($sText, $oSettings); +``` ### Manipulation @@ -88,7 +100,7 @@ If you want to manipulate a `RuleSet`, use the methods `addRule(Rule $oRule)`, ` * `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. +* `CSSString` – 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: @@ -114,52 +126,64 @@ There are a few convenience methods on Document to ease finding, manipulating an ### 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()); - } +```php +$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); - } +```php +$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'); - } +```php +$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(); +```php +$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); +```php +$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()); +```php +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`. @@ -169,344 +193,428 @@ To see what you can do with output formatting, look at the tests in `tests/Sabbe #### Input - @charset "utf-8"; +```css +@charset "utf-8"; - @font-face { - font-family: "CrassRoots"; - src: url("../media/cr.ttf") - } +@font-face { + font-family: "CrassRoots"; + src: url("../media/cr.ttf") +} - html, body { - font-size: 1.6em - } +html, body { + font-size: 1.6em +} - @keyframes mymove { - from { top: 0px; } - to { top: 200px; } - } +@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) - } - } - } - } - } - } - } - } +```php +class Sabberworm\CSS\CSSList\Document#4 (2) { + protected $aContents => + array(4) { + [0] => + class Sabberworm\CSS\Property\Charset#6 (2) { + private $sCharset => + class Sabberworm\CSS\Value\CSSString#5 (2) { + private $sString => + string(5) "utf-8" + protected $iLineNo => + int(1) + } + protected $iLineNo => + int(1) + } + [1] => + class Sabberworm\CSS\RuleSet\AtRuleSet#7 (4) { + private $sType => + string(9) "font-face" + private $sArgs => + string(0) "" + private $aRules => + array(2) { + 'font-family' => + array(1) { + [0] => + class Sabberworm\CSS\Rule\Rule#8 (4) { + private $sRule => + string(11) "font-family" + private $mValue => + class Sabberworm\CSS\Value\CSSString#9 (2) { + private $sString => + string(10) "CrassRoots" + protected $iLineNo => + int(4) + } + private $bIsImportant => + bool(false) + protected $iLineNo => + int(4) + } + } + 'src' => + array(1) { + [0] => + class Sabberworm\CSS\Rule\Rule#10 (4) { + private $sRule => + string(3) "src" + private $mValue => + class Sabberworm\CSS\Value\URL#11 (2) { + private $oURL => + class Sabberworm\CSS\Value\CSSString#12 (2) { + private $sString => + string(15) "../media/cr.ttf" + protected $iLineNo => + int(5) + } + protected $iLineNo => + int(5) + } + private $bIsImportant => + bool(false) + protected $iLineNo => + int(5) + } + } + } + protected $iLineNo => + int(3) + } + [2] => + class Sabberworm\CSS\RuleSet\DeclarationBlock#13 (3) { + private $aSelectors => + array(2) { + [0] => + class Sabberworm\CSS\Property\Selector#14 (2) { + private $sSelector => + string(4) "html" + private $iSpecificity => + NULL + } + [1] => + class Sabberworm\CSS\Property\Selector#15 (2) { + private $sSelector => + string(4) "body" + private $iSpecificity => + NULL + } + } + private $aRules => + array(1) { + 'font-size' => + array(1) { + [0] => + class Sabberworm\CSS\Rule\Rule#16 (4) { + private $sRule => + string(9) "font-size" + private $mValue => + class Sabberworm\CSS\Value\Size#17 (4) { + private $fSize => + double(1.6) + private $sUnit => + string(2) "em" + private $bIsColorComponent => + bool(false) + protected $iLineNo => + int(9) + } + private $bIsImportant => + bool(false) + protected $iLineNo => + int(9) + } + } + } + protected $iLineNo => + int(8) + } + [3] => + class Sabberworm\CSS\CSSList\KeyFrame#18 (4) { + private $vendorKeyFrame => + string(9) "keyframes" + private $animationName => + string(6) "mymove" + protected $aContents => + array(2) { + [0] => + class Sabberworm\CSS\RuleSet\DeclarationBlock#19 (3) { + private $aSelectors => + array(1) { + [0] => + class Sabberworm\CSS\Property\Selector#20 (2) { + private $sSelector => + string(4) "from" + private $iSpecificity => + NULL + } + } + private $aRules => + array(1) { + 'top' => + array(1) { + [0] => + class Sabberworm\CSS\Rule\Rule#21 (4) { + private $sRule => + string(3) "top" + private $mValue => + class Sabberworm\CSS\Value\Size#22 (4) { + private $fSize => + double(0) + private $sUnit => + string(2) "px" + private $bIsColorComponent => + bool(false) + protected $iLineNo => + int(13) + } + private $bIsImportant => + bool(false) + protected $iLineNo => + int(13) + } + } + } + protected $iLineNo => + int(13) + } + [1] => + class Sabberworm\CSS\RuleSet\DeclarationBlock#23 (3) { + private $aSelectors => + array(1) { + [0] => + class Sabberworm\CSS\Property\Selector#24 (2) { + private $sSelector => + string(2) "to" + private $iSpecificity => + NULL + } + } + private $aRules => + array(1) { + 'top' => + array(1) { + [0] => + class Sabberworm\CSS\Rule\Rule#25 (4) { + private $sRule => + string(3) "top" + private $mValue => + class Sabberworm\CSS\Value\Size#26 (4) { + private $fSize => + double(200) + private $sUnit => + string(2) "px" + private $bIsColorComponent => + bool(false) + protected $iLineNo => + int(14) + } + private $bIsImportant => + bool(false) + protected $iLineNo => + int(14) + } + } + } + protected $iLineNo => + int(14) + } + } + protected $iLineNo => + int(12) + } + } + protected $iLineNo => + int(1) +} + +``` #### 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;} - } +```css +@charset "utf-8"; +@font-face {font-family: "CrassRoots";src: url("../media/cr.ttf");} +html, body {font-size: 1.6em;} +@keyframes mymove {from {top: 0px;} + to {top: 200px;}} +``` ### Example 2 (Values) #### Input - #header { - margin: 10px 2em 1cm 2%; - font-family: Verdana, Helvetica, "Gill Sans", sans-serif; - color: red !important; - } - +```css +#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) - } - } - } - } - } - } +```php +class Sabberworm\CSS\CSSList\Document#4 (2) { + protected $aContents => + array(1) { + [0] => + class Sabberworm\CSS\RuleSet\DeclarationBlock#5 (3) { + private $aSelectors => + array(1) { + [0] => + class Sabberworm\CSS\Property\Selector#6 (2) { + private $sSelector => + string(7) "#header" + private $iSpecificity => + NULL + } + } + private $aRules => + array(3) { + 'margin' => + array(1) { + [0] => + class Sabberworm\CSS\Rule\Rule#7 (4) { + private $sRule => + string(6) "margin" + private $mValue => + class Sabberworm\CSS\Value\RuleValueList#12 (3) { + protected $aComponents => + array(4) { + [0] => + class Sabberworm\CSS\Value\Size#8 (4) { + private $fSize => + double(10) + private $sUnit => + string(2) "px" + private $bIsColorComponent => + bool(false) + protected $iLineNo => + int(2) + } + [1] => + class Sabberworm\CSS\Value\Size#9 (4) { + private $fSize => + double(2) + private $sUnit => + string(2) "em" + private $bIsColorComponent => + bool(false) + protected $iLineNo => + int(2) + } + [2] => + class Sabberworm\CSS\Value\Size#10 (4) { + private $fSize => + double(1) + private $sUnit => + string(2) "cm" + private $bIsColorComponent => + bool(false) + protected $iLineNo => + int(2) + } + [3] => + class Sabberworm\CSS\Value\Size#11 (4) { + private $fSize => + double(2) + private $sUnit => + string(1) "%" + private $bIsColorComponent => + bool(false) + protected $iLineNo => + int(2) + } + } + protected $sSeparator => + string(1) " " + protected $iLineNo => + int(2) + } + private $bIsImportant => + bool(false) + protected $iLineNo => + int(2) + } + } + 'font-family' => + array(1) { + [0] => + class Sabberworm\CSS\Rule\Rule#13 (4) { + private $sRule => + string(11) "font-family" + private $mValue => + class Sabberworm\CSS\Value\RuleValueList#15 (3) { + protected $aComponents => + array(4) { + [0] => + string(7) "Verdana" + [1] => + string(9) "Helvetica" + [2] => + class Sabberworm\CSS\Value\CSSString#14 (2) { + private $sString => + string(9) "Gill Sans" + protected $iLineNo => + int(3) + } + [3] => + string(10) "sans-serif" + } + protected $sSeparator => + string(1) "," + protected $iLineNo => + int(3) + } + private $bIsImportant => + bool(false) + protected $iLineNo => + int(3) + } + } + 'color' => + array(1) { + [0] => + class Sabberworm\CSS\Rule\Rule#16 (4) { + private $sRule => + string(5) "color" + private $mValue => + string(3) "red" + private $bIsImportant => + bool(true) + protected $iLineNo => + int(4) + } + } + } + protected $iLineNo => + int(1) + } + } + protected $iLineNo => + int(1) +} + +``` #### Output (`render()`) - #header {margin: 10px 2em 1cm 2%;font-family: Verdana,Helvetica,"Gill Sans",sans-serif;color: red !important;} +```css +#header {margin: 10px 2em 1cm 2%;font-family: Verdana,Helvetica,"Gill Sans",sans-serif;color: red !important;} +``` ## Contributors/Thanks to +* [FMCorz](https://github.com/FMCorz) for many patches and suggestions, for being able to parse comments and IE hacks (in lenient mode). +* [Lullabot](https://github.com/Lullabot) for a patch that allows to know the line number for each parsed token. * [ju1ius](https://github.com/ju1ius) for the specificity parsing code and the ability to expand/compact shorthand properties. +* [ossinkine](https://github.com/ossinkine) for a 150 time performance boost. * [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. diff --git a/vendor/sabberworm/php-css-parser/composer.json b/vendor/sabberworm/php-css-parser/composer.json index bd3830ced..b970db756 100644 --- a/vendor/sabberworm/php-css-parser/composer.json +++ b/vendor/sabberworm/php-css-parser/composer.json @@ -11,6 +11,9 @@ "require": { "php": ">=5.3.2" }, + "require-dev": { + "phpunit/phpunit": "*" + }, "autoload": { "psr-0": { "Sabberworm\\CSS": "lib/" } } diff --git a/vendor/sabberworm/php-css-parser/composer.lock b/vendor/sabberworm/php-css-parser/composer.lock new file mode 100644 index 000000000..cef0668e8 --- /dev/null +++ b/vendor/sabberworm/php-css-parser/composer.lock @@ -0,0 +1,1317 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "bed930f26e019e0a48bd041d15c90e7d", + "content-hash": "8a1a6e7f5a04b933b11b9677113dcc44", + "packages": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "myclabs/deep-copy", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "a8773992b362b58498eed24bf85005f363c34771" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/a8773992b362b58498eed24bf85005f363c34771", + "reference": "a8773992b362b58498eed24bf85005f363c34771", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "homepage": "https://github.com/myclabs/DeepCopy", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2015-11-20 12:04:31" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2015-12-27 11:43:31" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "9270140b940ff02e58ec577c237274e92cd40cdd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd", + "reference": "9270140b940ff02e58ec577c237274e92cd40cdd", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.2.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2016-06-10 09:48:41" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2016-06-10 07:14:17" + }, + { + "name": "phpspec/prophecy", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1", + "sebastian/recursion-context": "^1.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2016-06-07 08:13:47" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "900370c81280cc0d942ffbc5912d80464eaee7e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/900370c81280cc0d942ffbc5912d80464eaee7e9", + "reference": "900370c81280cc0d942ffbc5912d80464eaee7e9", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "^1.4.2", + "sebastian/code-unit-reverse-lookup": "~1.0", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0|~2.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.4.0", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2016-06-03 05:03:56" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2015-06-21 13:08:43" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21 13:50:34" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4|~5" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2016-05-12 18:03:57" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2015-09-15 10:49:45" + }, + { + "name": "phpunit/phpunit", + "version": "5.4.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "2f1fc94b77ea6418bd6a06c64a1dac0645fbce59" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2f1fc94b77ea6418bd6a06c64a1dac0645fbce59", + "reference": "2f1fc94b77ea6418bd6a06c64a1dac0645fbce59", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "^4.0", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "^1.3 || ^2.0", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/object-enumerator": "~1.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "~1.0|~2.0", + "symfony/yaml": "~2.1|~3.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2016-06-16 06:01:15" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.2.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "b13d0d9426ced06958bd32104653526a6c998a52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/b13d0d9426ced06958bd32104653526a6c998a52", + "reference": "b13d0d9426ced06958bd32104653526a6c998a52", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2016-06-12 07:37:26" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2016-02-13 06:45:14" + }, + { + "name": "sebastian/comparator", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-07-26 15:48:44" + }, + { + "name": "sebastian/diff", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-12-08 07:14:41" + }, + { + "name": "sebastian/environment", + "version": "1.3.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716", + "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-05-17 03:18:57" + }, + { + "name": "sebastian/exporter", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-06-17 09:04:28" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12 03:26:01" + }, + { + "name": "sebastian/object-enumerator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2016-01-28 13:25:10" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "913401df809e99e4f47b27cdd781f4a258d58791" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", + "reference": "913401df809e99e4f47b27cdd781f4a258d58791", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-11-11 19:50:13" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28 20:34:47" + }, + { + "name": "sebastian/version", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-02-04 12:56:52" + }, + { + "name": "symfony/yaml", + "version": "v3.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/2884c26ce4c1d61aebf423a8b912950fe7c764de", + "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2016-06-29 05:41:56" + }, + { + "name": "webmozart/assert", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde", + "reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2015-08-24 13:29:44" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.3.2" + }, + "platform-dev": [] +} diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/AtRuleBlockList.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/AtRuleBlockList.php index 70b9c4025..a1ff8f8d1 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/AtRuleBlockList.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/AtRuleBlockList.php @@ -12,8 +12,8 @@ class AtRuleBlockList extends CSSBlockList implements AtRule { private $sType; private $sArgs; - public function __construct($sType, $sArgs = '') { - parent::__construct(); + public function __construct($sType, $sArgs = '', $iLineNo = 0) { + parent::__construct($iLineNo); $this->sType = $sType; $this->sArgs = $sArgs; } diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSBlockList.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSBlockList.php index 55a594f5b..17c68142e 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSBlockList.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSBlockList.php @@ -14,6 +14,10 @@ * Most CSSLists conform to this category but some at-rules (such as @keyframes) do not. */ abstract class CSSBlockList extends CSSList { + public function __construct($iLineNo = 0) { + parent::__construct($iLineNo); + } + protected function allDeclarationBlocks(&$aResult) { foreach ($this->aContents as $mContent) { if ($mContent instanceof DeclarationBlock) { @@ -52,7 +56,7 @@ protected function allValues($oElement, &$aResult, $sSearchString = null, $bSear } } } else { - //Non-List Value or String (CSS identifier) + //Non-List Value or CSSString (CSS identifier) $aResult[] = $oElement; } } diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSList.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSList.php index c9ec93156..bc90460b9 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSList.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSList.php @@ -2,23 +2,33 @@ namespace Sabberworm\CSS\CSSList; +use Sabberworm\CSS\Renderable; 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; +use Sabberworm\CSS\Comment\Commentable; /** * 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 { +abstract class CSSList implements Renderable, Commentable { + protected $aComments; protected $aContents; + protected $iLineNo; - public function __construct() { + public function __construct($iLineNo = 0) { + $this->aComments = array(); $this->aContents = array(); + $this->iLineNo = $iLineNo; + } + + /** + * @return int + */ + public function getLineNo() { + return $this->iLineNo; } public function append($oItem) { @@ -38,6 +48,17 @@ public function remove($oItemToRemove) { return false; } + /** + * Set the contents. + * @param array $aContents Objects to set as content. + */ + public function setContents(array $aContents) { + $this->aContents = array(); + foreach ($aContents as $content) { + $this->append($content); + } + } + /** * Removes a declaration block from the CSS list if it matches all given selectors. * @param array|string $mSelector The selectors to match. @@ -111,4 +132,26 @@ public abstract function isRootList(); public function getContents() { return $this->aContents; } + + /** + * @param array $aComments Array of comments. + */ + public function addComments(array $aComments) { + $this->aComments = array_merge($this->aComments, $aComments); + } + + /** + * @return array + */ + public function getComments() { + return $this->aComments; + } + + /** + * @param array $aComments Array containing Comment objects. + */ + public function setComments(array $aComments) { + $this->aComments = $aComments; + } + } diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/Document.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/Document.php index 0349886f5..bd4a23ee3 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/Document.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/Document.php @@ -6,6 +6,13 @@ * 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 { + /** + * Document constructor. + * @param int $iLineNo + */ + public function __construct($iLineNo = 0) { + parent::__construct($iLineNo); + } /** * Gets all DeclarationBlock objects recursively. diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/KeyFrame.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/KeyFrame.php index 3faf2e3ff..0334b1b3f 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/KeyFrame.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/KeyFrame.php @@ -9,8 +9,8 @@ class KeyFrame extends CSSList implements AtRule { private $vendorKeyFrame; private $animationName; - public function __construct() { - parent::__construct(); + public function __construct($iLineNo = 0) { + parent::__construct($iLineNo); $this->vendorKeyFrame = null; $this->animationName = null; } diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Comment/Comment.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Comment/Comment.php new file mode 100644 index 000000000..70521b16a --- /dev/null +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Comment/Comment.php @@ -0,0 +1,51 @@ +sComment = $sComment; + $this->iLineNo = $iLineNo; + } + + /** + * @return string + */ + public function getComment() { + return $this->sComment; + } + + /** + * @return int + */ + public function getLineNo() { + return $this->iLineNo; + } + + /** + * @return string + */ + public function setComment($sComment) { + $this->sComment = $sComment; + } + + /** + * @return string + */ + public function __toString() { + return $this->render(new \Sabberworm\CSS\OutputFormat()); + } + + /** + * @return string + */ + public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) { + return '/*' . $this->sComment . '*/'; + } + +} diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Comment/Commentable.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Comment/Commentable.php new file mode 100644 index 000000000..3100f17a8 --- /dev/null +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Comment/Commentable.php @@ -0,0 +1,23 @@ +sText = $sText; $this->iCurrentPosition = 0; + $this->iLineNo = $iLineNo; if ($oParserSettings === null) { $oParserSettings = Settings::create(); } @@ -56,7 +68,8 @@ public function __construct($sText, Settings $oParserSettings = null) { public function setCharset($sCharset) { $this->sCharset = $sCharset; - $this->iLength = $this->strlen($this->sText); + $this->aText = $this->strsplit($this->sText); + $this->iLength = count($this->aText); } public function getCharset() { @@ -65,46 +78,71 @@ public function getCharset() { public function parse() { $this->setCharset($this->oParserSettings->sDefaultCharset); - $oResult = new Document(); + $oResult = new Document($this->iLineNo); $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; + $comments = $this->consumeWhiteSpace(); + $oListItem = null; + if($this->oParserSettings->bLenientParsing) { + try { + $oListItem = $this->parseListItem($oList, $bIsRoot); + } catch (UnexpectedTokenException $e) { + $oListItem = false; } } else { - if($this->oParserSettings->bLenientParsing) { - try { - $oList->append($this->parseSelector()); - } catch (UnexpectedTokenException $e) {} - } else { - $oList->append($this->parseSelector()); - } + $oListItem = $this->parseListItem($oList, $bIsRoot); + } + if($oListItem === null) { + // List parsing finished + return; + } + if($oListItem) { + $oListItem->setComments($comments); + $oList->append($oListItem); } - $this->consumeWhiteSpace(); } if (!$bIsRoot) { - throw new \Exception("Unexpected end of document"); + throw new SourceException("Unexpected end of document", $this->iLineNo); + } + } + + private function parseListItem(CSSList $oList, $bIsRoot = false) { + if ($this->comes('@')) { + $oAtRule = $this->parseAtRule(); + if($oAtRule instanceof Charset) { + if(!$bIsRoot) { + throw new UnexpectedTokenException('@charset may only occur in root document', '', 'custom', $this->iLineNo); + } + if(count($oList->getContents()) > 0) { + throw new UnexpectedTokenException('@charset must be the first parseable token in a document', '', 'custom', $this->iLineNo); + } + $this->setCharset($oAtRule->getCharset()->getString()); + } + return $oAtRule; + } else if ($this->comes('}')) { + $this->consume('}'); + if ($bIsRoot) { + throw new SourceException("Unopened {", $this->iLineNo); + } else { + return null; + } + } else { + return $this->parseSelector(); } } private function parseAtRule() { $this->consume('@'); - $sIdentifier = $this->parseIdentifier(); + $sIdentifier = $this->parseIdentifier(false); + $iIdentifierLineNum = $this->iLineNo; $this->consumeWhiteSpace(); if ($sIdentifier === 'import') { $oLocation = $this->parseURLValue(); @@ -114,18 +152,16 @@ private function parseAtRule() { $sMediaQuery = $this->consumeUntil(';'); } $this->consume(';'); - return new Import($oLocation, $sMediaQuery); + return new Import($oLocation, $sMediaQuery, $iIdentifierLineNum); } else if ($sIdentifier === 'charset') { $sCharset = $this->parseStringValue(); $this->consumeWhiteSpace(); $this->consume(';'); - $this->setCharset($sCharset->getString()); - return new Charset($sCharset); + return new Charset($sCharset, $iIdentifierLineNum); } else if ($this->identifierIs($sIdentifier, 'keyframes')) { - $oResult = new KeyFrame(); + $oResult = new KeyFrame($iIdentifierLineNum); $oResult->setVendorKeyFrame($sIdentifier); $oResult->setAnimationName(trim($this->consumeUntil('{', false, true))); - $this->consumeWhiteSpace(); $this->parseList($oResult); return $oResult; } else if ($sIdentifier === 'namespace') { @@ -137,16 +173,15 @@ private function parseAtRule() { } $this->consume(';'); if ($sPrefix !== null && !is_string($sPrefix)) { - throw new \Exception('Wrong namespace prefix '.$sPrefix); + throw new UnexpectedTokenException('Wrong namespace prefix', $sPrefix, 'custom', $iIdentifierLineNum); } - if (!($mUrl instanceof String || $mUrl instanceof URL)) { - throw new \Exception('Wrong namespace url of invalid type '.$mUrl); + if (!($mUrl instanceof CSSString || $mUrl instanceof URL)) { + throw new UnexpectedTokenException('Wrong namespace url of invalid type', $mUrl, 'custom', $iIdentifierLineNum); } - return new CSSNamespace($mUrl, $sPrefix); + return new CSSNamespace($mUrl, $sPrefix, $iIdentifierLineNum); } 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)) { @@ -155,10 +190,10 @@ private function parseAtRule() { } } if($bUseRuleSet) { - $oAtRule = new AtRuleSet($sIdentifier, $sArgs); + $oAtRule = new AtRuleSet($sIdentifier, $sArgs, $iIdentifierLineNum); $this->parseRuleSet($oAtRule); } else { - $oAtRule = new AtRuleBlockList($sIdentifier, $sArgs); + $oAtRule = new AtRuleBlockList($sIdentifier, $sArgs, $iIdentifierLineNum); $this->parseList($oAtRule); } return $oAtRule; @@ -168,7 +203,7 @@ private function parseAtRule() { private function parseIdentifier($bAllowFunctions = true, $bIgnoreCase = true) { $sResult = $this->parseCharacter(true); if ($sResult === null) { - throw new UnexpectedTokenException($sResult, $this->peek(5), 'identifier'); + throw new UnexpectedTokenException($sResult, $this->peek(5), 'identifier', $this->iLineNo); } $sCharacter = null; while (($sCharacter = $this->parseCharacter(true)) !== null) { @@ -180,7 +215,7 @@ private function parseIdentifier($bAllowFunctions = true, $bIgnoreCase = true) { if ($bAllowFunctions && $this->comes('(')) { $this->consume('('); $aArguments = $this->parseValue(array('=', ' ', ',')); - $sResult = new CSSFunction($sResult, $aArguments); + $sResult = new CSSFunction($sResult, $aArguments, ',', $this->iLineNo); $this->consume(')'); } return $sResult; @@ -208,17 +243,21 @@ private function parseStringValue() { while (!$this->comes($sQuote)) { $sContent = $this->parseCharacter(false); if ($sContent === null) { - throw new \Exception("Non-well-formed quoted string {$this->peek(3)}"); + throw new SourceException("Non-well-formed quoted string {$this->peek(3)}", $this->iLineNo); } $sResult .= $sContent; } $this->consume($sQuote); } - return new String($sResult); + return new CSSString($sResult, $this->iLineNo); } private function parseCharacter($bIsForIdentifier) { if ($this->peek() === '\\') { + if ($bIsForIdentifier && $this->oParserSettings->bLenientParsing && ($this->comes('\0') || $this->comes('\9'))) { + // Non-strings can contain \0 or \9 which is an IE hack supported in lenient parsing. + return null; + } $this->consume('\\'); if ($this->comes('\n') || $this->comes('\r')) { return ''; @@ -263,9 +302,10 @@ private function parseCharacter($bIsForIdentifier) { } private function parseSelector() { - $oResult = new DeclarationBlock(); - $oResult->setSelector($this->consumeUntil('{', false, true)); - $this->consumeWhiteSpace(); + $aComments = array(); + $oResult = new DeclarationBlock($this->iLineNo); + $oResult->setSelector($this->consumeUntil('{', false, true, $aComments)); + $oResult->setComments($aComments); $this->parseRuleSet($oResult); return $oResult; } @@ -273,7 +313,6 @@ private function parseSelector() { private function parseRuleSet($oRuleSet) { while ($this->comes(';')) { $this->consume(';'); - $this->consumeWhiteSpace(); } while (!$this->comes('}')) { $oRule = null; @@ -284,11 +323,9 @@ private function parseRuleSet($oRuleSet) { 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), '}')) { + if($this->streql(substr($sConsume, -1), '}')) { --$this->iCurrentPosition; - $this->peekCache = null; } else { - $this->consumeWhiteSpace(); while ($this->comes(';')) { $this->consume(';'); } @@ -304,17 +341,25 @@ private function parseRuleSet($oRuleSet) { if($oRule) { $oRuleSet->addRule($oRule); } - $this->consumeWhiteSpace(); } $this->consume('}'); } private function parseRule() { - $oRule = new Rule($this->parseIdentifier()); - $this->consumeWhiteSpace(); + $aComments = $this->consumeWhiteSpace(); + $oRule = new Rule($this->parseIdentifier(), $this->iLineNo); + $oRule->setComments($aComments); + $oRule->addComments($this->consumeWhiteSpace()); $this->consume(':'); $oValue = $this->parseValue(self::listDelimiterForRule($oRule->getRule())); $oRule->setValue($oValue); + if ($this->oParserSettings->bLenientParsing) { + while ($this->comes('\\')) { + $this->consume('\\'); + $oRule->addIeHack($this->consume()); + $this->consumeWhiteSpace(); + } + } if ($this->comes('!')) { $this->consume('!'); $this->consumeWhiteSpace(); @@ -323,7 +368,6 @@ private function parseRule() { } while ($this->comes(';')) { $this->consume(';'); - $this->consumeWhiteSpace(); } return $oRule; } @@ -332,7 +376,7 @@ 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(')'))) { + while (!($this->comes('}') || $this->comes(';') || $this->comes('!') || $this->comes(')') || $this->comes('\\'))) { if (count($aStack) > 0) { $bFoundDelimiter = false; foreach ($aListDelimiters as $sDelimiter) { @@ -364,7 +408,7 @@ private function parseValue($aListDelimiters) { break; } } - $oList = new RuleValueList($sDelimiter); + $oList = new RuleValueList($sDelimiter, $this->iLineNo); for ($i = $iStartPosition - 1; $i - $iStartPosition + 1 < $iLength * 2; $i+=2) { $oList->addListComponent($aStack[$i]); } @@ -414,12 +458,15 @@ private function parseNumericValue($bForColor = false) { $sUnit = null; foreach ($this->aSizeUnits as $iLength => &$aValues) { - if(($sUnit = @$aValues[strtolower($this->peek($iLength))]) !== null) { - $this->consume($iLength); - break; + $sKey = strtolower($this->peek($iLength)); + if(array_key_exists($sKey, $aValues)) { + if (($sUnit = $aValues[$sKey]) !== null) { + $this->consume($iLength); + break; + } } } - return new Size(floatval($sSize), $sUnit, $bForColor); + return new Size(floatval($sSize), $sUnit, $bForColor, $this->iLineNo); } private function parseColorValue() { @@ -430,7 +477,7 @@ private function parseColorValue() { 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)); + $aColor = array('r' => new Size(intval($sValue[0] . $sValue[1], 16), null, true, $this->iLineNo), 'g' => new Size(intval($sValue[2] . $sValue[3], 16), null, true, $this->iLineNo), 'b' => new Size(intval($sValue[4] . $sValue[5], 16), null, true, $this->iLineNo)); } else { $sColorMode = $this->parseIdentifier(false); $this->consumeWhiteSpace(); @@ -446,7 +493,7 @@ private function parseColorValue() { } $this->consume(')'); } - return new Color($aColor); + return new Color($aColor, $this->iLineNo); } private function parseURLValue() { @@ -457,7 +504,7 @@ private function parseURLValue() { $this->consume('('); } $this->consumeWhiteSpace(); - $oResult = new URL($this->parseStringValue()); + $oResult = new URL($this->parseStringValue(), $this->iLineNo); if ($bUseUrl) { $this->consumeWhiteSpace(); $this->consume(')'); @@ -466,8 +513,8 @@ private function parseURLValue() { } /** - * 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. - */ + * 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; @@ -481,38 +528,31 @@ private function comes($sString, $bCaseInsensitive = false) { } 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; + return $this->substr($iOffset, $iLength); } private function consume($mValue = 1) { if (is_string($mValue)) { + $iLineCount = substr_count($mValue, "\n"); $iLength = $this->strlen($mValue); - if (!$this->streql($this->substr($this->sText, $this->iCurrentPosition, $iLength), $mValue)) { - throw new UnexpectedTokenException($mValue, $this->peek(max($iLength, 5))); + if (!$this->streql($this->substr($this->iCurrentPosition, $iLength), $mValue)) { + throw new UnexpectedTokenException($mValue, $this->peek(max($iLength, 5)), $this->iLineNo); } + $this->iLineNo += $iLineCount; $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'); + throw new UnexpectedTokenException($mValue, $this->peek(5), 'count', $this->iLineNo); } - $sResult = $this->substr($this->sText, $this->iCurrentPosition, $mValue); + $sResult = $this->substr($this->iCurrentPosition, $mValue); + $iLineCount = substr_count($sResult, "\n"); + $this->iLineNo += $iLineCount; $this->iCurrentPosition += $mValue; - $this->peekCache = null; return $sResult; } } @@ -522,52 +562,69 @@ private function consumeExpression($mExpression) { 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'); + throw new UnexpectedTokenException($mExpression, $this->peek(5), 'expression', $this->iLineNo); } private function consumeWhiteSpace() { + $comments = array(); do { while (preg_match('/\\s/isSu', $this->peek()) === 1) { $this->consume(1); } if($this->oParserSettings->bLenientParsing) { try { - $bHasComment = $this->consumeComment(); + $oComment = $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(); + $oComment = $this->consumeComment(); + } + if ($oComment !== false) { + $comments[] = $oComment; } - } while($bHasComment); + } while($oComment !== false); + return $comments; } + /** + * @return false|Comment + */ private function consumeComment() { + $mComment = false; if ($this->comes('/*')) { + $iLineNo = $this->iLineNo; $this->consume(1); - while ($this->consume(1) !== '') { + $mComment = ''; + while (($char = $this->consume(1)) !== '') { + $mComment .= $char; if ($this->comes('*/')) { $this->consume(2); - return true; + break; } } } - return false; + + if ($mComment !== false) { + // We skip the * which was included in the comment. + return new Comment(substr($mComment, 1), $iLineNo); + } + + return $mComment; } private function isEnd() { return $this->iCurrentPosition >= $this->iLength; } - private function consumeUntil($aEnd, $bIncludeEnd = false, $consumeEnd = false) { + private function consumeUntil($aEnd, $bIncludeEnd = false, $consumeEnd = false, array &$comments = array()) { $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; @@ -577,22 +634,33 @@ private function consumeUntil($aEnd, $bIncludeEnd = false, $consumeEnd = false) return $out; } $out .= $char; + if ($comment = $this->consumeComment()) { + $comments[] = $comment; + } } $this->iCurrentPosition = $start; - throw new UnexpectedTokenException('One of ("'.implode('","', $aEnd).'")', $this->peek(5), 'search'); + throw new UnexpectedTokenException('One of ("'.implode('","', $aEnd).'")', $this->peek(5), 'search', $this->iLineNo); } private function inputLeft() { - return $this->substr($this->sText, $this->iCurrentPosition, -1); + return $this->substr($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 substr($iStart, $iLength) { + if ($iLength < 0) { + $iLength = $this->iLength - $iStart + $iLength; + } + if ($iStart + $iLength > $this->iLength) { + $iLength = $this->iLength - $iStart; } + $sResult = ''; + while ($iLength > 0) { + $sResult .= $this->aText[$iStart]; + $iStart++; + $iLength--; + } + return $sResult; } private function strlen($sString) { @@ -619,6 +687,27 @@ private function strtolower($sString) { } } + private function strsplit($sString) { + if ($this->oParserSettings->bMultibyteSupport) { + if ($this->streql($this->sCharset, 'utf-8')) { + return preg_split('//u', $sString, null, PREG_SPLIT_NO_EMPTY); + } else { + $iLength = mb_strlen($sString, $this->sCharset); + $aResult = array(); + for ($i = 0; $i < $iLength; ++$i) { + $aResult[] = mb_substr($sString, $i, 1, $this->sCharset); + } + return $aResult; + } + } else { + if($sString === '') { + return array(); + } else { + return str_split($sString); + } + } + } + private function strpos($sString, $sNeedle, $iOffset) { if ($this->oParserSettings->bMultibyteSupport) { return mb_strpos($sString, $sNeedle, $iOffset, $this->sCharset); diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/OutputException.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/OutputException.php index 5dc4b2c0c..1c8117704 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/OutputException.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/OutputException.php @@ -5,5 +5,8 @@ /** * Thrown if the CSS parsers attempts to print something invalid */ -class OutputException extends \Exception { +class OutputException extends SourceException { + public function __construct($sMessage, $iLineNo = 0) { + parent::__construct($sMessage, $iLineNo); + } } \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/SourceException.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/SourceException.php new file mode 100644 index 000000000..9bb991384 --- /dev/null +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/SourceException.php @@ -0,0 +1,18 @@ +iLineNo = $iLineNo; + if (!empty($iLineNo)) { + $sMessage .= " [line no: $iLineNo]"; + } + parent::__construct($sMessage); + } + + public function getLineNo() { + return $this->iLineNo; + } +} \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/UnexpectedTokenException.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/UnexpectedTokenException.php index 410f5de3f..0ef881846 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/UnexpectedTokenException.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/UnexpectedTokenException.php @@ -5,13 +5,13 @@ /** * Thrown if the CSS parsers encounters a token it did not expect */ -class UnexpectedTokenException extends \Exception { +class UnexpectedTokenException extends SourceException { private $sExpected; private $sFound; // Possible values: literal, identifier, count, expression, search private $sMatchType; - public function __construct($sExpected, $sFound, $sMatchType = 'literal') { + public function __construct($sExpected, $sFound, $sMatchType = 'literal', $iLineNo = 0) { $this->sExpected = $sExpected; $this->sFound = $sFound; $this->sMatchType = $sMatchType; @@ -22,7 +22,10 @@ public function __construct($sExpected, $sFound, $sMatchType = 'literal') { $sMessage = "Next token was expected to have {$sExpected} chars. Context: “{$sFound}”."; } else if($this->sMatchType === 'identifier') { $sMessage = "Identifier expected. Got “{$sFound}”"; + } else if($this->sMatchType === 'custom') { + $sMessage = trim("$sExpected $sFound"); } - parent::__construct($sMessage); + + parent::__construct($sMessage, $iLineNo); } } \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/AtRule.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/AtRule.php index e9009cc36..de3eea192 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/AtRule.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/AtRule.php @@ -3,8 +3,9 @@ namespace Sabberworm\CSS\Property; use Sabberworm\CSS\Renderable; +use Sabberworm\CSS\Comment\Commentable; -interface AtRule extends Renderable { +interface AtRule extends Renderable, Commentable { 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) diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/CSSNamespace.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/CSSNamespace.php index 3d5a80d18..7c0dee159 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/CSSNamespace.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/CSSNamespace.php @@ -8,12 +8,23 @@ class CSSNamespace implements AtRule { private $mUrl; private $sPrefix; + private $iLineNo; + protected $aComments; - public function __construct($mUrl, $sPrefix = null) { + public function __construct($mUrl, $sPrefix = null, $iLineNo = 0) { $this->mUrl = $mUrl; $this->sPrefix = $sPrefix; + $this->iLineNo = $iLineNo; + $this->aComments = array(); } - + + /** + * @return int + */ + public function getLineNo() { + return $this->iLineNo; + } + public function __toString() { return $this->render(new \Sabberworm\CSS\OutputFormat()); } @@ -49,4 +60,16 @@ public function atRuleArgs() { } return $aResult; } + + public function addComments(array $aComments) { + $this->aComments = array_merge($this->aComments, $aComments); + } + + public function getComments() { + return $this->aComments; + } + + public function setComments(array $aComments) { + $this->aComments = $aComments; + } } \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Charset.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Charset.php index 69604220a..61c6ebc5b 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Charset.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Charset.php @@ -12,9 +12,20 @@ class Charset implements AtRule { private $sCharset; + protected $iLineNo; + protected $aComment; - public function __construct($sCharset) { + public function __construct($sCharset, $iLineNo = 0) { $this->sCharset = $sCharset; + $this->iLineNo = $iLineNo; + $this->aComments = array(); + } + + /** + * @return int + */ + public function getLineNo() { + return $this->iLineNo; } public function setCharset($sCharset) { @@ -40,4 +51,16 @@ public function atRuleName() { public function atRuleArgs() { return $this->sCharset; } + + public function addComments(array $aComments) { + $this->aComments = array_merge($this->aComments, $aComments); + } + + public function getComments() { + return $this->aComments; + } + + public function setComments(array $aComments) { + $this->aComments = $aComments; + } } \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Import.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Import.php index 4fd08b1cd..4d40f5a04 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Import.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Import.php @@ -10,12 +10,23 @@ class Import implements AtRule { private $oLocation; private $sMediaQuery; + protected $iLineNo; + protected $aComments; - public function __construct(URL $oLocation, $sMediaQuery) { + public function __construct(URL $oLocation, $sMediaQuery, $iLineNo = 0) { $this->oLocation = $oLocation; $this->sMediaQuery = $sMediaQuery; + $this->iLineNo = $iLineNo; + $this->aComments = array(); } - + + /** + * @return int + */ + public function getLineNo() { + return $this->iLineNo; + } + public function setLocation($oLocation) { $this->oLocation = $oLocation; } @@ -43,4 +54,16 @@ public function atRuleArgs() { } return $aResult; } + + public function addComments(array $aComments) { + $this->aComments = array_merge($this->aComments, $aComments); + } + + public function getComments() { + return $this->aComments; + } + + public function setComments(array $aComments) { + $this->aComments = $aComments; + } } \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Renderable.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Renderable.php index 626613a48..3ac06652e 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Renderable.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Renderable.php @@ -5,4 +5,5 @@ interface Renderable { public function __toString(); public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat); + public function getLineNo(); } \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php index 79967278c..3e4853753 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php @@ -2,23 +2,38 @@ namespace Sabberworm\CSS\Rule; +use Sabberworm\CSS\Renderable; use Sabberworm\CSS\Value\RuleValueList; use Sabberworm\CSS\Value\Value; +use Sabberworm\CSS\Comment\Commentable; /** * 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 { +class Rule implements Renderable, Commentable { private $sRule; private $mValue; private $bIsImportant; + private $aIeHack; + protected $iLineNo; + protected $aComments; - public function __construct($sRule) { + public function __construct($sRule, $iLineNo = 0) { $this->sRule = $sRule; $this->mValue = null; $this->bIsImportant = false; + $this->aIeHack = array(); + $this->iLineNo = $iLineNo; + $this->aComments = array(); + } + + /** + * @return int + */ + public function getLineNo() { + return $this->iLineNo; } public function setRule($sRule) { @@ -43,12 +58,12 @@ public function setValue($mValue) { public function setValues($aSpaceSeparatedValues) { $oSpaceSeparatedList = null; if (count($aSpaceSeparatedValues) > 1) { - $oSpaceSeparatedList = new RuleValueList(' '); + $oSpaceSeparatedList = new RuleValueList(' ', $this->iLineNo); } foreach ($aSpaceSeparatedValues as $aCommaSeparatedValues) { $oCommaSeparatedList = null; if (count($aCommaSeparatedValues) > 1) { - $oCommaSeparatedList = new RuleValueList(','); + $oCommaSeparatedList = new RuleValueList(',', $this->iLineNo); } foreach ($aCommaSeparatedValues as $mValue) { if (!$oSpaceSeparatedList && !$oCommaSeparatedList) { @@ -107,7 +122,7 @@ public function addValue($mValue, $sType = ' ') { } if (!$this->mValue instanceof RuleValueList || $this->mValue->getListSeparator() !== $sType) { $mCurrentValue = $this->mValue; - $this->mValue = new RuleValueList($sType); + $this->mValue = new RuleValueList($sType, $this->iLineNo); if ($mCurrentValue) { $this->mValue->addListComponent($mCurrentValue); } @@ -117,6 +132,18 @@ public function addValue($mValue, $sType = ' ') { } } + public function addIeHack($iModifier) { + $this->aIeHack[] = $iModifier; + } + + public function setIeHack(array $aModifiers) { + $this->aIeHack = $aModifiers; + } + + public function getIeHack() { + return $this->aIeHack; + } + public function setIsImportant($bIsImportant) { $this->bIsImportant = $bIsImportant; } @@ -136,6 +163,9 @@ public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) { } else { $sResult .= $this->mValue; } + if (!empty($this->aIeHack)) { + $sResult .= ' \\' . implode('\\', $this->aIeHack); + } if ($this->bIsImportant) { $sResult .= ' !important'; } @@ -143,4 +173,25 @@ public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) { return $sResult; } + /** + * @param array $aComments Array of comments. + */ + public function addComments(array $aComments) { + $this->aComments = array_merge($this->aComments, $aComments); + } + + /** + * @return array + */ + public function getComments() { + return $this->aComments; + } + + /** + * @param array $aComments Array containing Comment objects. + */ + public function setComments(array $aComments) { + $this->aComments = $aComments; + } + } diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/AtRuleSet.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/AtRuleSet.php index a21737dc2..a1042a95a 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/AtRuleSet.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/AtRuleSet.php @@ -12,8 +12,8 @@ class AtRuleSet extends RuleSet implements AtRule { private $sType; private $sArgs; - public function __construct($sType, $sArgs = '') { - parent::__construct(); + public function __construct($sType, $sArgs = '', $iLineNo = 0) { + parent::__construct($iLineNo); $this->sType = $sType; $this->sArgs = $sArgs; } diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php index c59e601de..e18f5d829 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php @@ -19,8 +19,8 @@ class DeclarationBlock extends RuleSet { private $aSelectors; - public function __construct() { - parent::__construct(); + public function __construct($iLineNo = 0) { + parent::__construct($iLineNo); $this->aSelectors = array(); } @@ -134,7 +134,7 @@ public function expandBorderShorthand() { $sNewRuleName = $sBorderRule . "-style"; } } - $oNewRule = new Rule($sNewRuleName); + $oNewRule = new Rule($sNewRuleName, $this->iLineNo); $oNewRule->setIsImportant($oRule->getIsImportant()); $oNewRule->addValue(array($mNewValue)); $this->addRule($oNewRule); @@ -190,7 +190,7 @@ public function expandDimensionsShorthand() { break; } foreach (array('top', 'right', 'bottom', 'left') as $sPosition) { - $oNewRule = new Rule(sprintf($sExpanded, $sPosition)); + $oNewRule = new Rule(sprintf($sExpanded, $sPosition), $this->iLineNo); $oNewRule->setIsImportant($oRule->getIsImportant()); $oNewRule->addValue(${$sPosition}); $this->addRule($oNewRule); @@ -255,7 +255,7 @@ public function expandFontShorthand() { } } foreach ($aFontProperties as $sProperty => $mValue) { - $oNewRule = new Rule($sProperty); + $oNewRule = new Rule($sProperty, $this->iLineNo); $oNewRule->addValue($mValue); $oNewRule->setIsImportant($oRule->getIsImportant()); $this->addRule($oNewRule); @@ -278,7 +278,7 @@ public function expandBackgroundShorthand() { $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, '%')) + 'background-position' => array(new Size(0, '%', null, false, $this->iLineNo), new Size(0, '%', null, false, $this->iLineNo)) ); $mRuleValue = $oRule->getValue(); $aValues = array(); @@ -289,7 +289,7 @@ public function expandBackgroundShorthand() { } if (count($aValues) == 1 && $aValues[0] == 'inherit') { foreach ($aBgProperties as $sProperty => $mValue) { - $oNewRule = new Rule($sProperty); + $oNewRule = new Rule($sProperty, $this->iLineNo); $oNewRule->addValue('inherit'); $oNewRule->setIsImportant($oRule->getIsImportant()); $this->addRule($oNewRule); @@ -323,7 +323,7 @@ public function expandBackgroundShorthand() { } } foreach ($aBgProperties as $sProperty => $mValue) { - $oNewRule = new Rule($sProperty); + $oNewRule = new Rule($sProperty, $this->iLineNo); $oNewRule->setIsImportant($oRule->getIsImportant()); $oNewRule->addValue($mValue); $this->addRule($oNewRule); @@ -359,7 +359,7 @@ public function expandListStyleShorthand() { } if (count($aValues) == 1 && $aValues[0] == 'inherit') { foreach ($aListProperties as $sProperty => $mValue) { - $oNewRule = new Rule($sProperty); + $oNewRule = new Rule($sProperty, $this->iLineNo); $oNewRule->addValue('inherit'); $oNewRule->setIsImportant($oRule->getIsImportant()); $this->addRule($oNewRule); @@ -380,7 +380,7 @@ public function expandListStyleShorthand() { } } foreach ($aListProperties as $sProperty => $mValue) { - $oNewRule = new Rule($sProperty); + $oNewRule = new Rule($sProperty, $this->iLineNo); $oNewRule->setIsImportant($oRule->getIsImportant()); $oNewRule->addValue($mValue); $this->addRule($oNewRule); @@ -410,7 +410,7 @@ public function createShorthandProperties(array $aProperties, $sShorthand) { } } if (count($aNewValues)) { - $oNewRule = new Rule($sShorthand); + $oNewRule = new Rule($sShorthand, $this->iLineNo); foreach ($aNewValues as $mValue) { $oNewRule->addValue($mValue); } @@ -483,7 +483,7 @@ public function createDimensionsShorthand() { } $aValues[$sPosition] = $aRuleValues; } - $oNewRule = new Rule($sProperty); + $oNewRule = new Rule($sProperty, $this->iLineNo); 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]) { @@ -528,7 +528,7 @@ public function createFontShorthand() { if (!isset($aRules['font-size']) || !isset($aRules['font-family'])) { return; } - $oNewRule = new Rule('font'); + $oNewRule = new Rule('font', $this->iLineNo); foreach (array('font-style', 'font-variant', 'font-weight') as $sProperty) { if (isset($aRules[$sProperty])) { $oRule = $aRules[$sProperty]; @@ -564,7 +564,7 @@ public function createFontShorthand() { $aLHValues = $mRuleValue->getListComponents(); } if ($aLHValues[0] !== 'normal') { - $val = new RuleValueList('/'); + $val = new RuleValueList('/', $this->iLineNo); $val->addListComponent($aFSValues[0]); $val->addListComponent($aLHValues[0]); $oNewRule->addValue($val); @@ -580,7 +580,7 @@ public function createFontShorthand() { } else { $aFFValues = $mRuleValue->getListComponents(); } - $oFFValue = new RuleValueList(','); + $oFFValue = new RuleValueList(',', $this->iLineNo); $oFFValue->setListComponents($aFFValues); $oNewRule->addValue($oFFValue); @@ -597,7 +597,7 @@ public function __toString() { 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"); + throw new OutputException("Attempt to print declaration block with missing selector", $this->iLineNo); } $sResult = $oOutputFormat->implode($oOutputFormat->spaceBeforeSelectorSeparator() . ',' . $oOutputFormat->spaceAfterSelectorSeparator(), $this->aSelectors) . $oOutputFormat->spaceBeforeOpeningBrace() . '{'; $sResult .= parent::render($oOutputFormat); diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/RuleSet.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/RuleSet.php index d33f9cde8..124be88db 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/RuleSet.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/RuleSet.php @@ -4,25 +4,47 @@ use Sabberworm\CSS\Rule\Rule; use Sabberworm\CSS\Renderable; +use Sabberworm\CSS\Comment\Commentable; /** * 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 { +abstract class RuleSet implements Renderable, Commentable { private $aRules; + protected $iLineNo; + protected $aComments; - public function __construct() { + public function __construct($iLineNo = 0) { $this->aRules = array(); + $this->iLineNo = $iLineNo; + $this->aComments = array(); } - public function addRule(Rule $oRule) { + /** + * @return int + */ + public function getLineNo() { + return $this->iLineNo; + } + + public function addRule(Rule $oRule, Rule $oSibling = null) { $sRule = $oRule->getRule(); if(!isset($this->aRules[$sRule])) { $this->aRules[$sRule] = array(); } - $this->aRules[$sRule][] = $oRule; + + $iPosition = count($this->aRules[$sRule]); + + if ($oSibling !== null) { + $iSiblingPos = array_search($oSibling, $this->aRules[$sRule], true); + if ($iSiblingPos !== false) { + $iPosition = $iSiblingPos; + } + } + + array_splice($this->aRules[$sRule], $iPosition, 0, array($oRule)); } /** @@ -44,7 +66,18 @@ public function getRules($mRule = null) { } return $aResult; } - + + /** + * Override all the rules of this set. + * @param array $aRules The rules to override with. + */ + public function setRules(array $aRules) { + $this->aRules = array(); + foreach ($aRules as $rule) { + $this->addRule($rule); + } + } + /** * 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()). @@ -116,4 +149,25 @@ public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) { return $oOutputFormat->removeLastSemicolon($sResult); } + /** + * @param array $aComments Array of comments. + */ + public function addComments(array $aComments) { + $this->aComments = array_merge($this->aComments, $aComments); + } + + /** + * @return array + */ + public function getComments() { + return $this->aComments; + } + + /** + * @param array $aComments Array containing Comment objects. + */ + public function setComments(array $aComments) { + $this->aComments = $aComments; + } + } diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CSSFunction.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CSSFunction.php index 29c43748a..3633abc75 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CSSFunction.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CSSFunction.php @@ -6,13 +6,14 @@ class CSSFunction extends ValueList { private $sName; - public function __construct($sName, $aArguments, $sSeparator = ',') { + public function __construct($sName, $aArguments, $sSeparator = ',', $iLineNo = 0) { if($aArguments instanceof RuleValueList) { $sSeparator = $aArguments->getListSeparator(); $aArguments = $aArguments->getListComponents(); } $this->sName = $sName; - parent::__construct($aArguments, $sSeparator); + $this->iLineNo = $iLineNo; + parent::__construct($aArguments, $sSeparator, $iLineNo); } public function getName() { diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/String.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CSSString.php similarity index 82% rename from vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/String.php rename to vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CSSString.php index c68847e51..b07000818 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/String.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CSSString.php @@ -2,12 +2,13 @@ namespace Sabberworm\CSS\Value; -class String extends PrimitiveValue { +class CSSString extends PrimitiveValue { private $sString; - public function __construct($sString) { + public function __construct($sString, $iLineNo = 0) { $this->sString = $sString; + parent::__construct($iLineNo); } public function setString($sString) { diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Color.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Color.php index 3ee43cdb0..e05b924a6 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Color.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Color.php @@ -4,8 +4,8 @@ class Color extends CSSFunction { - public function __construct($aColor) { - parent::__construct(implode('', array_keys($aColor)), $aColor); + public function __construct($aColor, $iLineNo = 0) { + parent::__construct(implode('', array_keys($aColor)), $aColor, ',', $iLineNo); } public function getColor() { diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/PrimitiveValue.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/PrimitiveValue.php index 2e6e2ab25..187ce7e6a 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/PrimitiveValue.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/PrimitiveValue.php @@ -3,5 +3,8 @@ namespace Sabberworm\CSS\Value; abstract class PrimitiveValue extends Value { - + public function __construct($iLineNo = 0) { + parent::__construct($iLineNo); + } + } \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/RuleValueList.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/RuleValueList.php index fdb2a4144..d89c326ca 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/RuleValueList.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/RuleValueList.php @@ -3,9 +3,7 @@ namespace Sabberworm\CSS\Value; class RuleValueList extends ValueList { - - public function __construct($sSeparator = ',') { - parent::__construct(array(), $sSeparator); + public function __construct($sSeparator = ',', $iLineNo = 0) { + parent::__construct(array(), $sSeparator, $iLineNo); } - } \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Size.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Size.php index 6d995a065..9ad5eb086 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Size.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Size.php @@ -12,7 +12,8 @@ class Size extends PrimitiveValue { private $sUnit; private $bIsColorComponent; - public function __construct($fSize, $sUnit = null, $bIsColorComponent = false) { + public function __construct($fSize, $sUnit = null, $bIsColorComponent = false, $iLineNo = 0) { + parent::__construct($iLineNo); $this->fSize = floatval($fSize); $this->sUnit = $sUnit; $this->bIsColorComponent = $bIsColorComponent; diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/URL.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/URL.php index 62de10299..02cf5812d 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/URL.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/URL.php @@ -7,11 +7,12 @@ class URL extends PrimitiveValue { private $oURL; - public function __construct(String $oURL) { + public function __construct(CSSString $oURL, $iLineNo = 0) { + parent::__construct($iLineNo); $this->oURL = $oURL; } - public function setURL(String $oURL) { + public function setURL(CSSString $oURL) { $this->oURL = $oURL; } diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Value.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Value.php index 3b511bdff..5d30bd97f 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Value.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Value.php @@ -5,7 +5,20 @@ 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 + protected $iLineNo; + + public function __construct($iLineNo = 0) { + $this->iLineNo = $iLineNo; + } + + /** + * @return int + */ + public function getLineNo() { + return $this->iLineNo; + } + + //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); } diff --git a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/ValueList.php b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/ValueList.php index 64b102480..5c3d0e4fb 100644 --- a/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/ValueList.php +++ b/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/ValueList.php @@ -7,7 +7,8 @@ abstract class ValueList extends Value { protected $aComponents; protected $sSeparator; - public function __construct($aComponents = array(), $sSeparator = ',') { + public function __construct($aComponents = array(), $sSeparator = ',', $iLineNo = 0) { + parent::__construct($iLineNo); if (!is_array($aComponents)) { $aComponents = array($aComponents); } diff --git a/vendor/sabberworm/php-css-parser/phpunit.xml b/vendor/sabberworm/php-css-parser/phpunit.xml index 229736986..33cbef56c 100644 --- a/vendor/sabberworm/php-css-parser/phpunit.xml +++ b/vendor/sabberworm/php-css-parser/phpunit.xml @@ -1 +1,10 @@ - + + + + tests + + + diff --git a/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/CSSList/AtRuleBlockListTest.php b/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/CSSList/AtRuleBlockListTest.php new file mode 100644 index 000000000..551d0ea58 --- /dev/null +++ b/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/CSSList/AtRuleBlockListTest.php @@ -0,0 +1,27 @@ +parse(); + $aContents = $oDoc->getContents(); + $oMediaQuery = $aContents[0]; + $this->assertSame('media', $oMediaQuery->atRuleName(), 'Does not interpret the type as a function'); + $this->assertSame('(min-width: 768px)', $oMediaQuery->atRuleArgs(), 'The media query is the value'); + + $sCss = '@media (min-width: 768px) {.class{color:red}}'; + $oParser = new Parser($sCss); + $oDoc = $oParser->parse(); + $aContents = $oDoc->getContents(); + $oMediaQuery = $aContents[0]; + $this->assertSame('media', $oMediaQuery->atRuleName(), 'Does not interpret the type as a function'); + $this->assertSame('(min-width: 768px)', $oMediaQuery->atRuleArgs(), 'The media query is the value'); + } + +} diff --git a/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/CSSList/DocumentTest.php b/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/CSSList/DocumentTest.php new file mode 100644 index 000000000..003958097 --- /dev/null +++ b/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/CSSList/DocumentTest.php @@ -0,0 +1,26 @@ +parse(); + $aContents = $oDoc->getContents(); + $this->assertCount(1, $aContents); + + $sCss2 = '.otherthing { right: 10px; }'; + $oParser2 = new Parser($sCss); + $oDoc2 = $oParser2->parse(); + $aContents2 = $oDoc2->getContents(); + + $oDoc->setContents(array($aContents[0], $aContents2[0])); + $aFinalContents = $oDoc->getContents(); + $this->assertCount(2, $aFinalContents); + } + +} diff --git a/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/ParserTest.php b/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/ParserTest.php index e5db6b888..0b5f8d616 100644 --- a/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/ParserTest.php +++ b/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/ParserTest.php @@ -2,10 +2,13 @@ namespace Sabberworm\CSS; +use Sabberworm\CSS\CSSList\KeyFrame; use Sabberworm\CSS\Value\Size; use Sabberworm\CSS\Property\Selector; use Sabberworm\CSS\RuleSet\DeclarationBlock; use Sabberworm\CSS\Property\AtRule; +use Sabberworm\CSS\Value\URL; +use Sabberworm\CSS\Parsing\UnexpectedTokenException; class ParserTest extends \PHPUnit_Framework_TestCase { @@ -52,21 +55,21 @@ function testColorParsing() { $this->assertSame('red', $oColor); $aColorRule = $oRuleSet->getRules('background-'); $oColor = $aColorRule[0]->getValue(); - $this->assertEquals(array('r' => new Size(35.0, null, true), 'g' => new Size(35.0, null, true), 'b' => new Size(35.0, null, true)), $oColor->getColor()); + $this->assertEquals(array('r' => new Size(35.0, null, true, $oColor->getLineNo()), 'g' => new Size(35.0, null, true, $oColor->getLineNo()), 'b' => new Size(35.0, null, true, $oColor->getLineNo())), $oColor->getColor()); $aColorRule = $oRuleSet->getRules('border-color'); $oColor = $aColorRule[0]->getValue(); - $this->assertEquals(array('r' => new Size(10.0, null, true), 'g' => new Size(100.0, null, true), 'b' => new Size(230.0, null, true)), $oColor->getColor()); + $this->assertEquals(array('r' => new Size(10.0, null, true, $oColor->getLineNo()), 'g' => new Size(100.0, null, true, $oColor->getLineNo()), 'b' => new Size(230.0, null, true, $oColor->getLineNo())), $oColor->getColor()); $oColor = $aColorRule[1]->getValue(); - $this->assertEquals(array('r' => new Size(10.0, null, true), 'g' => new Size(100.0, null, true), 'b' => new Size(231.0, null, true), 'a' => new Size("0000.3", null, true)), $oColor->getColor()); + $this->assertEquals(array('r' => new Size(10.0, null, true, $oColor->getLineNo()), 'g' => new Size(100.0, null, true, $oColor->getLineNo()), 'b' => new Size(231.0, null, true, $oColor->getLineNo()), 'a' => new Size("0000.3", null, true, $oColor->getLineNo())), $oColor->getColor()); $aColorRule = $oRuleSet->getRules('outline-color'); $oColor = $aColorRule[0]->getValue(); - $this->assertEquals(array('r' => new Size(34.0, null, true), 'g' => new Size(34.0, null, true), 'b' => new Size(34.0, null, true)), $oColor->getColor()); + $this->assertEquals(array('r' => new Size(34.0, null, true, $oColor->getLineNo()), 'g' => new Size(34.0, null, true, $oColor->getLineNo()), 'b' => new Size(34.0, null, true, $oColor->getLineNo())), $oColor->getColor()); } else if($sSelector === '#yours') { $aColorRule = $oRuleSet->getRules('background-color'); $oColor = $aColorRule[0]->getValue(); - $this->assertEquals(array('h' => new Size(220.0, null, true), 's' => new Size(10.0, '%', true), 'l' => new Size(220.0, '%', true)), $oColor->getColor()); + $this->assertEquals(array('h' => new Size(220.0, null, true, $oColor->getLineNo()), 's' => new Size(10.0, '%', true, $oColor->getLineNo()), 'l' => new Size(220.0, '%', true, $oColor->getLineNo())), $oColor->getColor()); $oColor = $aColorRule[1]->getValue(); - $this->assertEquals(array('h' => new Size(220.0, null, true), 's' => new Size(10.0, '%', true), 'l' => new Size(220.0, '%', true), 'a' => new Size(0000.3, null, true)), $oColor->getColor()); + $this->assertEquals(array('h' => new Size(220.0, null, true, $oColor->getLineNo()), 's' => new Size(10.0, '%', true, $oColor->getLineNo()), 'l' => new Size(220.0, '%', true, $oColor->getLineNo()), 'a' => new Size(0000.3, null, true, $oColor->getLineNo())), $oColor->getColor()); } } foreach ($oDoc->getAllValues('color') as $sColor) { @@ -350,7 +353,7 @@ function testListValueRemoval() { $this->assertSame('@media screen {html {some: -test(val2);}} #unrelated {other: yes;}', $oDoc->render()); } - + /** * @expectedException Sabberworm\CSS\Parsing\OutputException */ @@ -377,10 +380,206 @@ function testComments() { $this->assertSame($sExpected, $oDoc->render()); } - function parsedStructureForFile($sFileName) { + function testUrlInFile() { + $oDoc = $this->parsedStructureForFile('url', Settings::create()->withMultibyteSupport(true)); + $sExpected = 'body {background: #fff url("http://somesite.com/images/someimage.gif") repeat top center;} +body {background-url: url("http://somesite.com/images/someimage.gif");}'; + $this->assertSame($sExpected, $oDoc->render()); + } + + function testUrlInFileMbOff() { + $oDoc = $this->parsedStructureForFile('url', Settings::create()->withMultibyteSupport(false)); + $sExpected = 'body {background: #fff url("http://somesite.com/images/someimage.gif") repeat top center;} +body {background-url: url("http://somesite.com/images/someimage.gif");}'; + $this->assertSame($sExpected, $oDoc->render()); + } + + function testEmptyFile() { + $oDoc = $this->parsedStructureForFile('-empty', Settings::create()->withMultibyteSupport(true)); + $sExpected = ''; + $this->assertSame($sExpected, $oDoc->render()); + } + + function testEmptyFileMbOff() { + $oDoc = $this->parsedStructureForFile('-empty', Settings::create()->withMultibyteSupport(false)); + $sExpected = ''; + $this->assertSame($sExpected, $oDoc->render()); + } + + function testCharsetLenient1() { + $oDoc = $this->parsedStructureForFile('-charset-after-rule', Settings::create()->withLenientParsing(true)); + $sExpected = '#id {prop: var(--val);}'; + $this->assertSame($sExpected, $oDoc->render()); + } + + function testCharsetLenient2() { + $oDoc = $this->parsedStructureForFile('-charset-in-block', Settings::create()->withLenientParsing(true)); + $sExpected = '@media print {}'; + $this->assertSame($sExpected, $oDoc->render()); + } + + /** + * @expectedException Sabberworm\CSS\Parsing\UnexpectedTokenException + */ + function testCharsetFailure1() { + $this->parsedStructureForFile('-charset-after-rule', Settings::create()->withLenientParsing(false)); + } + + /** + * @expectedException Sabberworm\CSS\Parsing\UnexpectedTokenException + */ + function testCharsetFailure2() { + $this->parsedStructureForFile('-charset-in-block', Settings::create()->withLenientParsing(false)); + } + + function parsedStructureForFile($sFileName, $oSettings = null) { $sFile = dirname(__FILE__) . '/../../files' . DIRECTORY_SEPARATOR . "$sFileName.css"; - $oParser = new Parser(file_get_contents($sFile)); + $oParser = new Parser(file_get_contents($sFile), $oSettings); return $oParser->parse(); } + /** + * @depends testFiles + */ + function testLineNumbersParsing() { + $oDoc = $this->parsedStructureForFile('line-numbers'); + // array key is the expected line number + $aExpected = array( + 1 => array('Sabberworm\CSS\Property\Charset'), + 3 => array('Sabberworm\CSS\Property\CSSNamespace'), + 5 => array('Sabberworm\CSS\RuleSet\AtRuleSet'), + 11 => array('Sabberworm\CSS\RuleSet\DeclarationBlock'), + // Line Numbers of the inner declaration blocks + 17 => array('Sabberworm\CSS\CSSList\KeyFrame', 18, 20), + 23 => array('Sabberworm\CSS\Property\Import'), + 25 => array('Sabberworm\CSS\RuleSet\DeclarationBlock') + ); + + $aActual = array(); + foreach ($oDoc->getContents() as $oContent) { + $aActual[$oContent->getLineNo()] = array(get_class($oContent)); + if ($oContent instanceof KeyFrame) { + foreach ($oContent->getContents() as $block) { + $aActual[$oContent->getLineNo()][] = $block->getLineNo(); + } + } + } + + $aUrlExpected = array(7, 26); // expected line numbers + $aUrlActual = array(); + foreach ($oDoc->getAllValues() as $oValue) { + if ($oValue instanceof URL) { + $aUrlActual[] = $oValue->getLineNo(); + } + } + + // Checking for the multiline color rule lines 27-31 + $aExpectedColorLines = array(28, 29, 30); + $aDeclBlocks = $oDoc->getAllDeclarationBlocks(); + // Choose the 2nd one + $oDeclBlock = $aDeclBlocks[1]; + $aRules = $oDeclBlock->getRules(); + // Choose the 2nd one + $oColor = $aRules[1]->getValue(); + $this->assertEquals(27, $aRules[1]->getLineNo()); + + foreach ($oColor->getColor() as $oSize) { + $aActualColorLines[] = $oSize->getLineNo(); + } + + $this->assertEquals($aExpectedColorLines, $aActualColorLines); + $this->assertEquals($aUrlExpected, $aUrlActual); + $this->assertEquals($aExpected, $aActual); + } + + /** + * @expectedException \Sabberworm\CSS\Parsing\UnexpectedTokenException + * Credit: This test by @sabberworm (from https://github.com/sabberworm/PHP-CSS-Parser/pull/105#issuecomment-229643910 ) + */ + function testUnexpectedTokenExceptionLineNo() { + $oParser = new Parser("\ntest: 1;", Settings::create()->beStrict()); + try { + $oParser->parse(); + } catch (UnexpectedTokenException $e) { + $this->assertSame(2, $e->getLineNo()); + throw $e; + } + } + + /** + * @expectedException Sabberworm\CSS\Parsing\UnexpectedTokenException + */ + function testIeHacksStrictParsing() { + // We can't strictly parse IE hacks. + $this->parsedStructureForFile('ie-hacks', Settings::create()->beStrict()); + } + + function testIeHacksParsing() { + $oDoc = $this->parsedStructureForFile('ie-hacks', Settings::create()->withLenientParsing(true)); + $sExpected = 'p {padding-right: .75rem \9;background-image: none \9;color: red \9\0;background-color: red \9\0;background-color: red \9\0 !important;content: "red \0";content: "red઼";}'; + $this->assertEquals($sExpected, $oDoc->render()); + } + + /** + * @depends testFiles + */ + function testCommentExtracting() { + $oDoc = $this->parsedStructureForFile('comments'); + $aNodes = $oDoc->getContents(); + + // Import property. + $importComments = $aNodes[0]->getComments(); + $this->assertCount(1, $importComments); + $this->assertEquals("*\n * Comments Hell.\n ", $importComments[0]->getComment()); + + // Declaration block. + $fooBarBlock = $aNodes[1]; + $fooBarBlockComments = $fooBarBlock->getComments(); + // TODO Support comments in selectors. + // $this->assertCount(2, $fooBarBlockComments); + // $this->assertEquals("* Number 4 *", $fooBarBlockComments[0]->getComment()); + // $this->assertEquals("* Number 5 *", $fooBarBlockComments[1]->getComment()); + + // Declaration rules. + $fooBarRules = $fooBarBlock->getRules(); + $fooBarRule = $fooBarRules[0]; + $fooBarRuleComments = $fooBarRule->getComments(); + $this->assertCount(1, $fooBarRuleComments); + $this->assertEquals(" Number 6 ", $fooBarRuleComments[0]->getComment()); + + // Media property. + $mediaComments = $aNodes[2]->getComments(); + $this->assertCount(0, $mediaComments); + + // Media children. + $mediaRules = $aNodes[2]->getContents(); + $fooBarComments = $mediaRules[0]->getComments(); + $this->assertCount(1, $fooBarComments); + $this->assertEquals("* Number 10 *", $fooBarComments[0]->getComment()); + + // Media -> declaration -> rule. + $fooBarRules = $mediaRules[0]->getRules(); + $fooBarChildComments = $fooBarRules[0]->getComments(); + $this->assertCount(1, $fooBarChildComments); + $this->assertEquals("* Number 10b *", $fooBarChildComments[0]->getComment()); + } + + function testFlatCommentExtracting() { + $parser = new Parser('div {/*Find Me!*/left:10px; text-align:left;}'); + $doc = $parser->parse(); + $contents = $doc->getContents(); + $divRules = $contents[0]->getRules(); + $comments = $divRules[0]->getComments(); + $this->assertCount(1, $comments); + $this->assertEquals("Find Me!", $comments[0]->getComment()); + } + + function testTopLevelCommentExtracting() { + $parser = new Parser('/*Find Me!*/div {left:10px; text-align:left;}'); + $doc = $parser->parse(); + $contents = $doc->getContents(); + $comments = $contents[0]->getComments(); + $this->assertCount(1, $comments); + $this->assertEquals("Find Me!", $comments[0]->getComment()); + } } diff --git a/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/RuleSet/DeclarationBlockTest.php b/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/RuleSet/DeclarationBlockTest.php index 7a545d03f..16a4a2d11 100644 --- a/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/RuleSet/DeclarationBlockTest.php +++ b/vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/RuleSet/DeclarationBlockTest.php @@ -3,6 +3,8 @@ namespace Sabberworm\CSS\RuleSet; use Sabberworm\CSS\Parser; +use Sabberworm\CSS\Rule\Rule; +use Sabberworm\CSS\Value\Size; class DeclarationBlockTest extends \PHPUnit_Framework_TestCase { @@ -205,4 +207,61 @@ public function createBackgroundShorthandProvider() { ); } + public function testOverrideRules() { + $sCss = '.wrapper { left: 10px; text-align: left; }'; + $oParser = new Parser($sCss); + $oDoc = $oParser->parse(); + $oRule = new Rule('right'); + $oRule->setValue('-10px'); + $aContents = $oDoc->getContents(); + $oWrapper = $aContents[0]; + + $this->assertCount(2, $oWrapper->getRules()); + $aContents[0]->setRules(array($oRule)); + + $aRules = $oWrapper->getRules(); + $this->assertCount(1, $aRules); + $this->assertEquals('right', $aRules[0]->getRule()); + $this->assertEquals('-10px', $aRules[0]->getValue()); + } + + public function testRuleInsertion() { + $sCss = '.wrapper { left: 10px; text-align: left; }'; + $oParser = new Parser($sCss); + $oDoc = $oParser->parse(); + $aContents = $oDoc->getContents(); + $oWrapper = $aContents[0]; + + $oFirst = $oWrapper->getRules('left'); + $this->assertCount(1, $oFirst); + $oFirst = $oFirst[0]; + + $oSecond = $oWrapper->getRules('text-'); + $this->assertCount(1, $oSecond); + $oSecond = $oSecond[0]; + + $oBefore = new Rule('left'); + $oBefore->setValue(new Size(16, 'em')); + + $oMiddle = new Rule('text-align'); + $oMiddle->setValue(new Size(1)); + + $oAfter = new Rule('border-bottom-width'); + $oAfter->setValue(new Size(1, 'px')); + + $oWrapper->addRule($oAfter); + $oWrapper->addRule($oBefore, $oFirst); + $oWrapper->addRule($oMiddle, $oSecond); + + $aRules = $oWrapper->getRules(); + + $this->assertSame($oBefore, $aRules[0]); + $this->assertSame($oFirst, $aRules[1]); + $this->assertSame($oMiddle, $aRules[2]); + $this->assertSame($oSecond, $aRules[3]); + $this->assertSame($oAfter, $aRules[4]); + + $this->assertSame('.wrapper {left: 16em;left: 10px;text-align: 1;text-align: left;border-bottom-width: 1px;}', $oDoc->render()); + } + } diff --git a/vendor/sabberworm/php-css-parser/tests/files/-charset-after-rule.css b/vendor/sabberworm/php-css-parser/tests/files/-charset-after-rule.css new file mode 100644 index 000000000..135690d3a --- /dev/null +++ b/vendor/sabberworm/php-css-parser/tests/files/-charset-after-rule.css @@ -0,0 +1,5 @@ +#id { + prop: var(--val); +} + +@charset 'utf-16'; diff --git a/vendor/sabberworm/php-css-parser/tests/files/-charset-in-block.css b/vendor/sabberworm/php-css-parser/tests/files/-charset-in-block.css new file mode 100644 index 000000000..c40ee9da6 --- /dev/null +++ b/vendor/sabberworm/php-css-parser/tests/files/-charset-in-block.css @@ -0,0 +1,3 @@ +@media print { + @charset 'utf-16'; +} diff --git a/vendor/sabberworm/php-css-parser/tests/files/-empty.css b/vendor/sabberworm/php-css-parser/tests/files/-empty.css new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/sabberworm/php-css-parser/tests/files/-tobedone.css b/vendor/sabberworm/php-css-parser/tests/files/-tobedone.css index 2de3ba091..d9fc1117b 100644 --- a/vendor/sabberworm/php-css-parser/tests/files/-tobedone.css +++ b/vendor/sabberworm/php-css-parser/tests/files/-tobedone.css @@ -1,3 +1,9 @@ .some[selectors-may='contain-a-{'] { +} + +@media only screen and (min-width: 200px) { + .test { + prop: val; + } } \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/tests/files/comments.css b/vendor/sabberworm/php-css-parser/tests/files/comments.css index d30bc5379..ea136bccd 100644 --- a/vendor/sabberworm/php-css-parser/tests/files/comments.css +++ b/vendor/sabberworm/php-css-parser/tests/files/comments.css @@ -10,6 +10,7 @@ @media /* Number 8 */screen /* Number 9 */{ /** Number 10 **/ #foo.bar { + /** Number 10b **/ position: absolute;/**/ } } diff --git a/vendor/sabberworm/php-css-parser/tests/files/ie-hacks.css b/vendor/sabberworm/php-css-parser/tests/files/ie-hacks.css new file mode 100644 index 000000000..3f5f215eb --- /dev/null +++ b/vendor/sabberworm/php-css-parser/tests/files/ie-hacks.css @@ -0,0 +1,9 @@ +p { + padding-right: .75rem \9; + background-image: none \9; + color:red\9\0; + background-color:red \9 \0; + background-color:red \9 \0 !important; + content: "red \9\0"; + content: "red\0abc"; +} diff --git a/vendor/sabberworm/php-css-parser/tests/files/line-numbers.css b/vendor/sabberworm/php-css-parser/tests/files/line-numbers.css new file mode 100644 index 000000000..73d3189f8 --- /dev/null +++ b/vendor/sabberworm/php-css-parser/tests/files/line-numbers.css @@ -0,0 +1,32 @@ +@charset "utf-8"; /* line 1 */ + +@namespace "http://toto.example.org"; /* line 3 */ + +@font-face { /* line 5 */ + font-family: "CrassRoots"; + src: url("http://example.com/media/cr.ttf") /* line 7 */ +} + + +#header { /* line 11 */ + margin: 10px 2em 1cm 2%; + font-family: Verdana, Helvetica, "Gill Sans", sans-serif; + color: red !important; +} + +@keyframes mymove { /* line 17 */ + from { top: 0px; } /* line 18 */ + + to { top: 200px; } /* line 20 */ +} + +@IMPORT uRL(test.css); /* line 23 */ + +body { + background: #FFFFFF url("http://somesite.com/images/someimage.gif") repeat top center; /* line 25 */ + color: rgb( /* line 27 */ + 233, /* line 28 */ + 100, /* line 29 */ + 450 /* line 30 */ + ); +} diff --git a/vendor/sabberworm/php-css-parser/tests/files/url.css b/vendor/sabberworm/php-css-parser/tests/files/url.css new file mode 100644 index 000000000..1ec8deb9d --- /dev/null +++ b/vendor/sabberworm/php-css-parser/tests/files/url.css @@ -0,0 +1,4 @@ +body { background: #FFFFFF url("http://somesite.com/images/someimage.gif") repeat top center; } +body { + background-url: url("http://somesite.com/images/someimage.gif"); +} \ No newline at end of file diff --git a/vendor/sabberworm/php-css-parser/tests/quickdump.php b/vendor/sabberworm/php-css-parser/tests/quickdump.php index d3e7283ab..4b54c71ed 100644 --- a/vendor/sabberworm/php-css-parser/tests/quickdump.php +++ b/vendor/sabberworm/php-css-parser/tests/quickdump.php @@ -1,15 +1,20 @@ +#!/usr/bin/env php parse(); +echo "\n".'#### Input'."\n\n```css\n"; +print $sSource; -echo '#### Structure (`var_dump()`)'."\n"; +echo "\n```\n\n".'#### Structure (`var_dump()`)'."\n\n```php\n"; var_dump($oDoc); -echo '#### Output (`render()`)'."\n"; +echo "\n```\n\n".'#### Output (`render()`)'."\n\n```css\n"; print $oDoc->render(); -echo "\n"; + +echo "\n```\n";