From: Tim Düsterhus Date: Mon, 10 Dec 2018 12:05:34 +0000 (+0100) Subject: Update to pelago/emogrifier 2.1.* X-Git-Tag: 5.2.0_Alpha_1~420^2~7^2~1 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=5ef47e854d57370a701a5da1172b465da447b2e7;p=GitHub%2FWoltLab%2FWCF.git Update to pelago/emogrifier 2.1.* --- diff --git a/wcfsetup/install/files/lib/system/api/composer.json b/wcfsetup/install/files/lib/system/api/composer.json index 46fb8ac624..65ecab83ea 100644 --- a/wcfsetup/install/files/lib/system/api/composer.json +++ b/wcfsetup/install/files/lib/system/api/composer.json @@ -6,7 +6,7 @@ "require": { "ezyang/htmlpurifier": "4.10.*", "erusev/parsedown": "1.7.*", - "pelago/emogrifier": "2.0.*", + "pelago/emogrifier": "2.1.*", "chrisjean/php-ico": "1.0.*", "true/punycode": "~2.0", "pear/net_idna2": "^0.2.0", diff --git a/wcfsetup/install/files/lib/system/api/composer.lock b/wcfsetup/install/files/lib/system/api/composer.lock index e479a1cc3a..89eaf185da 100644 --- a/wcfsetup/install/files/lib/system/api/composer.lock +++ b/wcfsetup/install/files/lib/system/api/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8bb68a1df86b612a3b7196301df662b3", + "content-hash": "c2cc66e87530c77c42e08cef2e6af144", "packages": [ { "name": "chrisjean/php-ico", @@ -299,24 +299,29 @@ }, { "name": "pelago/emogrifier", - "version": "v2.0.0", + "version": "v2.1.1", "source": { "type": "git", "url": "https://github.com/MyIntervals/emogrifier.git", - "reference": "8babf8ddbf348f26b29674e2f84db66ff7e3d95e" + "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8babf8ddbf348f26b29674e2f84db66ff7e3d95e", - "reference": "8babf8ddbf348f26b29674e2f84db66ff7e3d95e", + "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8ee7fb5ad772915451ed3415c1992bd3697d4983", + "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983", "shasum": "" }, "require": { - "php": "^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0" + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0", + "symfony/css-selector": "^3.4.0 || ^4.0.0" }, "require-dev": { + "friendsofphp/php-cs-fixer": "^2.2.0", + "phpmd/phpmd": "^2.6.0", "phpunit/phpunit": "^4.8.0", - "squizlabs/php_codesniffer": "^3.1.0" + "squizlabs/php_codesniffer": "^3.3.2" }, "type": "library", "extra": { @@ -326,7 +331,7 @@ }, "autoload": { "psr-4": { - "Pelago\\": "Classes/" + "Pelago\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -344,10 +349,6 @@ { "name": "Jaime Prado" }, - { - "name": "Roman Ožana", - "email": "ozana@omdesign.cz" - }, { "name": "Oliver Klee", "email": "github@oliverklee.de" @@ -355,6 +356,10 @@ { "name": "Zoli Szabó", "email": "zoli.szabo+github@gmail.com" + }, + { + "name": "Jake Hotson", + "email": "jake@qzdesign.co.uk" } ], "description": "Converts CSS styles into inline style attributes in your HTML code", @@ -364,7 +369,60 @@ "email", "pre-processing" ], - "time": "2018-01-05T23:30:21+00:00" + "time": "2018-12-10T10:36:30+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v4.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "aa9fa526ba1b2ec087ffdfb32753803d999fcfcd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/aa9fa526ba1b2ec087ffdfb32753803d999fcfcd", + "reference": "aa9fa526ba1b2ec087ffdfb32753803d999fcfcd", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/polyfill-mbstring", diff --git a/wcfsetup/install/files/lib/system/api/composer/autoload_psr4.php b/wcfsetup/install/files/lib/system/api/composer/autoload_psr4.php index e71c2cfc74..1cae62ff68 100644 --- a/wcfsetup/install/files/lib/system/api/composer/autoload_psr4.php +++ b/wcfsetup/install/files/lib/system/api/composer/autoload_psr4.php @@ -8,6 +8,7 @@ $baseDir = $vendorDir; return array( 'TrueBV\\' => array($vendorDir . '/true/punycode/src'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), - 'Pelago\\' => array($vendorDir . '/pelago/emogrifier/Classes'), + 'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'), + 'Pelago\\' => array($vendorDir . '/pelago/emogrifier/src'), 'Leafo\\ScssPhp\\' => array($vendorDir . '/leafo/scssphp/src'), ); diff --git a/wcfsetup/install/files/lib/system/api/composer/autoload_static.php b/wcfsetup/install/files/lib/system/api/composer/autoload_static.php index 52ee683b4e..acad207606 100644 --- a/wcfsetup/install/files/lib/system/api/composer/autoload_static.php +++ b/wcfsetup/install/files/lib/system/api/composer/autoload_static.php @@ -19,6 +19,7 @@ class ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab 'S' => array ( 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Component\\CssSelector\\' => 30, ), 'P' => array ( @@ -39,9 +40,13 @@ class ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', ), + 'Symfony\\Component\\CssSelector\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/css-selector', + ), 'Pelago\\' => array ( - 0 => __DIR__ . '/..' . '/pelago/emogrifier/Classes', + 0 => __DIR__ . '/..' . '/pelago/emogrifier/src', ), 'Leafo\\ScssPhp\\' => array ( diff --git a/wcfsetup/install/files/lib/system/api/composer/installed.json b/wcfsetup/install/files/lib/system/api/composer/installed.json index 070b11b6df..f36b09bd4c 100644 --- a/wcfsetup/install/files/lib/system/api/composer/installed.json +++ b/wcfsetup/install/files/lib/system/api/composer/installed.json @@ -304,27 +304,32 @@ }, { "name": "pelago/emogrifier", - "version": "v2.0.0", - "version_normalized": "2.0.0.0", + "version": "v2.1.1", + "version_normalized": "2.1.1.0", "source": { "type": "git", "url": "https://github.com/MyIntervals/emogrifier.git", - "reference": "8babf8ddbf348f26b29674e2f84db66ff7e3d95e" + "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8babf8ddbf348f26b29674e2f84db66ff7e3d95e", - "reference": "8babf8ddbf348f26b29674e2f84db66ff7e3d95e", + "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8ee7fb5ad772915451ed3415c1992bd3697d4983", + "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983", "shasum": "" }, "require": { - "php": "^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0" + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0", + "symfony/css-selector": "^3.4.0 || ^4.0.0" }, "require-dev": { + "friendsofphp/php-cs-fixer": "^2.2.0", + "phpmd/phpmd": "^2.6.0", "phpunit/phpunit": "^4.8.0", - "squizlabs/php_codesniffer": "^3.1.0" + "squizlabs/php_codesniffer": "^3.3.2" }, - "time": "2018-01-05T23:30:21+00:00", + "time": "2018-12-10T10:36:30+00:00", "type": "library", "extra": { "branch-alias": { @@ -334,7 +339,7 @@ "installation-source": "dist", "autoload": { "psr-4": { - "Pelago\\": "Classes/" + "Pelago\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -352,10 +357,6 @@ { "name": "Jaime Prado" }, - { - "name": "Roman Ožana", - "email": "ozana@omdesign.cz" - }, { "name": "Oliver Klee", "email": "github@oliverklee.de" @@ -363,6 +364,10 @@ { "name": "Zoli Szabó", "email": "zoli.szabo+github@gmail.com" + }, + { + "name": "Jake Hotson", + "email": "jake@qzdesign.co.uk" } ], "description": "Converts CSS styles into inline style attributes in your HTML code", @@ -373,6 +378,61 @@ "pre-processing" ] }, + { + "name": "symfony/css-selector", + "version": "v4.2.1", + "version_normalized": "4.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "aa9fa526ba1b2ec087ffdfb32753803d999fcfcd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/aa9fa526ba1b2ec087ffdfb32753803d999fcfcd", + "reference": "aa9fa526ba1b2ec087ffdfb32753803d999fcfcd", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "time": "2018-11-11T19:52:12+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.10.0", diff --git a/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.github/CONTRIBUTING.md b/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.github/CONTRIBUTING.md index 5347d662bc..6287d6549c 100644 --- a/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.github/CONTRIBUTING.md +++ b/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.github/CONTRIBUTING.md @@ -9,7 +9,7 @@ When you contribute, please take the following things into account: ## Contributor Code of Conduct Please note that this project is released with a -[Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this +[Contributor Code of Conduct](../CODE_OF_CONDUCT.md). By participating in this project, you agree to abide by its terms. @@ -59,20 +59,30 @@ first before investing a lot of time in writing code. ## Install the development dependencies To install the development dependencies (PHPUnit and PHP_CodeSniffer), please -run the following command: +run the following commands: - composer install +```shell +composer install +composer require --dev slevomat/coding-standard:^4.0 +``` + +Note that the development dependencies (in particular, for PHP_CodeSniffer) +require PHP 7.0 or later. The second command installs the PHP_CodeSniffer +dependencies and should be omitted if specifically testing against an earlier +version of PHP, however you will not be able to run the static code analysis. ## Unit-test your changes Please cover all changes with unit tests and make sure that your code does not -break any existing tests. We will only merge pull request that include full +break any existing tests. We will only merge pull requests that include full code coverage of the fixed bugs and the new features. To run the existing PHPUnit tests, run this command: - vendor/bin/phpunit Tests/ +```shell +composer ci:tests:unit +``` ## Coding Style @@ -82,9 +92,11 @@ is four spaces. We will only merge pull requests that follow the project's coding style. -Please check your code with the provided PHP_CodeSniffer standard: +Please check your code with the provided static code analysis tools: - vendor/bin/phpcs --standard=Configuration/PhpCodeSniffer/Standards/Emogrifier/ Classes/ Tests/ +```shell +composer ci:static +``` Please make your code clean, well-readable and easy to understand. @@ -92,17 +104,18 @@ If you add new methods or fields, please add proper PHPDoc for the new methods/fields. Please use grammatically correct, complete sentences in the code documentation. +You can autoformat your code using the following command: + +```shell +composer php:fix +``` + ## Git commits Commit message should have a <= 50 character summary, optionally followed by a blank line and a more in depth description of 79 characters per line. -[Please squash related commits together](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html). - -If you already have a commit and work on it, you can also -[amend the first commit](https://nathanhoad.net/git-amend-your-last-commit). - Please use grammatically correct, complete sentences in the commit messages. Also, please prefix the subject line of the commit message with either diff --git a/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.gitignore b/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.gitignore index 6be926125b..8bfbb851e4 100644 --- a/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.gitignore +++ b/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.gitignore @@ -20,5 +20,6 @@ .TemporaryItems .webprj nbproject +/.php_cs.cache /vendor/ composer.lock diff --git a/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.travis.yml b/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.travis.yml index da143168ce..f3a6c22ea5 100644 --- a/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.travis.yml +++ b/wcfsetup/install/files/lib/system/api/pelago/emogrifier/.travis.yml @@ -8,6 +8,7 @@ php: - 7.0 - 7.1 - 7.2 +- 7.3 cache: directories: @@ -16,35 +17,49 @@ cache: env: matrix: - - DEPENDENCIES=latest - - DEPENDENCIES=oldest + - DEPENDENCIES_PREFERENCE="--prefer-lowest" + - DEPENDENCIES_PREFERENCE="" + +before_install: +- phpenv config-rm xdebug.ini || echo "xdebug not available" install: - > + export IGNORE_PLATFORM_REQS="$(composer php:version |grep -q '^7.3' && printf -- --ignore-platform-reqs)"; echo; - if [ "$DEPENDENCIES" = "latest" ]; then - echo "Installing the latest dependencies"; - composer update --with-dependencies --prefer-stable --prefer-dist - else - echo "Installing the lowest dependencies"; - composer update --with-dependencies --prefer-stable --prefer-dist --prefer-lowest - fi; + echo "Updating the dependencies"; + composer update $IGNORE_PLATFORM_REQS --with-dependencies $DEPENDENCIES_PREFERENCE; composer show; -before_script: - - | - if [ -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini ]; then - phpenv config-rm xdebug.ini - else - echo "xdebug.ini does not exist" - fi - - vendor/bin/phpcs --config-set encoding utf-8 - - if [ "$GITHUB_COMPOSER_AUTH" ]; then composer config -g github-oauth.github.com $GITHUB_COMPOSER_AUTH; fi - script: - # Run PHP lint on all PHP files. - - find Classes/ Tests/ -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l - # Check the coding style. - - vendor/bin/phpcs --standard=Configuration/PhpCodeSniffer/Standards/Emogrifier/ Classes/ Tests/ - # Run the unit tests. - - vendor/bin/phpunit Tests/ +- > + echo; + echo "Validating the composer.json"; + composer validate --no-check-all --no-check-lock --strict; + +- > + echo; + echo "Linting all PHP files"; + composer ci:php:lint; + +- > + echo; + echo "Running the unit tests"; + composer ci:tests:unit; + +- > + echo; + echo "Running PHPMD"; + composer ci:php:md; + +- > + echo; + function version_gte() { test "$(printf '%s\n' "$@" | sort -n -t. -r | head -n 1)" = "$1"; }; + if version_gte $(composer php:version) 7; then + echo "Installing slevomat/coding-standard only for PHP 7.x"; + composer require $IGNORE_PLATFORM_REQS --dev slevomat/coding-standard:^4.0 $DEPENDENCIES_PREFERENCE; + echo "Running PHP_CodeSniffer"; + composer ci:php:sniff; + else + echo "Skipped PHP_CodeSniffer due to insufficient PHP version: $(composer php:version)"; + fi; diff --git a/wcfsetup/install/files/lib/system/api/pelago/emogrifier/CHANGELOG.md b/wcfsetup/install/files/lib/system/api/pelago/emogrifier/CHANGELOG.md index 255db41f79..a3866a4bbd 100644 --- a/wcfsetup/install/files/lib/system/api/pelago/emogrifier/CHANGELOG.md +++ b/wcfsetup/install/files/lib/system/api/pelago/emogrifier/CHANGELOG.md @@ -3,6 +3,132 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). +## x.y.z + +### Added + +### Changed + +### Deprecated + +### Removed + +### Fixed + +## 2.1.1 + +### Changed +- Add a test that a missing document type gets added + ([#641](https://github.com/MyIntervals/emogrifier/pull/641)) + +### Fixed +- Keep the `style` element the `head` + ([#642](https://github.com/MyIntervals/emogrifier/pull/642)) + +## 2.1.0 + +### Added +- PHP 7.3 support + ([#638](https://github.com/MyIntervals/emogrifier/pull/638)) + - Allow PHP 7.3 in `composer.json` + - Test in Travis for PHP 7.3 +- Add a `renderBodyContent()` method + ([#633](https://github.com/MyIntervals/emogrifier/pull/633)) +- Add a `getDomDocument()` method + ([#630](https://github.com/MyIntervals/emogrifier/pull/630)) +- Add a Composer script for PHP CS Fixer + ([#607](https://github.com/MyIntervals/emogrifier/pull/607)) +- Copy matching rules with dynamic pseudo-classes or pseudo-elements in + selectors to the style element + ([#280](https://github.com/MyIntervals/emogrifier/issues/280), + [#562](https://github.com/MyIntervals/emogrifier/pull/562), + [#567](https://github.com/MyIntervals/emogrifier/pull/567)) +- Add a CssToAttributeConverter + ([#546](https://github.com/jjriv/emogrifier/pull/546)) +- Expose the DOMDocument in AbstractHtmlProcessor + ([#520](https://github.com/jjriv/emogrifier/pull/520)) +- Add an HtmlNormalizer class + ([#513](https://github.com/jjriv/emogrifier/pull/513), + [#516](https://github.com/jjriv/emogrifier/pull/516)) +- Add a CssInliner class + ([#514](https://github.com/jjriv/emogrifier/pull/514), + [#522](https://github.com/jjriv/emogrifier/pull/522)) +- Composer scripts for the various CI build steps +- Validate the composer.json on Travis + ([#476](https://github.com/jjriv/emogrifier/pull/476)) + +### Changed +- Mark the work-in-progress classes as `@internal` + ([#640](https://github.com/MyIntervals/emogrifier/pull/640)) +- Remove the unprocessable tags from the DOM, not from the raw HTML + ([#627](https://github.com/MyIntervals/emogrifier/pull/627)) +- Reject empty HTML in `setHtml()` + ([#622](https://github.com/MyIntervals/emogrifier/pull/622)) +- Stop passing the DOM document around + ([#618](https://github.com/MyIntervals/emogrifier/pull/618)) +- Improve performance by using explicit namespaces for PHP functions + ([#573](https://github.com/MyIntervals/emogrifier/pull/573), + [#576](https://github.com/MyIntervals/emogrifier/pull/576)) +- Add type hint checking to the code sniffs + ([#566](https://github.com/MyIntervals/emogrifier/pull/566)) +- Check the code with PHPMD + ([#561](https://github.com/jjriv/emogrifier/pull/561)) +- Add the cyclomatic complexity to the checked code sniffs + ([#558](https://github.com/jjriv/emogrifier/pull/558)) +- Use the Symfony CSS selector component + ([#540](https://github.com/jjriv/emogrifier/pull/540)) + +### Deprecated +- Support for PHP 5.5 will be removed in Emogrifier 3.0. +- Support for PHP 5.6 will be removed in Emogrifier 4.0. +- The removal of invisible nodes will be removed in Emogrifier 3.0. + ([#473](https://github.com/jjriv/emogrifier/pull/473)) +- Converting CSS styles to (non-CSS) HTML attributes will be removed + in Emogrifier 3.0. Please use the new CssToAttributeConverter instead. + ([#474](https://github.com/jjriv/emogrifier/pull/474)) +- Emogrifier 3.x.y will be the last release that supports usage without + Composer (i.e., you can still require the class file). + Starting with version 4.0, Emogrifier will only work with Composer. +- The Emogrifier class will be superseded by CssInliner class in + Emogrifier 3.0. For this, the Emogrifier class will be deprecated for + version 3.0 and removed for version 4.0. + +### Removed +- Drop the `@version` PHPDoc annotations + ([#637](https://github.com/MyIntervals/emogrifier/pull/637)) +- Drop the destructors + ([#619](https://github.com/MyIntervals/emogrifier/pull/619)) + +### Fixed +- Add required XML PHP extension to `composer.json` + ([#614](https://github.com/MyIntervals/emogrifier/pull/614)) +- Add required DOM PHP extension to `composer.json` + ([#595](https://github.com/MyIntervals/emogrifier/pull/595)) +- Escape hyphens in regular expressions + ([#588](https://github.com/MyIntervals/emogrifier/pull/588)) +- Fix Travis for PHP 5.x + ([#589](https://github.com/MyIntervals/emogrifier/pull/589)) +- Allow CSS between empty `@media` rule and another `@media` rule + ([#534](https://github.com/MyIntervals/emogrifier/pull/534)) +- Allow additional whitespace in media-query-list of disallowed `@media` rules + ([#532](https://github.com/MyIntervals/emogrifier/pull/532)) +- Allow multiple minified `@import` rules in the CSS without error (note: + `@import`s are currently ignored, + [#527](https://github.com/MyIntervals/emogrifier/pull/527)) +- Style property ordering when multiple mixed individual and shorthand + properties apply ([#511](https://github.com/MyIntervals/emogrifier/pull/511), + [#508](https://github.com/MyIntervals/emogrifier/issues/508)) +- Calculation of selector precedence for selectors involving pseudo-classes + and/or attributes ([#502](https://github.com/MyIntervals/emogrifier/pull/502)) +- Allow `@charset` in the CSS without error (note: its value is currently + ignored, [#507](https://github.com/MyIntervals/emogrifier/pull/507)) +- Allow attribute selectors in descendants + ([#506](https://github.com/MyIntervals/emogrifier/pull/506), + [#381](https://github.com/MyIntervals/emogrifier/issues/381)) +- Allow adjacent sibling CSS selector combinator in minified CSS + ([#505](https://github.com/MyIntervals/emogrifier/pull/505)) +- Allow CSS property values containing newlines + ([#504](https://github.com/MyIntervals/emogrifier/pull/504)) ## 2.0.0 @@ -19,7 +145,6 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Debug mode. Throw debug exceptions only if debug is active. ([#392](https://github.com/MyIntervals/emogrifier/pull/392)) - ### Changed - Test with latest and oldest dependencies on Travis ([#463](https://github.com/MyIntervals/emogrifier/pull/463)) @@ -28,19 +153,16 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Optimize the string operations ([#430](https://github.com/MyIntervals/emogrifier/pull/430)) - ### Deprecated - Support for PHP 5.5 will be removed in Emogrifier 3.0. - Support for PHP 5.6 will be removed in Emogrifier 4.0. - ### Removed - Drop support for PHP 5.4 ([#422](https://github.com/MyIntervals/emogrifier/pull/422)) - Drop support for HHVM ([#386](https://github.com/MyIntervals/emogrifier/pull/386)) - ### Fixed - Handle invalid/unrecognized selectors in media query blocks ([#442](https://github.com/MyIntervals/emogrifier/pull/442)) @@ -59,31 +181,22 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Silence purposefully ignored PHP Warnings ([#400](https://github.com/MyIntervals/emogrifier/pull/400)) - -### Security - - - ## 1.2.0 (2017-03-02) ### Added - Handling invalid xPath expression warnings ([#361](https://github.com/MyIntervals/emogrifier/pull/361)) - ### Deprecated - Support for PHP 5.5 will be removed in Emogrifier 3.0. - Support for PHP 5.4 will be removed in Emogrifier 2.0. - ### Fixed - Allow colon (`:`) and semi-colon (`;`) when using the `*=` selector ([#371](https://github.com/MyIntervals/emogrifier/pull/371)) - Ignore "auto" width and height ([#365](https://github.com/MyIntervals/emogrifier/pull/365)) - - ## 1.1.0 (2016-09-18) ### Added @@ -102,18 +215,15 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Add CSS to HTML attribute mapper ([#288](https://github.com/MyIntervals/emogrifier/pull/288)) - ### Changed - Remove composer dependency from PHP mbstring extension (Actual code dependency were removed a lot of time ago) ([#295](https://github.com/MyIntervals/emogrifier/pull/295)) - ### Deprecated - Support for PHP 5.5 will be removed in Emogrifier 3.0. - Support for PHP 5.4 will be removed in Emogrifier 2.0. - ### Fixed - Method emogrifyBodyContent() doesn't keeps utf8 umlauts ([#349](https://github.com/MyIntervals/emogrifier/pull/349)) @@ -131,8 +241,6 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Second !important rule needs to overwrite the first one ([#292](https://github.com/MyIntervals/emogrifier/pull/292)) - - ## 1.0.0 (2015-10-15) ### Added @@ -159,7 +267,6 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Add several new pseudo-selectors (first-child, last-child, nth-child, and nth-of-type) - ### Changed - Make HTML5 the default document type ([#245](https://github.com/MyIntervals/emogrifier/pull/245)) @@ -170,17 +277,14 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Convert the classes to namespaces ([#41](https://github.com/MyIntervals/emogrifier/pull/41)) - ### Deprecated - Support for PHP 5.4 will be removed in Emogrifier 2.0. - ### Removed - Drop support for PHP 5.3 ([#114](https://github.com/MyIntervals/emogrifier/pull/114)) - Support for character sets other than UTF-8 was removed. - ### Fixed - Fix failing tests on Windows due to line endings ([#263](https://github.com/MyIntervals/emogrifier/pull/263)) diff --git a/wcfsetup/install/files/lib/system/api/pelago/emogrifier/Classes/Emogrifier.php b/wcfsetup/install/files/lib/system/api/pelago/emogrifier/Classes/Emogrifier.php deleted file mode 100644 index 01c800a036..0000000000 --- a/wcfsetup/install/files/lib/system/api/pelago/emogrifier/Classes/Emogrifier.php +++ /dev/null @@ -1,1814 +0,0 @@ - - * @author Roman Ožana - * @author Sander Kruger - * @author Zoli Szabó - */ -class Emogrifier -{ - /** - * @var int - */ - const CACHE_KEY_CSS = 0; - - /** - * @var int - */ - const CACHE_KEY_SELECTOR = 1; - - /** - * @var int - */ - const CACHE_KEY_XPATH = 2; - - /** - * @var int - */ - const CACHE_KEY_CSS_DECLARATIONS_BLOCK = 3; - - /** - * @var int - */ - const CACHE_KEY_COMBINED_STYLES = 4; - - /** - * for calculating nth-of-type and nth-child selectors - * - * @var int - */ - const INDEX = 0; - - /** - * for calculating nth-of-type and nth-child selectors - * - * @var int - */ - const MULTIPLIER = 1; - - /** - * @var string - */ - const ID_ATTRIBUTE_MATCHER = '/(\\w+)?\\#([\\w\\-]+)/'; - - /** - * @var string - */ - const CLASS_ATTRIBUTE_MATCHER = '/(\\w+|[\\*\\]])?((\\.[\\w\\-]+)+)/'; - - /** - * @var string - */ - const CONTENT_TYPE_META_TAG = ''; - - /** - * @var string - */ - const DEFAULT_DOCUMENT_TYPE = ''; - - /** - * @var string - */ - private $html = ''; - - /** - * @var string - */ - private $css = ''; - - /** - * @var bool[] - */ - private $excludedSelectors = []; - - /** - * @var string[] - */ - private $unprocessableHtmlTags = ['wbr']; - - /** - * @var bool[] - */ - private $allowedMediaTypes = ['all' => true, 'screen' => true, 'print' => true]; - - /** - * @var mixed[] - */ - private $caches = [ - self::CACHE_KEY_CSS => [], - self::CACHE_KEY_SELECTOR => [], - self::CACHE_KEY_XPATH => [], - self::CACHE_KEY_CSS_DECLARATIONS_BLOCK => [], - self::CACHE_KEY_COMBINED_STYLES => [], - ]; - - /** - * the visited nodes with the XPath paths as array keys - * - * @var \DOMElement[] - */ - private $visitedNodes = []; - - /** - * the styles to apply to the nodes with the XPath paths as array keys for the outer array - * and the attribute names/values as key/value pairs for the inner array - * - * @var string[][] - */ - private $styleAttributesForNodes = []; - - /** - * Determines whether the "style" attributes of tags in the the HTML passed to this class should be preserved. - * If set to false, the value of the style attributes will be discarded. - * - * @var bool - */ - private $isInlineStyleAttributesParsingEnabled = true; - - /** - * Determines whether the

target

' - ); - - $result = $this->subject->emogrify(); - - self::assertContains( - '

target

', - $result - ); - } - - /** - * @test - */ - public function emogrifyRemovesStyleNodes() - { - $this->subject->setHtml(''); - - $result = $this->subject->emogrify(); - - self::assertNotContains('subject->setDebug(true); - - $this->subject->setHtml( - '' - ); - - $this->subject->emogrify(); - } - - /** - * @test - */ - public function emogrifyNotInDebugModeIgnoresInvalidCssSelectors() - { - $this->subject->setDebug(false); - - $html = ' ' . - '

'; - $this->subject->setHtml($html); - - $html = $this->subject->emogrify(); - - self::assertContains('color: red', $html); - self::assertContains('background-color: blue', $html); - } - - /** - * @test - */ - public function emogrifyByDefaultIgnoresInvalidCssSelectors() - { - $subject = new Emogrifier(); - - $html = ' ' . - '

'; - $subject->setHtml($html); - - $html = $subject->emogrify(); - self::assertContains('color: red', $html); - self::assertContains('background-color: blue', $html); - } - - /** - * Data provider for things that should be left out when applying the CSS. - * - * @return string[][] - */ - public function unneededCssThingsDataProvider() - { - return [ - 'CSS comments with one asterisk' => ['p {color: #000;/* black */}', 'black'], - 'CSS comments with two asterisks' => ['p {color: #000;/** black */}', 'black'], - '@import directive' => ['@import "foo.css";', '@import'], - 'style in "aural" media type rule' => ['@media aural {p {color: #000;}}', '#000'], - 'style in "braille" media type rule' => ['@media braille {p {color: #000;}}', '#000'], - 'style in "embossed" media type rule' => ['@media embossed {p {color: #000;}}', '#000'], - 'style in "handheld" media type rule' => ['@media handheld {p {color: #000;}}', '#000'], - 'style in "projection" media type rule' => ['@media projection {p {color: #000;}}', '#000'], - 'style in "speech" media type rule' => ['@media speech {p {color: #000;}}', '#000'], - 'style in "tty" media type rule' => ['@media tty {p {color: #000;}}', '#000'], - 'style in "tv" media type rule' => ['@media tv {p {color: #000;}}', '#000'], - ]; - } - - /** - * @test - * - * @param string $css - * @param string $markerNotExpectedInHtml - * - * @dataProvider unneededCssThingsDataProvider - */ - public function emogrifyFiltersUnneededCssThings($css, $markerNotExpectedInHtml) - { - $this->subject->setHtml('

foo

'); - $this->subject->setCss($css); - - $result = $this->subject->emogrify(); - - self::assertNotContains($markerNotExpectedInHtml, $result); - } - - /** - * Data provider for media rules. - * - * @return string[][] - */ - public function mediaRulesDataProvider() - { - return [ - 'style in "only all" media type rule' => ['@media only all {p {color: #000;}}'], - 'style in "only screen" media type rule' => ['@media only screen {p {color: #000;}}'], - 'style in media type rule' => ['@media {p {color: #000;}}'], - 'style in "screen" media type rule' => ['@media screen {p {color: #000;}}'], - 'style in "print" media type rule' => ['@media print {p {color: #000;}}'], - 'style in "all" media type rule' => ['@media all {p {color: #000;}}'], - ]; - } - - /** - * @test - * - * @param string $css - * - * @dataProvider mediaRulesDataProvider - */ - public function emogrifyKeepsMediaRules($css) - { - $this->subject->setHtml('

foo

'); - $this->subject->setCss($css); - - $result = $this->subject->emogrify(); - - self::assertContains($css, $result); - } - - /** - * @test - */ - public function removeAllowedMediaTypeRemovesStylesForTheGivenMediaType() - { - $css = '@media screen { html {} }'; - $this->subject->setHtml(''); - $this->subject->setCss($css); - $this->subject->removeAllowedMediaType('screen'); - - $result = $this->subject->emogrify(); - - self::assertNotContains($css, $result); - } - - /** - * @test - */ - public function addAllowedMediaTypeKeepsStylesForTheGivenMediaType() - { - $css = '@media braille { html { some-property: value; } }'; - $this->subject->setHtml(''); - $this->subject->setCss($css); - $this->subject->addAllowedMediaType('braille'); - - $result = $this->subject->emogrify(); - - self::assertContains($css, $result); - } - - /** - * @test - */ - public function emogrifyAddsMissingHeadElement() - { - $this->subject->setHtml(''); - $this->subject->setCss('@media all { html {} }'); - - $result = $this->subject->emogrify(); - - self::assertContains('', $result); - } - - /** - * @test - */ - public function emogrifyKeepExistingHeadElementContent() - { - $this->subject->setHtml(''); - $this->subject->setCss('@media all { html {} }'); - - $result = $this->subject->emogrify(); - - self::assertContains('', $result); - } - - /** - * @test - */ - public function emogrifyAddsStyleElementToBody() - { - $html = $this->html5DocumentType . ''; - $this->subject->setHtml($html); - $this->subject->setCss('@media all { html {} }'); - - $result = $this->subject->emogrify(); - - self::assertContains('', $result); - } - - /** - * @test - * - * @param string $css - * - * @dataProvider validMediaPreserveDataProvider - */ - public function emogrifyWithValidMinifiedMediaQueryContainsInnerCss($css) - { - // Minify CSS by removing unnecessary whitespace. - $css = preg_replace('/\\s*{\\s*/', '{', $css); - $css = preg_replace('/;?\\s*}\\s*/', '}', $css); - $css = preg_replace('/@media{/', '@media {', $css); - - $this->subject->setHtml('

'); - $this->subject->setCss($css); - - $result = $this->subject->emogrify(); - - self::assertContains('', $result); - } - - /** - * @test - * - * @param string $css - * - * @dataProvider validMediaPreserveDataProvider - */ - public function emogrifyForHtmlWithValidMediaQueryContainsInnerCss($css) - { - $this->subject->setHtml('

'); - - $result = $this->subject->emogrify(); - - self::assertContains('', $result); - } - - /** - * @test - * - * @param string $css - * - * @dataProvider validMediaPreserveDataProvider - */ - public function emogrifyWithValidMediaQueryNotContainsInlineCss($css) - { - $this->subject->setHtml('

'); - $this->subject->setCss($css); - - $result = $this->subject->emogrify(); - - self::assertNotContains('style="color:red"', $result); - } - - /** - * Invalid media query which need to be strip - * - * @return string[][] - */ - public function invalidMediaPreserveDataProvider() - { - return [ - 'style in "braille" type rule' => ['@media braille { h1 { color:red; } }'], - 'style in "embossed" type rule' => ['@media embossed { h1 { color:red; } }'], - 'style in "handheld" type rule' => ['@media handheld { h1 { color:red; } }'], - 'style in "projection" type rule' => ['@media projection { h1 { color:red; } }'], - 'style in "speech" type rule' => ['@media speech { h1 { color:red; } }'], - 'style in "tty" type rule' => ['@media tty { h1 { color:red; } }'], - 'style in "tv" type rule' => ['@media tv { h1 { color:red; } }'], - ]; - } - - /** - * @test - * - * @param string $css - * - * @dataProvider invalidMediaPreserveDataProvider - */ - public function emogrifyWithInvalidMediaQueryNotContainsInnerCss($css) - { - $this->subject->setHtml('

'); - $this->subject->setCss($css); - - $result = $this->subject->emogrify(); - - self::assertNotContains($css, $result); - } - - /** - * @test - * - * @param string $css - * - * @dataProvider invalidMediaPreserveDataProvider - */ - public function emogrifyWithInvalidMediaQueryNotContainsInlineCss($css) - { - $this->subject->setHtml('

'); - $this->subject->setCss($css); - - $result = $this->subject->emogrify(); - - self::assertNotContains('style="color: red"', $result); - } - - /** - * @test - * - * @param string $css - * - * @dataProvider invalidMediaPreserveDataProvider - */ - public function emogrifyFromHtmlWithInvalidMediaQueryNotContainsInnerCss($css) - { - $this->subject->setHtml('

'); - - $result = $this->subject->emogrify(); - - self::assertNotContains($css, $result); - } - - /** - * @test - * - * @param string $css - * - * @dataProvider invalidMediaPreserveDataProvider - */ - public function emogrifyFromHtmlWithInvalidMediaQueryNotContainsInlineCss($css) - { - $this->subject->setHtml('

'); - - $result = $this->subject->emogrify(); - - self::assertNotContains('style="color: red"', $result); - } - - /** - * @test - */ - public function emogrifyIgnoresEmptyMediaQuery() - { - $this->subject->setHtml('

'); - $this->subject->setCss('@media screen {} @media tv { h1 { color: red; } }'); - - $result = $this->subject->emogrify(); - - self::assertNotContains('style="color: red"', $result); - self::assertNotContains('@media screen', $result); - } - - /** - * @test - */ - public function emogrifyIgnoresMediaQueryWithWhitespaceOnly() - { - $this->subject->setHtml('

'); - $this->subject->setCss('@media screen { } @media tv { h1 { color: red; } }'); - - $result = $this->subject->emogrify(); - - self::assertNotContains('style="color: red"', $result); - self::assertNotContains('@media screen', $result); - } - - /** - * @test - */ - public function emogrifyAppliesCssFromStyleNodes() - { - $styleAttributeValue = 'color: #ccc;'; - $this->subject->setHtml(''); - - $result = $this->subject->emogrify(); - - self::assertContains( - '', - $result - ); - } - - /** - * @test - */ - public function emogrifyWhenDisabledNotAppliesCssFromStyleBlocks() - { - $styleAttributeValue = 'color: #ccc;'; - $this->subject->setHtml(''); - $this->subject->disableStyleBlocksParsing(); - - $result = $this->subject->emogrify(); - - self::assertNotContains( - '', - $result - ); - } - - /** - * @test - */ - public function emogrifyWhenStyleBlocksParsingDisabledKeepInlineStyles() - { - $styleAttributeValue = 'text-align: center;'; - $this->subject->setHtml( - '' . - '

paragraph

' - ); - $this->subject->disableStyleBlocksParsing(); - - $result = $this->subject->emogrify(); - - self::assertContains( - '

', - $result - ); - } - - /** - * @test - */ - public function emogrifyWhenDisabledNotAppliesCssFromInlineStyles() - { - $this->subject->setHtml(''); - $this->subject->disableInlineStyleAttributesParsing(); - - $result = $this->subject->emogrify(); - - self::assertNotContains('subject->setHtml( - '' . - '

paragraph

' - ); - $this->subject->disableInlineStyleAttributesParsing(); - - $result = $this->subject->emogrify(); - - self::assertContains( - '

', - $result - ); - } - - /** - * @test - */ - public function emogrifyAppliesCssWithUpperCaseSelector() - { - $this->subject->setHtml( - '

paragraph

' - ); - - $result = $this->subject->emogrify(); - - self::assertContains('

', $result); - } - - /** - * Emogrify was handling case differently for passed in CSS vs CSS parsed from style blocks. - * - * @test - */ - public function emogrifyAppliesCssWithMixedCaseAttributesInStyleBlock() - { - $this->subject->setHtml( - '' . - '

some content

' - ); - - $result = $this->subject->emogrify(); - - self::assertContains('

', $result); - } - - /** - * Passed in CSS sets the order, but style block CSS overrides values. - * - * @test - */ - public function emogrifyMergesCssWithMixedCaseAttribute() - { - $this->subject->setHtml( - '' . - '

some content

' - ); - $this->subject->setCss('p { margin: 0; padding-TOP: 0; PADDING-bottom: 1PX;}'); - - $result = $this->subject->emogrify(); - - self::assertContains( - '

', - $result - ); - } - - /** - * @test - */ - public function emogrifyMergesCssWithMixedUnits() - { - $this->subject->setHtml( - '' . - '

some content

' - ); - $this->subject->setCss('p { margin: 1px; padding-bottom:0;}'); - - $result = $this->subject->emogrify(); - - self::assertContains('

', $result); - } - - /** - * @test - */ - public function emogrifyByDefaultRemovesElementsWithDisplayNoneFromExternalCss() - { - $this->subject->setHtml('

'); - $this->subject->setCss('div.foo { display: none; }'); - - $result = $this->subject->emogrify(); - - self::assertContains('
', $result); - } - - /** - * @test - */ - public function emogrifyByDefaultRemovesElementsWithDisplayNoneInStyleAttribute() - { - $this->subject->setHtml( - '
' . - '' - ); - - $result = $this->subject->emogrify(); - - self::assertContains('
', $result); - } - - /** - * @test - */ - public function emogrifyAfterDisableInvisibleNodeRemovalPreservesInvisibleElements() - { - $this->subject->setHtml('
'); - $this->subject->setCss('div.foo { display: none; }'); - - $this->subject->disableInvisibleNodeRemoval(); - $result = $this->subject->emogrify(); - - self::assertContains('