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__ |