File Coverage

blib/lib/Tags/HTML/Image/Grid.pm
Criterion Covered Total %
statement 44 84 52.3
branch 2 26 7.6
condition 2 11 18.1
subroutine 10 13 76.9
pod 1 1 100.0
total 59 135 43.7


line stmt bran cond sub pod time code
1             package Tags::HTML::Image::Grid;
2              
3 3     3   84261 use base qw(Tags::HTML);
  3         22  
  3         1522  
4 3     3   82860 use strict;
  3         8  
  3         59  
5 3     3   15 use warnings;
  3         5  
  3         89  
6              
7 3     3   17 use Class::Utils qw(set_params split_params);
  3         7  
  3         126  
8 3     3   17 use Error::Pure qw(err);
  3         6  
  3         103  
9 3     3   17 use List::MoreUtils qw(none);
  3         6  
  3         15  
10 3     3   1928 use Scalar::Util qw(blessed);
  3         7  
  3         173  
11 3     3   1369 use Unicode::UTF8 qw(decode_utf8);
  3         1436  
  3         3316  
12              
13             our $VERSION = 0.02;
14              
15             # Constructor.
16             sub new {
17 5     5 1 5783 my ($class, @params) = @_;
18              
19             # Create object.
20 5         31 my ($object_params_ar, $other_params_ar) = split_params(
21             ['css_image_grid', 'img_link_cb', 'img_select_cb', 'img_src_cb',
22             'img_width', 'title'], @params);
23 5         118 my $self = $class->SUPER::new(@{$other_params_ar});
  5         23  
24              
25             # Form CSS style.
26 5         127 $self->{'css_image_grid'} = 'image-grid';
27              
28             # Image link callback.
29 5         10 $self->{'img_link_cb'} = undef;
30              
31             # Image select callback.
32 5         10 $self->{'img_select_cb'} = undef;
33              
34             # Image src callback across data object.
35 5         8 $self->{'img_src_cb'} = undef;
36              
37             # Image width in pixels.
38 5         25 $self->{'img_width'} = 340;
39              
40             # Image grid title.
41 5         8 $self->{'title'} = undef;
42              
43             # Process params.
44 5         9 set_params($self, @{$object_params_ar});
  5         27  
45              
46             # Check callback codes.
47 5         54 $self->_check_callback('img_link_cb');
48 4         9 $self->_check_callback('img_select_cb');
49 3         7 $self->_check_callback('img_src_cb');
50              
51             # Object.
52 2         12 return $self;
53             }
54              
55             sub _check_callback {
56 12     12   20 my ($self, $callback_key) = @_;
57              
58 12 100 66     39 if (defined $self->{$callback_key}
59             && ref $self->{$callback_key} ne 'CODE') {
60              
61 3         17 err "Parameter '$callback_key' must be a code.";
62             }
63              
64 9         16 return;
65             }
66              
67             sub _check_images {
68 0     0     my ($self, $images_ar) = @_;
69              
70 0           foreach my $image (@{$images_ar}) {
  0            
71 0 0 0       if (! blessed($image) && ! $image->isa('Data::Image')) {
72              
73 0           err 'Bad data image object.';
74             }
75             }
76              
77 0           return;
78             }
79              
80             # Process 'Tags'.
81             sub _process {
82 0     0     my ($self, $images_ar) = @_;
83              
84 0           $self->_check_images($images_ar);
85              
86             $self->{'tags'}->put(
87             ['b', 'div'],
88             ['a', 'class', $self->{'css_image_grid'}],
89              
90             ['b', 'div'],
91 0           ['a', 'class', $self->{'css_image_grid'}.'-inner'],
92             );
93 0 0         if (defined $self->{'title'}) {
94             $self->{'tags'}->put(
95             ['b', 'fieldset'],
96             ['b', 'legend'],
97 0           ['d', $self->{'title'}],
98             ['e', 'legend'],
99             );
100             }
101 0           foreach my $image (@{$images_ar}) {
  0            
102 0 0         if (defined $self->{'img_link_cb'}) {
103             $self->{'tags'}->put(
104             ['b', 'a'],
105 0           ['a', 'href', $self->{'img_link_cb'}->($image)],
106             );
107             }
108 0           $self->{'tags'}->put(
109             ['b', 'figure'],
110             );
111 0           my $image_url;
112 0 0         if (defined $image->url) {
    0          
    0          
113 0           $image_url = $image->url;
114             } elsif (defined $image->url_cb) {
115 0           $image_url = $image->url_cb->($image);
116             } elsif (defined $self->{'img_src_cb'}) {
117 0           $image_url = $self->{'img_src_cb'}->($image);
118             } else {
119 0           err 'No image URL.';
120             }
121              
122 0 0         if (defined $self->{'img_select_cb'}) {
123 0           my $select_hr = $self->{'img_select_cb'}->($self, $image);
124 0 0 0       if (ref $select_hr eq 'HASH' && exists $select_hr->{'value'}) {
125 0   0       $select_hr->{'css_background_color'} ||= 'lightgreen';
126             $self->{'tags'}->put(
127             ['b', 'i'],
128             ['a', 'class', 'selected'],
129             ['a', 'style', 'background-color: '.$select_hr->{'css_background_color'}.';'],
130             exists $select_hr->{'value'} ? (
131 0 0         ['d', $select_hr->{'value'}],
132             ) : (),
133             ['e', 'i'],
134             );
135             }
136             }
137              
138 0           $self->{'tags'}->put(
139             ['b', 'img'],
140             ['a', 'src', $image_url],
141             ['e', 'img'],
142             );
143 0 0         if ($image->comment) {
144 0           $self->{'tags'}->put(
145             ['b', 'figcaption'],
146             ['d', $image->comment],
147             ['e', 'figcaption'],
148             );
149             }
150 0           $self->{'tags'}->put(
151             ['e', 'figure'],
152             );
153 0 0         if (defined $self->{'img_link_cb'}) {
154 0           $self->{'tags'}->put(
155             ['e', 'a'],
156             );
157             }
158             }
159 0 0         if (defined $self->{'title'}) {
160 0           $self->{'tags'}->put(
161             ['e', 'fieldset'],
162             );
163             }
164 0           $self->{'tags'}->put(
165             ['e', 'div'],
166             ['e', 'div'],
167             );
168              
169 0           return;
170             }
171              
172             sub _process_css {
173 0     0     my $self = shift;
174              
175             $self->{'css'}->put(
176              
177             # Grid center on page.
178             ['s', '.'.$self->{'css_image_grid'}],
179             ['d', 'display', 'flex'],
180             ['d', 'align-items', 'center'],
181             ['d', 'justify-content', 'center'],
182             ['e'],
183              
184             # 4 columns in grid.
185             ['s', '.'.$self->{'css_image_grid'}.'-inner'],
186             ['d', 'display', 'grid'],
187             ['d', 'grid-gap', '1px'],
188             ['d', 'grid-template-columns', 'repeat(4, '.$self->{'img_width'}.'px)'],
189             ['e'],
190              
191             # Create rectangle.
192             ['s', '.'.$self->{'css_image_grid'}.' figure'],
193             ['d', 'object-fit', 'cover'],
194             ['d', 'width', $self->{'img_width'}.'px'],
195             ['d', 'height', $self->{'img_width'}.'px'],
196             ['d', 'position', 'relative'],
197             ['d', 'overflow', 'hidden'],
198             ['d', 'border', '1px solid white'],
199             ['d', 'margin', 0],
200             ['d', 'padding', 0],
201             ['e'],
202              
203             ['s', '.'.$self->{'css_image_grid'}.' img'],
204             ['d', 'object-fit', 'cover'],
205             ['d', 'width', '100%'],
206             ['d', 'height', '100%'],
207             ['d', 'vertical-align', 'middle'],
208             ['e'],
209              
210             ['s', '.'.$self->{'css_image_grid'}.' figcaption'],
211             ['d', 'margin', 0],
212             ['d', 'padding', '1em'],
213             ['d', 'position', 'absolute'],
214             ['d', 'z-index', 1],
215             ['d', 'bottom', 0],
216             ['d', 'left', 0],
217             ['d', 'width', '100%'],
218             ['d', 'max-height', '100%'],
219             ['d', 'overflow', 'auto'],
220             ['d', 'box-sizing', 'border-box'],
221             ['d', 'transition', 'transform 0.5s'],
222             ['d', 'transform', 'translateY(100%)'],
223             ['d', 'background', 'rgba(0, 0, 0, 0.7)'],
224             ['d', 'color', 'rgb(255, 255, 255)'],
225             ['e'],
226              
227             ['s', '.'.$self->{'css_image_grid'}.' figure:hover figcaption'],
228             ['d', 'transform', 'translateY(0%)'],
229             ['e'],
230              
231 0           ['s', '.'.$self->{'css_image_grid'}.' .selected'],
232             ['d', 'border', '1px solid black'],
233             ['d', 'border-radius', '0.5em'],
234             ['d', 'color', 'black'],
235             ['d', 'padding', '0.5em'],
236             ['d', 'position', 'absolute'],
237             ['d', 'right', '10px'],
238             ['d', 'top', '10px'],
239             ['e'],
240             );
241              
242 0           return;
243             }
244              
245             1;
246              
247             __END__