File Coverage

blib/lib/Tags/HTML/Tree.pm
Criterion Covered Total %
statement 82 82 100.0
branch 6 6 100.0
condition 6 6 100.0
subroutine 18 18 100.0
pod 1 1 100.0
total 113 113 100.0


line stmt bran cond sub pod time code
1             package Tags::HTML::Tree;
2              
3 8     8   209847 use base qw(Tags::HTML);
  8         18  
  8         4485  
4 8     8   101232 use strict;
  8         13  
  8         202  
5 8     8   33 use warnings;
  8         13  
  8         2640  
6              
7 8     8   39 use Class::Utils qw(set_params split_params);
  8         17  
  8         580  
8 8     8   47 use English;
  8         11  
  8         46  
9 8     8   3510 use Error::Pure qw(err);
  8         12  
  8         430  
10 8     8   4618 use Mo::utils 0.12 qw(check_code check_required);
  8         22116  
  8         173  
11 8     8   5710 use Mo::utils::CSS 0.07 qw(check_css_class check_css_unit);
  8         80072  
  8         173  
12 8     8   793 use Scalar::Util qw(blessed);
  8         26  
  8         384  
13 8     8   3304 use Unicode::UTF8 qw(decode_utf8);
  8         4933  
  8         6913  
14              
15             our $VERSION = 0.07;
16              
17             # Constructor.
18             sub new {
19 29     29 1 1898949 my ($class, @params) = @_;
20              
21             # Create object.
22 29         133 my ($object_params_ar, $other_params_ar) = split_params(
23             ['cb_value', 'css_class', 'indent'], @params);
24 29         632 my $self = $class->SUPER::new(@{$other_params_ar});
  29         146  
25              
26             # Callback for tree value.
27             $self->{'cb_value'} = sub {
28 10     10   12 my ($self, $tree) = @_;
29              
30 10         20 $self->{'tags'}->put(
31             ['d', $tree->value],
32             );
33              
34 10         208 return;
35 22         791 };
36              
37             # CSS class.
38 22         70 $self->{'css_class'} = 'tree';
39              
40             # Tree indent.
41 22         49 $self->{'indent'} = '2em';
42              
43             # Process params.
44 22         32 set_params($self, @{$object_params_ar});
  22         59  
45              
46 22         257 check_code($self, 'cb_value');
47              
48 21         357 check_required($self, 'css_class');
49 20         192 check_css_class($self, 'css_class');
50              
51 18         384 check_css_unit($self, 'indent');
52              
53             # Object.
54 15         1399 return $self;
55             }
56              
57             sub _cleanup {
58 1     1   11 my $self = shift;
59              
60 1         2 delete $self->{'_tree'};
61              
62 1         8 return;
63             }
64              
65             sub _init {
66 8     8   1468 my ($self, $tree) = @_;
67              
68 8 100 100     72 if (! defined $tree
      100        
69             || ! blessed($tree)
70             || ! $tree->isa('Tree')) {
71              
72 3         56 err "Data object must be a 'Tree' instance.";
73             }
74              
75 5         9 $self->{'_tree'} = $tree;
76              
77 5         13 return;
78             }
79              
80             sub _prepare {
81 1     1   842 my $self = shift;
82              
83 1         11 $self->script_js([<<"END"]);
84             window.addEventListener('load', (event) => {
85             let toggler = document.getElementsByClassName("caret");
86             for (let i = 0; i < toggler.length; i++) {
87             toggler[i].addEventListener("click", function() {
88             this.parentElement.querySelector(".nested").classList.toggle("active");
89             this.classList.toggle("caret-down");
90             });
91             }
92             });
93             END
94              
95 1         6 return;
96             }
97              
98             # Process 'Tags'.
99             sub _process {
100 5     5   37 my $self = shift;
101              
102 5 100       10 if (! exists $self->{'_tree'}) {
103 1         2 return;
104             }
105              
106             $self->{'tags'}->put(
107             ['b', 'ul'],
108 4         19 ['a', 'class', $self->{'css_class'}],
109             );
110 4         208 $self->_li($self->{'_tree'});
111 4         8 $self->{'tags'}->put(
112             ['e', 'ul'],
113             );
114              
115 4         98 return;
116             }
117              
118             sub _process_css {
119 3     3   49 my $self = shift;
120              
121             $self->{'css'}->put(
122             ['s', 'ul, .'.$self->{'css_class'}],
123             ['d', 'list-style-type', 'none'],
124 3         81 ['d', 'padding-left', $self->{'indent'}],
125             ['e'],
126              
127             ['s', '.caret'],
128             ['d', 'cursor', 'pointer'],
129             ['d', '-webkit-user-select', 'none'],
130             ['d', '-moz-user-select', 'none'],
131             ['d', '-ms-user-select', 'none'],
132             ['d', 'user-select', 'none'],
133             ['e'],
134              
135             ['s', '.caret::before'],
136             ['d', 'content', decode_utf8('"⯈"')],
137             ['d', 'color', 'black'],
138             ['d', 'display', 'inline-block'],
139             ['d', 'margin-right', '6px'],
140             ['e'],
141              
142             ['s', '.caret-down::before'],
143             ['d', 'transform', 'rotate(90deg)'],
144             ['e'],
145              
146             ['s', '.nested'],
147             ['d', 'display', 'none'],
148             ['e'],
149              
150             ['s', '.active'],
151             ['d', 'display', 'block'],
152             ['e'],
153             );
154              
155 3         2556 return;
156             }
157              
158             sub _li {
159 11     11   13 my ($self, $tree) = @_;
160              
161 11         18 my $meta_hr = $tree->meta;
162 11         60 $self->{'tags'}->put(
163             ['b', 'li'],
164             );
165 11         273 my @children = $tree->children;
166 11 100       119 if (@children) {
167 4         11 $self->{'tags'}->put(
168             ['b', 'span'],
169             ['a', 'class', 'caret'],
170             );
171 4         169 $self->{'cb_value'}->($self, $tree);
172 4         12 $self->{'tags'}->put(
173             ['e', 'span'],
174              
175             ['b', 'ul'],
176             ['a', 'class', 'nested'],
177             );
178 4         259 foreach my $child (@children) {
179 7         13 $self->_li($child);
180             }
181 4         8 $self->{'tags'}->put(
182             ['e', 'ul'],
183             );
184             } else {
185 7         13 $self->{'cb_value'}->($self, $tree);
186             }
187 11         225 $self->{'tags'}->put(
188             ['e', 'li'],
189             );
190              
191 11         256 return;
192             }
193              
194             1;
195              
196             __END__