line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
HTML::Tested::Value - Base class for most HTML::Tested widgets. |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 DESCRIPTION |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
This class provides the most basic HTML::Tested widget - simple value to be |
8
|
|
|
|
|
|
|
output in the template. |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 METHODS |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=cut |
13
|
|
|
|
|
|
|
|
14
|
20
|
|
|
20
|
|
1838
|
use strict; |
|
20
|
|
|
|
|
41
|
|
|
20
|
|
|
|
|
2021
|
|
15
|
20
|
|
|
20
|
|
113
|
use warnings FATAL => 'all'; |
|
20
|
|
|
|
|
58
|
|
|
20
|
|
|
|
|
1052
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
package HTML::Tested::Value; |
18
|
20
|
|
|
20
|
|
25053
|
use HTML::Entities; |
|
20
|
|
|
|
|
283850
|
|
|
20
|
|
|
|
|
3215
|
|
19
|
20
|
|
|
20
|
|
45529
|
use HTML::Tested::Seal; |
|
20
|
|
|
|
|
70
|
|
|
20
|
|
|
|
|
698
|
|
20
|
20
|
|
|
20
|
|
132
|
use Carp; |
|
20
|
|
|
|
|
250
|
|
|
20
|
|
|
|
|
2618
|
|
21
|
20
|
|
|
20
|
|
126
|
use Data::Dumper; |
|
20
|
|
|
|
|
388
|
|
|
20
|
|
|
|
|
63876
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub setup_datetime_option { |
24
|
0
|
|
|
0
|
0
|
0
|
my ($self, $dto, $opts) = @_; |
25
|
0
|
|
0
|
|
|
0
|
$opts ||= $self->options; |
26
|
0
|
|
|
|
|
0
|
eval "use DateTime::Format::Strptime"; |
27
|
0
|
0
|
|
|
|
0
|
confess "Unable to use DateTime::Format::Strptime: $@" if $@; |
28
|
0
|
0
|
|
|
|
0
|
$dto = { pattern => $dto } unless ref($dto); |
29
|
0
|
|
|
|
|
0
|
$opts->{is_datetime} = DateTime::Format::Strptime->new($dto); |
30
|
0
|
|
|
|
|
0
|
$self->compile; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head2 $class->new($parent, $name, %opts) |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Creates new L named C<$name> at parent class C<$parent>. |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
C<%opts> is a hash containing various options changing behaviour of this widget. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
See OPTIONS section for description of available options. |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=cut |
42
|
|
|
|
|
|
|
sub new { |
43
|
106
|
|
|
106
|
1
|
387
|
my ($class, $parent, $name, %opts) = @_; |
44
|
106
|
|
|
|
|
871
|
my $self = bless({ name => $name, _options => \%opts |
45
|
|
|
|
|
|
|
, constraints => [], validators => [] }, $class); |
46
|
106
|
|
100
|
|
|
671
|
my $cs = $opts{constraints} || []; |
47
|
106
|
|
|
|
|
337
|
$self->push_constraint($_) for @$cs; |
48
|
|
|
|
|
|
|
|
49
|
106
|
|
|
|
|
3947
|
my $dto = $self->options->{is_datetime}; |
50
|
106
|
50
|
|
|
|
327
|
$self->setup_datetime_option($dto) if $dto; |
51
|
106
|
|
|
|
|
407
|
return $self; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub _get_option { |
55
|
1143
|
|
|
1143
|
|
2897
|
my ($self, $caller, $wname, $opname) = @_; |
56
|
1143
|
100
|
66
|
|
|
6530
|
if ($caller && ref($caller)) { |
57
|
513
|
|
|
|
|
1090
|
my $n = "__ht__$wname\_$opname"; |
58
|
513
|
100
|
|
|
|
1970
|
return $caller->{$n} if exists $caller->{$n}; |
59
|
|
|
|
|
|
|
} |
60
|
1132
|
|
|
|
|
3794
|
return $self->options->{$opname}; |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=head2 $widget->name |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
Returns the name of the widget. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=cut |
68
|
942
|
|
|
942
|
1
|
5765
|
sub name { return shift()->{name}; } |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=head2 $widget->options |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
Returns hash of options assigned to this widget. See OPTIONS section for |
73
|
|
|
|
|
|
|
description of available options. |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=cut |
76
|
1710
|
|
|
1710
|
1
|
9860
|
sub options { return shift()->{_options}; } |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head2 $widget->value_to_string($name, $val, $caller, $stash) |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
This function is called from C to return final string which will be |
81
|
|
|
|
|
|
|
rendered into stash. For HTML::Tested::Value it simply returns $val. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
C<$caller> is the object calling this function. C<$stash> is read-only hash of |
84
|
|
|
|
|
|
|
the values accummulated so far. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=cut |
87
|
|
|
|
|
|
|
sub value_to_string { |
88
|
88
|
|
|
88
|
1
|
282
|
my ($self, $name, $val) = @_; |
89
|
88
|
|
|
|
|
251
|
return $val; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head2 $widget->encode_value($val) |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
Uses HTML::Entities to encode $val. |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=cut |
97
|
|
|
|
|
|
|
sub encode_value { |
98
|
258
|
|
|
258
|
1
|
483
|
my ($self, $val) = @_; |
99
|
258
|
50
|
|
|
|
1849
|
confess ref($self) . "->" . $self->name . ": Non scalar value $val\n" |
100
|
|
|
|
|
|
|
. Dumper($val) if ref($val); |
101
|
258
|
|
|
|
|
1671
|
return encode_entities($val, '<>&"' . "'"); |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub get_default_value { |
105
|
38
|
|
|
38
|
0
|
82
|
my ($self, $caller, $n) = @_; |
106
|
38
|
|
66
|
|
|
316
|
my $func = $caller->{"__$n\_defval"} || $self->{__defval}; |
107
|
38
|
|
|
|
|
121
|
return $func->($self, $n, $caller); |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=head2 $widget->get_value($caller, $id) |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
It is called from $widget->render to get the value to render. If the value |
113
|
|
|
|
|
|
|
is C C will be used to get default value for the |
114
|
|
|
|
|
|
|
widget. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=cut |
117
|
|
|
|
|
|
|
sub get_value { |
118
|
219
|
|
|
219
|
1
|
558
|
my ($self, $caller, $id, $n) = @_; |
119
|
219
|
|
100
|
|
|
2082
|
return $caller->{$n} // $self->get_default_value($caller, $n); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=head2 $widget->seal_value($value, $caller) |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
If C option is used, this function is called from $widget->render to |
125
|
|
|
|
|
|
|
seal the value before putting it to stash. See HTML::Tested::Seal for sealing |
126
|
|
|
|
|
|
|
description. |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
This function maintains cache of sealed values in caller. Thus promising that |
129
|
|
|
|
|
|
|
the same value will map to the same id during request. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=cut |
132
|
|
|
|
|
|
|
sub seal_value { |
133
|
58
|
|
|
58
|
1
|
113
|
my ($self, $val, $caller) = @_; |
134
|
58
|
|
|
|
|
389
|
return HTML::Tested::Seal->instance->encrypt($val); |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub transform_value { |
138
|
161
|
|
|
161
|
0
|
321
|
my ($self, $caller, $val, $n) = @_; |
139
|
161
|
|
66
|
|
|
921
|
my $func = $caller->{"__$n\_transform"} || $self->{__transform}; |
140
|
161
|
|
|
|
|
434
|
return $func->($self, $val, $caller, $n); |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
sub prepare_value { |
144
|
202
|
|
|
202
|
0
|
464
|
my ($self, $caller, $id, $n) = @_; |
145
|
202
|
|
|
|
|
698
|
my $val = $self->get_value($caller, $id, $n); |
146
|
202
|
100
|
|
|
|
670
|
return undef unless defined($val); |
147
|
197
|
|
|
|
|
1555
|
return $self->transform_value($caller, $val, $n); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub _render_i { |
151
|
206
|
|
|
206
|
|
1171
|
my ($self, $caller, $stash, $id, $n) = @_; |
152
|
206
|
|
|
|
|
731
|
my $val = $self->prepare_value($caller, $id, $n); |
153
|
206
|
100
|
|
|
|
22261
|
return unless defined($val); |
154
|
201
|
|
|
|
|
863
|
return $self->value_to_string($id, $val, $caller, $stash); |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=head2 $widget->render($caller, $stash, $id, $name) |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
Renders widget into $stash. For HTML::Tested::Value it essentially means |
160
|
|
|
|
|
|
|
assigning $stash->{ $name } with $widget->get_value. |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=cut |
163
|
|
|
|
|
|
|
sub render { |
164
|
210
|
|
|
210
|
1
|
443
|
my ($self, $caller, $stash, $id, $n) = @_; |
165
|
210
|
|
66
|
|
|
2291
|
my $func = $caller->{"__$n\_render"} || $self->{__render}; |
166
|
210
|
|
|
|
|
576
|
my $res = $func->($self, $caller, $stash, $id, $n); |
167
|
210
|
100
|
|
|
|
4147
|
$stash->{$n} = $res if defined($res); |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
87
|
|
|
87
|
0
|
919
|
sub bless_from_tree { return $_[1]; } |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head2 $widget->push_constraint($constraint) |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
C<$constraint> should be ARRAY reference with the following format: |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
[ TYPE, OP, COOKIE ] |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
where C is type of the constraint, C is the operation to be done on |
179
|
|
|
|
|
|
|
the constraint and cookie is optional method for the application to recognize |
180
|
|
|
|
|
|
|
specific constraint. |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Available types are: |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=over |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=item C |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
With OP being regexp string (or C value) (e.g. [ regexp => '\d+' ] or [ |
189
|
|
|
|
|
|
|
regexp => qr/\d+/ ]). |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=item C |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Ensures that the value is defined. C doesn't matter here |
194
|
|
|
|
|
|
|
(e.g. [ defined => '' ]). |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=item C |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
Any user defined constraint - second parameter should be function to call. |
199
|
|
|
|
|
|
|
It gets the value and the caller as the arguments. |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
For example [ 'my_foo' => sub { my ($v, $caller) = @_; return is_ok? } ]. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=back |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=cut |
206
|
|
|
|
|
|
|
sub push_constraint { |
207
|
9
|
|
|
9
|
1
|
33
|
my ($self, $c) = @_; |
208
|
9
|
|
|
|
|
15
|
my $func; |
209
|
9
|
|
|
|
|
13
|
push @{ $self->{constraints} }, $c; |
|
9
|
|
|
|
|
24
|
|
210
|
9
|
50
|
33
|
|
|
59
|
confess "Constraint should be of [ TYPE, OP ] format" |
211
|
|
|
|
|
|
|
unless ($c && ref($c) eq 'ARRAY'); |
212
|
9
|
100
|
|
|
|
33
|
if ($c->[0] eq 'regexp') { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
213
|
6
|
|
|
|
|
12
|
my $rexp = $c->[1]; |
214
|
|
|
|
|
|
|
$func = sub { |
215
|
19
|
|
|
19
|
|
24
|
my $v = shift; |
216
|
19
|
100
|
|
|
|
242
|
return defined($v) ? $v =~ /$rexp/ : undef; |
217
|
6
|
|
|
|
|
30
|
}; |
218
|
|
|
|
|
|
|
} elsif ($c->[0] eq 'defined') { |
219
|
1
|
|
|
3
|
|
6
|
$func = sub { return defined($_[0]); }; |
|
3
|
|
|
|
|
13
|
|
220
|
|
|
|
|
|
|
} elsif ($c->[1]) { |
221
|
2
|
|
|
|
|
5
|
$func = $c->[1]; |
222
|
|
|
|
|
|
|
} else { |
223
|
0
|
|
|
|
|
0
|
confess "Unknown type " . $c->[0] . " found!\n"; |
224
|
|
|
|
|
|
|
} |
225
|
9
|
50
|
|
|
|
26
|
push @{ $self->{validators} }, $func if $func; |
|
9
|
|
|
|
|
33
|
|
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
=head2 $widget->validate($value, $caller) |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
Validate value returning list of failed constraints in the format specified |
231
|
|
|
|
|
|
|
above. |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
I.e. the C<$value> is "constraint-clean" when C returns empty list. |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
Validate is disabled if C widget option is set. |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=cut |
238
|
|
|
|
|
|
|
sub validate { |
239
|
33
|
|
|
33
|
1
|
124
|
my ($self, $caller) = @_; |
240
|
33
|
|
|
|
|
70
|
my $n = $self->name; |
241
|
33
|
|
|
|
|
119
|
my $val = $caller->$n; |
242
|
33
|
100
|
|
|
|
419
|
return () if $caller->ht_get_widget_option($n, "no_validate"); |
243
|
31
|
100
|
100
|
|
|
132
|
return ([ $n, 'integer' ]) if (defined($val) |
|
|
|
100
|
|
|
|
|
244
|
|
|
|
|
|
|
&& $caller->ht_get_widget_option($n, "is_integer") |
245
|
|
|
|
|
|
|
&& $val !~ /^\d+$/); |
246
|
29
|
|
|
|
|
46
|
my $vs = $self->{validators}; |
247
|
29
|
|
|
|
|
35
|
my @res; |
248
|
29
|
|
|
|
|
89
|
for (my $i = 0; $i < @$vs; $i++) { |
249
|
28
|
100
|
|
|
|
107
|
next if $vs->[$i]->($val, $caller); |
250
|
12
|
|
|
|
|
50
|
push @res, [ $n, @{ $self->{constraints}->[$i] } ]; |
|
12
|
|
|
|
|
63
|
|
251
|
|
|
|
|
|
|
} |
252
|
29
|
|
|
|
|
201
|
return @res; |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
sub unseal_value { |
256
|
4
|
|
|
4
|
0
|
9
|
my ($self, $val, $caller) = @_; |
257
|
4
|
|
|
|
|
30
|
return HTML::Tested::Seal->instance->decrypt($val); |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
1
|
|
|
1
|
0
|
11
|
sub merge_one_value { shift()->absorb_one_value(@_); } |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=head2 $widget->absorb_one_value($parent, $val, @path) |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
Parses C<$val> and puts the result into C<$parent> object. C<@path> is used for |
265
|
|
|
|
|
|
|
widgets aggregating other widgets (such as C). |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=cut |
268
|
|
|
|
|
|
|
sub absorb_one_value { |
269
|
128
|
|
|
128
|
1
|
250
|
my ($self, $root, $val, @path) = @_; |
270
|
128
|
100
|
|
|
|
280
|
return if $self->options->{is_trusted}; |
271
|
127
|
100
|
|
|
|
246
|
$val = $self->unseal_value($val, $root) |
272
|
|
|
|
|
|
|
if $self->options->{"is_sealed"}; |
273
|
127
|
|
|
|
|
317
|
my $dtfs = $self->options->{"is_datetime"}; |
274
|
127
|
50
|
|
|
|
526
|
$val = $dtfs->parse_datetime($val) if $dtfs; |
275
|
127
|
100
|
100
|
|
|
845
|
$root->{ $self->name } = (defined($val) && $val eq "" |
276
|
|
|
|
|
|
|
&& !$self->options->{keep_empty_string}) ? undef : $val; |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
sub _set_callback { |
280
|
354
|
|
|
354
|
|
725
|
my ($self, $caller, $n, $what, $func) = @_; |
281
|
354
|
100
|
66
|
|
|
1788
|
my $obj = ($caller && ref($caller)) ? $caller : $self; |
282
|
354
|
100
|
66
|
|
|
1598
|
my $key = ($caller && ref($caller)) ? "__$n\_$what" : "__$what"; |
283
|
354
|
|
|
|
|
1184
|
$obj->{$key} = $func; |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
sub _trans_datetime { |
287
|
0
|
|
|
0
|
|
0
|
my ($self, $dtfs, $val, $caller, $n) = @_; |
288
|
0
|
0
|
|
|
|
0
|
return $dtfs->format_datetime($val) if $val; |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
sub compile { |
292
|
118
|
|
|
118
|
0
|
265
|
my ($self, $caller) = @_; |
293
|
118
|
|
|
|
|
310
|
my $n = $self->name; |
294
|
118
|
|
|
|
|
617
|
my $trans = $self->can('encode_value'); |
295
|
118
|
|
|
|
|
528
|
my $func = $self->can('_render_i'); |
296
|
118
|
|
|
18
|
|
611
|
my $defval = sub { return '' }; |
|
18
|
|
|
|
|
79
|
|
297
|
118
|
100
|
|
|
|
521
|
if ($self->_get_option($caller, $n, 'is_disabled')) { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
298
|
3
|
|
|
|
|
7
|
$func = $defval; |
299
|
|
|
|
|
|
|
} elsif (my $dtfs = $self->_get_option($caller, $n, "is_datetime")) { |
300
|
0
|
|
|
0
|
|
0
|
$trans = sub { return shift()->_trans_datetime($dtfs, @_); }; |
|
0
|
|
|
|
|
0
|
|
301
|
|
|
|
|
|
|
} elsif ($self->_get_option($caller, $n, "is_sealed")) { |
302
|
|
|
|
|
|
|
$trans = sub { |
303
|
42
|
|
|
42
|
|
145
|
my $this = shift; |
304
|
42
|
|
|
|
|
128
|
my $val = shift; |
305
|
42
|
|
|
|
|
284
|
$val = $this->seal_value($val, @_); |
306
|
42
|
|
|
|
|
10319
|
return $this->encode_value($val, @_); |
307
|
16
|
|
|
|
|
81
|
}; |
308
|
|
|
|
|
|
|
} elsif ($self->_get_option($caller, $n, "is_trusted")) { |
309
|
3
|
|
|
6
|
|
17
|
$trans = sub { return $_[1]; }; |
|
6
|
|
|
|
|
30
|
|
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
|
312
|
118
|
|
|
|
|
348
|
my $dval = $self->_get_option($caller, $n, "default_value"); |
313
|
118
|
100
|
|
|
|
1705
|
if (defined($dval)) { |
|
|
100
|
|
|
|
|
|
314
|
16
|
100
|
|
18
|
|
100
|
$defval = ref($dval) eq 'CODE' ? $dval : sub { return $dval; }; |
|
18
|
|
|
|
|
85
|
|
315
|
|
|
|
|
|
|
} elsif ($self->_get_option($caller, $n, "skip_undef")) { |
316
|
3
|
|
|
5
|
|
16
|
$defval = sub { return undef; }; |
|
5
|
|
|
|
|
25
|
|
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
118
|
|
|
|
|
1480
|
$self->_set_callback($caller, $n, 'render', $func); |
320
|
118
|
|
|
|
|
333
|
$self->_set_callback($caller, $n, 'transform', $trans); |
321
|
118
|
|
|
|
|
312
|
$self->_set_callback($caller, $n, 'defval', $defval); |
322
|
|
|
|
|
|
|
} |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
1; |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
=head1 OPTIONS |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
Options can be used to customize widget behaviour. Each widget is free to |
329
|
|
|
|
|
|
|
define its own options. They can be set per class or per object using |
330
|
|
|
|
|
|
|
C. The options can be retrieved using |
331
|
|
|
|
|
|
|
C. |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
C defines the following options: |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=over |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=item is_sealed |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
The widget value is encrypted before rendering it. The value is decrypted from |
340
|
|
|
|
|
|
|
the request parameters in transparent fashion. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=item is_disabled |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
The widget is disabled: it is rendered as blank value. |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=item default_value |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
Default value for the widget. It is rendered if current widget value is |
349
|
|
|
|
|
|
|
C. |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
=item skip_undef |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
Normally, if widget value is C, the widget is rendered as blank value. |
354
|
|
|
|
|
|
|
When this option is set the widget will not appear in the stash at all. |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
=item constraints |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
Array reference containing widget value constraints. See C |
359
|
|
|
|
|
|
|
documentation for the individual entry format. |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=item is_trusted |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
Do not perform the escaping of special characters on the value. Improperly |
364
|
|
|
|
|
|
|
setting this option may result in XSS security breach. |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
=item is_integer |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
Ensures that the value is integer. |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
=back |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=head1 AUTHOR |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
Boris Sukholitko (boriss@gmail.com) |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=head1 COPYRIGHT |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
This program is free software; you can redistribute |
379
|
|
|
|
|
|
|
it and/or modify it under the same terms as Perl itself. |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
The full text of the license can be found in the |
382
|
|
|
|
|
|
|
LICENSE file included with this module. |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=head1 SEE ALSO |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
HTML::Tested |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=cut |
390
|
|
|
|
|
|
|
|