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             package HTML::FormFu::Role::Element::Layout;
2              
3 383     383   278911 use strict;
  383         616  
  383         16083  
4             our $VERSION = '2.05'; # VERSION
5              
6 383     383   1566 use Moose::Role;
  383         509  
  383         2549  
7 383     383   1326950 use MooseX::Attribute::FormFuChained;
  383         615  
  383         9299  
8              
9 383     383   1326 use Carp qw( carp croak );
  383         503  
  383         19675  
10 383     383   1623 use List::MoreUtils qw( first_index );
  383         522  
  383         4735  
11 383     383   128768 use Scalar::Util qw( reftype );
  383         555  
  383         16183  
12              
13 383     383   1510 use HTML::FormFu::Util qw( process_attrs );
  383         518  
  383         469840  
14              
15             has layout_errors_filename => ( is => 'rw', traits => ['FormFuChained'], default => 'field_layout_errors' );
16             has layout_label_filename => ( is => 'rw', traits => ['FormFuChained'], default => 'field_layout_label' );
17             has layout_field_filename => ( is => 'rw', traits => ['FormFuChained'], default => 'field_layout_field' );
18             has layout_comment_filename => ( is => 'rw', traits => ['FormFuChained'], default => 'field_layout_comment' );
19             has layout_javascript_filename => ( is => 'rw', traits => ['FormFuChained'], default => 'field_layout_javascript' );
20             has layout_label_text_filename => ( is => 'rw', traits => ['FormFuChained'], default => 'field_layout_label_text' );
21             has layout_block_filename => ( is => 'rw', traits => ['FormFuChained'], default => 'field_layout_block' );
22              
23             has layout_parser_filename => ( is => 'rw', traits => ['FormFuChained'], default => 'field_layout_parser' );
24              
25             has _layout => (
26             is => 'rw',
27             default => sub {
28             return [
29             'errors',
30             'label',
31             'field',
32             'comment',
33             'javascript',
34             ];
35             },
36             );
37              
38             # if we ever remove the reverse_single() method, we can make layout()
39             # a standard Moose attribute
40              
41             sub layout {
42 2178     2178 0 2814 my $self = shift;
43              
44 2178 100       3780 if ( @_ ) {
45 127         3378 $self->_layout(@_);
46 127         207 return $self;
47             }
48              
49 2051         53268 my $value = $self->_layout;
50              
51 2051 100 66     52572 if ( defined $value && $self->reverse_single ) {
52             # if it's an array-ref,
53             # and 'label' and 'field' are consecutive values (in any order)
54             # then just swap them around
55             # otherwise warn that reverse_single() is deprecated
56              
57 4         4 my ( $ok, $field_index, $label_index );
58              
59 4 50 33     25 if ( ref $value && 'ARRAY' eq reftype($value) ) {
60 4     12   40 $field_index = first_index { 'field' eq $_ } @$value;
  12         12  
61 4     8   16 $label_index = first_index { 'label' eq $_ } @$value;
  8         10  
62              
63 4 50 33     26 if ( defined $field_index
      33        
64             && defined $label_index
65             && 1 == abs( $field_index - $label_index )
66             ) {
67 4         5 $ok = 1;
68             }
69             }
70              
71 4 50       7 if ($ok) {
72             # create new arrayref so we don't change the stored value
73 4         9 $value = [ @$value ];
74              
75 4         7 @$value[$field_index] = 'label';
76 4         7 @$value[$label_index] = 'field';
77             }
78             else {
79 0         0 carp "reverse_single() is deprecated, and is having no affect.";
80             }
81             }
82              
83 2051         4319 return $value;
84             }
85              
86             has _multi_layout => (
87             is => 'rw',
88             default => sub {
89             return [
90             'label',
91             'field',
92             ];
93             },
94             );
95              
96             # if we ever remove the reverse_multi() method, we can make multi_layout()
97             # a standard Moose attribute
98              
99             sub multi_layout {
100 1631     1631 0 1678 my $self = shift;
101              
102 1631 100       2904 if ( @_ ) {
103 96         2449 $self->_multi_layout(@_);
104 96         131 return $self;
105             }
106              
107 1535         40199 my $value = $self->_multi_layout;
108              
109 1535 100 66     38843 if ( defined $value && $self->reverse_multi ) {
110             # if it's an array-ref,
111             # and 'label' and 'field' are consecutive values (in any order)
112             # then just swap them around
113             # otherwise warn that reverse_multi() is deprecated
114              
115 7         7 my ( $ok, $field_index, $label_index );
116              
117 7 50 33     32 if ( ref $value && 'ARRAY' eq reftype($value) ) {
118 7     14   28 $field_index = first_index { 'field' eq $_ } @$value;
  14         13  
119 7     7   23 $label_index = first_index { 'label' eq $_ } @$value;
  7         7  
120              
121 7 50 33     40 if ( defined $field_index
      33        
122             && defined $label_index
123             && 1 == abs( $field_index - $label_index )
124             ) {
125 7         8 $ok = 1;
126             }
127             }
128              
129 7 50       8 if ($ok) {
130             # create new arrayref so we don't change the stored value
131 7         9 $value = [ @$value ];
132              
133 7         13 @$value[$field_index] = 'label';
134 7         8 @$value[$label_index] = 'field';
135             }
136             else {
137 0         0 carp "reverse_multi() is deprecated, and is having no affect.";
138             }
139             }
140              
141 1535         36302 return $value;
142             }
143              
144             after BUILD => sub {
145             my $self = shift;
146              
147             $self->filename('field_layout');
148              
149             return;
150             };
151              
152             around render_data_non_recursive => sub {
153             my ( $orig, $self, $args ) = @_;
154              
155             my $render = $self->$orig( {
156             layout => $self->layout,
157             multi_layout => $self->multi_layout,
158             layout_errors_filename => $self->layout_errors_filename,
159             layout_label_filename => $self->layout_label_filename,
160             layout_field_filename => $self->layout_field_filename,
161             layout_comment_filename => $self->layout_comment_filename,
162             layout_javascript_filename => $self->layout_javascript_filename,
163             layout_label_text_filename => $self->layout_label_text_filename,
164             layout_block_filename => $self->layout_block_filename,
165             layout_parser_filename => $self->layout_parser_filename,
166             $args ? %$args : (),
167             } );
168              
169             return $render;
170             };
171              
172             sub string {
173 950     950 0 1192 my ( $self, $args ) = @_;
174              
175 950   100     3110 $args ||= {};
176              
177             my $render
178             = exists $args->{render_data}
179             ? $args->{render_data}
180 950 100       3883 : $self->render_data;
181              
182             my $layout
183             = exists $args->{layout}
184             ? $args->{layout}
185 950 100       2774 : $self->layout;
186              
187 950         1513 my $html = "";
188              
189 950 100       2131 if ( defined $render->{container_tag} ) {
190             $html .= sprintf "<%s%s>\n",
191             $render->{container_tag},
192 702         2622 process_attrs( $render->{container_attributes} );
193             }
194              
195 950         2727 $html .= $self->_parse_layout( $render, $layout );
196              
197 950 100       2094 if ( defined $render->{container_tag} ) {
198 702         1841 $html .= sprintf "\n</%s>", $render->{container_tag},;
199             }
200              
201 950         17189 return $html;
202             }
203              
204             sub _parse_layout {
205 4927     4927   4632 my ( $self, $render, $layout ) = @_;
206              
207 4927 50       6790 croak "undefined 'layout'" if !defined $layout;
208              
209 4927         3717 my $html = "";
210              
211 4927 100 100     24143 if ( ref $layout && 'ARRAY' eq ref $layout ) {
    100 66        
    50          
212 952         973 my @item_html;
213 952         1490 for my $item ( @$layout ) {
214 3972         5780 push @item_html, $self->_parse_layout( $render, $item );
215             }
216             $html .=
217             join "\n",
218             grep {
219 952         1595 defined && length
220 3972 50       11353 }
221             @item_html;
222             }
223             elsif ( ref $layout && 'HASH' eq ref $layout ) {
224 5         10 my ( $key, $value ) = %$layout;
225              
226 5 100       25 if ( my $method = $self->can( "_parse_layout_$key" ) ) {
227 2         4 $html .= $self->$method( $render, $key, $value );
228             }
229             else {
230 3         8 $html .= $self->_parse_layout_block( $render, $key, $value );
231             }
232             }
233             elsif ( my $method = $self->can( "_parse_layout_$layout" ) ) {
234 3970         5684 $html .= $self->$method( $render );
235             }
236             else {
237 0         0 croak "Unknown layout() option: '$layout'";
238             }
239              
240 4927         8420 return $html;
241             }
242              
243             sub _parse_layout_errors {
244 700     700   849 my ( $self, $render ) = @_;
245              
246 700         2429 return $self->_string_errors( $render );
247             }
248              
249             sub _parse_layout_label {
250 920     920   999 my $self = shift;
251 920         880 my $render = shift;
252              
253             return "" unless exists $render->{label}
254             && defined $render->{label}
255 920 100 66     5345 && length $render->{label};
      66        
256              
257 89 100       175 if ( @_ ) {
258 2         3 my ( $tag, @content ) = @_;
259              
260             return $self->_parse_layout_block(
261             $render,
262             $tag,
263             {
264             attributes => $render->{label_attributes},
265 2         10 content => \@content,
266             },
267             );
268             }
269             else {
270 87         280 return $self->_string_label( $render );
271             }
272             }
273              
274             sub _parse_layout_field {
275 877     877   998 my ( $self, $render ) = @_;
276              
277 877         2762 return $self->_string_field( $render );
278             }
279              
280             sub _parse_layout_comment {
281 700     700   817 my ( $self, $render ) = @_;
282              
283 700 100       2491 return "" if !defined $render->{comment};
284              
285             my $html = sprintf "<%s%s>\n%s\n</%s>",
286             'span',
287             process_attrs( $render->{comment_attributes} ),
288             $render->{comment},
289 30         83 'span';
290              
291 30         58 return $html;
292             }
293              
294             sub _parse_layout_javascript {
295 700     700   1133 my ( $self, $render ) = @_;
296              
297 700 50       1924 return "" if !defined $render->{javascript};
298              
299             my $html = sprintf qq{<script type="text/javascript">\n%s\n</script>},
300 0         0 $render->{javascript};
301              
302 0         0 return $html;
303             }
304              
305             sub _parse_layout_label_text {
306 2     2   2 my ( $self, $render ) = @_;
307              
308 2 50 33     11 return "" unless exists $render->{label} && length $render->{label};
309              
310 2         3 return $render->{label};
311             }
312              
313             sub _parse_layout_block {
314 5     5   7 my ( $self, $render, $tag, $opts ) = @_;
315              
316 5   50     7 $opts ||= {};
317              
318 5         6 my $html = "<$tag";
319              
320 5 50       10 if ( $opts->{attributes} ) {
321 5         9 $html .= process_attrs( $opts->{attributes} );
322             }
323              
324 5         6 $html .= ">\n";
325              
326 5 50       8 if ( $opts->{content} ) {
327 5         8 $html .= $self->_parse_layout( $render, $opts->{content} );
328             }
329              
330 5         9 $html .= "\n</$tag>";
331              
332 5         9 return $html;
333             }
334              
335             1;