File Coverage

blib/lib/HTML/Linear/Path.pm
Criterion Covered Total %
statement 59 59 100.0
branch 10 10 100.0
condition 10 10 100.0
subroutine 14 14 100.0
pod 3 3 100.0
total 96 96 100.0


line stmt bran cond sub pod time code
1             package HTML::Linear::Path;
2             # ABSTRACT: represent paths inside HTML::Tree
3 64     64   373 use strict;
  64         121  
  64         2286  
4 64     64   339 use utf8;
  64         124  
  64         577  
5 64     64   1700 use warnings qw(all);
  64         118  
  64         2350  
6              
7 64     64   112190 use JSON;
  64         1154873  
  64         441  
8 64     64   12430 use Moo;
  64         140  
  64         615  
9 64     64   23648 use MooX::Types::MooseLike::Base qw(:all);
  64         797  
  64         37823  
10              
11 64     64   59367 use HTML::Linear::Path::Colors;
  64         234  
  64         19585  
12              
13             ## no critic (ProhibitPackageVars)
14              
15             our $VERSION = '0.019'; # VERSION
16              
17              
18             has json => (
19             is => 'ro',
20             isa => InstanceOf['JSON'],
21             default => sub { JSON->new->ascii->canonical },
22             lazy => 1,
23             );
24              
25              
26             has address => (is => 'rw', isa => Str, required => 1);
27             has attributes => (is => 'ro', isa => HashRef[Str], required => 1);
28             has is_groupable=> (is => 'rw', isa => Bool, default => sub { 0 });
29             has key => (is => 'rw', isa => Str, default => sub { '' });
30             has strict => (is => 'ro', isa => Bool, default => sub { 0 });
31             has tag => (is => 'ro', isa => Str, required => 1);
32              
33 64     64   736 use overload '""' => \&as_string, fallback => 1;
  64         147  
  64         871  
34              
35              
36             our %groupby = (
37             class => [qw(*)],
38             id => [qw(*)],
39             name => [qw(input meta)],
40             'http-equiv'=> [qw(meta)],
41             property => [qw(meta)],
42             rel => [qw(link)],
43             );
44              
45              
46             our %tag_weight = (
47             title => 15,
48             h1 => 10,
49             h2 => 9,
50             h3 => 8,
51             h4 => 7,
52             h5 => 6,
53             h6 => 5,
54             center => 3,
55             strong => 2,
56             b => 2,
57             u => 1,
58             em => 1,
59             a => 1,
60             sup => -1,
61             sub => -1,
62             samp => -1,
63             pre => -1,
64             kbd => -1,
65             code => -1,
66             blockquote => -1,
67             );
68              
69              
70             our (%xpath_wrap) = (%{$HTML::Linear::Path::Colors::scheme{default}});
71              
72              
73             sub as_string {
74 178     178 1 270 my ($self) = @_;
75 178 100       17950 return $self->key if $self->key;
76              
77 66         9638 my $ref = {
78             _tag => $self->tag,
79             addr => $self->address,
80             };
81 66 100       616 $ref->{attr} = $self->attributes if keys %{$self->attributes};
  66         524  
82              
83 66         1798 return $self->key($self->json->encode($ref));
84             }
85              
86              
87             sub as_xpath {
88 212732     212732 1 324767 my ($self, $strict) = @_;
89              
90 212732         388496 my $xpath = _wrap(separator => '/') . _wrap(tag => $self->tag);
91              
92 212732         379590 my $expr = '';
93 212732         587831 for my $attr (keys %groupby) {
94 1163844 100 100     2573935 if (_isgroup($self->tag, $attr) and $self->attributes->{$attr}) {
95 48993         97056 $expr .= _wrap(array => '[');
96 48993         94196 $expr .= _wrap(sigil => '@');
97 48993         101035 $expr .= _wrap(attribute => $attr);
98 48993         100840 $expr .= _wrap(equal => '=');
99 48993         145248 $expr .= _wrap(value => _quote($self->attributes->{$attr}));
100 48993         107870 $expr .= _wrap(array => ']');
101              
102 48993         1204765 $self->is_groupable(1);
103              
104 48993         2394545 last;
105             }
106             }
107              
108 212732 100 100     6501618 return $xpath . (
109             (not $self->strict and not $strict)
110             ? $expr
111             : ''
112             );
113             }
114              
115              
116             sub weight {
117 72     72 1 112 my ($self) = @_;
118 72   100     739 return $tag_weight{$self->tag} // 0;
119             }
120              
121              
122             sub _quote {
123 48993     48993   95762 local ($_) = @_;
124              
125 48993         81365 s/\\/\\\\/gsx;
126 48993         64848 s/'/\\'/gsx;
127 48993         84861 s/\s+/ /gsx;
128 48993         85756 s/^\s//sx;
129 48993         90747 s/\s$//sx;
130              
131 48993         160402 return "'$_'";
132             }
133              
134              
135             sub _wrap {
136 759268     759268   1266574 my ($p, $q) = @_;
137             return
138 759268         2838323 $xpath_wrap{$p}->[0]
139             . $q
140             . $xpath_wrap{$p}->[1];
141             }
142              
143              
144             sub _isgroup {
145 1170946     1170946   1627545 my ($tag, $attr) = @_;
146             return (
147 1370686 100       9469670 1 and grep {
148 1170946   100     3309660 $_ eq '*'
149             or
150             $_ eq $tag
151 1170946         1241222 } @{$groupby{$attr} // []}
152             );
153             }
154              
155             1;
156              
157             __END__