File Coverage

blib/lib/HTML/Zoom/Parser/BuiltIn.pm
Criterion Covered Total %
statement 55 57 96.4
branch 16 18 88.8
condition 5 5 100.0
subroutine 10 11 90.9
pod 0 4 0.0
total 86 95 90.5


line stmt bran cond sub pod time code
1             package HTML::Zoom::Parser::BuiltIn;
2              
3 14     14   56749 use strictures 1;
  14         108  
  14         404  
4 14     14   1209 use base qw(HTML::Zoom::SubObject);
  14         29  
  14         21311  
5              
6             sub html_to_events {
7 90     90 0 157 my ($self, $text) = @_;
8 90         117 my @events;
9 90     1209   458 _hacky_tag_parser($text => sub { push @events, $_[0] });
  1209         6267  
10 90         621 return \@events;
11             }
12              
13             sub html_to_stream {
14 29     29 0 48 my ($self, $text) = @_;
15 29         67 return $self->_zconfig->stream_utils
16 29         87 ->stream_from_array(@{$self->html_to_events($text)});
17             }
18              
19             sub _hacky_tag_parser {
20 90     90   154 my ($text, $handler) = @_;
21 90         400 $text =~ m{^([^<]*)}g;
22 90 100       321 if ( length $1 ) { # leading PCDATA
23 1         48 $handler->({ type => 'TEXT', raw => $1 });
24             }
25 90         1413 while (
26             $text =~ m{
27             (
28             (?:[^<]*) < (?:
29             ( / )? ( [^/!<>\s"'=]+ )
30             ( (?:"[^"]*"|'[^']*'|[^/"'<>])+? )?
31             |
32             (!-- .*? -- | ![^\-] .*? )
33             ) (\s*/\s*)? >
34             )
35             ([^<]*)
36             }sxg
37             ) {
38 673         2636 my ($whole, $is_close, $tag_name, $attributes, $is_special,
39             $in_place_close, $content)
40             = ($1, $2, $3, $4, $5, $6, $7, $8);
41 673 100       1187 if ($is_special) {
42 1         6 $handler->({ type => 'SPECIAL', raw => $whole });
43             } else {
44 672         834 $tag_name =~ tr/A-Z/a-z/;
45 672 100       1133 if ($is_close) {
46 317         1267 $handler->({ type => 'CLOSE', name => $tag_name, raw => $whole });
47             } else {
48 355 100 100     1734 $attributes = '' if !defined($attributes) or $attributes =~ /^ +$/;
49 355   100     722 $handler->({
50             type => 'OPEN',
51             name => $tag_name,
52             is_in_place_close => $in_place_close,
53             _hacky_attribute_parser($attributes),
54             raw_attrs => $attributes||'',
55             raw => $whole,
56             });
57 355 100       1027 if ($in_place_close) {
58 38         223 $handler->({
59             type => 'CLOSE', name => $tag_name, raw => '',
60             is_in_place_close => 1
61             });
62             }
63             }
64             }
65 673 100       2407 if (length $content) {
66 497         3083 $handler->({ type => 'TEXT', raw => $content });
67             }
68             }
69             }
70              
71             sub _hacky_attribute_parser {
72 355     355   501 my ($attr_text) = @_;
73 355         362 my (%attrs, @attr_names);
74 355         1501 while (
75             $attr_text =~ m{
76             ([^\s\=\"\']+)(\s*=\s*(?:(")(.*?)"|(')(.*?)'|([^'"\s=]+)['"]*))?
77             }sgx
78             ) {
79 251         447 my $key = $1;
80 251         339 my $test = $2;
81 251 50       626 my $val = ( $3 ? $4 : ( $5 ? $6 : $7 ));
    100          
82 251         491 my $lckey = lc($key);
83 251 50       428 if ($test) {
84 251         856 $attrs{$lckey} = _simple_unescape($val);
85             } else {
86 0         0 $attrs{$lckey} = $lckey;
87             }
88 251         982 push(@attr_names, $lckey);
89             }
90 355         3435 (attrs => \%attrs, attr_names => \@attr_names);
91             }
92              
93             sub _simple_unescape {
94 251     251   333 my $str = shift;
95 251         343 $str =~ s/"/"/g;
96 251         326 $str =~ s/</
97 251         300 $str =~ s/>/>/g;
98 251         292 $str =~ s/&/&/g;
99 251         723 $str;
100             }
101              
102             sub _simple_escape {
103 130     130   179 my $str = shift;
104 130         245 $str =~ s/&/&/g;
105 130         189 $str =~ s/"/"/g;
106 130         180 $str =~ s/
107 130         189 $str =~ s/>/>/g;
108 130         668 $str;
109             }
110              
111 130     130 0 335 sub html_escape { _simple_escape($_[1]) }
112              
113 0     0 0   sub html_unescape { _simple_unescape($_[1]) }
114              
115             1;