Update pelago/emogrifier bundle (^6.0.0)

This commit is contained in:
Benjamin Dalsass
2022-07-26 08:16:56 +02:00
committed by bdalsass
parent 25a612da04
commit f6c50733fc
19 changed files with 635 additions and 4531 deletions

View File

@@ -1015,14 +1015,16 @@ return array(
'PEAR_ErrorStack' => $vendorDir . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php',
'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php',
'Page' => $baseDir . '/sources/Application/WebPage/Page.php',
'Pelago\\Emogrifier' => $vendorDir . '/pelago/emogrifier/src/Emogrifier.php',
'Pelago\\Emogrifier\\CssInliner' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/CssInliner.php',
'Pelago\\Emogrifier\\HtmlProcessor\\AbstractHtmlProcessor' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/AbstractHtmlProcessor.php',
'Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/CssToAttributeConverter.php',
'Pelago\\Emogrifier\\HtmlProcessor\\HtmlNormalizer' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/HtmlNormalizer.php',
'Pelago\\Emogrifier\\HtmlProcessor\\HtmlPruner' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/HtmlPruner.php',
'Pelago\\Emogrifier\\Utilities\\ArrayIntersector' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/Utilities/ArrayIntersector.php',
'Pelago\\Emogrifier\\Utilities\\CssConcatenator' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/Utilities/CssConcatenator.php',
'Pelago\\Emogrifier\\Caching\\SimpleStringCache' => $vendorDir . '/pelago/emogrifier/src/Caching/SimpleStringCache.php',
'Pelago\\Emogrifier\\CssInliner' => $vendorDir . '/pelago/emogrifier/src/CssInliner.php',
'Pelago\\Emogrifier\\Css\\CssDocument' => $vendorDir . '/pelago/emogrifier/src/Css/CssDocument.php',
'Pelago\\Emogrifier\\Css\\StyleRule' => $vendorDir . '/pelago/emogrifier/src/Css/StyleRule.php',
'Pelago\\Emogrifier\\HtmlProcessor\\AbstractHtmlProcessor' => $vendorDir . '/pelago/emogrifier/src/HtmlProcessor/AbstractHtmlProcessor.php',
'Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter' => $vendorDir . '/pelago/emogrifier/src/HtmlProcessor/CssToAttributeConverter.php',
'Pelago\\Emogrifier\\HtmlProcessor\\HtmlNormalizer' => $vendorDir . '/pelago/emogrifier/src/HtmlProcessor/HtmlNormalizer.php',
'Pelago\\Emogrifier\\HtmlProcessor\\HtmlPruner' => $vendorDir . '/pelago/emogrifier/src/HtmlProcessor/HtmlPruner.php',
'Pelago\\Emogrifier\\Utilities\\ArrayIntersector' => $vendorDir . '/pelago/emogrifier/src/Utilities/ArrayIntersector.php',
'Pelago\\Emogrifier\\Utilities\\CssConcatenator' => $vendorDir . '/pelago/emogrifier/src/Utilities/CssConcatenator.php',
'PhpParser\\Builder' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder.php',
'PhpParser\\BuilderFactory' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php',
'PhpParser\\BuilderHelpers' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderHelpers.php',
@@ -1337,6 +1339,45 @@ return array(
'SQLQuery' => $baseDir . '/core/sqlquery.class.inc.php',
'SQLUnionQuery' => $baseDir . '/core/sqlunionquery.class.inc.php',
'SVGDOMSanitizer' => $baseDir . '/core/htmlsanitizer.class.inc.php',
'Sabberworm\\CSS\\CSSList\\AtRuleBlockList' => $vendorDir . '/sabberworm/php-css-parser/src/CSSList/AtRuleBlockList.php',
'Sabberworm\\CSS\\CSSList\\CSSBlockList' => $vendorDir . '/sabberworm/php-css-parser/src/CSSList/CSSBlockList.php',
'Sabberworm\\CSS\\CSSList\\CSSList' => $vendorDir . '/sabberworm/php-css-parser/src/CSSList/CSSList.php',
'Sabberworm\\CSS\\CSSList\\Document' => $vendorDir . '/sabberworm/php-css-parser/src/CSSList/Document.php',
'Sabberworm\\CSS\\CSSList\\KeyFrame' => $vendorDir . '/sabberworm/php-css-parser/src/CSSList/KeyFrame.php',
'Sabberworm\\CSS\\Comment\\Comment' => $vendorDir . '/sabberworm/php-css-parser/src/Comment/Comment.php',
'Sabberworm\\CSS\\Comment\\Commentable' => $vendorDir . '/sabberworm/php-css-parser/src/Comment/Commentable.php',
'Sabberworm\\CSS\\OutputFormat' => $vendorDir . '/sabberworm/php-css-parser/src/OutputFormat.php',
'Sabberworm\\CSS\\OutputFormatter' => $vendorDir . '/sabberworm/php-css-parser/src/OutputFormatter.php',
'Sabberworm\\CSS\\Parser' => $vendorDir . '/sabberworm/php-css-parser/src/Parser.php',
'Sabberworm\\CSS\\Parsing\\OutputException' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/OutputException.php',
'Sabberworm\\CSS\\Parsing\\ParserState' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/ParserState.php',
'Sabberworm\\CSS\\Parsing\\SourceException' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/SourceException.php',
'Sabberworm\\CSS\\Parsing\\UnexpectedEOFException' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/UnexpectedEOFException.php',
'Sabberworm\\CSS\\Parsing\\UnexpectedTokenException' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/UnexpectedTokenException.php',
'Sabberworm\\CSS\\Property\\AtRule' => $vendorDir . '/sabberworm/php-css-parser/src/Property/AtRule.php',
'Sabberworm\\CSS\\Property\\CSSNamespace' => $vendorDir . '/sabberworm/php-css-parser/src/Property/CSSNamespace.php',
'Sabberworm\\CSS\\Property\\Charset' => $vendorDir . '/sabberworm/php-css-parser/src/Property/Charset.php',
'Sabberworm\\CSS\\Property\\Import' => $vendorDir . '/sabberworm/php-css-parser/src/Property/Import.php',
'Sabberworm\\CSS\\Property\\KeyframeSelector' => $vendorDir . '/sabberworm/php-css-parser/src/Property/KeyframeSelector.php',
'Sabberworm\\CSS\\Property\\Selector' => $vendorDir . '/sabberworm/php-css-parser/src/Property/Selector.php',
'Sabberworm\\CSS\\Renderable' => $vendorDir . '/sabberworm/php-css-parser/src/Renderable.php',
'Sabberworm\\CSS\\RuleSet\\AtRuleSet' => $vendorDir . '/sabberworm/php-css-parser/src/RuleSet/AtRuleSet.php',
'Sabberworm\\CSS\\RuleSet\\DeclarationBlock' => $vendorDir . '/sabberworm/php-css-parser/src/RuleSet/DeclarationBlock.php',
'Sabberworm\\CSS\\RuleSet\\RuleSet' => $vendorDir . '/sabberworm/php-css-parser/src/RuleSet/RuleSet.php',
'Sabberworm\\CSS\\Rule\\Rule' => $vendorDir . '/sabberworm/php-css-parser/src/Rule/Rule.php',
'Sabberworm\\CSS\\Settings' => $vendorDir . '/sabberworm/php-css-parser/src/Settings.php',
'Sabberworm\\CSS\\Value\\CSSFunction' => $vendorDir . '/sabberworm/php-css-parser/src/Value/CSSFunction.php',
'Sabberworm\\CSS\\Value\\CSSString' => $vendorDir . '/sabberworm/php-css-parser/src/Value/CSSString.php',
'Sabberworm\\CSS\\Value\\CalcFunction' => $vendorDir . '/sabberworm/php-css-parser/src/Value/CalcFunction.php',
'Sabberworm\\CSS\\Value\\CalcRuleValueList' => $vendorDir . '/sabberworm/php-css-parser/src/Value/CalcRuleValueList.php',
'Sabberworm\\CSS\\Value\\Color' => $vendorDir . '/sabberworm/php-css-parser/src/Value/Color.php',
'Sabberworm\\CSS\\Value\\LineName' => $vendorDir . '/sabberworm/php-css-parser/src/Value/LineName.php',
'Sabberworm\\CSS\\Value\\PrimitiveValue' => $vendorDir . '/sabberworm/php-css-parser/src/Value/PrimitiveValue.php',
'Sabberworm\\CSS\\Value\\RuleValueList' => $vendorDir . '/sabberworm/php-css-parser/src/Value/RuleValueList.php',
'Sabberworm\\CSS\\Value\\Size' => $vendorDir . '/sabberworm/php-css-parser/src/Value/Size.php',
'Sabberworm\\CSS\\Value\\URL' => $vendorDir . '/sabberworm/php-css-parser/src/Value/URL.php',
'Sabberworm\\CSS\\Value\\Value' => $vendorDir . '/sabberworm/php-css-parser/src/Value/Value.php',
'Sabberworm\\CSS\\Value\\ValueList' => $vendorDir . '/sabberworm/php-css-parser/src/Value/ValueList.php',
'ScalarExpression' => $baseDir . '/core/oql/expression.class.inc.php',
'ScalarOqlExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
'ScssPhp\\ScssPhp\\Base\\Range' => $vendorDir . '/scssphp/scssphp/src/Base/Range.php',
@@ -1541,14 +1582,6 @@ return array(
'Symfony\\Bundle\\FrameworkBundle\\Secrets\\SodiumVault' => $vendorDir . '/symfony/framework-bundle/Secrets/SodiumVault.php',
'Symfony\\Bundle\\FrameworkBundle\\Session\\DeprecatedSessionFactory' => $vendorDir . '/symfony/framework-bundle/Session/DeprecatedSessionFactory.php',
'Symfony\\Bundle\\FrameworkBundle\\Session\\ServiceSessionFactory' => $vendorDir . '/symfony/framework-bundle/Session/ServiceSessionFactory.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\BrowserKitAssertionsTrait' => $vendorDir . '/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\DomCrawlerAssertionsTrait' => $vendorDir . '/symfony/framework-bundle/Test/DomCrawlerAssertionsTrait.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase' => $vendorDir . '/symfony/framework-bundle/Test/KernelTestCase.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\MailerAssertionsTrait' => $vendorDir . '/symfony/framework-bundle/Test/MailerAssertionsTrait.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\TestBrowserToken' => $vendorDir . '/symfony/framework-bundle/Test/TestBrowserToken.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\TestContainer' => $vendorDir . '/symfony/framework-bundle/Test/TestContainer.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestAssertionsTrait' => $vendorDir . '/symfony/framework-bundle/Test/WebTestAssertionsTrait.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase' => $vendorDir . '/symfony/framework-bundle/Test/WebTestCase.php',
'Symfony\\Bundle\\FrameworkBundle\\Translation\\Translator' => $vendorDir . '/symfony/framework-bundle/Translation/Translator.php',
'Symfony\\Bundle\\TwigBundle\\CacheWarmer\\TemplateCacheWarmer' => $vendorDir . '/symfony/twig-bundle/CacheWarmer/TemplateCacheWarmer.php',
'Symfony\\Bundle\\TwigBundle\\Command\\LintCommand' => $vendorDir . '/symfony/twig-bundle/Command/LintCommand.php',
@@ -2182,16 +2215,6 @@ return array(
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageFactoryInterface' => $vendorDir . '/symfony/http-foundation/Session/Storage/SessionStorageFactoryInterface.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface' => $vendorDir . '/symfony/http-foundation/Session/Storage/SessionStorageInterface.php',
'Symfony\\Component\\HttpFoundation\\StreamedResponse' => $vendorDir . '/symfony/http-foundation/StreamedResponse.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\RequestAttributeValueSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseCookieValueSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseFormatSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseFormatSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasCookie' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasHeader' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsRedirected' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsRedirected.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsSuccessful' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsSuccessful.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsUnprocessable' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseStatusCodeSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php',
'Symfony\\Component\\HttpFoundation\\UrlHelper' => $vendorDir . '/symfony/http-foundation/UrlHelper.php',
'Symfony\\Component\\HttpKernel\\Attribute\\ArgumentInterface' => $vendorDir . '/symfony/http-kernel/Attribute/ArgumentInterface.php',
'Symfony\\Component\\HttpKernel\\Attribute\\AsController' => $vendorDir . '/symfony/http-kernel/Attribute/AsController.php',
@@ -2517,9 +2540,7 @@ return array(
'Symfony\\Contracts\\Service\\ServiceProviderInterface' => $vendorDir . '/symfony/service-contracts/ServiceProviderInterface.php',
'Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => $vendorDir . '/symfony/service-contracts/ServiceSubscriberInterface.php',
'Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => $vendorDir . '/symfony/service-contracts/ServiceSubscriberTrait.php',
'Symfony\\Contracts\\Service\\Test\\ServiceLocatorTest' => $vendorDir . '/symfony/service-contracts/Test/ServiceLocatorTest.php',
'Symfony\\Contracts\\Translation\\LocaleAwareInterface' => $vendorDir . '/symfony/translation-contracts/LocaleAwareInterface.php',
'Symfony\\Contracts\\Translation\\Test\\TranslatorTest' => $vendorDir . '/symfony/translation-contracts/Test/TranslatorTest.php',
'Symfony\\Contracts\\Translation\\TranslatableInterface' => $vendorDir . '/symfony/translation-contracts/TranslatableInterface.php',
'Symfony\\Contracts\\Translation\\TranslatorInterface' => $vendorDir . '/symfony/translation-contracts/TranslatorInterface.php',
'Symfony\\Contracts\\Translation\\TranslatorTrait' => $vendorDir . '/symfony/translation-contracts/TranslatorTrait.php',

View File

@@ -12,11 +12,11 @@ return array(
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
'23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
'7e9bd612cc444b3eed788ebbe46263a0' => $vendorDir . '/laminas/laminas-zendframework-bridge/src/autoload.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
'7e9bd612cc444b3eed788ebbe46263a0' => $vendorDir . '/laminas/laminas-zendframework-bridge/src/autoload.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',

View File

@@ -45,13 +45,14 @@ return array(
'Symfony\\Bundle\\FrameworkBundle\\' => array($vendorDir . '/symfony/framework-bundle'),
'Symfony\\Bridge\\Twig\\' => array($vendorDir . '/symfony/twig-bridge'),
'ScssPhp\\ScssPhp\\' => array($vendorDir . '/scssphp/scssphp/src'),
'Sabberworm\\CSS\\' => array($vendorDir . '/sabberworm/php-css-parser/src'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'),
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
'Pelago\\' => array($vendorDir . '/pelago/emogrifier/src'),
'Pelago\\Emogrifier\\' => array($vendorDir . '/pelago/emogrifier/src'),
'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-client/src', $vendorDir . '/league/oauth2-google/src'),
'Laminas\\ZendFrameworkBridge\\' => array($vendorDir . '/laminas/laminas-zendframework-bridge/src'),
'Laminas\\Validator\\' => array($vendorDir . '/laminas/laminas-validator/src'),

View File

@@ -13,11 +13,11 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php',
'23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php',
'7e9bd612cc444b3eed788ebbe46263a0' => __DIR__ . '/..' . '/laminas/laminas-zendframework-bridge/src/autoload.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php',
'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
'7e9bd612cc444b3eed788ebbe46263a0' => __DIR__ . '/..' . '/laminas/laminas-zendframework-bridge/src/autoload.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
@@ -71,6 +71,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Bundle\\FrameworkBundle\\' => 31,
'Symfony\\Bridge\\Twig\\' => 20,
'ScssPhp\\ScssPhp\\' => 16,
'Sabberworm\\CSS\\' => 15,
),
'P' =>
array (
@@ -80,7 +81,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Psr\\Container\\' => 14,
'Psr\\Cache\\' => 10,
'PhpParser\\' => 10,
'Pelago\\' => 7,
'Pelago\\Emogrifier\\' => 18,
),
'L' =>
array (
@@ -266,6 +267,10 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
array (
0 => __DIR__ . '/..' . '/scssphp/scssphp/src',
),
'Sabberworm\\CSS\\' =>
array (
0 => __DIR__ . '/..' . '/sabberworm/php-css-parser/src',
),
'Psr\\Log\\' =>
array (
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
@@ -290,7 +295,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
array (
0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser',
),
'Pelago\\' =>
'Pelago\\Emogrifier\\' =>
array (
0 => __DIR__ . '/..' . '/pelago/emogrifier/src',
),
@@ -1380,14 +1385,16 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'PEAR_ErrorStack' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php',
'PEAR_Exception' => __DIR__ . '/..' . '/pear/pear_exception/PEAR/Exception.php',
'Page' => __DIR__ . '/../..' . '/sources/Application/WebPage/Page.php',
'Pelago\\Emogrifier' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier.php',
'Pelago\\Emogrifier\\CssInliner' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier/CssInliner.php',
'Pelago\\Emogrifier\\HtmlProcessor\\AbstractHtmlProcessor' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/AbstractHtmlProcessor.php',
'Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/CssToAttributeConverter.php',
'Pelago\\Emogrifier\\HtmlProcessor\\HtmlNormalizer' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/HtmlNormalizer.php',
'Pelago\\Emogrifier\\HtmlProcessor\\HtmlPruner' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/HtmlPruner.php',
'Pelago\\Emogrifier\\Utilities\\ArrayIntersector' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier/Utilities/ArrayIntersector.php',
'Pelago\\Emogrifier\\Utilities\\CssConcatenator' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier/Utilities/CssConcatenator.php',
'Pelago\\Emogrifier\\Caching\\SimpleStringCache' => __DIR__ . '/..' . '/pelago/emogrifier/src/Caching/SimpleStringCache.php',
'Pelago\\Emogrifier\\CssInliner' => __DIR__ . '/..' . '/pelago/emogrifier/src/CssInliner.php',
'Pelago\\Emogrifier\\Css\\CssDocument' => __DIR__ . '/..' . '/pelago/emogrifier/src/Css/CssDocument.php',
'Pelago\\Emogrifier\\Css\\StyleRule' => __DIR__ . '/..' . '/pelago/emogrifier/src/Css/StyleRule.php',
'Pelago\\Emogrifier\\HtmlProcessor\\AbstractHtmlProcessor' => __DIR__ . '/..' . '/pelago/emogrifier/src/HtmlProcessor/AbstractHtmlProcessor.php',
'Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter' => __DIR__ . '/..' . '/pelago/emogrifier/src/HtmlProcessor/CssToAttributeConverter.php',
'Pelago\\Emogrifier\\HtmlProcessor\\HtmlNormalizer' => __DIR__ . '/..' . '/pelago/emogrifier/src/HtmlProcessor/HtmlNormalizer.php',
'Pelago\\Emogrifier\\HtmlProcessor\\HtmlPruner' => __DIR__ . '/..' . '/pelago/emogrifier/src/HtmlProcessor/HtmlPruner.php',
'Pelago\\Emogrifier\\Utilities\\ArrayIntersector' => __DIR__ . '/..' . '/pelago/emogrifier/src/Utilities/ArrayIntersector.php',
'Pelago\\Emogrifier\\Utilities\\CssConcatenator' => __DIR__ . '/..' . '/pelago/emogrifier/src/Utilities/CssConcatenator.php',
'PhpParser\\Builder' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder.php',
'PhpParser\\BuilderFactory' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php',
'PhpParser\\BuilderHelpers' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderHelpers.php',
@@ -1702,6 +1709,45 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'SQLQuery' => __DIR__ . '/../..' . '/core/sqlquery.class.inc.php',
'SQLUnionQuery' => __DIR__ . '/../..' . '/core/sqlunionquery.class.inc.php',
'SVGDOMSanitizer' => __DIR__ . '/../..' . '/core/htmlsanitizer.class.inc.php',
'Sabberworm\\CSS\\CSSList\\AtRuleBlockList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/CSSList/AtRuleBlockList.php',
'Sabberworm\\CSS\\CSSList\\CSSBlockList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/CSSList/CSSBlockList.php',
'Sabberworm\\CSS\\CSSList\\CSSList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/CSSList/CSSList.php',
'Sabberworm\\CSS\\CSSList\\Document' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/CSSList/Document.php',
'Sabberworm\\CSS\\CSSList\\KeyFrame' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/CSSList/KeyFrame.php',
'Sabberworm\\CSS\\Comment\\Comment' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Comment/Comment.php',
'Sabberworm\\CSS\\Comment\\Commentable' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Comment/Commentable.php',
'Sabberworm\\CSS\\OutputFormat' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/OutputFormat.php',
'Sabberworm\\CSS\\OutputFormatter' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/OutputFormatter.php',
'Sabberworm\\CSS\\Parser' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parser.php',
'Sabberworm\\CSS\\Parsing\\OutputException' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/OutputException.php',
'Sabberworm\\CSS\\Parsing\\ParserState' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/ParserState.php',
'Sabberworm\\CSS\\Parsing\\SourceException' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/SourceException.php',
'Sabberworm\\CSS\\Parsing\\UnexpectedEOFException' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/UnexpectedEOFException.php',
'Sabberworm\\CSS\\Parsing\\UnexpectedTokenException' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/UnexpectedTokenException.php',
'Sabberworm\\CSS\\Property\\AtRule' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Property/AtRule.php',
'Sabberworm\\CSS\\Property\\CSSNamespace' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Property/CSSNamespace.php',
'Sabberworm\\CSS\\Property\\Charset' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Property/Charset.php',
'Sabberworm\\CSS\\Property\\Import' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Property/Import.php',
'Sabberworm\\CSS\\Property\\KeyframeSelector' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Property/KeyframeSelector.php',
'Sabberworm\\CSS\\Property\\Selector' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Property/Selector.php',
'Sabberworm\\CSS\\Renderable' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Renderable.php',
'Sabberworm\\CSS\\RuleSet\\AtRuleSet' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/RuleSet/AtRuleSet.php',
'Sabberworm\\CSS\\RuleSet\\DeclarationBlock' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/RuleSet/DeclarationBlock.php',
'Sabberworm\\CSS\\RuleSet\\RuleSet' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/RuleSet/RuleSet.php',
'Sabberworm\\CSS\\Rule\\Rule' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Rule/Rule.php',
'Sabberworm\\CSS\\Settings' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Settings.php',
'Sabberworm\\CSS\\Value\\CSSFunction' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/CSSFunction.php',
'Sabberworm\\CSS\\Value\\CSSString' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/CSSString.php',
'Sabberworm\\CSS\\Value\\CalcFunction' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/CalcFunction.php',
'Sabberworm\\CSS\\Value\\CalcRuleValueList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/CalcRuleValueList.php',
'Sabberworm\\CSS\\Value\\Color' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/Color.php',
'Sabberworm\\CSS\\Value\\LineName' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/LineName.php',
'Sabberworm\\CSS\\Value\\PrimitiveValue' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/PrimitiveValue.php',
'Sabberworm\\CSS\\Value\\RuleValueList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/RuleValueList.php',
'Sabberworm\\CSS\\Value\\Size' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/Size.php',
'Sabberworm\\CSS\\Value\\URL' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/URL.php',
'Sabberworm\\CSS\\Value\\Value' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/Value.php',
'Sabberworm\\CSS\\Value\\ValueList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/ValueList.php',
'ScalarExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
'ScalarOqlExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
'ScssPhp\\ScssPhp\\Base\\Range' => __DIR__ . '/..' . '/scssphp/scssphp/src/Base/Range.php',
@@ -1906,14 +1952,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Bundle\\FrameworkBundle\\Secrets\\SodiumVault' => __DIR__ . '/..' . '/symfony/framework-bundle/Secrets/SodiumVault.php',
'Symfony\\Bundle\\FrameworkBundle\\Session\\DeprecatedSessionFactory' => __DIR__ . '/..' . '/symfony/framework-bundle/Session/DeprecatedSessionFactory.php',
'Symfony\\Bundle\\FrameworkBundle\\Session\\ServiceSessionFactory' => __DIR__ . '/..' . '/symfony/framework-bundle/Session/ServiceSessionFactory.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\BrowserKitAssertionsTrait' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\DomCrawlerAssertionsTrait' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/DomCrawlerAssertionsTrait.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/KernelTestCase.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\MailerAssertionsTrait' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/MailerAssertionsTrait.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\TestBrowserToken' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/TestBrowserToken.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\TestContainer' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/TestContainer.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestAssertionsTrait' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/WebTestAssertionsTrait.php',
'Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/WebTestCase.php',
'Symfony\\Bundle\\FrameworkBundle\\Translation\\Translator' => __DIR__ . '/..' . '/symfony/framework-bundle/Translation/Translator.php',
'Symfony\\Bundle\\TwigBundle\\CacheWarmer\\TemplateCacheWarmer' => __DIR__ . '/..' . '/symfony/twig-bundle/CacheWarmer/TemplateCacheWarmer.php',
'Symfony\\Bundle\\TwigBundle\\Command\\LintCommand' => __DIR__ . '/..' . '/symfony/twig-bundle/Command/LintCommand.php',
@@ -2547,16 +2585,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageFactoryInterface' => __DIR__ . '/..' . '/symfony/http-foundation/Session/Storage/SessionStorageFactoryInterface.php',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface' => __DIR__ . '/..' . '/symfony/http-foundation/Session/Storage/SessionStorageInterface.php',
'Symfony\\Component\\HttpFoundation\\StreamedResponse' => __DIR__ . '/..' . '/symfony/http-foundation/StreamedResponse.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\RequestAttributeValueSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseCookieValueSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseFormatSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseFormatSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasCookie' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasHeader' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsRedirected' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsRedirected.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsSuccessful' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsSuccessful.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsUnprocessable' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseStatusCodeSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php',
'Symfony\\Component\\HttpFoundation\\UrlHelper' => __DIR__ . '/..' . '/symfony/http-foundation/UrlHelper.php',
'Symfony\\Component\\HttpKernel\\Attribute\\ArgumentInterface' => __DIR__ . '/..' . '/symfony/http-kernel/Attribute/ArgumentInterface.php',
'Symfony\\Component\\HttpKernel\\Attribute\\AsController' => __DIR__ . '/..' . '/symfony/http-kernel/Attribute/AsController.php',
@@ -2882,9 +2910,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Contracts\\Service\\ServiceProviderInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceProviderInterface.php',
'Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceSubscriberInterface.php',
'Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceSubscriberTrait.php',
'Symfony\\Contracts\\Service\\Test\\ServiceLocatorTest' => __DIR__ . '/..' . '/symfony/service-contracts/Test/ServiceLocatorTest.php',
'Symfony\\Contracts\\Translation\\LocaleAwareInterface' => __DIR__ . '/..' . '/symfony/translation-contracts/LocaleAwareInterface.php',
'Symfony\\Contracts\\Translation\\Test\\TranslatorTest' => __DIR__ . '/..' . '/symfony/translation-contracts/Test/TranslatorTest.php',
'Symfony\\Contracts\\Translation\\TranslatableInterface' => __DIR__ . '/..' . '/symfony/translation-contracts/TranslatableInterface.php',
'Symfony\\Contracts\\Translation\\TranslatorInterface' => __DIR__ . '/..' . '/symfony/translation-contracts/TranslatorInterface.php',
'Symfony\\Contracts\\Translation\\TranslatorTrait' => __DIR__ . '/..' . '/symfony/translation-contracts/TranslatorTrait.php',

View File

@@ -1502,42 +1502,42 @@
},
{
"name": "pelago/emogrifier",
"version": "v3.1.0",
"version_normalized": "3.1.0.0",
"version": "v6.0.0",
"version_normalized": "6.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/MyIntervals/emogrifier.git",
"reference": "f6a5c7d44612d86c3901c93f1592f5440e6b2cd8"
"reference": "aa72d5407efac118f3896bcb995a2cba793df0ae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/f6a5c7d44612d86c3901c93f1592f5440e6b2cd8",
"reference": "f6a5c7d44612d86c3901c93f1592f5440e6b2cd8",
"url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/aa72d5407efac118f3896bcb995a2cba793df0ae",
"reference": "aa72d5407efac118f3896bcb995a2cba793df0ae",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"php": "^5.6 || ~7.0 || ~7.1 || ~7.2 || ~7.3 || ~7.4",
"symfony/css-selector": "^2.8 || ^3.0 || ^4.0 || ^5.0"
"php": "~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0",
"sabberworm/php-css-parser": "^8.3.1",
"symfony/css-selector": "^3.4.32 || ^4.4 || ^5.3 || ^6.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.15.3",
"phpmd/phpmd": "^2.7.0",
"phpunit/phpunit": "^5.7.27",
"squizlabs/php_codesniffer": "^3.5.0"
"php-parallel-lint/php-parallel-lint": "^1.3.0",
"phpunit/phpunit": "^8.5.16",
"rawr/cross-data-providers": "^2.3.0"
},
"time": "2019-12-26T19:37:31+00:00",
"time": "2021-09-16T16:22:04+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
"dev-main": "7.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Pelago\\": "src/"
"Pelago\\Emogrifier\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1890,6 +1890,62 @@
},
"install-path": "../ralouphie/getallheaders"
},
{
"name": "sabberworm/php-css-parser",
"version": "8.4.0",
"version_normalized": "8.4.0.0",
"source": {
"type": "git",
"url": "https://github.com/sabberworm/PHP-CSS-Parser.git",
"reference": "e41d2140031d533348b2192a83f02d8dd8a71d30"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/e41d2140031d533348b2192a83f02d8dd8a71d30",
"reference": "e41d2140031d533348b2192a83f02d8dd8a71d30",
"shasum": ""
},
"require": {
"ext-iconv": "*",
"php": ">=5.6.20"
},
"require-dev": {
"codacy/coverage": "^1.4",
"phpunit/phpunit": "^4.8.36"
},
"suggest": {
"ext-mbstring": "for parsing UTF-8 CSS"
},
"time": "2021-12-11T13:40:54+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Sabberworm\\CSS\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Raphael Schweikert"
}
],
"description": "Parser for CSS Files written in PHP",
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
"keywords": [
"css",
"parser",
"stylesheet"
],
"support": {
"issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues",
"source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.4.0"
},
"install-path": "../sabberworm/php-css-parser"
},
{
"name": "scssphp/scssphp",
"version": "v1.10.3",

View File

@@ -5,7 +5,7 @@
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => 'd93a0b698b20940082f2c866981620199654e689',
'reference' => 'a329c57b34cee6a4829a80b19696284d7966bd7e',
'name' => 'combodo/itop',
'dev' => true,
),
@@ -16,7 +16,7 @@
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => 'd93a0b698b20940082f2c866981620199654e689',
'reference' => 'a329c57b34cee6a4829a80b19696284d7966bd7e',
'dev_requirement' => false,
),
'combodo/tcpdf' => array(
@@ -215,12 +215,12 @@
'dev_requirement' => false,
),
'pelago/emogrifier' => array(
'pretty_version' => 'v3.1.0',
'version' => '3.1.0.0',
'pretty_version' => 'v6.0.0',
'version' => '6.0.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../pelago/emogrifier',
'aliases' => array(),
'reference' => 'f6a5c7d44612d86c3901c93f1592f5440e6b2cd8',
'reference' => 'aa72d5407efac118f3896bcb995a2cba793df0ae',
'dev_requirement' => false,
),
'psr/cache' => array(
@@ -320,6 +320,15 @@
0 => 'v1.10.11',
),
),
'sabberworm/php-css-parser' => array(
'pretty_version' => '8.4.0',
'version' => '8.4.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../sabberworm/php-css-parser',
'aliases' => array(),
'reference' => 'e41d2140031d533348b2192a83f02d8dd8a71d30',
'dev_requirement' => false,
),
'scssphp/scssphp' => array(
'pretty_version' => 'v1.10.3',
'version' => '1.10.3.0',

View File

@@ -10,266 +10,255 @@ This project adheres to [Semantic Versioning](https://semver.org/).
### Changed
### Deprecated
- Support for PHP 7.3 will be removed in Emogrifier 8.0.
### Removed
### Fixed
## 6.0.0
### Added
- Test with Symfony 6-dev (#1109)
- Add support for PHP 8.1 (#1103)
- Add a dedicated class for caching (#1097)
- Allow installation together with Symfony 6 (#1065)
- Support more file types in the `.editorconfig` (#1035)
- Set `align` attribute of `<th>` elements with `CssToAttributeConverter` (#1008)
### Changed
- Use `sabberworm/php-css-parser` to parse the CSS (#1015)
- Also check the unit test code with Psalm (#1003)
### Deprecated
- Support for PHP 7.2 will be removed in Emogrifier 7.0.
### Removed
- Remove a redundant CSS data cache (#1018)
- Drop support for Symfony 5.1 and 5.2 (#972, #1104)
- Drop support for PHP 7.1 (#967)
### Fixed
- Allow `@import` after ignored invalid `@charset` (@1081)
- Allow line feeds within `<html>` tag (#987)
## 5.0.1
### Changed
- Switch the default branch from `master` to `main` (#951)
### Fixed
- Ignore `http-equiv` `Content-Type` in `<body>` (#961)
- Allow "Content-Type" in content (#959)
## 5.0.0
### Added
- Add an `.editorconfig` file (#940)
- Support PHP 8.0 (#926)
- Run the CI build once a week (#933)
- Move more development tools to PHIVE (#894, #907)
### Changed
- Automatically add a backslash for global functions (#909)
- Update the development tools (#898, #895)
- Upgrade to PHPUnit 7.5 (#888)
- Enforce constant visibility (#892)
- Rename the PHPCS configuration file (#891, #896)
- Make use of PHP 7.1 language features (#883)
### Deprecated
- Support for PHP 7.1 will be removed in Emogrifier 6.0.
### Removed
- Drop support for Symfony 4.3 and 5.0 (#936)
- Stop checking `tests/` with Psalm (#885)
- Drop support for PHP 7.0 (#880)
### Fixed
- Fix a nonsensical code example in the README (#920, #935)
- Remove `!important` from `style` attributes also when uppercase, mixed case or
having whitespace after `!` (#911)
- Copy rules using `:...of-type` without a type to the `<style>` element (#904)
- Support combinator followed by dynamic pseudo-class in minified CSS (#903)
- Preserve all uninlinable (or otherwise unprocessed) at-rules (#899)
- Allow Windows CLI to run development tools installed through PHIVE (#900)
- Switch to a maintained package for parallel PHP linting (#884)
- Add `.0` version suffixes to PHP version requirements (#881)
## 4.0.0
### Added
- Extract and inject `@font-face` rules into head (#870)
- Test tag omission in conformant supplied HTML (#868)
- Check for missing return type hint annotations in the code sniffs (#860)
- Support `:only-of-type` (with a type) (#849, #856)
- Configuration setting methods now all return `$this` to allow chaining (#824, #854)
- Disable php-cs-fixer Yoda conditions (#791, #794)
- Check the code with psalm (#537, #779)
- Composer script to run tests with `--stop-on-failure` (#782)
- Test universal selector with combinators (#776)
### Changed
- Normalize DOCTYPE declaration according to polyglot markup recommendation (#866)
- Upgrade to V2 of the PHP setup GitHub action (#861)
- Move the development tools to PHIVE (#850, #851)
- Switch the parallel linting to a maintained fork (#842)
- Move continuous integration from Travis CI to GitHub actions (#832, #834, #838, #839, #840, #841, #843, #846, #849)
- Clean up the folder structure and autoloading configuration (#529, #785)
- Use `self` as the return type for `fromHtml` (#784)
- Make use of PHP 7.0 language features (#777)
### Deprecated
- Support for PHP 7.0 will be removed in Emogrifier 5.0.
### Removed
- Drop support for Symfony versions that have reached their end of life (#847)
- Drop the `Emogrifier` class (#774)
- Drop support for PHP 5.6 (#773)
### Fixed
- Allow `:last-of-type` etc. without type, without causing exception (#875)
- Make sure to use the Composer-installed development tools (#862, #865)
- Add missing `<head>` element when there's a `<header>` element (#844, #853)
- Fix mapping width/height when decimal is used (#845)
- Actually use the specified PHP version on GitHub actions (#836)
- Support `ci:php:lint` on Windows (#740, #780)
## 3.1.0
### Added
- Add support for PHP 7.4
([#821](https://github.com/MyIntervals/emogrifier/pull/821),
[#829](https://github.com/MyIntervals/emogrifier/pull/829))
- Add support for PHP 7.4 (#821, #829)
### Changed
- Upgrade to Symfony 5.0
([#822](https://github.com/MyIntervals/emogrifier/pull/820)
- Upgrade to Symfony 5.0 (#820)
## 3.0.0
### Added
- Test and document excluding entire subtree with `addExcludedSelector()`
([#347](https://github.com/MyIntervals/emogrifier/issues/347),
[#768](https://github.com/MyIntervals/emogrifier/pull/768))
- Test and document excluding entire subtree with `addExcludedSelector()` (#347, #768)
- Test that rules with `:optional` or `:required` are copied to the `<style>`
element ([#748](https://github.com/MyIntervals/emogrifier/issues/748),
[#765](https://github.com/MyIntervals/emogrifier/pull/765))
- Test that rules with `:only-of-type` are copied to the `<style>` element
([#748](https://github.com/MyIntervals/emogrifier/issues/748),
[#760](https://github.com/MyIntervals/emogrifier/pull/760))
- Support `:last-of-type`
([#748](https://github.com/MyIntervals/emogrifier/issues/748),
[#758](https://github.com/MyIntervals/emogrifier/pull/758))
- Support `:first-of-type`
([#748](https://github.com/MyIntervals/emogrifier/issues/748),
[#757](https://github.com/MyIntervals/emogrifier/pull/757))
- Support `:empty`
([#748](https://github.com/MyIntervals/emogrifier/issues/748),
[#756](https://github.com/MyIntervals/emogrifier/pull/756))
- Test that rules with `:any-link` are copied to the `<style>` element
([#748](https://github.com/MyIntervals/emogrifier/issues/748),
[#755](https://github.com/MyIntervals/emogrifier/pull/755))
- Support and test `:only-child`
([#747](https://github.com/MyIntervals/emogrifier/issues/747),
[#754](https://github.com/MyIntervals/emogrifier/pull/754))
- Support and test `:nth-last-of-type`
([#747](https://github.com/MyIntervals/emogrifier/issues/747),
[#751](https://github.com/MyIntervals/emogrifier/pull/751))
- Support and test `:nth-last-child`
([#747](https://github.com/MyIntervals/emogrifier/issues/747),
[#750](https://github.com/MyIntervals/emogrifier/pull/750))
- Support and test general sibling combinator
([#723](https://github.com/MyIntervals/emogrifier/issues/723),
[#745](https://github.com/MyIntervals/emogrifier/pull/745))
- Test universal selector with combinators
([#723](https://github.com/MyIntervals/emogrifier/issues/723),
[#743](https://github.com/MyIntervals/emogrifier/pull/743))
- Preserve `display: none` elements with `-emogrifier-keep` class
([#252](https://github.com/MyIntervals/emogrifier/issues/252),
[#737](https://github.com/MyIntervals/emogrifier/pull/737))
- Preserve valid `@import` rules
([#338](https://github.com/MyIntervals/emogrifier/issues/338),
[#334](https://github.com/MyIntervals/emogrifier/pull/334),
[#732](https://github.com/MyIntervals/emogrifier/pull/732),
[#735](https://github.com/MyIntervals/emogrifier/pull/735))
- Add `HtmlPruner::removeRedundantClassesAfterCssInlined`
([#380](https://github.com/MyIntervals/emogrifier/issues/380),
[#724](https://github.com/MyIntervals/emogrifier/pull/724))
- Check on Travis that PHP-CS-Fixer will not change anything
[#727](https://github.com/MyIntervals/emogrifier/pull/727))
- Support `:not(…)` as an entire selector
([#469](https://github.com/MyIntervals/emogrifier/issues/469),
[#725](https://github.com/MyIntervals/emogrifier/pull/725))
- Add `HtmlPruner::removeRedundantClasses`
([#380](https://github.com/MyIntervals/emogrifier/issues/380),
[#708](https://github.com/MyIntervals/emogrifier/pull/708))
- Support multiple attributes selectors
([#385](https://github.com/MyIntervals/emogrifier/issues/385),
[#721](https://github.com/MyIntervals/emogrifier/pull/721))
- Support `> :first-child` and `> :last-child` in selectors
([#384](https://github.com/MyIntervals/emogrifier/issues/384),
[#720](https://github.com/MyIntervals/emogrifier/pull/720))
- Add an `ArrayIntersector` class
([#708](https://github.com/MyIntervals/emogrifier/pull/708),
[#710](https://github.com/MyIntervals/emogrifier/pull/710))
- Add `CssInliner::getMatchingUninlinableSelectors`
([#380](https://github.com/MyIntervals/emogrifier/issues/380),
[#707](https://github.com/MyIntervals/emogrifier/pull/707))
- Add tests for `:nth-child` and `:nth-of-type`
([#71](https://github.com/MyIntervals/emogrifier/issues/71),
[#698](https://github.com/MyIntervals/emogrifier/pull/698))
element (#748, #765)
- Test that rules with `:only-of-type` are copied to the `<style>` element (#748, #760)
- Support `:last-of-type` (#748, #758)
- Support `:first-of-type` (#748, #757)
- Support `:empty` (#748, #756)
- Test that rules with `:any-link` are copied to the `<style>` element (#748, #755)
- Support and test `:only-child` (#747, #754)
- Support and test `:nth-last-of-type` (#747, #751)
- Support and test `:nth-last-child` (#747, #750)
- Support and test general sibling combinator (#723, #745)
- Test universal selector with combinators (#723, #743)
- Preserve `display: none` elements with `-emogrifier-keep` class (#252, #737)
- Preserve valid `@import` rules (#338, #334, #732, #735)
- Add `HtmlPruner::removeRedundantClassesAfterCssInlined` (#380, #724)
- Check on Travis that PHP-CS-Fixer will not change anything (#727)
- Support `:not(…)` as an entire selector (#469, #725)
- Add `HtmlPruner::removeRedundantClasses` (#380, #708)
- Support multiple attributes selectors (#385, #721)
- Support `> :first-child` and `> :last-child` in selectors (#384, #720)
- Add an `ArrayIntersector` class (#708, #710)
- Add `CssInliner::getMatchingUninlinableSelectors` (#380, #707)
- Add tests for `:nth-child` and `:nth-of-type` (#71, #698)
### Changed
- Relax the dependency on `symfony/css-selector`
([#762](https://github.com/MyIntervals/emogrifier/pull/762))
- Relax the dependency on `symfony/css-selector` (#762)
- Rename `HtmlPruner::removeInvisibleNodes` to
`HtmlPruner::removeElementsWithDisplayNone`
([#717](https://github.com/MyIntervals/emogrifier/issues/717),
[#718](https://github.com/MyIntervals/emogrifier/pull/718))
- Mark the utility classes as internal
([#715](https://github.com/MyIntervals/emogrifier/pull/715))
- Move utility classes to the `Pelago\Emogrifier\Utilities` namespace
([#712](https://github.com/MyIntervals/emogrifier/pull/712))
- Make the `$css` parameter of the `inlineCss` method optional
([#700](https://github.com/MyIntervals/emogrifier/pull/700))
- Update the development dependencies
([#691](https://github.com/MyIntervals/emogrifier/pull/691))
`HtmlPruner::removeElementsWithDisplayNone` (#717, #718)
- Mark the utility classes as internal (#715)
- Move utility classes to the `Pelago\Emogrifier\Utilities` namespace (#712)
- Make the `$css` parameter of the `inlineCss` method optional (#700)
- Update the development dependencies (#691)
### Deprecated
- Support for PHP 5.6 will be removed in Emogrifier 4.0.
- Deprecate the `Emogrifier` class
([#701](https://github.com/MyIntervals/emogrifier/pull/701))
- Deprecate the `Emogrifier` class (#701)
### Removed
- Drop `enableCssToHtmlMapping` and `disableInvisibleNodeRemoval`
([#692](https://github.com/MyIntervals/emogrifier/pull/692))
- Drop support for PHP 5.5
([#690](https://github.com/MyIntervals/emogrifier/pull/690))
- Drop `enableCssToHtmlMapping` and `disableInvisibleNodeRemoval` (#692)
- Drop support for PHP 5.5 (#690)
### Fixed
- Fix PhpStorm code inspection warnings
([#729](https://github.com/MyIntervals/emogrifier/issues/729),
[#770](https://github.com/MyIntervals/emogrifier/pull/770))
- Uppercase type combined with class or ID in selector
([#590](https://github.com/MyIntervals/emogrifier/issues/590),
[#769](https://github.com/MyIntervals/emogrifier/pull/769))
- Fix PhpStorm code inspection warnings (#729, #770)
- Uppercase type combined with class or ID in selector (#590, #769)
- Dynamic pseudo-class combined with static one (rules copied to `<style>`
element, [#746](https://github.com/MyIntervals/emogrifier/pull/746))
- Descendant attribute selectors (such as `html input[disabled]`)
([#375](https://github.com/MyIntervals/emogrifier/pull/375),
[#709](https://github.com/MyIntervals/emogrifier/pull/709))
- Attribute selectors with hyphen in attribute name
([#284](https://github.com/MyIntervals/emogrifier/issues/284),
[#540](https://github.com/MyIntervals/emogrifier/pull/540),
[#704](https://github.com/MyIntervals/emogrifier/pull/702))
element, #746)
- Descendant attribute selectors (such as `html input[disabled]`) (#375, #709)
- Attribute selectors with hyphen in attribute name (#284, #540, #704)
- Attribute selectors with space, hyphen, colon, semicolon or (most) other
non-alphanumeric characters in attribute value
([#284](https://github.com/MyIntervals/emogrifier/issues/284),
[#333](https://github.com/MyIntervals/emogrifier/issues/333),
[#550](https://github.com/MyIntervals/emogrifier/issues/550),
[#540](https://github.com/MyIntervals/emogrifier/pull/540),
[#704](https://github.com/MyIntervals/emogrifier/pull/702))
- Dont create empty `style` attributes for unparsable declarations
([#259](https://github.com/MyIntervals/emogrifier/issues/259),
[#702](https://github.com/MyIntervals/emogrifier/pull/702))
- Allow `:not(:behavioural-pseudo-class)` in selectors
([#697](https://github.com/MyIntervals/emogrifier/pull/697),
[#703](https://github.com/MyIntervals/emogrifier/pull/703))
non-alphanumeric characters in attribute value (#284, #333, #550, #540, #704)
- Dont create empty `style` attributes for unparsable declarations (#259, #702)
- Allow `:not(:behavioural-pseudo-class)` in selectors (#697, #703)
## 2.2.0
### Added
- Add a `HtmlPruner` class
([#679](https://github.com/MyIntervals/emogrifier/pull/679))
- Add `AbstractHtmlProcessor::fromDomDocument`
([#676](https://github.com/MyIntervals/emogrifier/pull/676))
- Add `AbstractHtmlProcessor::fromHtml`
([#675](https://github.com/MyIntervals/emogrifier/pull/675))
- Add a `HtmlPruner` class (#679)
- Add `AbstractHtmlProcessor::fromDomDocument` (#676)
- Add `AbstractHtmlProcessor::fromHtml` (#675)
### Changed
- Make the closures static
([#674](https://github.com/MyIntervals/emogrifier/pull/674))
- Keep `<wbr>` elements by default with `CssInliner`
([#665](https://github.com/MyIntervals/emogrifier/pull/665))
- Make the `CssInliner` inherit `AbstractHtmlProcessor`
([#660](https://github.com/MyIntervals/emogrifier/pull/660))
- Separate `CssInliner::inlineCss` and the rendering
([#654](https://github.com/MyIntervals/emogrifier/pull/654))
- Make the closures static (#674)
- Keep `<wbr>` elements by default with `CssInliner` (#665)
- Make the `CssInliner` inherit `AbstractHtmlProcessor` (#660)
- Separate `CssInliner::inlineCss` and the rendering (#654)
### Removed
- Drop the removal of unprocessable tags from `CssInliner`
([#685](https://github.com/MyIntervals/emogrifier/pull/685))
- Drop the removal of invisible nodes from `CssInliner`
([#684](https://github.com/MyIntervals/emogrifier/pull/684))
- Drop the removal of unprocessable tags from `CssInliner` (#685)
- Drop the removal of invisible nodes from `CssInliner` (#684)
### Fixed
- Remove opening `<body>` tag from `body` content when element has attribute(s)
([#677](https://github.com/MyIntervals/emogrifier/issues/677),
[#683](https://github.com/MyIntervals/emogrifier/pull/683))
- Keep development files out of the Composer packages
([#678](https://github.com/MyIntervals/emogrifier/pull/678))
- Call all static methods statically in `CssConcatenator`
([#670](https://github.com/MyIntervals/emogrifier/pull/670))
- Remove opening `<body>` tag from `body` content when element has attribute(s) (#677, #683)
- Keep development files out of the Composer packages (#678)
- Call all static methods statically in `CssConcatenator` (#670)
- Support all HTML5 self-closing tags, including `<embed>`, `<source>`,
`<track>` and `<wbr>`
([#653](https://github.com/MyIntervals/emogrifier/pull/653))
- Remove all "unprocessable" (e.g. `<wbr>`) tags
([#650](https://github.com/MyIntervals/emogrifier/pull/650))
- Correct translated xpath of `:nth-child` selector
([#648](https://github.com/MyIntervals/emogrifier/pull/648))
`<track>` and `<wbr>` (#653)
- Remove all "unprocessable" (e.g. `<wbr>`) tags (#650)
- Correct translated xpath of `:nth-child` selector (#648)
## 2.1.1
### Changed
- Add a test that a missing document type gets added
([#641](https://github.com/MyIntervals/emogrifier/pull/641))
- Add a test that a missing document type gets added (#641)
### Fixed
- Keep the `style` element the `head`
([#642](https://github.com/MyIntervals/emogrifier/pull/642))
- Keep the `style` element the `head` (#642)
## 2.1.0
### Added
- PHP 7.3 support
([#638](https://github.com/MyIntervals/emogrifier/pull/638))
- PHP 7.3 support (#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))
- Add a `renderBodyContent()` method (#633)
- Add a `getDomDocument()` method (#630)
- Add a Composer script for PHP CS Fixer (#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/MyIntervals/emogrifier/pull/546))
- Expose the DOMDocument in AbstractHtmlProcessor
([#520](https://github.com/MyIntervals/emogrifier/pull/520))
- Add an HtmlNormalizer class
([#513](https://github.com/MyIntervals/emogrifier/pull/513),
[#516](https://github.com/MyIntervals/emogrifier/pull/516))
- Add a CssInliner class
([#514](https://github.com/MyIntervals/emogrifier/pull/514),
[#522](https://github.com/MyIntervals/emogrifier/pull/522))
selectors to the style element (#280, #562, #567)
- Add a CssToAttributeConverter (#546)
- Expose the DOMDocument in AbstractHtmlProcessor (#520)
- Add an HtmlNormalizer class (#513, #516)
- Add a CssInliner class (#514, #522)
- Composer scripts for the various CI build steps
- Validate the composer.json on Travis
([#476](https://github.com/MyIntervals/emogrifier/pull/476))
- Validate the composer.json on Travis (#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/MyIntervals/emogrifier/pull/561))
- Add the cyclomatic complexity to the checked code sniffs
([#558](https://github.com/MyIntervals/emogrifier/pull/558))
- Use the Symfony CSS selector component
([#540](https://github.com/MyIntervals/emogrifier/pull/540))
- Mark the work-in-progress classes as `@internal` (#640)
- Remove the unprocessable tags from the DOM, not from the raw HTML (#627)
- Reject empty HTML in `setHtml()` (#622)
- Stop passing the DOM document around (#618)
- Improve performance by using explicit namespaces for PHP functions (#573, #576)
- Add type hint checking to the code sniffs (#566)
- Check the code with PHPMD (#561)
- Add the cyclomatic complexity to the checked code sniffs (#558)
- Use the Symfony CSS selector component (#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/MyIntervals/emogrifier/pull/473))
- The removal of invisible nodes will be removed in Emogrifier 3.0. (#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/MyIntervals/emogrifier/pull/474))
in Emogrifier 3.0. Please use the new CssToAttributeConverter instead. (#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.
@@ -278,230 +267,149 @@ This project adheres to [Semantic Versioning](https://semver.org/).
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))
- Drop the `@version` PHPDoc annotations (#637)
- Drop the destructors (#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))
- Add required XML PHP extension to `composer.json` (#614)
- Add required DOM PHP extension to `composer.json` (#595)
- Escape hyphens in regular expressions (#588)
- Fix Travis for PHP 5.x (#589)
- Allow CSS between empty `@media` rule and another `@media` rule (#534)
- Allow additional whitespace in media-query-list of disallowed `@media` rules (#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))
`@import`s are currently ignored, #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))
properties apply (#511, #508)
- Calculation of selector precedence for selectors involving pseudo-classes
and/or attributes ([#502](https://github.com/MyIntervals/emogrifier/pull/502))
and/or attributes (#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),
[#443](https://github.com/MyIntervals/emogrifier/issues/443))
- 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))
ignored, #507)
- Allow attribute selectors in descendants (#506, #381, #443)
- Allow adjacent sibling CSS selector combinator in minified CSS (#505)
- Allow CSS property values containing newlines (#504)
## 2.0.0
### Added
- Support for CSS :not() selector
([#431](https://github.com/MyIntervals/emogrifier/pull/431))
- Automatically remove !important annotations from final inline style declarations
([#420](https://github.com/MyIntervals/emogrifier/pull/420))
- Automatically move `<style>` block from `<head>` to `<body>`
([#396](https://github.com/MyIntervals/emogrifier/pull/396))
- PHP 7.2 support ([#398](https://github.com/MyIntervals/emogrifier/pull/398))
- Support for CSS :not() selector (#431)
- Automatically remove !important annotations from final inline style declarations (#420)
- Automatically move `<style>` block from `<head>` to `<body>` (#396)
- PHP 7.2 support (#398)
- Allow PHP 7.2 in `composer.json`, cleaner PHP version constraint
- Test in Travis for PHP 7.2
- Debug mode. Throw debug exceptions only if debug is active.
([#392](https://github.com/MyIntervals/emogrifier/pull/392))
- Debug mode. Throw debug exceptions only if debug is active. (#392)
### Changed
- Test with latest and oldest dependencies on Travis
([#463](https://github.com/MyIntervals/emogrifier/pull/463))
- Always enable the debug mode in the tests
([#448](https://github.com/MyIntervals/emogrifier/pull/448))
- Optimize the string operations
([#430](https://github.com/MyIntervals/emogrifier/pull/430))
- Test with latest and oldest dependencies on Travis (#463)
- Always enable the debug mode in the tests (#448)
- Optimize the string operations (#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))
- Drop support for PHP 5.4 (#422)
- Drop support for HHVM (#386)
### Fixed
- Handle invalid/unrecognized selectors in media query blocks
([#442](https://github.com/MyIntervals/emogrifier/pull/442))
- Throw (the correct) exception for invalid excluded selectors
([#437](https://github.com/MyIntervals/emogrifier/pull/437))
- emogrifyBody must not encode umlaut entities
([#414](https://github.com/MyIntervals/emogrifier/pull/414))
- Fix mapped HTML attribute values
([#405](https://github.com/MyIntervals/emogrifier/pull/405))
- Make sure the HTML always has a BODY element
([#410](https://github.com/MyIntervals/emogrifier/pull/410))
- Make inline style priority higher than css block priority
([#404](https://github.com/MyIntervals/emogrifier/pull/404))
- Fix media regex parsing
([#402](https://github.com/MyIntervals/emogrifier/pull/402))
- Silence purposefully ignored PHP Warnings
([#400](https://github.com/MyIntervals/emogrifier/pull/400))
- Handle invalid/unrecognized selectors in media query blocks (#442)
- Throw (the correct) exception for invalid excluded selectors (#437)
- emogrifyBody must not encode umlaut entities (#414)
- Fix mapped HTML attribute values (#405)
- Make sure the HTML always has a BODY element (#410)
- Make inline style priority higher than css block priority (#404)
- Fix media regex parsing (#402)
- Silence purposefully ignored PHP Warnings (#400)
## 1.2.0 (2017-03-02)
### Added
- Handling invalid xPath expression warnings
([#361](https://github.com/MyIntervals/emogrifier/pull/361))
- Handling invalid xPath expression warnings (#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))
- Allow colon (`:`) and semi-colon (`;`) when using the `*=` selector (#371)
- Ignore "auto" width and height (#365)
## 1.1.0 (2016-09-18)
### Added
- Add support for PHP 7.1
([#342](https://github.com/MyIntervals/emogrifier/pull/342))
- Support the attr|=value selector
([#337](https://github.com/MyIntervals/emogrifier/pull/337))
- Support the attr*=value selector
([#330](https://github.com/MyIntervals/emogrifier/pull/330))
- Support the attr$=value selector
([#329](https://github.com/MyIntervals/emogrifier/pull/329))
- Support the attr^=value selector
([#324](https://github.com/MyIntervals/emogrifier/pull/324))
- Support the attr~=value selector
([#323](https://github.com/MyIntervals/emogrifier/pull/323))
- Add CSS to HTML attribute mapper
([#288](https://github.com/MyIntervals/emogrifier/pull/288))
- Add support for PHP 7.1 (#342)
- Support the attr|=value selector (#337)
- Support the attr*=value selector (#330)
- Support the attr$=value selector (#329)
- Support the attr^=value selector (#324)
- Support the attr~=value selector (#323)
- Add CSS to HTML attribute mapper (#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))
- Remove composer dependency from PHP mbstring extension (Actual code dependency were removed a lot of time ago) (#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))
- Ignore value with words more than one in the attribute selector
([#327](https://github.com/MyIntervals/emogrifier/pull/327))
- Ignore spaces around the > in the direct child selector
([#322](https://github.com/MyIntervals/emogrifier/pull/322))
- Ignore empty media queries
([#307](https://github.com/MyIntervals/emogrifier/pull/307))
([#237](https://github.com/MyIntervals/emogrifier/issues/237))
- Ignore pseudo-class when combined with pseudo-element
([#308](https://github.com/MyIntervals/emogrifier/pull/308))
- First-child and last-child selectors are broken
([#293](https://github.com/MyIntervals/emogrifier/pull/293))
- Second !important rule needs to overwrite the first one
([#292](https://github.com/MyIntervals/emogrifier/pull/292))
- Method emogrifyBodyContent() doesn't keeps utf8 umlauts (#349)
- Ignore value with words more than one in the attribute selector (#327)
- Ignore spaces around the > in the direct child selector (#322)
- Ignore empty media queries (#307) (#237)
- Ignore pseudo-class when combined with pseudo-element (#308)
- First-child and last-child selectors are broken (#293)
- Second !important rule needs to overwrite the first one (#292)
## 1.0.0 (2015-10-15)
### Added
- Add branch alias ([#231](https://github.com/MyIntervals/emogrifier/pull/231))
- Remove media queries which do not impact the document
([#217](https://github.com/MyIntervals/emogrifier/pull/217))
- Allow elements to be excluded from emogrification
([#215](https://github.com/MyIntervals/emogrifier/pull/215))
- Handle !important ([#214](https://github.com/MyIntervals/emogrifier/pull/214))
- emogrifyBodyContent() method
([#206](https://github.com/MyIntervals/emogrifier/pull/206))
- Cache combinedStyles ([#211](https://github.com/MyIntervals/emogrifier/pull/211))
- Allow user to define media types to keep
([#200](https://github.com/MyIntervals/emogrifier/pull/200))
- Ignore invalid CSS selectors
([#194](https://github.com/MyIntervals/emogrifier/pull/194))
- isRemoveDisplayNoneEnabled option
([#162](https://github.com/MyIntervals/emogrifier/pull/162))
- Allow disabling of "inline style" and "style block" parsing
([#156](https://github.com/MyIntervals/emogrifier/pull/156))
- Preserve @media if necessary
([#62](https://github.com/MyIntervals/emogrifier/pull/62))
- Add branch alias (#231)
- Remove media queries which do not impact the document (#217)
- Allow elements to be excluded from emogrification (#215)
- Handle !important (#214)
- emogrifyBodyContent() method (#206)
- Cache combinedStyles (#211)
- Allow user to define media types to keep (#200)
- Ignore invalid CSS selectors (#194)
- isRemoveDisplayNoneEnabled option (#162)
- Allow disabling of "inline style" and "style block" parsing (#156)
- Preserve @media if necessary (#62)
- Add extraction of style blocks within the HTML
- 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))
- Make copyCssWithMediaToStyleNode private
([#218](https://github.com/MyIntervals/emogrifier/pull/218))
- Stop encoding umlauts and dollar signs
([#170](https://github.com/MyIntervals/emogrifier/pull/170))
- Convert the classes to namespaces
([#41](https://github.com/MyIntervals/emogrifier/pull/41))
- Make HTML5 the default document type (#245)
- Make copyCssWithMediaToStyleNode private (#218)
- Stop encoding umlauts and dollar signs (#170)
- Convert the classes to namespaces (#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))
- Drop support for PHP 5.3 (#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))
- Parsing CSS declaration blocks
([#261](https://github.com/MyIntervals/emogrifier/pull/261))
- Fix first-child and last-child selectors
([#257](https://github.com/MyIntervals/emogrifier/pull/257))
- Fix parsing of CSS for data URIs
([#243](https://github.com/MyIntervals/emogrifier/pull/243))
- Fix multi-line media queries
([#241](https://github.com/MyIntervals/emogrifier/pull/241))
- Keep CSS media queries even if followed by CSS comments
([#201](https://github.com/MyIntervals/emogrifier/pull/201))
- Fix CSS selectors with exact attribute only
([#197](https://github.com/MyIntervals/emogrifier/pull/197))
- Properly handle UTF-8 characters and entities
([#189](https://github.com/MyIntervals/emogrifier/pull/189))
- Add mbstring extension to composer.json
([#93](https://github.com/MyIntervals/emogrifier/pull/93))
- Prevent incorrectly capitalized CSS selectors from being stripped
([#85](https://github.com/MyIntervals/emogrifier/pull/85))
- Fix CSS selectors with exact attribute only
([#197](https://github.com/MyIntervals/emogrifier/pull/197))
- Wrong selector extraction from minified CSS
([#69](https://github.com/MyIntervals/emogrifier/pull/69))
- Restore libxml error handler state after clearing
([#65](https://github.com/MyIntervals/emogrifier/pull/65))
- Ignore all warnings produced by DOMDocument::loadHTML()
([#63](https://github.com/MyIntervals/emogrifier/pull/63))
- Style tags in HTML cause an Xpath invalid query error
([#60](https://github.com/MyIntervals/emogrifier/pull/60))
- Fix PHP warnings with PHP 5.5
([#26](https://github.com/MyIntervals/emogrifier/pull/26))
- Fix failing tests on Windows due to line endings (#263)
- Parsing CSS declaration blocks (#261)
- Fix first-child and last-child selectors (#257)
- Fix parsing of CSS for data URIs (#243)
- Fix multi-line media queries (#241)
- Keep CSS media queries even if followed by CSS comments (#201)
- Fix CSS selectors with exact attribute only (#197)
- Properly handle UTF-8 characters and entities (#189)
- Add mbstring extension to composer.json (#93)
- Prevent incorrectly capitalized CSS selectors from being stripped (#85)
- Fix CSS selectors with exact attribute only (#197)
- Wrong selector extraction from minified CSS (#69)
- Restore libxml error handler state after clearing (#65)
- Ignore all warnings produced by DOMDocument::loadHTML() (#63)
- Style tags in HTML cause an Xpath invalid query error (#60)
- Fix PHP warnings with PHP 5.5 (#26)
- Make removal of invisible nodes operate in a case-insensitive manner
- Fix a bug that was overwriting existing inline styles from the original HTML

View File

@@ -1,6 +1,6 @@
# Emogrifier
[![Build Status](https://travis-ci.org/MyIntervals/emogrifier.svg?branch=master)](https://travis-ci.org/MyIntervals/emogrifier)
[![Build Status](https://github.com/MyIntervals/emogrifier/workflows/CI/badge.svg?branch=main)](https://github.com/MyIntervals/emogrifier/actions/)
[![Latest Stable Version](https://poser.pugx.org/pelago/emogrifier/v/stable.svg)](https://packagist.org/packages/pelago/emogrifier)
[![Total Downloads](https://poser.pugx.org/pelago/emogrifier/downloads.svg)](https://packagist.org/packages/pelago/emogrifier)
[![Latest Unstable Version](https://poser.pugx.org/pelago/emogrifier/v/unstable.svg)](https://packagist.org/packages/pelago/emogrifier)
@@ -75,8 +75,9 @@ elements in the HTML, you can omit the `$css` parameter:
$visualHtml = CssInliner::fromHtml($html)->inlineCss()->render();
```
If you would like to get back only the content of the `<body>` element instead of
the complete HTML document, you can use the `renderBodyContent` method instead:
If you would like to get back only the content of the `<body>` element instead
of the complete HTML document, you can use the `renderBodyContent` method
instead:
```php
$bodyContent = $visualHtml = CssInliner::fromHtml($html)->inlineCss()
@@ -210,8 +211,7 @@ method, if invoked after `removeElementsWithDisplayNone`, will remove the
### Options
There are several options that you can set on the `CssInliner` instance before
calling the `inlineCss` method (or on the `Emogrifier` instance before calling
the `emogrify` method):
calling the `inlineCss` method:
* `->disableStyleBlocksParsing()` - By default, `CssInliner` will grab
all `<style>` blocks in the HTML and will apply the CSS styles as inline
@@ -221,7 +221,7 @@ the `emogrify` method):
use this option. If you use this option, the contents of the `<style>` blocks
will _not_ be applied as inline styles and any CSS you want `CssInliner` to
use must be passed in as described in the [Usage section](#usage) above.
* `->disableInlineStylesParsing()` - By default, `CssInliner`
* `->disableInlineStyleAttributesParsing()` - By default, `CssInliner`
preserves all of the "style" attributes on tags in the HTML you pass to it.
However if you want to discard all existing inline styles in the HTML before
the CSS is applied, you should use this option.
@@ -241,53 +241,7 @@ the `emogrify` method):
$cssInliner->addExcludedSelector('.message-preview *');
```
### Using the legacy Emogrifier class
In version 3.0.0, the `Emogrifier` class has been deprecated, and it will be
removed for version 4.0.0. Please update your code to use the new
`CssInliner` class instead.
If you are still using the deprecated class, here is how to use it:
First, you provide Emogrifier with the HTML and CSS you would like to merge.
This can happen directly during instantiation:
```php
$html = '<html><h1>Hello world!</h1></html>';
$css = 'h1 {font-size: 32px;}';
$emogrifier = new \Pelago\Emogrifier($html, $css);
```
You could also use the setters for providing this data after instantiation:
```php
$emogrifier = new \Pelago\Emogrifier();
$html = '<html><h1>Hello world!</h1></html>';
$css = 'h1 {font-size: 32px;}';
$emogrifier->setHtml($html);
$emogrifier->setCss($css);
```
After you have set the HTML and CSS, you can call the `emogrify` method to
merge both:
```php
$mergedHtml = $emogrifier->emogrify();
```
Emogrifier automatically adds a Content-Type meta tag to set the charset for
the document (if it is not provided).
If you would like to get back only the content of the BODY element instead of
the complete HTML document, you can use the `emogrifyBodyContent` instead:
```php
$bodyContent = $emogrifier->emogrifyBodyContent();
```
### Migrating from `Emogrifier` to `CssInliner`
### Migrating from the dropped `Emogrifier` class to the `CssInliner` class
#### Minimal example
@@ -324,7 +278,7 @@ New code using `CssInliner` and family:
```php
$domDocument = CssInliner::fromHtml($html)->inlineCss($css)->getDomDocument();
HtmlPruner::fromDomDocument($domDocument)->removeElementsWithDisplayNone(),
HtmlPruner::fromDomDocument($domDocument)->removeElementsWithDisplayNone();
$html = CssToAttributeConverter::fromDomDocument($domDocument)
->convertCssToVisualAttributes()->render();
```
@@ -338,7 +292,6 @@ Emogrifier currently supports the following
* [class](https://developer.mozilla.org/en-US/docs/Web/CSS/Class_selectors)
* [ID](https://developer.mozilla.org/en-US/docs/Web/CSS/ID_selectors)
* [universal](https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors)
(partial support)
* [attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors):
* presence
* exact value match
@@ -355,8 +308,7 @@ Emogrifier currently supports the following
* [empty](https://developer.mozilla.org/en-US/docs/Web/CSS/:empty)
* [first-child](https://developer.mozilla.org/en-US/docs/Web/CSS/:first-child)
* [first-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:first-of-type)
(with a type, e.g. `p:first-of-type` but not `*:first-of-type` which will
behave as `*:first-child`)
(with a type, e.g. `p:first-of-type` but not `*:first-of-type`)
* [last-child](https://developer.mozilla.org/en-US/docs/Web/CSS/:last-child)
* [last-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:last-of-type)
(with a type)
@@ -368,36 +320,33 @@ Emogrifier currently supports the following
* [nth-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-of-type)
(with a type)
* [only-child](https://developer.mozilla.org/en-US/docs/Web/CSS/:only-child)
* [only-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:only-of-type)
(with a type)
The following selectors are not implemented yet:
* [universal](https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors):
* with
[child combinator](https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator)
* as ancestor with
[descendant combinator](https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_combinator)
(e.g. `p *` is supported but `* p` is not)
* [case-insensitive attribute value](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors#case-insensitive)
* static [pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes):
* static [pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes)
not listed above as supported rules involving them will nonetheless be
preserved and copied to a `<style>` element in the HTML including (but not
necessarily limited to) the following:
* [any-link](https://developer.mozilla.org/en-US/docs/Web/CSS/:any-link)
* [first-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:first-of-type)
without a type (will behave as `:first-child`)
without a type
* [last-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:last-of-type)
without a type (will behave as `:last-child`)
without a type
* [nth-last-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-last-of-type)
without a type (will behave as `:nth-last-child()`)
without a type
* [nth-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-of-type)
without a type (will behave as `:nth-child()`)
* any pseudo-classes not listed above as supported rules involving them
will nonetheless be preserved and copied to a `<style>` element in the
HTML including (but not necessarily limited to) the following:
* [any-link](https://developer.mozilla.org/en-US/docs/Web/CSS/:any-link)
* [only-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:only-of-type)
* [optional](https://developer.mozilla.org/en-US/docs/Web/CSS/:optional)
* [required](https://developer.mozilla.org/en-US/docs/Web/CSS/:required)
without a type
* [only-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:only-of-type)
without a type
* [optional](https://developer.mozilla.org/en-US/docs/Web/CSS/:optional)
* [required](https://developer.mozilla.org/en-US/docs/Web/CSS/:required)
Rules involving the following selectors cannot be applied as inline styles.
They will, however, be preserved and copied to a `<style>` element in the HTML:
* dynamic [pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes)
(such as `:hover`)
* [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements)
@@ -414,7 +363,7 @@ They will, however, be preserved and copied to a `<style>` element in the HTML:
to some of the declarations within them so that they will override CSS styles
that have been inlined. For example, with the following CSS, the `font-size`
declaration in the `@media` rule would not override the font size for `p`
elements from the preceding rule after that has been inlined as
elements from the preceding rule after that has been inlined as
`<p style="font-size: 16px;">` in the HTML, without the `!important` directive
(even though `!important` would not be necessary if the CSS were not inlined):
```css
@@ -425,7 +374,7 @@ They will, however, be preserved and copied to a `<style>` element in the HTML:
p {
font-size: 14px !important;
}
}
}
```
* Emogrifier cannot inline CSS rules involving selectors with pseudo-elements
(such as `::after`) or dynamic pseudo-classes (such as `:hover`) it is
@@ -457,13 +406,13 @@ They will, however, be preserved and copied to a `<style>` element in the HTML:
## Steps to release a new version
1. Create a pull request "Prepare release of version x.y.z" with the following
changes.
1. In the [composer.json](composer.json), update the `branch-alias` entry to
point to the release _after_ the upcoming release.
1. In the [CHANGELOG.md](CHANGELOG.md), create a new section with subheadings
for changes _after_ the upcoming release, set the version number for the
upcoming release, and remove any empty sections.
1. Create a pull request "Prepare release of version x.y.z" with those
changes.
1. Have the pull request reviewed and merged.
1. Tag the new release.
1. In the [Releases tab](https://github.com/MyIntervals/emogrifier/releases),

View File

@@ -32,66 +32,94 @@
"name": "Jaime Prado"
}
],
"support": {
"issues": "https://github.com/MyIntervals/emogrifier/issues",
"source": "https://github.com/MyIntervals/emogrifier"
},
"require": {
"php": "^5.6 || ~7.0 || ~7.1 || ~7.2 || ~7.3 || ~7.4",
"php": "~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0",
"ext-dom": "*",
"ext-libxml": "*",
"symfony/css-selector": "^2.8 || ^3.0 || ^4.0 || ^5.0"
"sabberworm/php-css-parser": "^8.3.1",
"symfony/css-selector": "^3.4.32 || ^4.4 || ^5.3 || ^6.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.15.3",
"squizlabs/php_codesniffer": "^3.5.0",
"phpmd/phpmd": "^2.7.0",
"phpunit/phpunit": "^5.7.27"
"php-parallel-lint/php-parallel-lint": "^1.3.0",
"phpunit/phpunit": "^8.5.16",
"rawr/cross-data-providers": "^2.3.0"
},
"config": {
"preferred-install": {
"*": "dist"
},
"sort-packages": true
},
"extra": {
"branch-alias": {
"dev-main": "7.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Pelago\\": "src/"
"Pelago\\Emogrifier\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Pelago\\Tests\\": "tests/"
"Pelago\\Emogrifier\\Tests\\": "tests/"
}
},
"prefer-stable": true,
"config": {
"preferred-install": {
"*": "dist"
}
},
"scripts": {
"php:version": "php -v | grep -Po 'PHP\\s++\\K(?:\\d++\\.)*+\\d++(?:-\\w++)?+'",
"php:fix": "php-cs-fixer --config=config/php-cs-fixer.php fix config/ src/ tests/",
"ci:php:lint": "find config src tests -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l",
"ci:php:sniff": "phpcs config src tests",
"ci:php:fixer": "php-cs-fixer --config=config/php-cs-fixer.php fix --dry-run -v --show-progress=dots --diff-format=udiff config/ src/ tests/",
"ci:php:md": "phpmd src text config/phpmd.xml",
"ci:tests:unit": "phpunit tests/",
"ci:tests": [
"@ci:tests:unit"
],
"ci:dynamic": [
"@ci:tests"
],
"ci:static": [
"@ci:php:lint",
"@ci:php:sniff",
"@ci:php:fixer",
"@ci:php:md"
],
"ci": [
"@ci:static",
"@ci:dynamic"
]
],
"ci:composer:normalize": "@php \"./.phive/composer-normalize\" --dry-run",
"ci:dynamic": [
"@ci:tests"
],
"ci:php:fixer": "@php \"./.phive/php-cs-fixer\" --config=config/php-cs-fixer.php fix --dry-run -v --show-progress=dots config/ src/ tests/",
"ci:php:lint": "\"./vendor/bin/parallel-lint\" config src tests",
"ci:php:md": "@php \"./.phive/phpmd\" src text config/phpmd.xml",
"ci:php:psalm": "@php \"./.phive/psalm\" --show-info=false",
"ci:php:sniff": "@php \"./.phive/phpcs\" config src tests",
"ci:static": [
"@ci:composer:normalize",
"@ci:php:lint",
"@ci:php:sniff",
"@ci:php:fixer",
"@ci:php:md",
"@ci:php:psalm"
],
"ci:tests": [
"@ci:tests:unit"
],
"ci:tests:sof": "@php \"./vendor/bin/phpunit\" --stop-on-failure",
"ci:tests:unit": "@php \"./vendor/bin/phpunit\"",
"composer:normalize": "@php \"./.phive/composer-normalize\"",
"php:fix": "@php \"./.phive/php-cs-fixer\" --config=config/php-cs-fixer.php fix config/ src/ tests/",
"php:version": "@php -v | grep -Po 'PHP\\s++\\K(?:\\d++\\.)*+\\d++(?:-\\w++)?+'",
"psalm:baseline": "@php \"./.phive/psalm\" --set-baseline=psalm.baseline.xml",
"psalm:cc": "@php \"./.phive/psalm\" --clear-cache"
},
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
}
"scripts-descriptions": {
"ci": "Runs all dynamic and static code checks.",
"ci:composer:normalize": "Checks the formatting and structure of the composer.json.",
"ci:dynamic": "Runs all dynamic tests (i.e., currently, the unit tests).",
"ci:php:fixer": "Checks the code style with PHP CS Fixer.",
"ci:php:lint": "Lints the PHP files for syntax errors.",
"ci:php:md": "Checks the code complexity with PHPMD.",
"ci:php:psalm": "Checks the types with Psalm.",
"ci:php:sniff": "Checks the code style with PHP_CodeSniffer.",
"ci:static": "Runs all static code analysis checks for the code and the composer.json.",
"ci:tests": "Runs all dynamic tests (i.e., currently, the unit tests).",
"ci:tests:sof": "Runs the unit tests and stops at the first failure.",
"ci:tests:unit": "Runs all unit tests.",
"composer:normalize": "Reformats and sorts the composer.json file.",
"php:fix": "Reformats the code with php-cs-fixer.",
"php:version": "Outputs the installed PHP version.",
"psalm:baseline": "Updates the Psalm baseline file to match the code.",
"psalm:cc": "Clears the Psalm cache."
},
"support": {
"issues": "https://github.com/MyIntervals/emogrifier/issues",
"source": "https://github.com/MyIntervals/emogrifier"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,313 +0,0 @@
<?php
namespace Pelago\Emogrifier\HtmlProcessor;
/**
* Base class for HTML processor that e.g., can remove, add or modify nodes or attributes.
*
* The "vanilla" subclass is the HtmlNormalizer.
*
* @author Oliver Klee <github@oliverklee.de>
*/
abstract class AbstractHtmlProcessor
{
/**
* @var string
*/
const DEFAULT_DOCUMENT_TYPE = '<!DOCTYPE html>';
/**
* @var string
*/
const CONTENT_TYPE_META_TAG = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
/**
* @var string Regular expression part to match tag names that PHP's DOMDocument implementation is not aware are
* self-closing. These are mostly HTML5 elements, but for completeness <command> (obsolete) and <keygen>
* (deprecated) are also included.
*
* @see https://bugs.php.net/bug.php?id=73175
*/
const PHP_UNRECOGNIZED_VOID_TAGNAME_MATCHER = '(?:command|embed|keygen|source|track|wbr)';
/**
* @var \DOMDocument
*/
protected $domDocument = null;
/**
* @var \DOMXPath
*/
protected $xPath = null;
/**
* The constructor.
*
* Please use ::fromHtml instead.
*/
private function __construct()
{
}
/**
* Builds a new instance from the given HTML.
*
* @param string $unprocessedHtml raw HTML, must be UTF-encoded, must not be empty
*
* @return static
*
* @throws \InvalidArgumentException if $unprocessedHtml is anything other than a non-empty string
*/
public static function fromHtml($unprocessedHtml)
{
if (!\is_string($unprocessedHtml)) {
throw new \InvalidArgumentException('The provided HTML must be a string.', 1515459744);
}
if ($unprocessedHtml === '') {
throw new \InvalidArgumentException('The provided HTML must not be empty.', 1515763647);
}
$instance = new static();
$instance->setHtml($unprocessedHtml);
return $instance;
}
/**
* Builds a new instance from the given DOM document.
*
* @param \DOMDocument $document a DOM document returned by getDomDocument() of another instance
*
* @return static
*/
public static function fromDomDocument(\DOMDocument $document)
{
$instance = new static();
$instance->setDomDocument($document);
return $instance;
}
/**
* Sets the HTML to process.
*
* @param string $html the HTML to process, must be UTF-8-encoded
*
* @return void
*/
private function setHtml($html)
{
$this->createUnifiedDomDocument($html);
}
/**
* Provides access to the internal DOMDocument representation of the HTML in its current state.
*
* @return \DOMDocument
*/
public function getDomDocument()
{
return $this->domDocument;
}
/**
* @param \DOMDocument $domDocument
*
* @return void
*/
private function setDomDocument(\DOMDocument $domDocument)
{
$this->domDocument = $domDocument;
$this->xPath = new \DOMXPath($this->domDocument);
}
/**
* Renders the normalized and processed HTML.
*
* @return string
*/
public function render()
{
$htmlWithPossibleErroneousClosingTags = $this->domDocument->saveHTML();
return $this->removeSelfClosingTagsClosingTags($htmlWithPossibleErroneousClosingTags);
}
/**
* Renders the content of the BODY element of the normalized and processed HTML.
*
* @return string
*/
public function renderBodyContent()
{
$htmlWithPossibleErroneousClosingTags = $this->domDocument->saveHTML($this->getBodyElement());
$bodyNodeHtml = $this->removeSelfClosingTagsClosingTags($htmlWithPossibleErroneousClosingTags);
return \preg_replace('%</?+body(?:\\s[^>]*+)?+>%', '', $bodyNodeHtml);
}
/**
* Eliminates any invalid closing tags for void elements from the given HTML.
*
* @param string $html
*
* @return string
*/
private function removeSelfClosingTagsClosingTags($html)
{
return \preg_replace('%</' . static::PHP_UNRECOGNIZED_VOID_TAGNAME_MATCHER . '>%', '', $html);
}
/**
* Returns the BODY element.
*
* This method assumes that there always is a BODY element.
*
* @return \DOMElement
*/
private function getBodyElement()
{
return $this->domDocument->getElementsByTagName('body')->item(0);
}
/**
* Creates a DOM document from the given HTML and stores it in $this->domDocument.
*
* The DOM document will always have a BODY element and a document type.
*
* @param string $html
*
* @return void
*/
private function createUnifiedDomDocument($html)
{
$this->createRawDomDocument($html);
$this->ensureExistenceOfBodyElement();
}
/**
* Creates a DOMDocument instance from the given HTML and stores it in $this->domDocument.
*
* @param string $html
*
* @return void
*/
private function createRawDomDocument($html)
{
$domDocument = new \DOMDocument();
$domDocument->strictErrorChecking = false;
$domDocument->formatOutput = true;
$libXmlState = \libxml_use_internal_errors(true);
$domDocument->loadHTML($this->prepareHtmlForDomConversion($html));
\libxml_clear_errors();
\libxml_use_internal_errors($libXmlState);
$this->setDomDocument($domDocument);
}
/**
* Returns the HTML with added document type, Content-Type meta tag, and self-closing slashes, if needed,
* ensuring that the HTML will be good for creating a DOM document from it.
*
* @param string $html
*
* @return string the unified HTML
*/
private function prepareHtmlForDomConversion($html)
{
$htmlWithSelfClosingSlashes = $this->ensurePhpUnrecognizedSelfClosingTagsAreXml($html);
$htmlWithDocumentType = $this->ensureDocumentType($htmlWithSelfClosingSlashes);
return $this->addContentTypeMetaTag($htmlWithDocumentType);
}
/**
* Makes sure that the passed HTML has a document type.
*
* @param string $html
*
* @return string HTML with document type
*/
private function ensureDocumentType($html)
{
$hasDocumentType = \stripos($html, '<!DOCTYPE') !== false;
if ($hasDocumentType) {
return $html;
}
return static::DEFAULT_DOCUMENT_TYPE . $html;
}
/**
* Adds a Content-Type meta tag for the charset.
*
* This method also ensures that there is a HEAD element.
*
* @param string $html
*
* @return string the HTML with the meta tag added
*/
private function addContentTypeMetaTag($html)
{
$hasContentTypeMetaTag = \stripos($html, 'Content-Type') !== false;
if ($hasContentTypeMetaTag) {
return $html;
}
// We are trying to insert the meta tag to the right spot in the DOM.
// If we just prepended it to the HTML, we would lose attributes set to the HTML tag.
$hasHeadTag = \stripos($html, '<head') !== false;
$hasHtmlTag = \stripos($html, '<html') !== false;
if ($hasHeadTag) {
$reworkedHtml = \preg_replace('/<head(.*?)>/i', '<head$1>' . static::CONTENT_TYPE_META_TAG, $html);
} elseif ($hasHtmlTag) {
$reworkedHtml = \preg_replace(
'/<html(.*?)>/i',
'<html$1><head>' . static::CONTENT_TYPE_META_TAG . '</head>',
$html
);
} else {
$reworkedHtml = static::CONTENT_TYPE_META_TAG . $html;
}
return $reworkedHtml;
}
/**
* Makes sure that any self-closing tags not recognized as such by PHP's DOMDocument implementation have a
* self-closing slash.
*
* @param string $html
*
* @return string HTML with problematic tags converted.
*/
private function ensurePhpUnrecognizedSelfClosingTagsAreXml($html)
{
return \preg_replace(
'%<' . static::PHP_UNRECOGNIZED_VOID_TAGNAME_MATCHER . '\\b[^>]*+(?<!/)(?=>)%',
'$0/',
$html
);
}
/**
* Checks that $this->domDocument has a BODY element and adds it if it is missing.
*
* @return void
*
* @throws \UnexpectedValueException
*/
private function ensureExistenceOfBodyElement()
{
if ($this->domDocument->getElementsByTagName('body')->item(0) !== null) {
return;
}
$htmlElement = $this->domDocument->getElementsByTagName('html')->item(0);
if ($htmlElement === null) {
throw new \UnexpectedValueException('There is no HTML element although there should be one.', 1569930853);
}
$htmlElement->appendChild($this->domDocument->createElement('body'));
}
}

View File

@@ -1,316 +0,0 @@
<?php
namespace Pelago\Emogrifier\HtmlProcessor;
/**
* This HtmlProcessor can convert style HTML attributes to the corresponding other visual HTML attributes,
* e.g. it converts style="width: 100px" to width="100".
*
* It will only add attributes, but leaves the style attribute untouched.
*
* To trigger the conversion, call the convertCssToVisualAttributes method.
*
* @author Oliver Klee <github@oliverklee.de>
*/
class CssToAttributeConverter extends AbstractHtmlProcessor
{
/**
* This multi-level array contains simple mappings of CSS properties to
* HTML attributes. If a mapping only applies to certain HTML nodes or
* only for certain values, the mapping is an object with a whitelist
* of nodes and values.
*
* @var mixed[][]
*/
private $cssToHtmlMap = [
'background-color' => [
'attribute' => 'bgcolor',
],
'text-align' => [
'attribute' => 'align',
'nodes' => ['p', 'div', 'td'],
'values' => ['left', 'right', 'center', 'justify'],
],
'float' => [
'attribute' => 'align',
'nodes' => ['table', 'img'],
'values' => ['left', 'right'],
],
'border-spacing' => [
'attribute' => 'cellspacing',
'nodes' => ['table'],
],
];
/**
* @var string[][]
*/
private static $parsedCssCache = [];
/**
* Maps the CSS from the style nodes to visual HTML attributes.
*
* @return self fluent interface
*/
public function convertCssToVisualAttributes()
{
/** @var \DOMElement $node */
foreach ($this->getAllNodesWithStyleAttribute() as $node) {
$inlineStyleDeclarations = $this->parseCssDeclarationsBlock($node->getAttribute('style'));
$this->mapCssToHtmlAttributes($inlineStyleDeclarations, $node);
}
return $this;
}
/**
* Returns a list with all DOM nodes that have a style attribute.
*
* @return \DOMNodeList
*/
private function getAllNodesWithStyleAttribute()
{
return $this->xPath->query('//*[@style]');
}
/**
* Parses a CSS declaration block into property name/value pairs.
*
* Example:
*
* The declaration block
*
* "color: #000; font-weight: bold;"
*
* will be parsed into the following array:
*
* "color" => "#000"
* "font-weight" => "bold"
*
* @param string $cssDeclarationsBlock the CSS declarations block without the curly braces, may be empty
*
* @return string[]
* the CSS declarations with the property names as array keys and the property values as array values
*/
private function parseCssDeclarationsBlock($cssDeclarationsBlock)
{
if (isset(self::$parsedCssCache[$cssDeclarationsBlock])) {
return self::$parsedCssCache[$cssDeclarationsBlock];
}
$properties = [];
foreach (\preg_split('/;(?!base64|charset)/', $cssDeclarationsBlock) as $declaration) {
$matches = [];
if (!\preg_match('/^([A-Za-z\\-]+)\\s*:\\s*(.+)$/s', \trim($declaration), $matches)) {
continue;
}
$propertyName = \strtolower($matches[1]);
$propertyValue = $matches[2];
$properties[$propertyName] = $propertyValue;
}
self::$parsedCssCache[$cssDeclarationsBlock] = $properties;
return $properties;
}
/**
* Applies $styles to $node.
*
* This method maps CSS styles to HTML attributes and adds those to the
* node.
*
* @param string[] $styles the new CSS styles taken from the global styles to be applied to this node
* @param \DOMElement $node node to apply styles to
*
* @return void
*/
private function mapCssToHtmlAttributes(array $styles, \DOMElement $node)
{
foreach ($styles as $property => $value) {
// Strip !important indicator
$value = \trim(\str_replace('!important', '', $value));
$this->mapCssToHtmlAttribute($property, $value, $node);
}
}
/**
* Tries to apply the CSS style to $node as an attribute.
*
* This method maps a CSS rule to HTML attributes and adds those to the node.
*
* @param string $property the name of the CSS property to map
* @param string $value the value of the style rule to map
* @param \DOMElement $node node to apply styles to
*
* @return void
*/
private function mapCssToHtmlAttribute($property, $value, \DOMElement $node)
{
if (!$this->mapSimpleCssProperty($property, $value, $node)) {
$this->mapComplexCssProperty($property, $value, $node);
}
}
/**
* Looks up the CSS property in the mapping table and maps it if it matches the conditions.
*
* @param string $property the name of the CSS property to map
* @param string $value the value of the style rule to map
* @param \DOMElement $node node to apply styles to
*
* @return bool true if the property can be mapped using the simple mapping table
*/
private function mapSimpleCssProperty($property, $value, \DOMElement $node)
{
if (!isset($this->cssToHtmlMap[$property])) {
return false;
}
$mapping = $this->cssToHtmlMap[$property];
$nodesMatch = !isset($mapping['nodes']) || \in_array($node->nodeName, $mapping['nodes'], true);
$valuesMatch = !isset($mapping['values']) || \in_array($value, $mapping['values'], true);
$canBeMapped = $nodesMatch && $valuesMatch;
if ($canBeMapped) {
$node->setAttribute($mapping['attribute'], $value);
}
return $canBeMapped;
}
/**
* Maps CSS properties that need special transformation to an HTML attribute.
*
* @param string $property the name of the CSS property to map
* @param string $value the value of the style rule to map
* @param \DOMElement $node node to apply styles to
*
* @return void
*/
private function mapComplexCssProperty($property, $value, \DOMElement $node)
{
switch ($property) {
case 'background':
$this->mapBackgroundProperty($node, $value);
break;
case 'width':
// intentional fall-through
case 'height':
$this->mapWidthOrHeightProperty($node, $value, $property);
break;
case 'margin':
$this->mapMarginProperty($node, $value);
break;
case 'border':
$this->mapBorderProperty($node, $value);
break;
default:
}
}
/**
* @param \DOMElement $node node to apply styles to
* @param string $value the value of the style rule to map
*
* @return void
*/
private function mapBackgroundProperty(\DOMElement $node, $value)
{
// parse out the color, if any
$styles = \explode(' ', $value, 2);
$first = $styles[0];
if (\is_numeric($first[0]) || \strncmp($first, 'url', 3) === 0) {
return;
}
// as this is not a position or image, assume it's a color
$node->setAttribute('bgcolor', $first);
}
/**
* @param \DOMElement $node node to apply styles to
* @param string $value the value of the style rule to map
* @param string $property the name of the CSS property to map
*
* @return void
*/
private function mapWidthOrHeightProperty(\DOMElement $node, $value, $property)
{
// only parse values in px and %, but not values like "auto"
if (!\preg_match('/^(\\d+)(px|%)$/', $value)) {
return;
}
$number = \preg_replace('/[^0-9.%]/', '', $value);
$node->setAttribute($property, $number);
}
/**
* @param \DOMElement $node node to apply styles to
* @param string $value the value of the style rule to map
*
* @return void
*/
private function mapMarginProperty(\DOMElement $node, $value)
{
if (!$this->isTableOrImageNode($node)) {
return;
}
$margins = $this->parseCssShorthandValue($value);
if ($margins['left'] === 'auto' && $margins['right'] === 'auto') {
$node->setAttribute('align', 'center');
}
}
/**
* @param \DOMElement $node node to apply styles to
* @param string $value the value of the style rule to map
*
* @return void
*/
private function mapBorderProperty(\DOMElement $node, $value)
{
if (!$this->isTableOrImageNode($node)) {
return;
}
if ($value === 'none' || $value === '0') {
$node->setAttribute('border', '0');
}
}
/**
* @param \DOMElement $node
*
* @return bool
*/
private function isTableOrImageNode(\DOMElement $node)
{
return $node->nodeName === 'table' || $node->nodeName === 'img';
}
/**
* Parses a shorthand CSS value and splits it into individual values
*
* @param string $value a string of CSS value with 1, 2, 3 or 4 sizes
* For example: padding: 0 auto;
* '0 auto' is split into top: 0, left: auto, bottom: 0,
* right: auto.
*
* @return string[] an array of values for top, right, bottom and left (using these as associative array keys)
*/
private function parseCssShorthandValue($value)
{
/** @var string[] $values */
$values = \preg_split('/\\s+/', $value);
$css = [];
$css['top'] = $values[0];
$css['right'] = (\count($values) > 1) ? $values[1] : $css['top'];
$css['bottom'] = (\count($values) > 2) ? $values[2] : $css['top'];
$css['left'] = (\count($values) > 3) ? $values[3] : $css['right'];
return $css;
}
}

View File

@@ -1,16 +0,0 @@
<?php
namespace Pelago\Emogrifier\HtmlProcessor;
/**
* Normalizes HTML:
* - add a document type (HTML5) if missing
* - disentangle incorrectly nested tags
* - add HEAD and BODY elements (if they are missing)
* - reformat the HTML
*
* @author Oliver Klee <github@oliverklee.de>
*/
class HtmlNormalizer extends AbstractHtmlProcessor
{
}

View File

@@ -1,143 +0,0 @@
<?php
namespace Pelago\Emogrifier\HtmlProcessor;
use Pelago\Emogrifier\CssInliner;
use Pelago\Emogrifier\Utilities\ArrayIntersector;
/**
* This class can remove things from HTML.
*
* @author Oliver Klee <github@oliverklee.de>
* @author Jake Hotson <jake.github@qzdesign.co.uk>
*/
class HtmlPruner extends AbstractHtmlProcessor
{
/**
* We need to look for display:none, but we need to do a case-insensitive search. Since DOMDocument only
* supports XPath 1.0, lower-case() isn't available to us. We've thus far only set attributes to lowercase,
* not attribute values. Consequently, we need to translate() the letters that would be in 'NONE' ("NOE")
* to lowercase.
*
* @var string
*/
const DISPLAY_NONE_MATCHER
= '//*[@style and contains(translate(translate(@style," ",""),"NOE","noe"),"display:none")'
. ' and not(@class and contains(concat(" ", normalize-space(@class), " "), " -emogrifier-keep "))]';
/**
* Removes elements that have a "display: none;" style.
*
* @return self fluent interface
*/
public function removeElementsWithDisplayNone()
{
$elementsWithStyleDisplayNone = $this->xPath->query(self::DISPLAY_NONE_MATCHER);
if ($elementsWithStyleDisplayNone->length === 0) {
return $this;
}
/** @var \DOMNode $element */
foreach ($elementsWithStyleDisplayNone as $element) {
$parentNode = $element->parentNode;
if ($parentNode !== null) {
$parentNode->removeChild($element);
}
}
return $this;
}
/**
* Removes classes that are no longer required (e.g. because there are no longer any CSS rules that reference them)
* from `class` attributes.
*
* Note that this does not inspect the CSS, but expects to be provided with a list of classes that are still in use.
*
* This method also has the (presumably beneficial) side-effect of minifying (removing superfluous whitespace from)
* `class` attributes.
*
* @param string[] $classesToKeep names of classes that should not be removed
*
* @return self fluent interface
*/
public function removeRedundantClasses(array $classesToKeep = [])
{
$elementsWithClassAttribute = $this->xPath->query('//*[@class]');
if ($classesToKeep !== []) {
$this->removeClassesFromElements($elementsWithClassAttribute, $classesToKeep);
} else {
// Avoid unnecessary processing if there are no classes to keep.
$this->removeClassAttributeFromElements($elementsWithClassAttribute);
}
return $this;
}
/**
* Removes classes from the `class` attribute of each element in `$elements`, except any in `$classesToKeep`,
* removing the `class` attribute itself if the resultant list is empty.
*
* @param \DOMNodeList $elements
* @param string[] $classesToKeep
*
* @return void
*/
private function removeClassesFromElements(\DOMNodeList $elements, array $classesToKeep)
{
$classesToKeepIntersector = new ArrayIntersector($classesToKeep);
/** @var \DOMNode $element */
foreach ($elements as $element) {
$elementClasses = \preg_split('/\\s++/', \trim($element->getAttribute('class')));
$elementClassesToKeep = $classesToKeepIntersector->intersectWith($elementClasses);
if ($elementClassesToKeep !== []) {
$element->setAttribute('class', \implode(' ', $elementClassesToKeep));
} else {
$element->removeAttribute('class');
}
}
}
/**
* Removes the `class` attribute from each element in `$elements`.
*
* @param \DOMNodeList $elements
*
* @return void
*/
private function removeClassAttributeFromElements(\DOMNodeList $elements)
{
/** @var \DOMNode $element */
foreach ($elements as $element) {
$element->removeAttribute('class');
}
}
/**
* After CSS has been inlined, there will likely be some classes in `class` attributes that are no longer referenced
* by any remaining (uninlinable) CSS. This method removes such classes.
*
* Note that it does not inspect the remaining CSS, but uses information readily available from the `CssInliner`
* instance about the CSS rules that could not be inlined.
*
* @param CssInliner $cssInliner object instance that performed the CSS inlining
*
* @return self fluent interface
*
* @throws \BadMethodCallException if `inlineCss` has not first been called on `$cssInliner`
*/
public function removeRedundantClassesAfterCssInlined(CssInliner $cssInliner)
{
$classesToKeepAsKeys = [];
foreach ($cssInliner->getMatchingUninlinableSelectors() as $selector) {
\preg_match_all('/\\.(-?+[_a-zA-Z][\\w\\-]*+)/', $selector, $matches);
$classesToKeepAsKeys += \array_fill_keys($matches[1], true);
}
$this->removeRedundantClasses(\array_keys($classesToKeepAsKeys));
return $this;
}
}

View File

@@ -1,56 +0,0 @@
<?php
namespace Pelago\Emogrifier\Utilities;
/**
* When computing many array intersections using the same array, it is more efficient to use `array_flip()` first and
* then `array_intersect_key()`, than `array_intersect()`. See the discussion at
* {@link https://stackoverflow.com/questions/6329211/php-array-intersect-efficiency Stack Overflow} for more
* information.
*
* Of course, this is only possible if the arrays contain integer or string values, and either don't contain duplicates,
* or that fact that duplicates will be removed does not matter.
*
* This class takes care of the detail.
*
* @internal
*
* @author Jake Hotson <jake.github@qzdesign.co.uk>
*/
class ArrayIntersector
{
/**
* the array with which the object was constructed, with all its keys exchanged with their associated values
*
* @var (int|string)[]
*/
private $invertedArray;
/**
* Constructs the object with the array that will be reused for many intersection computations.
*
* @param (int|string)[] $array
*/
public function __construct(array $array)
{
$this->invertedArray = \array_flip($array);
}
/**
* Computes the intersection of `$array` and the array with which this object was constructed.
*
* @param (int|string)[] $array
*
* @return (int|string)[] Returns an array containing all of the values in `$array` whose values exist in the array
* with which this object was constructed. Note that keys are preserved, order is maintained, but
* duplicates are removed.
*/
public function intersectWith(array $array)
{
$invertedArray = \array_flip($array);
$invertedIntersection = \array_intersect_key($invertedArray, $this->invertedArray);
return \array_flip($invertedIntersection);
}
}

View File

@@ -1,156 +0,0 @@
<?php
namespace Pelago\Emogrifier\Utilities;
/**
* Facilitates building a CSS string by appending rule blocks one at a time, checking whether the media query,
* selectors, or declarations block are the same as those from the preceding block and combining blocks in such cases.
*
* Example:
* $concatenator = new CssConcatenator();
* $concatenator->append(['body'], 'color: blue;');
* $concatenator->append(['body'], 'font-size: 16px;');
* $concatenator->append(['p'], 'margin: 1em 0;');
* $concatenator->append(['ul', 'ol'], 'margin: 1em 0;');
* $concatenator->append(['body'], 'font-size: 14px;', '@media screen and (max-width: 400px)');
* $concatenator->append(['ul', 'ol'], 'margin: 0.75em 0;', '@media screen and (max-width: 400px)');
* $css = $concatenator->getCss();
*
* `$css` (if unminified) would contain the following CSS:
* ` body {
* ` color: blue;
* ` font-size: 16px;
* ` }
* ` p, ul, ol {
* ` margin: 1em 0;
* ` }
* ` @media screen and (max-width: 400px) {
* ` body {
* ` font-size: 14px;
* ` }
* ` ul, ol {
* ` margin: 0.75em 0;
* ` }
* ` }
*
* @internal
*
* @author Jake Hotson <jake.github@qzdesign.co.uk>
*/
class CssConcatenator
{
/**
* Array of media rules in order. Each element is an object with the following properties:
* - string `media` - The media query string, e.g. "@media screen and (max-width:639px)", or an empty string for
* rules not within a media query block;
* - \stdClass[] `ruleBlocks` - Array of rule blocks in order, where each element is an object with the following
* properties:
* - mixed[] `selectorsAsKeys` - Array whose keys are selectors for the rule block (values are of no
* significance);
* - string `declarationsBlock` - The property declarations, e.g. "margin-top: 0.5em; padding: 0".
*
* @var \stdClass[]
*/
private $mediaRules = [];
/**
* Appends a declaration block to the CSS.
*
* @param string[] $selectors Array of selectors for the rule, e.g. ["ul", "ol", "p:first-child"].
* @param string $declarationsBlock The property declarations, e.g. "margin-top: 0.5em; padding: 0".
* @param string $media The media query for the rule, e.g. "@media screen and (max-width:639px)",
* or an empty string if none.
*/
public function append(array $selectors, $declarationsBlock, $media = '')
{
$selectorsAsKeys = \array_flip($selectors);
$mediaRule = $this->getOrCreateMediaRuleToAppendTo($media);
$lastRuleBlock = \end($mediaRule->ruleBlocks);
$hasSameDeclarationsAsLastRule = $lastRuleBlock !== false
&& $declarationsBlock === $lastRuleBlock->declarationsBlock;
if ($hasSameDeclarationsAsLastRule) {
$lastRuleBlock->selectorsAsKeys += $selectorsAsKeys;
} else {
$hasSameSelectorsAsLastRule = $lastRuleBlock !== false
&& self::hasEquivalentSelectors($selectorsAsKeys, $lastRuleBlock->selectorsAsKeys);
if ($hasSameSelectorsAsLastRule) {
$lastDeclarationsBlockWithoutSemicolon = \rtrim(\rtrim($lastRuleBlock->declarationsBlock), ';');
$lastRuleBlock->declarationsBlock = $lastDeclarationsBlockWithoutSemicolon . ';' . $declarationsBlock;
} else {
$mediaRule->ruleBlocks[] = (object)\compact('selectorsAsKeys', 'declarationsBlock');
}
}
}
/**
* @return string
*/
public function getCss()
{
return \implode('', \array_map([self::class, 'getMediaRuleCss'], $this->mediaRules));
}
/**
* @param string $media The media query for rules to be appended, e.g. "@media screen and (max-width:639px)",
* or an empty string if none.
*
* @return \stdClass Object with properties as described for elements of `$mediaRules`.
*/
private function getOrCreateMediaRuleToAppendTo($media)
{
$lastMediaRule = \end($this->mediaRules);
if ($lastMediaRule !== false && $media === $lastMediaRule->media) {
return $lastMediaRule;
}
$newMediaRule = (object)[
'media' => $media,
'ruleBlocks' => [],
];
$this->mediaRules[] = $newMediaRule;
return $newMediaRule;
}
/**
* Tests if two sets of selectors are equivalent (i.e. the same selectors, possibly in a different order).
*
* @param mixed[] $selectorsAsKeys1 Array in which the selectors are the keys, and the values are of no
* significance.
* @param mixed[] $selectorsAsKeys2 Another such array.
*
* @return bool
*/
private static function hasEquivalentSelectors(array $selectorsAsKeys1, array $selectorsAsKeys2)
{
return \count($selectorsAsKeys1) === \count($selectorsAsKeys2)
&& \count($selectorsAsKeys1) === \count($selectorsAsKeys1 + $selectorsAsKeys2);
}
/**
* @param \stdClass $mediaRule Object with properties as described for elements of `$mediaRules`.
*
* @return string CSS for the media rule.
*/
private static function getMediaRuleCss(\stdClass $mediaRule)
{
$css = \implode('', \array_map([self::class, 'getRuleBlockCss'], $mediaRule->ruleBlocks));
if ($mediaRule->media !== '') {
$css = $mediaRule->media . '{' . $css . '}';
}
return $css;
}
/**
* @param \stdClass $ruleBlock Object with properties as described for elements of the `ruleBlocks` property of
* elements of `$mediaRules`.
*
* @return string CSS for the rule block.
*/
private static function getRuleBlockCss(\stdClass $ruleBlock)
{
$selectors = \array_keys($ruleBlock->selectorsAsKeys);
return \implode(',', $selectors) . '{' . $ruleBlock->declarationsBlock . '}';
}
}