Fix styles inlining so that more specific styles are preserved
[MAILPOET-1730]
This commit is contained in:
@@ -236,10 +236,7 @@ class CSS {
|
|||||||
|
|
||||||
// Unserialize the style array, merge the rule's CSS into it...
|
// Unserialize the style array, merge the rule's CSS into it...
|
||||||
$nodeStyles = self::styleToArray($node->style);
|
$nodeStyles = self::styleToArray($node->style);
|
||||||
$style = array_merge($nodeStyles, $rule['properties']);
|
$style = array_merge($rule['properties'], $nodeStyles);
|
||||||
|
|
||||||
// !important node styles should take precedence over other styles
|
|
||||||
$style = array_merge($style, preg_grep("/important/i", $nodeStyles));
|
|
||||||
|
|
||||||
// And put the CSS back as a string!
|
// And put the CSS back as a string!
|
||||||
$node->style = self::arrayToStyle($style);
|
$node->style = self::arrayToStyle($style);
|
||||||
@@ -256,10 +253,12 @@ class CSS {
|
|||||||
// Now a tricky part: do a second pass with only stuff marked !important
|
// Now a tricky part: do a second pass with only stuff marked !important
|
||||||
// because !important properties do not care about specificity, except when fighting
|
// because !important properties do not care about specificity, except when fighting
|
||||||
// against another !important property
|
// against another !important property
|
||||||
|
// We need to start with a rule with lowest specificity
|
||||||
|
$rules = array_reverse($rules);
|
||||||
foreach ($rules as $rule) {
|
foreach ($rules as $rule) {
|
||||||
foreach($rule['properties'] as $key => $value) {
|
foreach($rule['properties'] as $key => $value) {
|
||||||
if(strpos($value, '!important') !== false) {
|
if(strpos($value, '!important') !== false) {
|
||||||
foreach($html->find($rule['selector']) as $node) {
|
foreach($html->query($rule['selector']) as $node) {
|
||||||
$style = self::styleToArray($node->style);
|
$style = self::styleToArray($node->style);
|
||||||
$style[$key] = $value;
|
$style[$key] = $value;
|
||||||
$node->style = self::arrayToStyle($style);
|
$node->style = self::arrayToStyle($style);
|
||||||
|
@@ -36,4 +36,40 @@ class CSSTest extends \MailPoetUnitTest {
|
|||||||
$this->assertEquals('brown', $parsed[3]['properties']['color']);
|
$this->assertEquals('brown', $parsed[3]['properties']['color']);
|
||||||
$this->assertEquals('red', $parsed[4]['properties']['color']);
|
$this->assertEquals('red', $parsed[4]['properties']['color']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testItCanInlineARule() {
|
||||||
|
$styles = 'p { color: red; }';
|
||||||
|
$content = '<p>Foo</p>';
|
||||||
|
$html = $this->buildHtml($styles, $content);
|
||||||
|
$result_html = $this->css->inlineCSS(null, $html);
|
||||||
|
$this->assertContains('<p style="color:red">', $result_html);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItInlinesMoreSpecificRule() {
|
||||||
|
$styles = 'p { color: red; } .blue { color: blue; }';
|
||||||
|
$content = '<p class="blue">Foo</p>';
|
||||||
|
$html = $this->buildHtml($styles, $content);
|
||||||
|
$result_html = $this->css->inlineCSS(null, $html);
|
||||||
|
$this->assertContains('<p class="blue" style="color:blue">', $result_html);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItPreserveInlinedRule() {
|
||||||
|
$styles = 'p { color: red; }';
|
||||||
|
$content = '<p style="color:green">Foo</p>';
|
||||||
|
$html = $this->buildHtml($styles, $content);
|
||||||
|
$result_html = $this->css->inlineCSS(null, $html);
|
||||||
|
$this->assertContains('<p style="color:green">', $result_html);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItAlwaysInlinesGlobalImportantRule() {
|
||||||
|
$styles = 'p { color: red !important; }';
|
||||||
|
$content = '<p style="color:green !important">Foo</p>';
|
||||||
|
$html = $this->buildHtml($styles, $content);
|
||||||
|
$result_html = $this->css->inlineCSS(null, $html);
|
||||||
|
$this->assertContains('<p style="color:red">', $result_html);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildHtml($styles, $content) {
|
||||||
|
return "<html><style>{$styles}</style><body>{$content}</body></html>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user