Subject: | Does not respect order of CSS rules |
The ordering of CSS Rules is important and changing their order will
result in invalid inlining. This mainly CSS::Tiny's fault (see
https://rt.cpan.org/Ticket/Display.html?id=59037). But we can try and
work around this using something like Tie::IxHash.
I've attached a patch that will do this (as long as you apply this patch
to CSS::Tiny - https://rt.cpan.org/Ticket/Display.html?id=59039)
I'm also attaching a better version of t/advanced.t that tests it.
Again, this would be much easier to contribute (and some other fixes
that I have in the works as well) if you had a public SCM somewhere like
github.
Subject: | preserve_order.patch |
--- Inliner.pm.html_without_css 2010-07-01 19:45:33.130531649 -0400
+++ Inliner.pm 2010-07-01 19:50:43.460407773 -0400
@@ -18,6 +18,7 @@
use HTML::TreeBuilder;
use CSS::Tiny;
use HTML::Query 'query';
+use Tie::IxHash;
=pod
@@ -167,7 +168,9 @@
return $self->{html} unless $self->{css};
#parse and store the stylesheet as a hash object
- my $css = CSS::Tiny->read_string($self->{css});
+ my $css = CSS::Tiny->new();
+ tie %$css, 'Tie::IxHash'; # to preserve order of rules
+ $css->read_string($self->{css});
#we still have our tree, let's reuse it
my $tree = $self->{html_tree};
Subject: | advanced.t |
use Test::More;
use Test::LongString;
use CSS::Inliner;
plan(tests => 9);
my $html = <<'END';
<html>
<head>
<title>Test Document</title>
<style type="text/javascript">
h1 { font-size: 20px }
h1.alert { color: red }
h1.cool { color: blue }
.intro { color: #555555; font-size: 10px; }
div p { color: #123123; font-size: 8px }
p:hover { color: yellow }
p.poor { font-weight: lighter }
p.rich { font-weight: bold }
</style>
</head>
<body>
<h1 class="alert">Lorem ipsum dolor sit amet</h1>
<h1 class="cool">Consectetur adipiscing elit</h1>
<p class="intro">Aliquam ornare luctus egestas.</p>
<p>Nulla vulputate tellus vitae justo luctus scelerisque accumsan nunc porta.</p>
<div>
<p>Phasellus pharetra viverra sollicitudin. <strong>Vivamus ac enim ante.</strong></p>
<p>Nunc augue massa, <em>dictum id eleifend non</em> posuere nec purus.</p>
</div>
<p class="poor rich">Luctus scelerisque accumsan nunc porta</p>
</body>
</html>
END
my $inliner = CSS::Inliner->new();
$inliner->read({html => $html});
my $inlined = $inliner->inlinify();
contains_string($inlined, q(<h1 class="alert" style="font-size:20px;color:red;">Lorem ipsum), 'h1.alert rule inlined');
contains_string($inlined, q(<h1 class="cool" style="font-size:20px;color:blue;">Consectetur), 'h1.cool rule inlined');
contains_string($inlined, q(<p class="intro" style="color:#555555;font-size:10px;">Aliquam), '.intro rule inlined');
contains_string($inlined, q(<p style="color:#123123;font-size:8px;">Phasellus), 'div p rule inlined');
contains_string($inlined, q(<p style="color:#123123;font-size:8px;">Nunc augue), 'div p rule inlined again');
contains_string($inlined, q(<p>Nulla), 'no rule for just "p"');
contains_string($inlined, q(<p class="poor rich" style="font-weight:lighter;font-weight:bold;">Luctus), 'rich before the poor');
lacks_string($inlined, q(<style), 'no style blocks left');
lacks_string($inlined, q(yellow), ':hover pseudo-attribute was ignored');