File Coverage

blib/lib/HTML/ValidationRules/Parser.pm
Criterion Covered Total %
statement 49 50 98.0
branch 16 20 80.0
condition 10 13 76.9
subroutine 9 9 100.0
pod 0 5 0.0
total 84 97 86.6


line stmt bran cond sub pod time code
1             package HTML::ValidationRules::Parser;
2 3     3   14 use strict;
  3         5  
  3         85  
3 3     3   15 use warnings;
  3         6  
  3         59  
4 3     3   11282 use autodie;
  3         67852  
  3         22  
5 3     3   43388 use HTML::Parser;
  3         28837  
  3         2191  
6              
7             my %ELEMENTS = (
8             input => [qw(
9             max
10             maxlength
11             min
12             pattern
13             required
14             ), {
15             name => 'type',
16             values => [qw(
17             url
18             email
19             number
20             range
21             )],
22             }],
23              
24             textarea => [qw(
25             maxlength
26             required
27             )],
28              
29             select => [qw(
30             required
31             )],
32             );
33              
34             my $ELEMENTS_PATTERN = qr/(@{[join '|', (map { quotemeta } keys %ELEMENTS)]})/o;
35             my %ATTRS_MAP = map {
36             my $attr = ref $_ ? $_->{name} : $_;
37             $attr => +{ map { $_ => 1 } @{$ELEMENTS{$_}} };
38             } keys %ELEMENTS;
39             my %TYPE_ATTR_MAP = map {
40             my $attr = $_;
41             map { $_ => 1 } @{$attr->{values}};
42             } grep { ref $_ && $_->{name} eq 'type' } @{$ELEMENTS{input}};
43              
44             sub new {
45 52     52 0 122 my ($class, %args) = @_;
46 52         361 bless \%args, $class;
47             }
48              
49             sub parser {
50 208     208 0 276 my ($self) = @_;
51 52 50       374 $self->{parser} ||= HTML::Parser->new(
52             api_version => 3,
53             start_h => [\&start, 'self, tagname, attr, attrseq'],
54 208   66     1876 %{$self->{options} || {}},
55             );
56             }
57              
58             sub load_rules {
59 52     52 0 108 my ($self, %args) = @_;
60 52         87 my $file = delete $args{file};
61 52         112 my $html = delete $args{html};
62              
63 52         248 undef $self->parser->{rules};
64              
65 52 50       2250 if ($file) {
66 0         0 $self->parser->parse_file($file);
67             }
68             else {
69 52         147 $self->parser->parse($html);
70 52         134 $self->parser->eof;
71             }
72              
73 52         104 $self->parser->{rules};
74             }
75              
76             sub start {
77 65     65 0 133 my ($parser, $tag, $attr, $attrseq) = @_;
78 65 100       632 return if $tag !~ $ELEMENTS_PATTERN;
79              
80 61         245 my $name = $attr->{name};
81 61 100       132 return if !defined $name;
82              
83 60         71 my @rules;
84 60         148 my $attrs = $ATTRS_MAP{lc $tag};
85              
86 60 100 50     598 if (defined $attr->{type} && $TYPE_ATTR_MAP{lc $attr->{type} || ''}) {
      100        
87 37         63 my $type = $attr->{type};
88 37         80 unshift @rules, key($type);
89 37         84 $attrseq = [ grep { lc $_ ne 'type' } @$attrseq ];
  109         296  
90             }
91              
92 60 50       73 for my $key (@{$attrseq || []}) {
  60         179  
93 133 100       376 next if !$attrs->{$key};
94              
95 52         92 my $value = $attr->{$key};
96 52 100 66     236 if (defined $value && $key ne $value) {
    50          
97 43         84 push @rules, [ key($key) => $value ];
98             }
99             elsif ($key eq $value) {
100 9         20 push @rules, key($key);
101             }
102             }
103              
104 60   100     473 $parser->{rules} ||= [];
105 60         75 push @{$parser->{rules}}, $name => \@rules;
  60         498  
106             }
107              
108             sub key {
109 89     89 0 128 my $key = shift;
110 89 100       224 return 'NOT_BLANK' if $key eq 'required';
111 80         560 sprintf 'HTML_%s', uc $key;
112             }
113              
114             !!1;