File Coverage

blib/lib/CSS/Scopifier.pm
Criterion Covered Total %
statement 48 51 94.1
branch 10 16 62.5
condition 3 5 60.0
subroutine 6 6 100.0
pod 2 2 100.0
total 69 80 86.2


line stmt bran cond sub pod time code
1             package CSS::Scopifier;
2 1     1   908 use strict;
  1         3  
  1         41  
3 1     1   8 use warnings;
  1         2  
  1         57  
4            
5             # ABSTRACT: Prepends CSS selectors to apply scope/context
6            
7             our $VERSION = 0.03;
8            
9 1     1   2018 use CSS::Tiny 1.19;
  1         9278  
  1         32  
10            
11 1     1   4084 use Moo;
  1         30322  
  1         9  
12             extends 'CSS::Tiny';
13            
14             sub scopify {
15 2     2 1 519 my ($self, $selector, @arg) = @_;
16 2 50       8 my %opt = ref($arg[0]) ? %{$arg[0]} : @arg;
  0         0  
17            
18 2 50 33     11 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 2         2 my $root_sel;
24 2 100       6 if($opt{merge}) {
25 1 50       4 my @list = ref $opt{merge} ? @{$opt{merge}} : ($opt{merge});
  1         3  
26 1         2 $root_sel = {};
27 1         2 %$root_sel = ( %$root_sel, %$_ ) for (
  1         8  
28 2         5 map { delete $self->{$_} }
29             grep { exists $self->{$_} }
30             @list
31             );
32             }
33            
34 2         18 $self->{"$selector $_"} = delete $self->{$_} for (keys %$self);
35 2 100       8 $self->{$selector} = $root_sel if ($root_sel);
36            
37 2         7 return 1;
38             }
39            
40             # Redefining read_string() until CSS::Tiny bug [rt.cpan.org #87261] is fixed
41             sub read_string {
42 2 50   2 1 4968 my $self = ref $_[0] ? shift : bless {}, shift;
43            
44             # Flatten whitespace and remove /* comment */ style comments
45 2         7 my $string = shift;
46 2         6 $string =~ tr/\n\t/ /;
47 2         5 $string =~ s!/\*.*?\*\/!!g;
48            
49             # Split into styles
50 2         179 foreach ( grep { /\S/ } split /(?<=\})/, $string ) {
  10         54  
51 8 50       43 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 8         13 my $style = $1;
57 8         14 my $properties = $2;
58 8         13 $style =~ s/\s{2,}/ /g;
59 8         138 my @styles = grep { s/\s+/ /g; 1; } grep { /\S/ } split /\s*,\s*/, $style;
  10         17  
  10         17  
  10         25  
60 8   100     11 foreach ( @styles ) { $self->{$_} ||= {} }
  10         85  
61            
62             # Split into properties
63 8         42 foreach ( grep { /\S/ } split /\;/, $properties ) {
  16         42  
64 12 50       69 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 12         14 foreach ( @styles ) { $self->{$_}->{lc $1} = $2 }
  16         72  
68             }
69             }
70            
71             $self
72 2         17 }
73            
74            
75             1;
76            
77             __END__