Skip Menu |

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

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

People
Owner: Nobody in particular
Requestors: wonko [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 2544
Fixed in: 2544



Subject: Does not respect the weight of CSS rules
CSS::Inliner doesn't support the CSS idea of "weights" for the different selectors It just inlines them in whatever order CSS::Tiny gives them back. This not only has problems because CSS rules are order dependent (https://rt.cpan.org/Ticket/Display.html?id=59042) but it also causes problems because certain rules should have more precedence than others. Attached is a version of Inliner.pm that does support CSS selector weights. It's not a patch because it also includes other patches that I've submitted (https://rt.cpan.org/Ticket/Display.html?id=59042, https://rt.cpan.org/Ticket/Display.html?id=58957 and https://rt.cpan.org/Ticket/Display.html?id=58923). I'm also attaching tests for this weighting (css_rule_weights.t) and a version of t/advanced.t that has tests for the actual inlining of this.
Subject: css_rule_weights.t
use Test::More; use Test::LongString; plan(tests => 16); use_ok('CSS::Inliner'); my %rules = ( "li" => 1, "ul li" => 2, "ul ol li" => 3, "li.red" => 11, "ul ol li.red" => 13, "td.foo p.bar em" => 23, "td.foo" => 11, "td.foo p" => 12, "td.foo p.bar em.blah" => 33, "td p em" => 3, "td #blah" => 102, "#blah td" => 102, "#blah td.foo" => 112, "#blah td.foo span" => 113, "#blah td.foo span.bar" => 123, ); foreach my $rule (keys %rules) { my $weight = CSS::Inliner->_get_css_weight($rule); is($weight, $rules{$rule}, "correct weight for \"$rule\""); }
Subject: Inliner.pm.with_weight
Download Inliner.pm.with_weight
application/octet-stream 8.3k

Message body not shown because it is not plain text.

Subject: advanced.t
use Test::More; use Test::LongString; use CSS::Inliner; #plan(tests => 9); plan('no_plan'); # moderately complicated rules with elements and classes my $html = <<'END'; <html> <head> <title>Moderate 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="color:red;font-size:20px;">Lorem ipsum), 'h1.alert rule inlined'); contains_string($inlined, q(<h1 class="cool" style="color:blue;font-size:20px;">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: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'); # a more complicated example with ids, class, attribute selectors # in a cascading layout $html = <<'END'; <html> <head> <title>Complicated Document</title> <style type="text/javascript"> h1 { font-size: 20px } #title { font-size: 25px } h1.cool { color: blue } h1.alert { color: red } h1.cool.alert { font-size: 30px; font-weight: normal } .intro { color: #555555; font-size: 10px; } div p { color: #123123; font-size: 8px } p { font-weight: normal; font-size: 9px } p:hover { color: yellow } p.poor { font-weight: lighter; color: black } p.rich { font-weight: bold; color: black } div[align=right] p { color: gray } </style> </head> <body> <h1 class="alert cool" id="title">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 align="left"> <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> <div align="right"> <p>Vivamus ac enim ante.</p> <p class="rich">Dictum id eleifend non.</p> </div> <p class="poor rich">Luctus scelerisque accumsan nunc porta</p> </body> </html> END $inliner = CSS::Inliner->new(); $inliner->read({html => $html}); $inlined = $inliner->inlinify(); contains_string($inlined, q(<h1 class="alert cool" id="title" style="color:red;font-size:25px;font-weight:normal;">Lorem ipsum), 'cascading rules for h1.alert.cool inlined'); contains_string($inlined, q(<h1 class="cool" style="color:blue;font-size:20px;">Consectetur), 'h1.cool rule inlined'); contains_string($inlined, q(<p class="intro" style="color:#555555;font-size:10px;font-weight:normal;">Aliquam), '.intro rule inlined'); contains_string($inlined, q(<p style="color:#123123;font-size:8px;font-weight:normal;">Phasellus), 'div p rule inlined'); contains_string($inlined, q(<p style="color:#123123;font-size:8px;font-weight:normal;">Nunc augue), 'div p rule inlined again'); contains_string($inlined, q(<p style="font-size:9px;font-weight:normal;">Nulla), 'just the "p" rule'); contains_string($inlined, q(<p style="color:gray;font-size:8px;font-weight:normal;">Vivamus), '"div[align=right] p" + "div p" + "p"'); contains_string($inlined, q(<p class="rich" style="color:gray;font-size:8px;font-weight:bold;">Dictum), '"div[align=right] p" + "div p" + "p" + "p.rich"'); contains_string($inlined, q(<p class="poor rich" style="color:black;font-size:9px;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'); lacks_string($inlined, q(30px), 'h1.cool.alert font-size ignored');
Hi Michael, Oh wow, I did not know about this entire concept of weighting within CSS at *all*. Give me a little bit to read the attached W3C summary that you included within this file and to see if this is the best approach. Supporting this feature should make the library substantially more robust in edge cases, so I definitely want to research it. I think my current plan is to release the other changes for this particular version, and then merge this in. Additionally you will be happy to know that I'm looking at a few options for a public source control system - either git or svn, I haven't figured which really is best for the project just yet. I'll send you an email when I have that all figured out. In the meantime I am merging the other resources you've contributed into the project, and I am adding a requested option whereby you can automatically strip classes/ids after inlining is complete (as they become superfluous). thanks again for your help! -Kevin On Fri Jul 02 16:29:19 2010, WONKO wrote: Show quoted text
> CSS::Inliner doesn't support the CSS idea of "weights" for the different > selectors It just inlines them in whatever order CSS::Tiny gives them > back. This not only has problems because CSS rules are order dependent > (https://rt.cpan.org/Ticket/Display.html?id=59042) but it also causes > problems because certain rules should have more precedence than others. > > Attached is a version of Inliner.pm that does support CSS selector > weights. It's not a patch because it also includes other patches that > I've submitted (https://rt.cpan.org/Ticket/Display.html?id=59042, > https://rt.cpan.org/Ticket/Display.html?id=58957 and > https://rt.cpan.org/Ticket/Display.html?id=58923). > > I'm also attaching tests for this weighting (css_rule_weights.t) and a > version of t/advanced.t that has tests for the actual inlining of this.
And released. This version is substantially more versatile. There are still a bunch of little quirks here and there, but I'm getting them out of there. Let me know if you see anything noteworthy. -Kevin On Mon Aug 16 23:02:40 2010, KAMELKEV wrote: Show quoted text
> Hi Michael, > > Oh wow, I did not know about this entire concept of weighting within > CSS at *all*. > > Give me a little bit to read the attached W3C summary that you > included within this file and to see if this is the best approach. > Supporting this feature should make the library substantially more > robust in edge cases, so I definitely want to research it. > > I think my current plan is to release the other changes for this > particular version, and then merge this in. Additionally you will be > happy to know that I'm looking at a few options for a public source > control system - either git or svn, I haven't figured which really is > best for the project just yet. > > I'll send you an email when I have that all figured out. > > In the meantime I am merging the other resources you've contributed > into the project, and I am adding a requested option whereby you can > automatically strip classes/ids after inlining is complete (as they > become superfluous). > > thanks again for your help! > > -Kevin > > > > > > > On Fri Jul 02 16:29:19 2010, WONKO wrote:
> > CSS::Inliner doesn't support the CSS idea of "weights" for the different > > selectors It just inlines them in whatever order CSS::Tiny gives them > > back. This not only has problems because CSS rules are order dependent > > (https://rt.cpan.org/Ticket/Display.html?id=59042) but it also causes > > problems because certain rules should have more precedence than others. > > > > Attached is a version of Inliner.pm that does support CSS selector > > weights. It's not a patch because it also includes other patches that > > I've submitted (https://rt.cpan.org/Ticket/Display.html?id=59042, > > https://rt.cpan.org/Ticket/Display.html?id=58957 and > > https://rt.cpan.org/Ticket/Display.html?id=58923). > > > > I'm also attaching tests for this weighting (css_rule_weights.t) and a > > version of t/advanced.t that has tests for the actual inlining of this.
>