File Coverage

blib/lib/CSS/Scopifier.pm
Criterion Covered Total %
statement 48 51 94.1
branch 11 16 68.7
condition 3 5 60.0
subroutine 6 6 100.0
pod 2 2 100.0
total 70 80 87.5


line stmt bran cond sub pod time code
1             package CSS::Scopifier;
2 2     2   782 use strict;
  2         3  
  2         54  
3 2     2   10 use warnings;
  2         3  
  2         106  
4            
5             # ABSTRACT: Prepends CSS selectors to apply scope/context
6            
7             our $VERSION = 0.04;
8            
9 2     2   1489 use CSS::Tiny 1.19;
  2         5352  
  2         57  
10            
11 2     2   925 use Moo;
  2         13905  
  2         17  
12             extends 'CSS::Tiny';
13            
14             sub scopify {
15 7     7 1 555 my ($self, $selector, @arg) = @_;
16 7 50       33 my %opt = ref($arg[0]) ? %{$arg[0]} : @arg;
  0         0  
17            
18 7 50 33     275 die "scopify() requires string selector argument"
19             unless ($selector && ! ref($selector));
20            
21             # Merge specified selectors into the root/scoped selector. Useful
22             # with merge => ['html','body'] if scopifying a base css file
23 7         12 my $root_sel;
24 7 100       27 if($opt{merge}) {
25 1 50       5 my @list = ref $opt{merge} ? @{$opt{merge}} : ($opt{merge});
  1         4  
26 1         2 $root_sel = {};
27 1         2 %$root_sel = ( %$root_sel, %$_ ) for (
28 1         83 map { delete $self->{$_} }
29 2         6 grep { exists $self->{$_} }
30             @list
31             );
32             }
33            
34 7         95 $self->{"$selector $_"} = delete $self->{$_} for (keys %$self);
35 7 100       30 $self->{$selector} = $root_sel if ($root_sel);
36            
37 7         48 return 1;
38             }
39            
40             # Redefining read_string() until CSS::Tiny bug [rt.cpan.org #87261] is fixed
41             sub read_string {
42 20 100   20 1 1835 my $self = ref $_[0] ? shift : bless {}, shift;
43            
44             # Flatten whitespace and remove /* comment */ style comments
45 20         41 my $string = shift;
46 20         45 $string =~ tr/\n\t/ /;
47 20         47 $string =~ s!/\*.*?\*\/!!g;
48            
49             # Split into styles
50 20         271 foreach ( grep { /\S/ } split /(?<=\})/, $string ) {
  24         103  
51 18 50       133 unless ( /^\s*([^{]+?)\s*\{(.*)\}\s*$/ ) {
52 0         0 return $self->_error( "Invalid or unexpected style data '$_'" );
53             }
54            
55             # Split in such a way as to support grouped styles
56 18         48 my $style = $1;
57 18         41 my $properties = $2;
58 18         41 $style =~ s/\s{2,}/ /g;
59 18         60 my @styles = grep { s/\s+/ /g; 1; } grep { /\S/ } split /\s*,\s*/, $style;
  22         46  
  22         75  
  22         72  
60 18   100     39 foreach ( @styles ) { $self->{$_} ||= {} }
  22         153  
61            
62             # Split into properties
63 18         82 foreach ( grep { /\S/ } split /\;/, $properties ) {
  39         119  
64 31 50       235 unless ( /^\s*(\*?[\w._-]+)\s*:\s*(.*?)\s*$/ ) { #<-- updated regex to support starting with '*'
65 0         0 return $self->_error( "Invalid or unexpected property '$_' in style '$style'" );
66             }
67 31         59 foreach ( @styles ) { $self->{$_}->{lc $1} = $2 }
  38         243  
68             }
69             }
70            
71             $self
72 20         80 }
73            
74            
75             1;
76            
77             __END__