From 5bf2e1487f5fb3d1d5cbd55068985c31f1c9b500 Mon Sep 17 00:00:00 2001 From: JakeQZ Date: Thu, 11 Jun 2020 11:11:29 +0100 Subject: [PATCH] [BUGFIX] Avoid exception with :last-of-type etc. (#875) This simply broadens the range of exceptions thrown by `symfony/css-selector` (for unsupported selector expressions) which will be caught and discarded in non-debug mode. It does not make anything magically work which didn't previously; however, it does allow the rest of the CSS to achieve full functionality, with only the affected CSS rule and selector suffering. The tests and changes to the README clarify and correct-as-documented the current behavior for these edge cases, which could be improved upon in future. These are currently rarely-used CSS pseudo-classes; their level of support in mainstream browsers has only [recently reached 95% of audiences](https://caniuse.com/#search=last-of-type). Their level of support in email clients is likely to be drastically lower per se of some time to come, but may be something Emogrifier can help with moving forwards, as their use becomes more widespread... Closes #872. New issue #876 for follow-up. --- CHANGELOG.md | 2 + README.md | 19 +++--- src/CssInliner.php | 16 ++--- tests/Unit/CssInlinerTest.php | 115 ++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61d472cb..30e3da7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). ([#773](https://github.com/MyIntervals/emogrifier/pull/773)) ### Fixed +- Allow `:last-of-type` etc. without type, without causing exception + ([#875](https://github.com/MyIntervals/emogrifier/pull/875)) - Make sure to use the Composer-installed development tools ([#862](https://github.com/MyIntervals/emogrifier/pull/862), [#865](https://github.com/MyIntervals/emogrifier/pull/865)) diff --git a/README.md b/README.md index effab2a8..c217ac60 100644 --- a/README.md +++ b/README.md @@ -308,33 +308,36 @@ Emogrifier currently supports the following * [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`) + currently be treated as `*:not(*)`) * [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) + (with a type – without a type, it will be treated as `:not(*)`) * [not()](https://developer.mozilla.org/en-US/docs/Web/CSS/:not) * [nth-child()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child) * [nth-last-child()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-last-child) * [nth-last-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-last-of-type) - (with a type) + (with a type – without a type, it will be treated as `:not(*)`) * [nth-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-of-type) - (with a type) + (with a type – without a type, it will be applied as if `:nth-child`) * [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) + (with a type – without a type, it will be applied as if `:only-child` + or `:not(*)`, depending on version constraints for `symfony/css-selector`) The following selectors are not implemented yet: * [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): * [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 (declarations discarded) * [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 (declarations discarded) * [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 (declarations discarded) * [nth-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-of-type) without a type (will behave as `:nth-child()`) + * [only-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:only-of-type) + without a type (will behave as `:only-child()` or `:not(*)`) * any pseudo-classes not listed above as supported – rules involving them will nonetheless be preserved and copied to a `