File Coverage

blib/lib/Tags/HTML/Pager.pm
Criterion Covered Total %
statement 77 87 88.5
branch 31 44 70.4
condition 12 21 57.1
subroutine 12 12 100.0
pod 1 1 100.0
total 133 165 80.6


line stmt bran cond sub pod time code
1             package Tags::HTML::Pager;
2              
3 5     5   133815 use base qw(Tags::HTML);
  5         56  
  5         2603  
4 5     5   41164 use strict;
  5         1669  
  5         106  
5 5     5   25 use warnings;
  5         9  
  5         133  
6              
7 5     5   25 use Class::Utils qw(set_params split_params);
  5         21  
  5         218  
8 5     5   29 use Error::Pure qw(err);
  5         9  
  5         172  
9 5     5   34 use Readonly;
  5         14  
  5         193  
10 5     5   2349 use Unicode::UTF8 qw(decode_utf8);
  5         2421  
  5         7445  
11              
12             Readonly::Scalar our $NUMBER_OF_BOXES => 7;
13              
14             our $VERSION = 0.05;
15              
16             # Constructor.
17             sub new {
18 16     16 1 20386 my ($class, @params) = @_;
19              
20             # Create object.
21 16         72 my ($object_params_ar, $other_params_ar) = split_params(
22             ['css_colors', 'css_pager', 'flag_prev_next', 'flag_paginator',
23             'url_page_cb'], @params);
24 16         749 my $self = $class->SUPER::new(@{$other_params_ar});
  16         61  
25              
26             # CSS colors.
27             $self->{'css_colors'} = {
28             'actual_background' => 'black',
29             'actual_color' => 'white',
30             'border' => 'black',
31             'hover_background' => 'black',
32             'hover_color' => 'white',
33             'other_background' => undef,
34             'other_color' => 'black',
35             },
36              
37             # CSS class.
38 14         472 $self->{'css_pager'} = 'pager';
39              
40             # Flag for prev/next buttons.
41 14         29 $self->{'flag_prev_next'} = 0;
42              
43             # Flag for paginator.
44 14         25 $self->{'flag_paginator'} = 1;
45              
46             # URL of page.
47 14         33 $self->{'url_page_cb'} = undef;
48              
49             # Process params.
50 14         25 set_params($self, @{$object_params_ar});
  14         43  
51              
52 14 100       205 if (! defined $self->{'css_pager'}) {
53 1         5 err "Parameter 'css_pager' is required.";
54             }
55              
56 13 100       33 if (! defined $self->{'url_page_cb'}) {
57 1         5 err "Missing 'url_page_cb' parameter.";
58             }
59              
60 12 100 100     50 if (! $self->{'flag_paginator'} && ! $self->{'flag_prev_next'}) {
61 1         3 err 'Both paginator styles disabled.';
62             }
63              
64             # Object.
65 11         132 return $self;
66             }
67              
68             sub _css_class {
69 20     20   42 my ($self, $suffix) = @_;
70              
71 20         169 return $self->{'css_pager'}.'-'.$suffix;
72             }
73              
74             sub _css_colors_optional {
75 4     4   16 my ($self, $css_color, $css_key) = @_;
76              
77             return defined $self->{'css_colors'}->{$css_color}
78 4 100       21 ? (['d', $css_key, $self->{'css_colors'}->{$css_color}])
79             : ();
80             }
81              
82             sub _process {
83 7     7   100 my ($self, $pages_hr) = @_;
84              
85 7 100       15 if (! $pages_hr) {
86 1         11 err 'Pages data structure is missing.';
87             }
88 6 100       14 if (! exists $pages_hr->{'pages_num'}) {
89 1         7 err "Missing 'pages_num' parameter in pages data structure.";
90             }
91 5 100       14 if (! exists $pages_hr->{'actual_page'}) {
92 1         3 err "Missing 'actual_page' parameter in pages data structure.";
93             }
94 4 100       11 if ($pages_hr->{'actual_page'} > $pages_hr->{'pages_num'}) {
95             err "Parameter 'actual_page' is greater than parameter 'pages_num'.",
96             'actual_page', $pages_hr->{'actual_page'},
97 1         9 'pages_num', $pages_hr->{'pages_num'},
98             ;
99             }
100              
101             # No code.
102 3 100 66     20 if (! $self->{'flag_paginator'}
      66        
103             && $self->{'flag_prev_next'} && $pages_hr->{'pages_num'} == 1) {
104              
105 1         3 return;
106             }
107              
108             $self->{'tags'}->put(
109             ['b', 'div'],
110 2         15 ['a', 'class', $self->{'css_pager'}],
111             );
112              
113             # Paginator
114 2 100       167 if ($self->{'flag_paginator'}) {
115 1         6 $self->{'tags'}->put(
116             ['b', 'p'],
117             ['a', 'class', $self->_css_class('paginator')],
118             );
119 1         60 my $buttons_from = 1;
120 1         2 my $buttons_to = $pages_hr->{'pages_num'};
121 1 50 33     4 if ($pages_hr->{'actual_page'} > 4
122             && $pages_hr->{'pages_num'} > $NUMBER_OF_BOXES) {
123              
124             $self->{'tags'}->put(
125             ['b', 'a'],
126 0         0 ['a', 'href', $self->{'url_page_cb'}->(1, $pages_hr)],
127             ['d', 1],
128             ['e', 'a'],
129              
130             ['b', 'span'],
131             ['d', decode_utf8('…')],
132             ['e', 'span'],
133             );
134 0 0       0 if ($pages_hr->{'actual_page'} < $pages_hr->{'pages_num'} - 3) {
135 0         0 $buttons_from = $pages_hr->{'actual_page'} - 1;
136             } else {
137 0         0 $buttons_from = $pages_hr->{'pages_num'} - 4;
138             }
139             }
140 1 50 33     6 if ($pages_hr->{'actual_page'} < $pages_hr->{'pages_num'} - 3
141             && $pages_hr->{'pages_num'} > $NUMBER_OF_BOXES) {
142              
143 0 0       0 if ($pages_hr->{'actual_page'} > 4) {
144 0         0 $buttons_to = $pages_hr->{'actual_page'} + 1;
145             } else {
146 0         0 $buttons_to = 5;
147             }
148             }
149 1         6 foreach my $button_num ($buttons_from .. $buttons_to) {
150 1 50       5 if ($pages_hr->{'actual_page'} eq $button_num) {
151 1         5 $self->{'tags'}->put(
152             ['b', 'strong'],
153             ['a', 'class', $self->_css_class('paginator-selected')],
154             ['d', $button_num],
155             ['e', 'strong'],
156             );
157             } else {
158             $self->{'tags'}->put(
159             ['b', 'a'],
160 0         0 ['a', 'href', $self->{'url_page_cb'}->($button_num, $pages_hr)],
161             ['d', $button_num],
162             ['e', 'a'],
163             );
164             }
165             }
166 1 50 33     137 if ($pages_hr->{'actual_page'} < $pages_hr->{'pages_num'} - 3
167             && $pages_hr->{'pages_num'} > $NUMBER_OF_BOXES) {
168              
169             $self->{'tags'}->put(
170             ['b', 'span'],
171             ['d', decode_utf8('…')],
172             ['e', 'span'],
173              
174             ['b', 'a'],
175             ['a', 'href', $self->{'url_page_cb'}->($pages_hr->{'pages_num'}, $pages_hr)],
176 0         0 ['d', $pages_hr->{'pages_num'}],
177             ['e', 'a'],
178             );
179             }
180 1         4 $self->{'tags'}->put(
181             ['e', 'p'],
182             );
183             }
184              
185             # Paging.
186 2 100 66     45 if ($self->{'flag_prev_next'} && $pages_hr->{'pages_num'} > 1) {
187 1         2 my ($prev, $next);
188 1 50       4 if ($pages_hr->{'pages_num'} > 1) {
189 1 50       3 if ($pages_hr->{'actual_page'} > 1) {
190 0         0 $prev = $pages_hr->{'actual_page'} - 1;
191             }
192 1 50       16 if ($pages_hr->{'actual_page'} < $pages_hr->{'pages_num'}) {
193 1         6 $next = $pages_hr->{'actual_page'} + 1;
194             }
195             }
196            
197             $self->{'tags'}->put(
198             ['b', 'p'],
199             ['a', 'class', $self->_css_class('prev_next')],
200              
201             # Previous page.
202             $prev ? (
203             ['b', 'a'],
204             ['a', 'class', $self->_css_class('prev')],
205             ['a', 'href', $self->{'url_page_cb'}->($prev, $pages_hr)],
206             ['d', decode_utf8('←')],
207             ['e', 'a'],
208             ) : (
209             ['b', 'span'],
210             ['a', 'class', $self->_css_class('prev-disabled')],
211             ['d', decode_utf8('←')],
212             ['e', 'span'],
213             ),
214              
215             # Next page.
216             $next ? (
217             ['b', 'a'],
218             ['a', 'class', $self->_css_class('next')],
219 1 50       5 ['a', 'href', $self->{'url_page_cb'}->($next, $pages_hr)],
    50          
220             ['d', decode_utf8('→')],
221             ['e', 'a'],
222             ) : (
223             ['b', 'span'],
224             ['a', 'class', $self->_css_class('next-disabled')],
225             ['d', decode_utf8('→')],
226             ['e', 'span'],
227             ),
228              
229             ['e', 'p'],
230             );
231             }
232              
233 2         320 $self->{'tags'}->put(
234             ['e', 'div'],
235             );
236              
237 2         71 return;
238             }
239              
240             sub _process_css {
241 1     1   18 my $self = shift;
242              
243             $self->{'css'}->put(
244             ['s', '.'.$self->{'css_pager'}.' a'],
245             ['d', 'text-decoration', 'none'],
246             ['e'],
247              
248             ['s', '.'.$self->_css_class('paginator')],
249             ['d', 'display', 'flex'],
250             ['d', 'flex-wrap', 'wrap'],
251             ['d', 'justify-content', 'center'],
252             ['d', 'padding-left', '130px'],
253             ['d', 'padding-right', '130px'],
254             ['d', 'float', 'both'],
255             ['e'],
256              
257             ['s', '.'.$self->_css_class('prev_next')],
258             ['d', 'display', 'flex'],
259             ['e'],
260              
261             ['s', '.'.$self->_css_class('paginator').' a'],
262             ['s', '.'.$self->_css_class('paginator').' strong'],
263             ['s', '.'.$self->_css_class('paginator').' span'],
264             ['s', '.'.$self->_css_class('next')],
265             ['s', '.'.$self->_css_class('next-disabled')],
266             ['s', '.'.$self->_css_class('prev')],
267             ['s', '.'.$self->_css_class('prev-disabled')],
268             ['d', 'display', 'flex'],
269             ['d', 'height', '55px'],
270             ['d', 'width', '55px'],
271             ['d', 'justify-content', 'center'],
272             ['d', 'align-items', 'center'],
273             ['d', 'border', '1px solid '.$self->{'css_colors'}->{'border'}],
274             ['d', 'margin-left', '-1px'],
275             ['e'],
276              
277              
278             ['s', '.'.$self->_css_class('prev')],
279             ['s', '.'.$self->_css_class('next')],
280             ['d', 'display', 'inline-flex'],
281             ['d', 'align-items', 'center'],
282             ['d', 'justify-content', 'center'],
283             ['e'],
284              
285             ['s', '.'.$self->_css_class('paginator').' a:hover'],
286             ['s', '.'.$self->_css_class('prev_next').' a:hover'],
287             $self->_css_colors_optional('hover_color', 'color'),
288             $self->_css_colors_optional('hover_background', 'background-color'),
289             ['e'],
290              
291             ['s', '.'.$self->_css_class('paginator').' a'],
292             $self->_css_colors_optional('other_color', 'color'),
293             $self->_css_colors_optional('other_background', 'background-color'),
294             ['e'],
295              
296             ['s', '.'.$self->_css_class('paginator-selected')],
297             ['d', 'background-color', $self->{'css_colors'}->{'actual_background'}],
298 1         9 ['d', 'color', $self->{'css_colors'}->{'actual_color'}],
299             ['e'],
300             );
301              
302 1         1259 return;
303             }
304              
305             1;
306              
307             __END__