| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Tags::HTML::Image::Grid; |
|
2
|
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
80514
|
use base qw(Tags::HTML); |
|
|
3
|
|
|
|
|
16
|
|
|
|
3
|
|
|
|
|
1433
|
|
|
4
|
3
|
|
|
3
|
|
72720
|
use strict; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
59
|
|
|
5
|
3
|
|
|
3
|
|
15
|
use warnings; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
82
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
3
|
|
|
3
|
|
15
|
use Class::Utils qw(set_params split_params); |
|
|
3
|
|
|
|
|
3
|
|
|
|
3
|
|
|
|
|
139
|
|
|
8
|
3
|
|
|
3
|
|
14
|
use Error::Pure qw(err); |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
88
|
|
|
9
|
3
|
|
|
3
|
|
14
|
use List::MoreUtils qw(none); |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
13
|
|
|
10
|
3
|
|
|
3
|
|
1660
|
use Scalar::Util qw(blessed); |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
122
|
|
|
11
|
3
|
|
|
3
|
|
1462
|
use Unicode::UTF8 qw(decode_utf8); |
|
|
3
|
|
|
|
|
1366
|
|
|
|
3
|
|
|
|
|
2860
|
|
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our $VERSION = 0.01; |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# Constructor. |
|
16
|
|
|
|
|
|
|
sub new { |
|
17
|
5
|
|
|
5
|
1
|
4919
|
my ($class, @params) = @_; |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# Create object. |
|
20
|
5
|
|
|
|
|
24
|
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
|
|
|
|
|
103
|
my $self = $class->SUPER::new(@{$other_params_ar}); |
|
|
5
|
|
|
|
|
18
|
|
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# Form CSS style. |
|
26
|
5
|
|
|
|
|
102
|
$self->{'css_image_grid'} = 'image-grid'; |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# Image link callback. |
|
29
|
5
|
|
|
|
|
9
|
$self->{'img_link_cb'} = undef; |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# Image select callback. |
|
32
|
5
|
|
|
|
|
8
|
$self->{'img_select_cb'} = undef; |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# Image src callback across data object. |
|
35
|
5
|
|
|
|
|
7
|
$self->{'img_src_cb'} = undef; |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# Image width in pixels. |
|
38
|
5
|
|
|
|
|
11
|
$self->{'img_width'} = 340; |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# Image grid title. |
|
41
|
5
|
|
|
|
|
7
|
$self->{'title'} = undef; |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# Process params. |
|
44
|
5
|
|
|
|
|
6
|
set_params($self, @{$object_params_ar}); |
|
|
5
|
|
|
|
|
26
|
|
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# Check callback codes. |
|
47
|
5
|
|
|
|
|
42
|
$self->_check_callback('img_link_cb'); |
|
48
|
4
|
|
|
|
|
6
|
$self->_check_callback('img_select_cb'); |
|
49
|
3
|
|
|
|
|
7
|
$self->_check_callback('img_src_cb'); |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# Object. |
|
52
|
2
|
|
|
|
|
9
|
return $self; |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub _check_callback { |
|
56
|
12
|
|
|
12
|
|
18
|
my ($self, $callback_key) = @_; |
|
57
|
|
|
|
|
|
|
|
|
58
|
12
|
100
|
66
|
|
|
34
|
if (defined $self->{$callback_key} |
|
59
|
|
|
|
|
|
|
&& ref $self->{$callback_key} ne 'CODE') { |
|
60
|
|
|
|
|
|
|
|
|
61
|
3
|
|
|
|
|
12
|
err "Parameter '$callback_key' must be a code."; |
|
62
|
|
|
|
|
|
|
} |
|
63
|
|
|
|
|
|
|
|
|
64
|
9
|
|
|
|
|
12
|
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' && $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__ |