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   86 use HTML::Blitz::pragma;
  11         25  
  11         74  
7 11         2264 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   5053 );
  11         25  
20              
21             our $VERSION = '0.08';
22              
23 287 50 33 287 0 642 method new($class: :$simple_selectors, :$link_type) {
  287 50       1078  
  287 50       529  
  287 50       865  
  287 50       718  
  287         625  
  287         647  
  287         391  
24 287         1358 bless {
25             simplesel => \@$simple_selectors,
26             link_type => $link_type,
27             }, $class
28             }
29              
30 518 50   518 0 1036 method link_type() {
  518 50       883  
  518         727  
  518         655  
31             $self->{link_type}
32 518         1026 }
33              
34 1797 50   1797 0 3600 method matches($tag, $attributes, $nth, $nth_of_type) {
  1797 50       3152  
  1797         2488  
  1797         3413  
  1797         2113  
35 1797         2272 for my $sel (@{$self->{simplesel}}) {
  1797         3286  
36 1907         2332 my $match;
37 1907         3090 my $type = $sel->{type};
38 1907 100 66     5902 if ($type eq ST_FALSE) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
39 16         29 $match = 0;
40             } elsif ($type eq ST_TAG_NAME) {
41 750   100     2603 $match = $sel->{name} eq '*' || $sel->{name} eq $tag;
42             } elsif ($type eq ST_ATTR_HAS) {
43 33         64 $match = exists $attributes->{$sel->{attr}};
44             } elsif ($type eq ST_ATTR_EQ) {
45 544         856 my $attr = $sel->{attr};
46 544   100     1414 $match = exists $attributes->{$attr} && $attributes->{$attr} eq $sel->{value};
47             } elsif ($type eq ST_ATTR_PREFIX) {
48 52         86 my $attr = $sel->{attr};
49 52         74 my $value = $sel->{value};
50 52   100     170 $match = exists $attributes->{$attr} && substr($attributes->{$attr}, 0, length $value) eq $value;
51             } elsif ($type eq ST_ATTR_SUFFIX) {
52 12         18 my $attr = $sel->{attr};
53 12         22 my $value = $sel->{value};
54 12   100     58 $match = exists $attributes->{$attr} && substr($attributes->{$attr}, -length $value) eq $value;
55             } elsif ($type eq ST_ATTR_INFIX) {
56 12         25 my $attr = $sel->{attr};
57 12         23 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 325         499 my $attr = $sel->{attr};
61 325         475 my $value = $sel->{value};
62 325   100     651 $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         14 my $value = $sel->{value};
75 8   100     82 $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       284 my $x = $type eq ST_NTH_CHILD ? $nth : $nth_of_type;
78 155         229 my $ka = $sel->{a};
79 155         218 my $kb = $sel->{b};
80 155         237 my $d = $x - $kb;
81 155   100     663 $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 1907 100       3804 if ($sel->{negated}) {
87 66         94 $match = !$match;
88             }
89              
90 1907 100       6281 $match or return 0;
91             }
92              
93             1
94 518         1309 }
95              
96             1