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   307161 use base qw(Tags::HTML);
  4         54  
  4         2621  
4 4     4   43199 use strict;
  4         9  
  4         112  
5 4     4   2112 use warnings;
  4         9  
  4         343  
6              
7 4     4   30 use Class::Utils qw(set_params split_params);
  4         12  
  4         1769  
8 4     4   77 use Error::Pure qw(err);
  4         11  
  4         244  
9 4     4   28 use List::Util 1.33 qw(none);
  4         96  
  4         336  
10 4     4   26 use Readonly;
  4         8  
  4         9172  
11              
12             # Constants.
13             Readonly::Hash my %LANG => (
14             'title' => 'Page title',
15             );
16              
17             our $VERSION = 0.17;
18              
19             # Constructor.
20             sub new {
21 34     34 1 1029405 my ($class, @params) = @_;
22              
23             # Create object.
24 34         297 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         3601 my $self = $class->SUPER::new(@{$other_params_ar});
  34         181  
31              
32             # Application name.
33 32         1596 $self->{'application-name'} = undef;
34              
35             # Author.
36 32         77 $self->{'author'} = undef;
37              
38             # Base element.
39 32         66 $self->{'base_href'} = undef;
40 32         75 $self->{'base_target'} = undef;
41              
42             # Init CSS style.
43 32         196 $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         89 $self->{'css_src'} = [];
53              
54             # Charset.
55 32         71 $self->{'charset'} = 'UTF-8';
56              
57             # Description.
58 32         101 $self->{'description'} = undef;
59              
60             # Doctype.
61 32         70 $self->{'doctype'} = '';
62              
63             # Favicon.
64 32         69 $self->{'favicon'} = undef;
65              
66             # Generator.
67 32         233 $self->{'generator'} = 'Perl module: '.__PACKAGE__.', Version: '.$VERSION;
68              
69             # HTML element lang attribute.
70 32         80 $self->{'html_lang'} = 'en';
71              
72             # http-equiv content-type.
73 32         73 $self->{'http_equiv_content_type'} = 'text/html';
74              
75             # Keywords.
76 32         59 $self->{'keywords'} = undef;
77              
78             # Languages.
79 32         85 $self->{'lang'} = \%LANG;
80              
81             # Refresh.
82 32         65 $self->{'refresh'} = undef;
83              
84             # Robots.
85 32         95 $self->{'robots'} = undef;
86              
87             # RSS
88 32         95 $self->{'rss'} = undef;
89              
90             # Script js code.
91 32         73 $self->{'script_js'} = [];
92              
93             # Script js sources.
94 32         67 $self->{'script_js_src'} = [];
95              
96             # Viewport.
97 32         96 $self->{'viewport'} = 'width=device-width, initial-scale=1.0';
98              
99             # Process params.
100 32         69 set_params($self, @{$object_params_ar});
  32         124  
101              
102             # Check for 'css_src' array.
103 32 100       659 if (ref $self->{'css_src'} ne 'ARRAY') {
104 1         5 err "Parameter 'css_src' must be a array.";
105             }
106 31         61 foreach my $css_src_hr (@{$self->{'css_src'}}) {
  31         97  
107 4 100       16 if (ref $css_src_hr ne 'HASH') {
108 1         3 err "Parameter 'css_src' must be a array of hash structures.";
109             }
110 3         8 foreach my $key (keys %{$css_src_hr}) {
  3         11  
111 4 100   6   25 if (none { $key eq $_ } qw(link media)) {
  6         21  
112 1         5 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       102 if (! defined $self->{'charset'}) {
120 1         5 err "Parameter 'charset' is required.";
121             }
122              
123             # Check for 'script_js' array.
124 28 100       98 if (ref $self->{'script_js'} ne 'ARRAY') {
125 2         8 err "Parameter 'script_js' must be a array.";
126             }
127              
128             # Check for 'script_js_src' array.
129 26 100       88 if (ref $self->{'script_js_src'} ne 'ARRAY') {
130 2         8 err "Parameter 'script_js_src' must be a array.";
131             }
132              
133             # Check for favicon.
134 24 100 100     151 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         277 return $self;
140             }
141              
142             # Process 'Tags'.
143             sub _process {
144 20     20   410 my $self = shift;
145              
146 20         39 my $css;
147 20 100       58 if ($self->{'css'}) {
148 2         15 $css = $self->{'css'}->flush(1);
149 2 100       89 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         158 ['a', 'lang', $self->{'html_lang'}],
162             ['b', 'head'],
163             );
164              
165 20 100       3509 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         132 '; charset='.$self->{'charset'}],
171             ['e', 'meta'],
172             );
173             }
174 20 100       2900 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       18 ['a', 'target', $self->{'base_target'}],
180             ) : (),
181             ['e', 'base'],
182             );
183             }
184 20 100       358 if (! defined $self->{'http_equiv_content_type'}) {
185             $self->{'tags'}->put(
186             ['b', 'meta'],
187 1         7 ['a', 'charset', $self->{'charset'}],
188             ['e', 'meta'],
189             );
190             }
191 20         178 $self->_meta('application-name');
192 20         92 $self->_meta('author');
193 20         49 $self->_meta('description');
194 20         54 $self->_meta('generator');
195 20         59 $self->_meta('keywords');
196 20         52 $self->_meta('robots');
197 20         57 $self->_meta('viewport');
198 20 100       54 if (defined $self->{'refresh'}) {
199             $self->{'tags'}->put(
200             ['b', 'meta'],
201             ['a', 'http-equiv', 'refresh'],
202 1         7 ['a', 'content', $self->{'refresh'}],
203             ['e', 'meta'],
204             );
205             }
206              
207 20         208 $self->_favicon;
208              
209 20 100       33 if (@{$self->{'script_js'}}) {
  20         72  
210 1         3 foreach my $script_js (@{$self->{'script_js'}}) {
  1         4  
211 2         141 $self->{'tags'}->put(
212             ['b', 'script'],
213             ['a', 'type', 'text/javascript'],
214             ['d', $script_js],
215             ['e', 'script'],
216             );
217             }
218             }
219 20 100       159 if (@{$self->{'script_js_src'}}) {
  20         58  
220 1         3 foreach my $script_js_src (@{$self->{'script_js_src'}}) {
  1         4  
221 2         147 $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       355 ['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       2605 if (@{$self->{'css_src'}}) {
  20         71  
247 1         3 foreach my $css_src_hr (@{$self->{'css_src'}}) {
  1         4  
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       235 ['a', 'media', $css_src_hr->{'media'}],
254             ) : (),
255             ['a', 'type', 'text/css'],
256             ['e', 'link'],
257             );
258             }
259             }
260              
261 20 100       283 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         8 ['a', 'href', $self->{'rss'}],
268             ['e', 'link'],
269             );
270             }
271              
272 20         295 $self->{'tags'}->put(
273             ['e', 'head'],
274             ['b', 'body'],
275             );
276              
277 20         1593 return;
278             }
279              
280             sub _process_css {
281 1     1   20 my $self = shift;
282              
283             $self->{'css'}->put(
284 1         3 @{$self->{'css_init'}},
  1         9  
285             );
286              
287 1         246 return;
288             }
289              
290             sub _favicon {
291 20     20   39 my $self = shift;
292              
293 20 100       53 if (! defined $self->{'favicon'}) {
294 15         31 return;
295             }
296              
297 5         32 my ($suffix) = $self->{'favicon'} =~ m/\.(ico|png|jpg|gif|svg)$/ms;
298 5         12 my $image_type;
299 5 100       31 if ($suffix eq 'ico') {
    100          
    100          
    100          
300 1         3 $image_type = 'image/vnd.microsoft.icon';
301             } elsif ($suffix eq 'png') {
302 1         2 $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         3 $image_type = 'image/jpeg';
309             }
310              
311             $self->{'tags'}->put(
312             ['b', 'link'],
313             ['a', 'rel', 'icon'],
314 5         77 ['a', 'href', $self->{'favicon'}],
315             ['a', 'type', $image_type],
316             ['e', 'link'],
317             );
318              
319 5         904 return;
320             }
321              
322             sub _meta {
323 140     140   281 my ($self, $key) = @_;
324              
325 140 100       385 if (! defined $self->{$key}) {
326 121         218 return;
327             }
328              
329             $self->{'tags'}->put(
330             ['b', 'meta'],
331             ['a', 'name', $key],
332 19         121 ['a', 'content', $self->{$key}],
333             ['e', 'meta'],
334             );
335              
336 19         2761 return;
337             }
338              
339             1;
340              
341             __END__