-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] Add the ability to excluded CSS selectors from being inlined #1202
[FEATURE] Add the ability to excluded CSS selectors from being inlined #1202
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for this contribution!
I've added some review comments.
And could you also please add a changelog entry (newest on top, and with a reference to the PR ID)? Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the neatness of this being an almost one-line change.
Some usage documentation for the feature should also be added to the README.md
file.
src/CssInliner.php
Outdated
if (\count(\array_intersect($cssRule->getSelectors(), \array_keys($this->excludedCssSelectors)))) { | ||
continue; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming the excluded selector list matches a full selector from a possibly comma-separated list, so .example
will not exclude p.example
or p .example
. It would be good to confirm though that p .example
would also exclude selectors written with varying whitespace (e.g. newline or multiple spaces), perhaps using a dataProvider
for the currently-named addExcludedCssSelector
test, so it can be run with a few different excluded selectors vs target selectors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been taken care of here: https://github.com/MyIntervals/emogrifier/pull/1202/files#diff-d57870a239314b85bdf5a191a3629018f9c95e6019b3405584d36b3b9abddd48R638-R642
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that I didn't normalized excluded CSS selectors, I assume developers are able to fill this with the right characters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume developers are able to fill this with the right characters.
My point was just to add a couple of extra tests to help define and isolate the precise behaviour of the new functionality. Thanks for continued engagement and persuing this. Your idea is good.
I'll look into your latest changes in the next few days, and expect @oliverklee will too.
Thanks again <3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point was just to add a couple of extra tests to help define and isolate the precise behaviour of the new functionality
And it was totally legit, I wasn't sure it was meant to be handled on the user input (addExcludedCssSelector('.example p')
), or on the selectors found in the provided CSS. I went for the provided CSS only since weird spaces/lines breaks or very unlikely passed in addExcludedCssSelector
method. Let me know if you feel like it normalization should be applied on both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure it was meant to be handled on the user input (
addExcludedCssSelector('.example p')
), or on the selectors found in the provided CSS.
Not quite sure what you mean by this. Aren't they both user input? In context, the most usery of input will be the CSS. The parameter to the function, whilst also user input, will likely be more carefully chosen ;)
Edit: OK, got it. We are on the same wavelength. The user input is the CSS. The parameter to the function, whilst techically also user input, I think should be considered more as programmer input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter to the function, whilst also user input, will likely be more carefully chosen ;)
I think w're both on the same side here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know if you feel like it normalization should be applied on both.
Sorry, I've only just fully read and understood your comment. Though that doesn't change anything, other than that my inrigue is now piqued as to whether a programmer error in the whitespacing department is covered too (it may well be).
Thank you both for your reviews and comments. I pushed some changes that will address those issues. |
c60ce2f
to
a4abcb2
Compare
Sorry, we both seem to have overlooked this. Maybe GitHub never sent us the notification email (it is notoriously flaky). I'll try and take a look in the next few days, and remember what it was about. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry it's taken so long to get back to you.
We've been busy and somehow missed your post-review changes for months.
Hope you're still around and able to complete this change. It would be useful functionality.
You can use \s++
to efficiently match a sequence of one or more whitespace characters in a regular expression. Doing so would greatly simplify this change and avoid the need for an ALL_SPACES
constant.
src/CssInliner.php
Outdated
$selector = \str_replace(["\r", "\n", "\t"], ' ', $selector); | ||
$selector = \preg_replace('@[ ' . self::ALL_SPACES . ']+@mu', ' ', $selector); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surely you can just use \s++
in the regular expression to match all whitespace sequences (without having to reinvent the wheel, so to speak) - ?
(Also, you don't need the m
modifier as you are not matching .
(any character) at all.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem, regex are not my strong suit, I changed it. Let me know if you see any other issues.
a4abcb2
to
ae1142f
Compare
It's open source, no deadline or expectations ;) @JakeQZ I just made the requested changes, let me know if it works for you. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a few minor issues that need to be addressed, but otherwise looks good.
Oh, and it will need to be rebased.
README.md
Outdated
* `->addExcludedCssSelector(string $selector)` - Contrary to `addExcludedSelector` | ||
which excludes HTML nodes, this method excludes CSS selectors from | ||
being inlined. This is for example useful if you don't want your CSS reset rules | ||
to be inlined on each HTML node (e.g. `* { margin: 0; padding: 0; font-size: 100% }`). | ||
Note that these selectors must precisely match the selectors you wish to exclude. | ||
Meaning that excluding `.example` will not exclude `p .example`. | ||
```php | ||
$cssInliner->addExcludedCssSelector('*'); | ||
$cssInliner->addExcludedCssSelector('form'); | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removeExcludedCssSelector
should also be (briefly) documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/CssInliner.php
Outdated
/** | ||
* regular expression component to match all kinds of whitespace | ||
* | ||
* @see https://github.com/jolicode/JoliTypo/blob/8799bae6cda2280b319750d2fe764bfd8e8f6ba2/src/JoliTypo/Fixer.php#L37 | ||
* | ||
* @var string | ||
*/ | ||
private const ALL_SPACES = '\\xE2\\x80\\xAF|\\xC2\\xAD|\\xC2\\xA0|\\s'; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't needed now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/CssInliner.php
Outdated
$selector = \preg_replace('@\s++@u', ' ', $selector); | ||
return $selector; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer not to modify the parameter, as this can cause confusion when debugging. Either a different local variable can be assigned and returned, or the result of preg_replace
can simply be returned.
Also the \
should be escaped (as \\
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@nlemoine Could you please rebase, resolve the merge conflicts and repush? Thanks! |
8274ffd
to
d59a873
Compare
007cb28
to
06785d1
Compare
@JakeQZ @oliverklee Sorry, I accidentally screwed up my rebase and this ended in my original PR to be closed. Please see #1236 for requested changes. |
No worries. Thanks for sorting it out. I guess you fell foul at step 7 of https://github.com/MyIntervals/emogrifier/blob/main/.github/CONTRIBUTING.md#rebasing, when |
Exclude CSS selectors from the stylesheets being inlined. This might for example prevent global CSS rules with universal selector (*) to be inlined on each node.