Skip to content

Commit 4844d9c

Browse files
committed
Keeps tabs on individual style-sheet property-sets
1 parent ee915c4 commit 4844d9c

File tree

3 files changed

+44
-38
lines changed

3 files changed

+44
-38
lines changed

lib/CSS.rakumod

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,14 @@ use CSS::Module::CSS3;
1717

1818
use LibXML::Document;
1919
use LibXML::Element;
20-
use LibXML::_ParentNode; # document, element or document fragment
2120
use LibXML::XPath::Context;
2221

2322
use URI;
24-
25-
has LibXML::_ParentNode:D $.doc is required;
23+
has LibXML::Document:D $.doc is required;
2624
has CSS::Stylesheet $!stylesheet;
2725
method stylesheet handles <Str gist ast page page-properties font-face font-sources font-family base-url> { $!stylesheet }
2826
has Array[CSS::Ruleset] %.rulesets; # rulesets to node-path mapping
27+
has Array[CSS::Properties] %.propsets; # rulesets to node-path mapping
2928
has CSS::Module:D $.module = CSS::Module::CSS3.module;
3029
has CSS::Properties %.style; # per node-path styling, including tags
3130
has CSS::TagSet $.tag-set;
@@ -43,8 +42,8 @@ method !build(
4342
if $!doc.isa(LibXML::Document);
4443

4544
$!tag-set //= $!doc ~~ LibXML::Document::HTML
46-
?? CSS::TagSet::XHTML.new: :$!module
47-
!! CSS::TagSet.new;
45+
?? CSS::TagSet::XHTML.new: :$!module
46+
!! CSS::TagSet.new;
4847

4948
$!stylesheet //= $!tag-set.stylesheet($!doc, :$media, :$base-url, :$imports, :$links, :$font-family);
5049
my LibXML::XPath::Context $xpath-context .= new: :$!doc;
@@ -56,20 +55,19 @@ method !build(
5655
%!rulesets{.nodePath}.push: $rule;
5756
}
5857
}
58+
59+
for %!rulesets {
60+
my CSS::Properties @propsets = .value.sort(*.specificity)».properties;
61+
%!propsets{.key} = @propsets;
62+
}
5963
}
6064

61-
multi submethod TWEAK(Str:D :stylesheet($string)!, |c) {
62-
$!stylesheet .= parse($string);
63-
self!build(|c);
64-
}
65-
66-
multi submethod TWEAK(CSS::Stylesheet :$!stylesheet, |c) {
65+
submethod TWEAK(CSS::Stylesheet() :$!stylesheet, |c) {
6766
self!build(|c);
6867
}
6968

70-
multi method COERCE(Str:D $_) { self.new: :stylesheet($_); }
71-
multi method COERCE(CSS::Stylesheet:D $stylesheet) { self.new: :$stylesheet; }
7269
multi method COERCE(LibXML::_ParentNode:D $doc) { self.new: :$doc }
70+
multi method COERCE(CSS::Stylesheet:D() $stylesheet) { self.new: :$stylesheet; }
7371

7472
# compute the style of an individual element
7573
method !base-style(Str:D $tag, Str :style-attr($style), Str :$path!) {
@@ -80,8 +78,7 @@ method !base-style(Str:D $tag, Str :style-attr($style), Str :$path!) {
8078
} // CSS::Properties.new: :$!module;
8179

8280
# Apply CSS Selector styles. Lower precedence than inline rules
83-
my CSS::Properties:D @prop-sets = .sort(*.specificity)».properties
84-
with %!rulesets{$path};
81+
my CSS::Properties:D @prop-sets = .List with %!propsets{$path};
8582

8683
CSS::Stylesheet::merge-properties(@prop-sets, $props);
8784

@@ -106,7 +103,7 @@ method !add-tag-styling(Str:D $tag, CSS::Properties $style, :%attrs) {
106103

107104
# styling, including any tag-specific styling
108105
multi method style(LibXML::Element:D $elem) {
109-
my $path = $elem.nodePath;
106+
my Str:D $path = $elem.nodePath;
110107

111108
%!style{$path} //= do {
112109
fail "document does not contain this element"
@@ -129,7 +126,12 @@ multi method style(LibXML::Element:D $elem) {
129126
}
130127

131128
multi method style(Str:D $xpath) {
132-
self.style: $!doc.first($xpath);
129+
do with $!doc.first($xpath) {
130+
self.style: $_;
131+
}
132+
else {
133+
CSS::Properties;
134+
}
133135
}
134136

135137
method prune($node = $!doc.root) {

t/tag-set-pango.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ is $css.style('/span/sup'), 'color:purple; font-size:0.83em; vertical-align:supe
5252
is $css.style('/span/small'), 'color:purple; font-size:smaller;', '<small/>';
5353
is $css.style('/span/tt'), 'color:purple; font-family:monospace;', '<tt/>';
5454
is $css.style('/span/u'), 'color:purple; text-decoration:underline;', '<u/>';
55-
is $css.style('/span/big/b/i/tt'), 'color:purple; font:italic 700 12pt monospace;', '<big/><b/><i/><tt/>';
55+
is $css.style('/span/big/b/i/tt'), 'color:purple; font:italic 700 14.4pt monospace;', '<big/><b/><i/><tt/>';
5656

5757
is $css.style('/span/i/span'), 'color:purple; font-style:italic;', '<i><span/></i>';
5858

t/tag-set-pdf.t

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,31 @@ is $tag-set.tag-style('P'), 'display:block; margin-bottom:1.12em; margin-top:1.1
2121

2222
is $css.style('P'), 'background:red; border:dotted; display:block; font-size:15pt; margin-bottom:1.12em; margin-top:1.12em; unicode-bidi:embed;', '<P/>';
2323

24-
my $frags = q:to<END>;
25-
<H1>NAME</H1>
26-
<Document><H1>NAME</H1><P>Para</P></Document>
27-
<H2><Span>Methods</Span></H2>
28-
<Code>createDocument()</Code>
29-
<L><LI><Lbl>new</Lbl><LBody>alias for <Code>createDocument()</Code></LBody></LI></L>
30-
<Span BorderStyle="Dotted">Dotted</Span>
31-
<Span SpaceBefore="5">Space Before</Span>
24+
$string = q:to<END>;
25+
<Document>
26+
<H1>NAME</H1>
27+
<H2>Methods</H2>
28+
<Code>createDocument()</Code>
29+
<L>
30+
<LI>
31+
<Lbl>new</Lbl>
32+
<LBody>alias for <Code>createDocument()</Code></LBody>
33+
</LI>
34+
</L>
35+
<Span BorderStyle="Dotted">Dotted</Span>
36+
<Span SpaceBefore="5">Space Before</Span>
37+
</Document>
3238
END
3339
34-
my LibXML::DocumentFragment $frag .= parse: :string($frags), :balanced;
35-
$css .= new: :doc($frag), :$tag-set, :inherit;
36-
37-
is $css.style('H1'), 'display:block; font-size:2em; font-weight:bolder; margin-bottom:0.67em; margin-top:0.67em; unicode-bidi:embed;';
38-
is $css.style('Document/H1'), 'display:block; font-size:2em; font-weight:bolder; margin-bottom:0.67em; margin-top:0.67em; unicode-bidi:embed;';
39-
is $css.style('Document/P'), 'display:block; margin-bottom:1.12em; margin-top:1.12em; unicode-bidi:embed;';
40-
is $css.style('H2/Span'), 'font-size:18pt; font-weight:700;';
41-
is $css.style('Code'), 'font-family:monospace; white-space:pre;';
42-
is $css.style('L/LI'), 'display:list-item; list-style:none; margin-left:40px;';
43-
is $css.style('L/LI/LBody/Code'), 'font-family:monospace; white-space:pre;';
44-
is $css.style('Span[1]'), 'border:dotted;';
45-
is $css.style('Span[2]'), '-pdf-space-before:5pt;';
40+
$doc .= parse: :$string;
41+
$css .= new: :$doc, :$tag-set, :inherit;
42+
43+
like $css.style('Document/H1'), /'display:block;'.*'font-size:2em;'.*'font-weight:bolder;'.*'margin-bottom:0.67em;'.*'margin-top:0.67em;'.*'unicode-bidi:embed;'/;
44+
like $css.style('Document/H2'), /'font-size:'[18pt|1.5em]';'.*'font-weight:'[700|bolder]';'/;
45+
like $css.style('Document/Code'), /'font-family:monospace;'.*'white-space:pre;'/;
46+
like $css.style('Document/L/LI'), /'display:list-item;'.*'list-style:none;'.*'margin-left:40px;'/;
47+
like $css.style('Document/L/LI/LBody/Code'), /'font-family:monospace;'.*'white-space:pre;'/;
48+
like $css.style('Document/Span[1]'), /'border:dotted;'/;
49+
like $css.style('Document/Span[2]'), /'-pdf-space-before:5pt;'/;
4650

4751
done-testing();

0 commit comments

Comments
 (0)