File Coverage

blib/lib/HTML/FormFu/Element.pm
Criterion Covered Total %
statement 110 119 92.4
branch 30 32 93.7
condition 14 15 93.3
subroutine 34 41 82.9
pod 4 26 15.3
total 192 233 82.4


line stmt bran cond sub pod time code
1 391     391   242231 use strict;
  391         1510  
  391         22918  
2              
3             package HTML::FormFu::Element;
4             $HTML::FormFu::Element::VERSION = '2.07';
5             # ABSTRACT: Element Base Class
6              
7 391     391   3076 use Moose;
  391         1037  
  391         2266  
8 391     391   2585251 use MooseX::Attribute::Chained;
  391         1200  
  391         22144  
9              
10             with 'HTML::FormFu::Role::Render',
11             'HTML::FormFu::Role::FormAndElementMethods',
12             'HTML::FormFu::Role::HasParent',
13             'HTML::FormFu::Role::CustomRoles',
14             'HTML::FormFu::Role::Populate';
15              
16 391         32474 use HTML::FormFu::Attribute qw(
17             mk_attrs
18             mk_attr_accessors
19             mk_output_accessors
20             mk_inherited_accessors
21             mk_inherited_merging_accessors
22 391     391   2589 );
  391         834  
23 391         28470 use HTML::FormFu::ObjectUtil qw(
24             load_config_file
25             load_config_filestem
26             form
27             stash
28             parent
29             get_parent
30 391     391   2794 );
  391         881  
31             use HTML::FormFu::Util
32 391     391   2564 qw( require_class xml_escape process_attrs _merge_hashes );
  391         883  
  391         22996  
33 391     391   2643 use Clone ();
  391         796  
  391         8878  
34 391     391   2138 use Scalar::Util qw( weaken );
  391         859  
  391         21399  
35 391     391   2764 use Carp qw( croak );
  391         906  
  391         41079  
36              
37             use overload (
38             'eq' => '_string_equals',
39             '==' => '_object_equals',
40 378     378   74289 '""' => sub { return shift->render },
41 299     299   2135 bool => sub {1},
42 391         4945 fallback => 1
43 391     391   2859 );
  391         841  
44              
45             __PACKAGE__->mk_attr_accessors(qw( id ));
46              
47             has type => ( is => 'rw', traits => ['Chained'] );
48             has filename => ( is => 'rw', traits => ['Chained'] );
49             has is_field => ( is => 'rw', traits => ['Chained'] );
50             has is_block => ( is => 'rw', traits => ['Chained'] );
51             has is_repeatable => ( is => 'rw', traits => ['Chained'] );
52              
53             after BUILD => sub {
54             my ( $self, $args ) = @_;
55              
56             # TODO move to attribute 'default'
57             $self->attributes( {} );
58             $self->stash( {} );
59              
60             return;
61             };
62              
63             sub name {
64 58630     58630 1 99042 my ( $self, $name ) = @_;
65              
66 58630 100       104195 if ( @_ > 1 ) {
67              
68 1254 100       5220 if ( $name =~ /[\.\[\]]/ ) {
69 1         190 croak <<'ERROR_MESSAGE';
70             element names may not contain periods or square brackets
71             see documentation on nested_names() for details
72             ERROR_MESSAGE
73             }
74              
75 1253         3618 $self->{name} = $name;
76              
77 1253         6235 return $self;
78             }
79              
80 57376         173446 return $self->{name};
81             }
82              
83       1468 0   sub setup { }
84              
85 0     0 0 0 sub get_elements { [] }
86              
87       1 0   sub get_element { }
88              
89 756     756 0 3342 sub get_all_elements { [] }
90              
91       0 0   sub get_all_element { }
92              
93 11     11 0 44 sub get_fields { [] }
94              
95       0 0   sub get_field { }
96              
97 0     0 0 0 sub get_deflators { [] }
98              
99 1     1 0 5 sub get_filters { [] }
100              
101 1     1 0 4 sub get_constraints { [] }
102              
103 1     1 0 4 sub get_inflators { [] }
104              
105 1     1 0 5 sub get_validators { [] }
106              
107 1     1 0 4 sub get_transformers { [] }
108              
109 3     3 0 10 sub get_errors { [] }
110              
111       1 0   sub clear_errors { }
112              
113       1223 0   sub pre_process { }
114              
115       1378 0   sub process { }
116              
117       1378 0   sub post_process { }
118              
119       3 1   sub prepare_id { }
120              
121       1635 1   sub prepare_attrs { }
122              
123             sub get_output_processors {
124 0     0 0 0 my $self = shift;
125              
126 0         0 return $self->form->get_output_processors(@_);
127             }
128              
129             sub get_output_processor {
130 0     0 0 0 my $self = shift;
131              
132 0         0 return $self->form->get_output_processor(@_);
133             }
134              
135             sub _match_default_args {
136 267     267   1170 my ( $self, $defaults ) = @_;
137              
138 267 100 66     1421 return {} if !$defaults || !%$defaults;
139              
140             # apply any starting with 'Block', 'Field', 'Input' first, each longest first
141 0         0 my @block = sort { length $a <=> length $b }
142 26         93 grep { $_ =~ /^Block/ } keys %$defaults;
  49         180  
143 0         0 my @field = sort { length $a <=> length $b }
144 26         79 grep { $_ =~ /^Field/ } keys %$defaults;
  49         140  
145 3         11 my @input = sort { length $a <=> length $b }
146 26         107 grep { $_ =~ /^Input/ } keys %$defaults;
  49         147  
147              
148 26         64 my %others = map { $_ => 1 } keys %$defaults;
  49         124  
149 26         64 map { delete $others{$_} } @block, @field, @input;
  32         68  
150              
151             # apply remaining keys, longest first
152 26         58 my $arg = {};
153              
154             KEY:
155 26         106 for my $key ( @block, @field, @input,
156 5         21 sort { length $a <=> length $b } keys %others )
157             {
158 49         336 my @type = split qr{\|}, $key;
159 49         111 my $match;
160              
161             TYPE:
162 49         93 for my $type (@type) {
163 52         80 my $not_in;
164             my $is_in;
165 52 100       180 if ( $type =~ s/^-// ) {
    100          
166 3         7 $not_in = 1;
167             }
168             elsif ( $type =~ s/^\+// ) {
169 1         3 $is_in = 1;
170             }
171              
172 52   100     155 my $check_parents = $not_in || $is_in;
173              
174 52 100       180 if ( $self->_match_default_args_type( $type, $check_parents ) ) {
175 26 100       70 if ($not_in) {
176 1         4 next KEY;
177             }
178             else {
179 25         38 $match = 1;
180 25         82 next TYPE;
181             }
182             }
183             }
184              
185 48 100       133 if ($match) {
186 24         90 $arg = _merge_hashes( $arg, $defaults->{$key} );
187             }
188             }
189              
190 26         93 return $arg;
191             }
192              
193             sub _match_default_args_type {
194 52     52   116 my ( $self, $type, $check_parents ) = @_;
195              
196 52         78 my @target;
197 52 100       98 if ($check_parents) {
198 4         7 my $self = $self;
199 4         19 while ( defined( my $parent = $self->parent ) ) {
200 5 100       35 last if !$parent->isa('HTML::FormFu::Element');
201 1         2 push @target, $parent;
202 1         3 $self = $parent;
203             }
204             }
205             else {
206 48         96 @target = ($self);
207             }
208              
209 52         96 for my $target (@target) {
210              
211             # handle Block default_args
212 49 100 100     193 if ( 'Block' eq $type
213             && $target->isa('HTML::FormFu::Element::Block') )
214             {
215 3         11 return 1;
216             }
217              
218             # handle Field default_args
219 46 100 100     180 if ( 'Field' eq $type
220             && $target->does('HTML::FormFu::Role::Element::Field') )
221             {
222 11         8635 return 1;
223             }
224              
225             # handle Input default_args
226 35 100 100     2678 if ( 'Input' eq $type
227             && $target->does('HTML::FormFu::Role::Element::Input') )
228             {
229 5         1666 return 1;
230             }
231              
232             # handle explicit default_args
233 30 100       2333 if ( $type eq $target->type ) {
234 7         80 return 1;
235             }
236             }
237             }
238              
239             sub clone {
240 197     197 1 435 my ($self) = @_;
241              
242 197         4936 my %new = %$self;
243              
244             $new{tt_args} = Clone::clone( $self->{tt_args} )
245 197 50       1023 if $self->{tt_args};
246              
247 197         770 $new{attributes} = Clone::clone( $self->attributes );
248 197         992 $new{model_config} = Clone::clone( $self->model_config );
249              
250 197         833 return bless \%new, ref $self;
251             }
252              
253             sub render_data {
254 1243     1243 0 5545 return shift->render_data_non_recursive(@_);
255             }
256              
257             sub render_data_non_recursive {
258 1635     1635 0 4521 my ( $self, $args ) = @_;
259              
260             my %render = (
261             name => xml_escape( $self->name ),
262             attributes => xml_escape( $self->attributes ),
263             type => $self->type,
264             filename => $self->filename,
265             is_field => $self->is_field,
266             stash => $self->stash,
267             parent => $self->parent,
268 0     0   0 form => sub { return shift->{parent}->form },
269 1635 50       5319 object => $self,
270             $args ? %$args : (),
271             );
272              
273 1635         10232 weaken( $render{parent} );
274              
275 1635         8004 $self->prepare_id( \%render );
276              
277 1635         8185 $self->prepare_attrs( \%render );
278              
279 1635         5024 return \%render;
280             }
281              
282             __PACKAGE__->meta->make_immutable;
283              
284             1;
285              
286             __END__
287              
288             =pod
289              
290             =encoding UTF-8
291              
292             =head1 NAME
293              
294             HTML::FormFu::Element - Element Base Class
295              
296             =head1 VERSION
297              
298             version 2.07
299              
300             =head1 SYNOPSIS
301              
302             ---
303             elements:
304             - type: Text
305             name: username
306             constraints:
307             - type: Required
308              
309             - type: Password
310             name: password
311             constraints:
312             - type: Required
313             - type: Equal
314             others: repeat-password
315              
316             - type: Password
317             name: repeat-password
318              
319             - type: Submit
320              
321             =head1 DESCRIPTION
322              
323             Elements are the basic building block of all forms. Elements may be logical
324             form-fields, blocks such as C<div>s and C<fieldset>s, non-blocks such as
325             C<hr>s and other special elements such as tables.
326              
327             For simple, automatic handling of fieldsets see the
328             L<HTML::FormFu/auto_fieldset> setting.
329              
330             See L<HTML::FormFu/deflators> for details of
331             L<Deflators|HTML::FormFu::Deflator>.
332              
333             See L<HTML::FormFu/FORM LOGIC AND VALIDATION> for details of
334             L<Filters|HTML::FormFu::Filter>,
335             L<Constraints|HTML::FormFu::Constraint>,
336             L<Inflators|HTML::FormFu::Inflator>,
337             L<Validators|HTML::FormFu::Validator> and
338             L<Transformers|HTML::FormFu::Transformer>.
339              
340             =head1 METHODS
341              
342             =head2 name
343              
344             For L<field|HTML::FormFu::Role::Element::Field> element, this value is used as
345             the C<name> attribute which the field's value is associated with.
346              
347             For all elements, the L</name> value can be useful for identifying and
348             retrieving specific elements.
349              
350             =head2 is_field
351              
352             Return Value: boolean
353              
354             Returns C<true> or C<false> depending on whether the element is a logical
355             form-field.
356              
357             This is used by L<HTML::FormFu/get_fields>.
358              
359             =head1 BUILDING AN ELEMENT
360              
361             =head2 load_config_file
362              
363             Arguments: $filename
364              
365             Arguments: \@filenames
366              
367             Populate an element using a config file:
368              
369             ---
370             elements:
371             - type: Block
372             load_config_file: 'elements.yml'
373              
374             See L<HTML::FormFu/load_config_file> for further details.
375              
376             =head2 load_config_filestem
377              
378             Arguments: $filestem
379              
380             Arguments: \@filestems
381              
382             Like L</load_config_file>, but you shouldn't include the file extension
383             in the passed string. This allows you to change your config-file type,
384             without having to change the code that loads the files.
385              
386             =head2 config_file_path
387              
388             Arguments: $directory_name
389              
390             L</config_file_path> defines where configuration files will be
391             searched for, if an absolute path is not given to
392             L</load_config_file>.
393              
394             Default Value: not defined
395              
396             This method is a special 'inherited accessor', which means it can be set on
397             the form, a block element or a single element. When the value is read, if
398             no value is defined it automatically traverses the element's hierarchy of
399             parents, through any block elements and up to the form, searching for a
400             defined value.
401              
402             =head2 config_callback
403              
404             See L<HTML::FormFu/config_callback> for details.
405              
406             =head2 populate
407              
408             See L<HTML::FormFu/populate> for details.
409              
410             =head2 stash
411              
412             See L<HTML::FormFu/stash> for details.
413              
414             =head2 type
415              
416             Returns the C<type> argument originally used to create the element.
417              
418             =head1 CHANGING DEFAULT BEHAVIOUR
419              
420             =head2 render_processed_value
421              
422             See L<HTML::FormFu/render_processed_value> for details.
423              
424             =head2 force_errors
425              
426             See L<HTML::FormFu/force_errors> for details.
427              
428             =head1 ELEMENT ATTRIBUTES
429              
430             See specific element types for which tag attributes are added to.
431              
432             =head2 attributes
433              
434             =head2 attrs
435              
436             Arguments: [%attributes]
437              
438             Arguments: [\%attributes]
439              
440             Return Value: $form
441              
442             See L<HTML::FormFu/attributes> for details.
443              
444             L</attrs> is an alias for L</attributes>.
445              
446             =head2 attributes_xml
447              
448             =head2 attrs_xml
449              
450             See L<HTML::FormFu/attributes_xml> for details.
451              
452             L</attrs_xml> is an alias for L</attributes_xml>.
453              
454             =head2 add_attributes
455              
456             =head2 add_attrs
457              
458             Arguments: [%attributes]
459              
460             Arguments: [\%attributes]
461              
462             Return Value: $form
463              
464             See L<HTML::FormFu/add_attributes> for details.
465              
466             L</add_attrs> is an alias for L</add_attributes>.
467              
468             =head2 add_attributes_xml
469              
470             =head2 add_attrs_xml
471              
472             See L<HTML::FormFu/add_attributes_xml> for details.
473              
474             L</add_attrs_xml> is an alias for L</add_attributes_xml>.
475              
476             =head2 del_attributes
477              
478             =head2 del_attrs
479              
480             Arguments: [%attributes]
481              
482             Arguments: [\%attributes]
483              
484             Return Value: $form
485              
486             See L<HTML::FormFu/del_attributes> for details.
487              
488             L</del_attrs> is an alias for L</del_attributes>.
489              
490             =head2 del_attributes_xml
491              
492             =head2 del_attrs_xml
493              
494             See L<HTML::FormFu/del_attributes_xml> for details.
495              
496             L</del_attrs_xml> is an alias for L</del_attributes_xml>.
497              
498             The following methods are shortcuts for accessing L</attributes> keys.
499              
500             =head2 id
501              
502             Arguments: [$id]
503              
504             Return Value: $id
505              
506             Get or set the element's DOM id.
507              
508             Default Value: none
509              
510             =head1 MODEL / DATABASE INTERACTION
511              
512             See L<HTML::FormFu::Model> for further details and available models.
513              
514             =head2 model_config
515              
516             Arguments: \%config
517              
518             =head1 RENDERING
519              
520             =head2 filename
521              
522             This value identifies which template file should be used by
523             L</render> to render the element.
524              
525             =head2 prepare_id
526              
527             Arguments: $render
528              
529             See L<HTML::FormFu::Role::Element::Field/prepare_id> for details.
530              
531             =head2 prepare_attrs
532              
533             Arguments: $render
534              
535             See L<HTML::FormFu::Role::Element::Field/prepare_attrs> for details.
536              
537             =head2 render
538              
539             Return Value: $string
540              
541             =head1 INTROSPECTION
542              
543             =head2 parent
544              
545             Returns the L<block element|HTML::FormFu::Element::Block> or
546             L<form|HTML::FormFu> object that this element is attached to.
547              
548             =head2 get_parent
549              
550             Arguments: \%options
551              
552             my $repeatable = $field->get_parent({ type => 'Repeatable' });
553              
554             Traverses the parent hierarchy, returning the first parent that matches the
555             supplied options.
556              
557             =head2 form
558              
559             Returns the L<HTML::FormFu> object that the constraint's field is attached
560             to.
561              
562             =head2 clone
563              
564             See L<HTML::FormFu/clone> for details.
565              
566             =head1 ADVANCED CUSTOMISATION
567              
568             =head2 tt_args
569              
570             See L<HTML::FormFu/tt_args> for details.
571              
572             =head2 render_method
573              
574             See L<HTML::FormFu/render_method> for details.
575              
576             =head1 CORE FORM FIELDS
577              
578             =over
579              
580             =item L<HTML::FormFu::Element::Button>
581              
582             =item L<HTML::FormFu::Element::Checkbox>
583              
584             =item L<HTML::FormFu::Element::Checkboxgroup>
585              
586             =item L<HTML::FormFu::Element::ComboBox>
587              
588             =item L<HTML::FormFu::Element::ContentButton>
589              
590             =item L<HTML::FormFu::Element::Date>
591              
592             =item L<HTML::FormFu::Element::Email>
593              
594             =item L<HTML::FormFu::Element::File>
595              
596             =item L<HTML::FormFu::Element::Hidden>
597              
598             =item L<HTML::FormFu::Element::Image>
599              
600             =item L<HTML::FormFu::Element::Number>
601              
602             =item L<HTML::FormFu::Element::Password>
603              
604             =item L<HTML::FormFu::Element::Radio>
605              
606             =item L<HTML::FormFu::Element::Radiogroup>
607              
608             =item L<HTML::FormFu::Element::Reset>
609              
610             =item L<HTML::FormFu::Element::Select>
611              
612             =item L<HTML::FormFu::Element::Submit>
613              
614             =item L<HTML::FormFu::Element::Textarea>
615              
616             =item L<HTML::FormFu::Element::Text>
617              
618             =item L<HTML::FormFu::Element::URL>
619              
620             =back
621              
622             =head1 OTHER CORE ELEMENTS
623              
624             =over
625              
626             =item L<HTML::FormFu::Element::Blank>
627              
628             =item L<HTML::FormFu::Element::Block>
629              
630             =item L<HTML::FormFu::Element::Fieldset>
631              
632             =item L<HTML::FormFu::Element::Hr>
633              
634             =item L<HTML::FormFu::Element::Label>
635              
636             =item L<HTML::FormFu::Element::Multi>
637              
638             =item L<HTML::FormFu::Element::Repeatable>
639              
640             =item L<HTML::FormFu::Element::SimpleTable>
641              
642             =item L<HTML::FormFu::Element::Src>
643              
644             =back
645              
646             =head1 ELEMENT BASE CLASSES
647              
648             The following are base classes for other elements, and generally needn't be
649             used directly.
650              
651             =over
652              
653             =item L<HTML::FormFu::Role::Element::Field>
654              
655             =item L<HTML::FormFu::Role::Element::Group>
656              
657             =item L<HTML::FormFu::Role::Element::Input>
658              
659             =item L<HTML::FormFu::Element::_MultiElement>
660              
661             =item L<HTML::FormFu::Element::_MultiSelect>
662              
663             =item L<HTML::FormFu::Element::_MultiText>
664              
665             =item L<HTML::FormFu::Role::Element::NonBlock>
666              
667             =back
668              
669             =head1 REMOVED METHODS
670              
671             =head2 db
672              
673             Has been removed; use L</default_args> instead.
674              
675             =head1 AUTHOR
676              
677             Carl Franks, C<cfranks@cpan.org>
678              
679             =head1 LICENSE
680              
681             This library is free software, you can redistribute it and/or modify it under
682             the same terms as Perl itself.
683              
684             =head1 AUTHOR
685              
686             Carl Franks <cpan@fireartist.com>
687              
688             =head1 COPYRIGHT AND LICENSE
689              
690             This software is copyright (c) 2018 by Carl Franks.
691              
692             This is free software; you can redistribute it and/or modify it under
693             the same terms as the Perl 5 programming language system itself.
694              
695             =cut