File Coverage

blib/lib/HTML/FormFu/Role/Element/Layout.pm
Criterion Covered Total %
statement 115 120 95.8
branch 41 54 75.9
condition 23 43 53.4
subroutine 22 22 100.0
pod 0 3 0.0
total 201 242 83.0


line stmt bran cond sub pod time code
1 384     384   381668 use strict;
  384         1196  
  384         22696  
2              
3             package HTML::FormFu::Role::Element::Layout;
4             # ABSTRACT: layout role
5             $HTML::FormFu::Role::Element::Layout::VERSION = '2.07';
6 384     384   2500 use Moose::Role;
  384         1290  
  384         3287  
7 384     384   2099694 use MooseX::Attribute::Chained;
  384         1038  
  384         12936  
8              
9 384     384   2294 use Carp qw( carp croak );
  384         885  
  384         25705  
10 384     384   2787 use List::MoreUtils qw( first_index );
  384         973  
  384         5967  
11 384     384   281033 use Scalar::Util qw( reftype );
  384         931  
  384         21401  
12              
13 384     384   2838 use HTML::FormFu::Util qw( process_attrs );
  384         1012  
  384         659914  
14              
15             has layout_errors_filename =>
16             ( is => 'rw', traits => ['Chained'], default => 'field_layout_errors' );
17             has layout_label_filename =>
18             ( is => 'rw', traits => ['Chained'], default => 'field_layout_label' );
19             has layout_field_filename =>
20             ( is => 'rw', traits => ['Chained'], default => 'field_layout_field' );
21             has layout_comment_filename =>
22             ( is => 'rw', traits => ['Chained'], default => 'field_layout_comment' );
23             has layout_javascript_filename =>
24             ( is => 'rw', traits => ['Chained'], default => 'field_layout_javascript' );
25             has layout_label_text_filename =>
26             ( is => 'rw', traits => ['Chained'], default => 'field_layout_label_text' );
27             has layout_block_filename =>
28             ( is => 'rw', traits => ['Chained'], default => 'field_layout_block' );
29              
30             has layout_parser_filename =>
31             ( is => 'rw', traits => ['Chained'], default => 'field_layout_parser' );
32              
33             has _layout => (
34             is => 'rw',
35             default => sub {
36             return [ 'errors', 'label', 'field', 'comment', 'javascript', ];
37             },
38             );
39              
40             # if we ever remove the reverse_single() method, we can make layout()
41             # a standard Moose attribute
42              
43             sub layout {
44 2193     2193 0 5046 my $self = shift;
45              
46 2193 100       5586 if (@_) {
47 128         4176 $self->_layout(@_);
48 128         308 return $self;
49             }
50              
51 2065         65273 my $value = $self->_layout;
52              
53 2065 100 66     63776 if ( defined $value && $self->reverse_single ) {
54              
55             # if it's an array-ref,
56             # and 'label' and 'field' are consecutive values (in any order)
57             # then just swap them around
58             # otherwise warn that reverse_single() is deprecated
59              
60 4         13 my ( $ok, $field_index, $label_index );
61              
62 4 50 33     47 if ( ref $value && 'ARRAY' eq reftype($value) ) {
63 4     12   47 $field_index = first_index { 'field' eq $_ } @$value;
  12         34  
64 4     8   25 $label_index = first_index { 'label' eq $_ } @$value;
  8         18  
65              
66 4 50 33     34 if ( defined $field_index
      33        
67             && defined $label_index
68             && 1 == abs( $field_index - $label_index ) )
69             {
70 4         9 $ok = 1;
71             }
72             }
73              
74 4 50       17 if ($ok) {
75              
76             # create new arrayref so we don't change the stored value
77 4         19 $value = [@$value];
78              
79 4         14 @$value[$field_index] = 'label';
80 4         10 @$value[$label_index] = 'field';
81             }
82             else {
83 0         0 carp "reverse_single() is deprecated, and is having no affect.";
84             }
85             }
86              
87 2065         6478 return $value;
88             }
89              
90             has _multi_layout => (
91             is => 'rw',
92             default => sub {
93             return [ 'label', 'field', ];
94             },
95             );
96              
97             # if we ever remove the reverse_multi() method, we can make multi_layout()
98             # a standard Moose attribute
99              
100             sub multi_layout {
101 1638     1638 0 3469 my $self = shift;
102              
103 1638 100       4395 if (@_) {
104 96         3531 $self->_multi_layout(@_);
105 96         223 return $self;
106             }
107              
108 1542         48551 my $value = $self->_multi_layout;
109              
110 1542 100 66     48059 if ( defined $value && $self->reverse_multi ) {
111              
112             # if it's an array-ref,
113             # and 'label' and 'field' are consecutive values (in any order)
114             # then just swap them around
115             # otherwise warn that reverse_multi() is deprecated
116              
117 7         14 my ( $ok, $field_index, $label_index );
118              
119 7 50 33     36 if ( ref $value && 'ARRAY' eq reftype($value) ) {
120 7     14   43 $field_index = first_index { 'field' eq $_ } @$value;
  14         28  
121 7     7   36 $label_index = first_index { 'label' eq $_ } @$value;
  7         13  
122              
123 7 50 33     53 if ( defined $field_index
      33        
124             && defined $label_index
125             && 1 == abs( $field_index - $label_index ) )
126             {
127 7         13 $ok = 1;
128             }
129             }
130              
131 7 50       16 if ($ok) {
132              
133             # create new arrayref so we don't change the stored value
134 7         17 $value = [@$value];
135              
136 7         16 @$value[$field_index] = 'label';
137 7         13 @$value[$label_index] = 'field';
138             }
139             else {
140 0         0 carp "reverse_multi() is deprecated, and is having no affect.";
141             }
142             }
143              
144 1542         44355 return $value;
145             }
146              
147             after BUILD => sub {
148             my $self = shift;
149              
150             $self->filename('field_layout');
151              
152             return;
153             };
154              
155             around render_data_non_recursive => sub {
156             my ( $orig, $self, $args ) = @_;
157              
158             my $render = $self->$orig(
159             { layout => $self->layout,
160             multi_layout => $self->multi_layout,
161             layout_errors_filename => $self->layout_errors_filename,
162             layout_label_filename => $self->layout_label_filename,
163             layout_field_filename => $self->layout_field_filename,
164             layout_comment_filename => $self->layout_comment_filename,
165             layout_javascript_filename => $self->layout_javascript_filename,
166             layout_label_text_filename => $self->layout_label_text_filename,
167             layout_block_filename => $self->layout_block_filename,
168             layout_parser_filename => $self->layout_parser_filename,
169             $args ? %$args : (),
170             } );
171              
172             return $render;
173             };
174              
175             sub string {
176 957     957 0 2740 my ( $self, $args ) = @_;
177              
178 957   100     6152 $args ||= {};
179              
180             my $render
181             = exists $args->{render_data}
182             ? $args->{render_data}
183 957 100       5189 : $self->render_data;
184              
185             my $layout
186             = exists $args->{layout}
187             ? $args->{layout}
188 957 100       3988 : $self->layout;
189              
190 957         1950 my $html = "";
191              
192 957 100       2781 if ( defined $render->{container_tag} ) {
193             $html .= sprintf "<%s%s>\n",
194             $render->{container_tag},
195 709         3166 process_attrs( $render->{container_attributes} );
196             }
197              
198 957         3914 $html .= $self->_parse_layout( $render, $layout );
199              
200 957 100       3036 if ( defined $render->{container_tag} ) {
201 709         2504 $html .= sprintf "\n</%s>", $render->{container_tag},;
202             }
203              
204 957         19654 return $html;
205             }
206              
207             sub _parse_layout {
208 4969     4969   9690 my ( $self, $render, $layout ) = @_;
209              
210 4969 50       10230 croak "undefined 'layout'" if !defined $layout;
211              
212 4969         8039 my $html = "";
213              
214 4969 100 100     28582 if ( ref $layout && 'ARRAY' eq ref $layout ) {
    100 66        
    50          
215 959         1767 my @item_html;
216 959         2557 for my $item (@$layout) {
217 4007         10117 push @item_html, $self->_parse_layout( $render, $item );
218             }
219             $html .=
220             join "\n",
221 959 50       2804 grep { defined && length } @item_html;
  4007         15309  
222             }
223             elsif ( ref $layout && 'HASH' eq ref $layout ) {
224 5         15 my ( $key, $value ) = %$layout;
225              
226 5 100       29 if ( my $method = $self->can("_parse_layout_$key") ) {
227 2         7 $html .= $self->$method( $render, $key, $value );
228             }
229             else {
230 3         11 $html .= $self->_parse_layout_block( $render, $key, $value );
231             }
232             }
233             elsif ( my $method = $self->can("_parse_layout_$layout") ) {
234 4005         9556 $html .= $self->$method($render);
235             }
236             else {
237 0         0 croak "Unknown layout() option: '$layout'";
238             }
239              
240 4969         14789 return $html;
241             }
242              
243             sub _parse_layout_errors {
244 707     707   1669 my ( $self, $render ) = @_;
245              
246 707         3037 return $self->_string_errors($render);
247             }
248              
249             sub _parse_layout_label {
250 927     927   2304 my $self = shift;
251 927         1802 my $render = shift;
252              
253             return ""
254             unless exists $render->{label}
255             && defined $render->{label}
256 927 100 66     6408 && length $render->{label};
      66        
257              
258 91 100       307 if (@_) {
259 2         5 my ( $tag, @content ) = @_;
260              
261             return $self->_parse_layout_block(
262             $render, $tag,
263             { attributes => $render->{label_attributes},
264 2         12 content => \@content,
265             },
266             );
267             }
268             else {
269 89         409 return $self->_string_label($render);
270             }
271             }
272              
273             sub _parse_layout_field {
274 884     884   2029 my ( $self, $render ) = @_;
275              
276 884         3656 return $self->_string_field($render);
277             }
278              
279             sub _parse_layout_comment {
280 707     707   1612 my ( $self, $render ) = @_;
281              
282 707 100       3348 return "" if !defined $render->{comment};
283              
284             my $html = sprintf "<%s%s>\n%s\n</%s>",
285             'span',
286             process_attrs( $render->{comment_attributes} ),
287             $render->{comment},
288 30         138 'span';
289              
290 30         90 return $html;
291             }
292              
293             sub _parse_layout_javascript {
294 707     707   1975 my ( $self, $render ) = @_;
295              
296 707 50       2699 return "" if !defined $render->{javascript};
297              
298             my $html = sprintf qq{<script type="text/javascript">\n%s\n</script>},
299 0         0 $render->{javascript};
300              
301 0         0 return $html;
302             }
303              
304             sub _parse_layout_label_text {
305 2     2   6 my ( $self, $render ) = @_;
306              
307 2 50 33     12 return "" unless exists $render->{label} && length $render->{label};
308              
309 2         5 return $render->{label};
310             }
311              
312             sub _parse_layout_block {
313 5     5   11 my ( $self, $render, $tag, $opts ) = @_;
314              
315 5   50     13 $opts ||= {};
316              
317 5         10 my $html = "<$tag";
318              
319 5 50       11 if ( $opts->{attributes} ) {
320 5         14 $html .= process_attrs( $opts->{attributes} );
321             }
322              
323 5         11 $html .= ">\n";
324              
325 5 50       13 if ( $opts->{content} ) {
326 5         12 $html .= $self->_parse_layout( $render, $opts->{content} );
327             }
328              
329 5         21 $html .= "\n</$tag>";
330              
331 5         17 return $html;
332             }
333              
334             1;
335              
336             __END__
337              
338             =pod
339              
340             =encoding UTF-8
341              
342             =head1 NAME
343              
344             HTML::FormFu::Role::Element::Layout - layout role
345              
346             =head1 VERSION
347              
348             version 2.07
349              
350             =head1 AUTHOR
351              
352             Carl Franks <cpan@fireartist.com>
353              
354             =head1 COPYRIGHT AND LICENSE
355              
356             This software is copyright (c) 2018 by Carl Franks.
357              
358             This is free software; you can redistribute it and/or modify it under
359             the same terms as the Perl 5 programming language system itself.
360              
361             =cut