File Coverage

blib/lib/HTML/Blitz/SSSelector.pm
Criterion Covered Total %
statement 59 60 98.3
branch 34 44 77.2
condition 27 30 90.0
subroutine 5 5 100.0
pod 0 3 0.0
total 125 142 88.0


line stmt bran cond sub pod time code
1             # This code can be redistributed and modified under the terms of the GNU Affero
2             # General Public License as published by the Free Software Foundation, either
3             # version 3 of the License, or (at your option) any later version.
4             # See the "COPYING" file for details.
5             package HTML::Blitz::SSSelector;
6 11     11   79 use HTML::Blitz::pragma;
  11         24  
  11         91  
7 11         2281 use HTML::Blitz::SelectorType qw(
8             ST_FALSE
9             ST_TAG_NAME
10             ST_ATTR_HAS
11             ST_ATTR_EQ
12             ST_ATTR_PREFIX
13             ST_ATTR_SUFFIX
14             ST_ATTR_INFIX
15             ST_ATTR_LIST_HAS
16             ST_ATTR_LANG_PREFIX
17             ST_NTH_CHILD
18             ST_NTH_CHILD_OF_TYPE
19 11     11   5230 );
  11         25  
20              
21             our $VERSION = '0.07';
22              
23 284 50 33 284 0 695 method new($class: :$simple_selectors, :$link_type) {
  284 50       1056  
  284 50       508  
  284 50       788  
  284 50       768  
  284         613  
  284         643  
  284         382  
24 284         1353 bless {
25             simplesel => \@$simple_selectors,
26             link_type => $link_type,
27             }, $class
28             }
29              
30 509 50   509 0 1085 method link_type() {
  509 50       892  
  509         687  
  509         618  
31             $self->{link_type}
32 509         996 }
33              
34 1765 50   1765 0 3567 method matches($tag, $attributes, $nth, $nth_of_type) {
  1765 50       3130  
  1765         2502  
  1765         3247  
  1765         2490  
35 1765         2303 for my $sel (@{$self->{simplesel}}) {
  1765         3253  
36 1873         2405 my $match;
37 1873         3133 my $type = $sel->{type};
38 1873 100 66     5758 if ($type eq ST_FALSE) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
39 16         32 $match = 0;
40             } elsif ($type eq ST_TAG_NAME) {
41 732   100     2439 $match = $sel->{name} eq '*' || $sel->{name} eq $tag;
42             } elsif ($type eq ST_ATTR_HAS) {
43 33         94 $match = exists $attributes->{$sel->{attr}};
44             } elsif ($type eq ST_ATTR_EQ) {
45 544         936 my $attr = $sel->{attr};
46 544   100     1411 $match = exists $attributes->{$attr} && $attributes->{$attr} eq $sel->{value};
47             } elsif ($type eq ST_ATTR_PREFIX) {
48 52         93 my $attr = $sel->{attr};
49 52         75 my $value = $sel->{value};
50 52   100     171 $match = exists $attributes->{$attr} && substr($attributes->{$attr}, 0, length $value) eq $value;
51             } elsif ($type eq ST_ATTR_SUFFIX) {
52 12         22 my $attr = $sel->{attr};
53 12         21 my $value = $sel->{value};
54 12   100     69 $match = exists $attributes->{$attr} && substr($attributes->{$attr}, -length $value) eq $value;
55             } elsif ($type eq ST_ATTR_INFIX) {
56 12         23 my $attr = $sel->{attr};
57 12         16 my $value = $sel->{value};
58 12   100     42 $match = exists $attributes->{$attr} && index($attributes->{$attr}, $value) >= 0;
59             } elsif ($type eq ST_ATTR_LIST_HAS) {
60 309         501 my $attr = $sel->{attr};
61 309         500 my $value = $sel->{value};
62 309   100     698 $match = exists $attributes->{$attr} && do {
63             my $r = 0;
64             for my $elem ($attributes->{$attr} =~ /[^ \t\n\r\f]+/g) {
65             if ($elem eq $value) {
66             $r = 1;
67             last;
68             }
69             }
70             $r
71             };
72             } elsif ($type eq ST_ATTR_LANG_PREFIX) {
73 8         13 my $attr = $sel->{attr};
74 8         16 my $value = $sel->{value};
75 8   100     77 $match = exists $attributes->{$attr} && $attributes->{$attr} =~ /\A\Q$value\E(?![^\-])/;
76             } elsif ($type eq ST_NTH_CHILD || $type eq ST_NTH_CHILD_OF_TYPE) {
77 155 100       270 my $x = $type eq ST_NTH_CHILD ? $nth : $nth_of_type;
78 155         237 my $ka = $sel->{a};
79 155         234 my $kb = $sel->{b};
80 155         234 my $d = $x - $kb;
81 155   100     635 $match = $d == 0 || ($ka != 0 && ($d < 0) == ($ka < 0) && $d % $ka == 0);
82             } else {
83 0         0 die "Internal error: invalid simple selector type '$type'";
84             }
85              
86 1873 100       3661 if ($sel->{negated}) {
87 66         124 $match = !$match;
88             }
89              
90 1873 100       6315 $match or return 0;
91             }
92              
93             1
94 509         1292 }
95              
96             1