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
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   83 use HTML::Blitz::pragma;
  11         25  
  11         77  
7 11         2274 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   5222 );
  11         29  
20              
21             our $VERSION = '0.09';
22              
23 290 50 33 290 0 673 method new($class: :$simple_selectors, :$link_type) {
  290 50       1073  
  290 50       504  
  290 50       845  
  290 50       750  
  290         618  
  290         666  
  290         373  
24 290         1392 bless {
25             simplesel => \@$simple_selectors,
26             link_type => $link_type,
27             }, $class
28             }
29              
30 521 50   521 0 1061 method link_type() {
  521 50       944  
  521         747  
  521         644  
31             $self->{link_type}
32 521         1015 }
33              
34 1806 50   1806 0 3678 method matches($tag, $attributes, $nth, $nth_of_type) {
  1806 50       3287  
  1806         2562  
  1806         3419  
  1806         2185  
35 1806         2372 for my $sel (@{$self->{simplesel}}) {
  1806         3417  
36 1916         2346 my $match;
37 1916         3162 my $type = $sel->{type};
38 1916 100 66     5963 if ($type eq ST_FALSE) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
39 16         26 $match = 0;
40             } elsif ($type eq ST_TAG_NAME) {
41 755   100     2406 $match = $sel->{name} eq '*' || $sel->{name} eq $tag;
42             } elsif ($type eq ST_ATTR_HAS) {
43 33         65 $match = exists $attributes->{$sel->{attr}};
44             } elsif ($type eq ST_ATTR_EQ) {
45 548         900 my $attr = $sel->{attr};
46 548   100     1367 $match = exists $attributes->{$attr} && $attributes->{$attr} eq $sel->{value};
47             } elsif ($type eq ST_ATTR_PREFIX) {
48 52         89 my $attr = $sel->{attr};
49 52         76 my $value = $sel->{value};
50 52   100     192 $match = exists $attributes->{$attr} && substr($attributes->{$attr}, 0, length $value) eq $value;
51             } elsif ($type eq ST_ATTR_SUFFIX) {
52 12         21 my $attr = $sel->{attr};
53 12         19 my $value = $sel->{value};
54 12   100     48 $match = exists $attributes->{$attr} && substr($attributes->{$attr}, -length $value) eq $value;
55             } elsif ($type eq ST_ATTR_INFIX) {
56 12         22 my $attr = $sel->{attr};
57 12         16 my $value = $sel->{value};
58 12   100     46 $match = exists $attributes->{$attr} && index($attributes->{$attr}, $value) >= 0;
59             } elsif ($type eq ST_ATTR_LIST_HAS) {
60 325         509 my $attr = $sel->{attr};
61 325         481 my $value = $sel->{value};
62 325   100     700 $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         18 my $attr = $sel->{attr};
74 8         11 my $value = $sel->{value};
75 8   100     78 $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       264 my $x = $type eq ST_NTH_CHILD ? $nth : $nth_of_type;
78 155         247 my $ka = $sel->{a};
79 155         226 my $kb = $sel->{b};
80 155         228 my $d = $x - $kb;
81 155   100     697 $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 1916 100       3692 if ($sel->{negated}) {
87 66         101 $match = !$match;
88             }
89              
90 1916 100       6370 $match or return 0;
91             }
92              
93             1
94 521         1369 }
95              
96             1