Skip Menu |

This queue is for tickets about the CSS-Inliner CPAN distribution.

Report information
The Basics
Id: 99934
Status: resolved
Priority: 0/
Queue: CSS-Inliner

People
Owner: KAMELKEV [...] cpan.org
Requestors: sixtease [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 3948
Fixed in: (no value)



Subject: Inliner ignores !important declarations
Declarations marked as !important do not take precedence over other declarations like they should according to CSS specs: http://www.w3.org/TR/CSS2/cascade.html#important-rules A patch is attached that resolves the issue.
Subject: important.patch
diff -rupN original/lib/CSS/Inliner.pm new/lib/CSS/Inliner.pm --- original/lib/CSS/Inliner.pm 2014-09-03 05:23:18.000000000 +0200 +++ new/lib/CSS/Inliner.pm 2014-10-31 14:41:37.938011967 +0100 @@ -346,16 +346,23 @@ sub inlinify { my @sorted_matches = sort { $a->{specificity} <=> $b->{specificity} || $a->{position} <=> $b->{position} } @$matches; my %new_style; + my %new_important_style; # keep track of declarations marked as !important + foreach my $match (@sorted_matches) { %new_style = (%new_style, %{$match->{css}}); + %new_important_style = (%new_important_style, _grep_important_declarations($match->{css})); } # styles already inlined have greater precedence if (defined($element->attr('style'))) { my $cur_style = $self->_split({ style => $element->attr('style') }); %new_style = (%new_style, %{$cur_style}); + %new_important_style = (%new_important_style, _grep_important_declarations($cur_style)); } + # override styles with !important styles + %new_style = (%new_style, %new_important_style); + $element->attr('style', $self->_expand({ declarations => \%new_style })); } @@ -857,6 +864,17 @@ sub _split { return \%split; } +sub _grep_important_declarations { + my ($declarations) = @_; + my %important; + while (my ($property, $value) = each %$declarations) { + if ($value =~ /!\s*important\s*$/i) { + $important{$property} = $value; + } + } + return %important; +} + 1; =pod
Here's a test
Subject: important.t
use strict; use warnings; use lib qw( ./lib ../lib ); use Test::More; use Cwd; use CSS::Inliner; plan(tests => 3); use_ok('CSS::Inliner'); my $html = <<END; <html> <head> <title>Test Document</title> <style type="text/css"> h1 { color: red !important; font-size: 20px } .green { color: green } </style> </head> <body> <h1 class="green">Howdy!</h1> </body> </html> END my $inliner = CSS::Inliner->new(); $inliner->read({ html => $html }); my $inlined = $inliner->inlinify(); ok($inlined =~ m/<h1 class="green" style=".*\bcolor: red\b/, '!important overrode more specific'); ok($inlined =~ m/<h1 class="green" style=".*\bfont-size: 20px\b/, 'non-!important style still present');
Hi, Thank you so much for this contribution. I actually thought I had merged it back in 2014, imagine my surprise when I went to my git checkout and saw uncommitted changes! :( This will be included in the forthcoming release, which should be in a week or so.
Merged in and credited. If you have a preferred email address to include within the Changelog reopen and let me know. This change is available in 3957