File Coverage

blib/lib/Tags/HTML/Page/Begin.pm
Criterion Covered Total %
statement 134 134 100.0
branch 54 54 100.0
condition 3 3 100.0
subroutine 13 13 100.0
pod 1 1 100.0
total 205 205 100.0


line stmt bran cond sub pod time code
1             package Tags::HTML::Page::Begin;
2              
3 4     4   141471 use base qw(Tags::HTML);
  4         31  
  4         2026  
4 4     4   29996 use strict;
  4         10  
  4         75  
5 4     4   21 use warnings;
  4         9  
  4         104  
6              
7 4     4   20 use Class::Utils qw(set_params split_params);
  4         18  
  4         174  
8 4     4   23 use Error::Pure qw(err);
  4         7  
  4         145  
9 4     4   2725 use List::MoreUtils qw(none);
  4         27312  
  4         25  
10 4     4   3725 use Readonly;
  4         10  
  4         5973  
11              
12             # Constants.
13             Readonly::Hash my %LANG => (
14             'title' => 'Page title',
15             );
16              
17             our $VERSION = 0.16;
18              
19             # Constructor.
20             sub new {
21 34     34 1 93781 my ($class, @params) = @_;
22              
23             # Create object.
24 34         218 my ($object_params_ar, $other_params_ar) = split_params(
25             ['application-name', 'author', 'base_href', 'base_target',
26             'css_init', 'css_src', 'charset', 'description', 'doctype',
27             'favicon', 'generator', 'html_lang', 'http_equiv_content_type',
28             'keywords', 'lang', 'refresh', 'robots', 'rss',
29             'script_js', 'script_js_src', 'viewport'], @params);
30 34         2509 my $self = $class->SUPER::new(@{$other_params_ar});
  34         119  
31              
32             # Application name.
33 32         1053 $self->{'application-name'} = undef;
34              
35             # Author.
36 32         52 $self->{'author'} = undef;
37              
38             # Base element.
39 32         59 $self->{'base_href'} = undef;
40 32         46 $self->{'base_target'} = undef;
41              
42             # Init CSS style.
43 32         164 $self->{'css_init'} = [
44             ['s', '*'],
45             ['d', 'box-sizing', 'border-box'],
46             ['d', 'margin', 0],
47             ['d', 'padding', 0],
48             ['e'],
49             ];
50              
51             # CSS links.
52 32         64 $self->{'css_src'} = [];
53              
54             # Charset.
55 32         58 $self->{'charset'} = 'UTF-8';
56              
57             # Description.
58 32         46 $self->{'description'} = undef;
59              
60             # Doctype.
61 32         58 $self->{'doctype'} = '';
62              
63             # Favicon.
64 32         86 $self->{'favicon'} = undef;
65              
66             # Generator.
67 32         199 $self->{'generator'} = 'Perl module: '.__PACKAGE__.', Version: '.$VERSION;
68              
69             # HTML element lang attribute.
70 32         59 $self->{'html_lang'} = 'en';
71              
72             # http-equiv content-type.
73 32         78 $self->{'http_equiv_content_type'} = 'text/html';
74              
75             # Keywords.
76 32         57 $self->{'keywords'} = undef;
77              
78             # Languages.
79 32         54 $self->{'lang'} = \%LANG;
80              
81             # Refresh.
82 32         59 $self->{'refresh'} = undef;
83              
84             # Robots.
85 32         43 $self->{'robots'} = undef;
86              
87             # RSS
88 32         53 $self->{'rss'} = undef;
89              
90             # Script js code.
91 32         55 $self->{'script_js'} = [];
92              
93             # Script js sources.
94 32         54 $self->{'script_js_src'} = [];
95              
96             # Viewport.
97 32         56 $self->{'viewport'} = 'width=device-width, initial-scale=1.0';
98              
99             # Process params.
100 32         46 set_params($self, @{$object_params_ar});
  32         93  
101              
102             # Check for 'css_src' array.
103 32 100       517 if (ref $self->{'css_src'} ne 'ARRAY') {
104 1         3 err "Parameter 'css_src' must be a array.";
105             }
106 31         47 foreach my $css_src_hr (@{$self->{'css_src'}}) {
  31         81  
107 4 100       16 if (ref $css_src_hr ne 'HASH') {
108 1         4 err "Parameter 'css_src' must be a array of hash structures.";
109             }
110 3         23 foreach my $key (keys %{$css_src_hr}) {
  3         15  
111 4 100   6   29 if (none { $key eq $_ } qw(link media)) {
  6         22  
112 1         6 err "Parameter 'css_src' must be a array of hash ".
113             "structures with 'media' and 'link' keys."
114             }
115             }
116             }
117              
118             # Check charset.
119 29 100       73 if (! defined $self->{'charset'}) {
120 1         5 err "Parameter 'charset' is required.";
121             }
122              
123             # Check for 'script_js' array.
124 28 100       76 if (ref $self->{'script_js'} ne 'ARRAY') {
125 2         10 err "Parameter 'script_js' must be a array.";
126             }
127              
128             # Check for 'script_js_src' array.
129 26 100       64 if (ref $self->{'script_js_src'} ne 'ARRAY') {
130 2         5 err "Parameter 'script_js_src' must be a array.";
131             }
132              
133             # Check for favicon.
134 24 100 100     109 if (defined $self->{'favicon'} && $self->{'favicon'} !~ m/\.(ico|png|jpg|gif|svg)$/ms) {
135 1         5 err "Parameter 'favicon' contain bad image type.";
136             }
137              
138             # Object.
139 23         197 return $self;
140             }
141              
142             # Process 'Tags'.
143             sub _process {
144 20     20   304 my $self = shift;
145              
146 20         30 my $css;
147 20 100       47 if ($self->{'css'}) {
148 2         29 $css = $self->{'css'}->flush(1);
149 2 100       80 if ($css ne '') {
150 1         3 $css .= "\n";
151             } else {
152 1         3 undef $css;
153             }
154             }
155              
156             # Begin of page.
157             $self->{'tags'}->put(
158             ['r', $self->{'doctype'}],
159             ['r', "\n"],
160             ['b', 'html'],
161 20         113 ['a', 'lang', $self->{'html_lang'}],
162             ['b', 'head'],
163             );
164              
165 20 100       2730 if (defined $self->{'http_equiv_content_type'}) {
166             $self->{'tags'}->put(
167             ['b', 'meta'],
168             ['a', 'http-equiv', 'Content-Type'],
169             ['a', 'content', $self->{'http_equiv_content_type'}.
170 19         108 '; charset='.$self->{'charset'}],
171             ['e', 'meta'],
172             );
173             }
174 20 100       2164 if (defined $self->{'base_href'}) {
175             $self->{'tags'}->put(
176             ['b', 'base'],
177             ['a', 'href', $self->{'base_href'}],
178             defined $self->{'base_target'} ? (
179 2 100       14 ['a', 'target', $self->{'base_target'}],
180             ) : (),
181             ['e', 'base'],
182             );
183             }
184 20 100       236 if (! defined $self->{'http_equiv_content_type'}) {
185             $self->{'tags'}->put(
186             ['b', 'meta'],
187 1         6 ['a', 'charset', $self->{'charset'}],
188             ['e', 'meta'],
189             );
190             }
191 20         138 $self->_meta('application-name');
192 20         42 $self->_meta('author');
193 20         41 $self->_meta('description');
194 20         43 $self->_meta('generator');
195 20         45 $self->_meta('keywords');
196 20         44 $self->_meta('robots');
197 20         40 $self->_meta('viewport');
198 20 100       45 if (defined $self->{'refresh'}) {
199             $self->{'tags'}->put(
200             ['b', 'meta'],
201             ['a', 'http-equiv', 'refresh'],
202 1         5 ['a', 'content', $self->{'refresh'}],
203             ['e', 'meta'],
204             );
205             }
206              
207 20         157 $self->_favicon;
208              
209 20 100       26 if (@{$self->{'script_js'}}) {
  20         44  
210 1         3 foreach my $script_js (@{$self->{'script_js'}}) {
  1         4  
211 2         111 $self->{'tags'}->put(
212             ['b', 'script'],
213             ['a', 'type', 'text/javascript'],
214             ['d', $script_js],
215             ['e', 'script'],
216             );
217             }
218             }
219 20 100       169 if (@{$self->{'script_js_src'}}) {
  20         43  
220 1         3 foreach my $script_js_src (@{$self->{'script_js_src'}}) {
  1         4  
221 2         118 $self->{'tags'}->put(
222             ['b', 'script'],
223             ['a', 'type', 'text/javascript'],
224             ['a', 'src', $script_js_src],
225             ['e', 'script'],
226             );
227             }
228             }
229              
230             $self->{'tags'}->put(
231             defined $self->{'lang'}->{'title'} ? (
232             ['b', 'title'],
233 20 100       219 ['d', $self->{'lang'}->{'title'}],
    100          
234             ['e', 'title'],
235             ) : (),
236              
237             (
238             defined $css ? (
239             ['b', 'style'],
240             ['a', 'type', 'text/css'],
241             ['d', $css],
242             ['e', 'style'],
243             ) : (),
244             ),
245             );
246 20 100       2037 if (@{$self->{'css_src'}}) {
  20         49  
247 1         9 foreach my $css_src_hr (@{$self->{'css_src'}}) {
  1         5  
248             $self->{'tags'}->put(
249             ['b', 'link'],
250             ['a', 'rel', 'stylesheet'],
251             ['a', 'href', $css_src_hr->{'link'}],
252             $css_src_hr->{'media'} ? (
253 2 100       151 ['a', 'media', $css_src_hr->{'media'}],
254             ) : (),
255             ['a', 'type', 'text/css'],
256             ['e', 'link'],
257             );
258             }
259             }
260              
261 20 100       194 if (defined $self->{'rss'}) {
262             $self->{'tags'}->put(
263             ['b', 'link'],
264             ['a', 'rel', 'alternate'],
265             ['a', 'type', 'application/rss+xml'],
266             ['a', 'title', 'RSS'],
267 1         9 ['a', 'href', $self->{'rss'}],
268             ['e', 'link'],
269             );
270             }
271              
272 20         220 $self->{'tags'}->put(
273             ['e', 'head'],
274             ['b', 'body'],
275             );
276              
277 20         1246 return;
278             }
279              
280             sub _process_css {
281 1     1   20 my $self = shift;
282              
283             $self->{'css'}->put(
284 1         2 @{$self->{'css_init'}},
  1         7  
285             );
286              
287 1         243 return;
288             }
289              
290             sub _favicon {
291 20     20   32 my $self = shift;
292              
293 20 100       40 if (! defined $self->{'favicon'}) {
294 15         24 return;
295             }
296              
297 5         33 my ($suffix) = $self->{'favicon'} =~ m/\.(ico|png|jpg|gif|svg)$/ms;
298 5         11 my $image_type;
299 5 100       37 if ($suffix eq 'ico') {
    100          
    100          
    100          
300 1         6 $image_type = 'image/vnd.microsoft.icon';
301             } elsif ($suffix eq 'png') {
302 1         3 $image_type = 'image/png';
303             } elsif ($suffix eq 'svg') {
304 1         3 $image_type = 'image/svg+xml';
305             } elsif ($suffix eq 'gif') {
306 1         3 $image_type = 'image/gif';
307             } else {
308 1         10 $image_type = 'image/jpeg';
309             }
310              
311             $self->{'tags'}->put(
312             ['b', 'link'],
313             ['a', 'rel', 'icon'],
314 5         28 ['a', 'href', $self->{'favicon'}],
315             ['a', 'type', $image_type],
316             ['e', 'link'],
317             );
318              
319 5         666 return;
320             }
321              
322             sub _meta {
323 140     140   218 my ($self, $key) = @_;
324              
325 140 100       289 if (! defined $self->{$key}) {
326 121         177 return;
327             }
328              
329             $self->{'tags'}->put(
330             ['b', 'meta'],
331             ['a', 'name', $key],
332 19         84 ['a', 'content', $self->{$key}],
333             ['e', 'meta'],
334             );
335              
336 19         2155 return;
337             }
338              
339             1;
340              
341             __END__