line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package HTML::Element::Library; |
2
|
2
|
|
|
2
|
|
68802
|
use strict; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
46
|
|
3
|
2
|
|
|
2
|
|
7
|
use warnings; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
73
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '5.220000'; |
6
|
|
|
|
|
|
|
our $DEBUG = 0; |
7
|
|
|
|
|
|
|
|
8
|
2
|
|
|
2
|
|
720
|
use Array::Group ':all'; |
|
2
|
|
|
|
|
912
|
|
|
2
|
|
|
|
|
189
|
|
9
|
2
|
|
|
2
|
|
8
|
use Carp 'confess'; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
78
|
|
10
|
2
|
|
|
2
|
|
976
|
use Data::Dumper; |
|
2
|
|
|
|
|
12576
|
|
|
2
|
|
|
|
|
90
|
|
11
|
2
|
|
|
2
|
|
888
|
use Data::Rmap 'rmap_array'; |
|
2
|
|
|
|
|
2009
|
|
|
2
|
|
|
|
|
97
|
|
12
|
2
|
|
|
2
|
|
9
|
use HTML::Element; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
23
|
|
13
|
2
|
|
|
2
|
|
909
|
use HTML::FillInForm; |
|
2
|
|
|
|
|
4443
|
|
|
2
|
|
|
|
|
54
|
|
14
|
2
|
|
|
2
|
|
843
|
use List::MoreUtils ':all'; |
|
2
|
|
|
|
|
15427
|
|
|
2
|
|
|
|
|
9
|
|
15
|
2
|
|
|
2
|
|
5629
|
use List::Rotation::Cycle; |
|
2
|
|
|
|
|
5274
|
|
|
2
|
|
|
|
|
54
|
|
16
|
2
|
|
|
2
|
|
9
|
use List::Util 'first'; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
128
|
|
17
|
2
|
|
|
2
|
|
881
|
use Params::Validate ':all'; |
|
2
|
|
|
|
|
12014
|
|
|
2
|
|
|
|
|
293
|
|
18
|
2
|
|
|
2
|
|
702
|
use Scalar::Listify; |
|
2
|
|
|
|
|
442
|
|
|
2
|
|
|
|
|
6221
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# https://rt.cpan.org/Ticket/Display.html?id=44105 |
21
|
|
|
|
|
|
|
sub HTML::Element::fillinform { |
22
|
0
|
|
|
0
|
0
|
|
my ($tree, $hashref, $return_tree, $guts) = @_; |
23
|
0
|
0
|
|
|
|
|
(ref $hashref) eq 'HASH' or confess 'hashref not supplied as argument' ; |
24
|
|
|
|
|
|
|
|
25
|
0
|
|
|
|
|
|
my $html = $tree->as_HTML; |
26
|
0
|
|
|
|
|
|
my $new_html = HTML::FillInForm->fill(\$html, $hashref); |
27
|
|
|
|
|
|
|
|
28
|
0
|
0
|
|
|
|
|
if ($return_tree) { |
29
|
0
|
|
|
|
|
|
$tree = HTML::TreeBuilder->new_from_content($new_html); |
30
|
0
|
0
|
|
|
|
|
$tree = $guts ? $tree->guts : $tree ; |
31
|
|
|
|
|
|
|
} else { |
32
|
0
|
|
|
|
|
|
$new_html; |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub HTML::Element::siblings { |
37
|
0
|
|
|
0
|
0
|
|
my $element = shift; |
38
|
0
|
|
|
|
|
|
my $p = $element->parent; |
39
|
0
|
0
|
|
|
|
|
return () unless $p; |
40
|
0
|
|
|
|
|
|
$p->content_list; |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub HTML::Element::defmap { |
44
|
0
|
|
|
0
|
0
|
|
my($tree, $attr, $hashref, $debug) = @_; |
45
|
|
|
|
|
|
|
|
46
|
0
|
|
|
|
|
|
while (my ($k, $v) = (each %$hashref)) { |
47
|
0
|
0
|
|
|
|
|
warn "defmap looks for ($attr => $k)" if $debug; |
48
|
0
|
|
|
|
|
|
my $found = $tree->look_down($attr => $k); |
49
|
0
|
0
|
|
|
|
|
if ($found) { |
50
|
0
|
0
|
|
|
|
|
warn "($attr => $k) was found.. replacing with '$v'" if $debug; |
51
|
0
|
|
|
|
|
|
$found->replace_content( $v ); |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub HTML::Element::_only_empty_content { |
57
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
58
|
0
|
|
|
|
|
|
my @c = $self->content_list; |
59
|
0
|
|
|
|
|
|
my $length = scalar @c; |
60
|
|
|
|
|
|
|
|
61
|
0
|
0
|
|
|
|
|
scalar @c == 1 and not length $c[0]; |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub HTML::Element::prune { |
65
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
66
|
|
|
|
|
|
|
|
67
|
0
|
|
|
|
|
|
for my $c ($self->content_list) { |
68
|
0
|
0
|
|
|
|
|
next unless ref $c; |
69
|
0
|
|
|
|
|
|
$c->prune; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# post-order: |
73
|
0
|
0
|
0
|
|
|
|
$self->delete if ($self->is_empty or $self->_only_empty_content); |
74
|
0
|
|
|
|
|
|
$self; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub HTML::Element::newchild { |
78
|
0
|
|
|
0
|
0
|
|
my ($lol, $parent_label, @newchild) = @_; |
79
|
|
|
|
|
|
|
rmap_array { |
80
|
0
|
0
|
|
0
|
|
|
if ($_->[0] eq $parent_label) { |
81
|
0
|
|
|
|
|
|
$_ = [ $parent_label => @newchild ]; |
82
|
0
|
|
|
|
|
|
Data::Rmap::cut($_); |
83
|
|
|
|
|
|
|
} else { |
84
|
0
|
|
|
|
|
|
$_; |
85
|
|
|
|
|
|
|
} |
86
|
0
|
|
|
|
|
|
} $lol; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub HTML::Element::crunch { ## no critic (RequireArgUnpacking) |
90
|
0
|
|
|
0
|
0
|
|
my $container = shift; |
91
|
|
|
|
|
|
|
|
92
|
0
|
|
|
|
|
|
my %p = validate(@_, { |
93
|
|
|
|
|
|
|
look_down => { type => ARRAYREF }, |
94
|
|
|
|
|
|
|
leave => { default => 1 }, |
95
|
|
|
|
|
|
|
}); |
96
|
|
|
|
|
|
|
|
97
|
0
|
|
|
|
|
|
my @look_down = @{$p{look_down}} ; |
|
0
|
|
|
|
|
|
|
98
|
0
|
|
|
|
|
|
my @elem = $container->look_down(@look_down) ; |
99
|
|
|
|
|
|
|
|
100
|
0
|
|
|
|
|
|
my $detached; |
101
|
|
|
|
|
|
|
|
102
|
0
|
|
|
|
|
|
for my $elem (@elem) { |
103
|
0
|
0
|
|
|
|
|
$elem->detach if $detached++ >= $p{leave}; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub HTML::Element::hash_map { ## no critic (RequireArgUnpacking) |
108
|
0
|
|
|
0
|
0
|
|
my $container = shift; |
109
|
|
|
|
|
|
|
|
110
|
0
|
|
|
|
|
|
my %p = validate(@_, { |
111
|
|
|
|
|
|
|
hash => { type => HASHREF }, |
112
|
|
|
|
|
|
|
to_attr => 1, |
113
|
|
|
|
|
|
|
excluding => { type => ARRAYREF , default => [] }, |
114
|
|
|
|
|
|
|
debug => { default => 0 }, |
115
|
|
|
|
|
|
|
}); |
116
|
|
|
|
|
|
|
|
117
|
0
|
0
|
|
|
|
|
warn 'The container tag is ', $container->tag if $p{debug} ; |
118
|
0
|
0
|
|
|
|
|
warn 'hash' . Dumper($p{hash}) if $p{debug} ; |
119
|
|
|
|
|
|
|
#warn 'at_under' . Dumper(\@_) if $p{debug} ; |
120
|
|
|
|
|
|
|
|
121
|
0
|
|
|
|
|
|
my @same_as = $container->look_down( $p{to_attr} => qr/.+/s ) ; |
122
|
|
|
|
|
|
|
|
123
|
0
|
0
|
|
|
|
|
warn 'Found ' . scalar(@same_as) . ' nodes' if $p{debug} ; |
124
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
|
for my $same_as (@same_as) { |
126
|
0
|
|
|
|
|
|
my $attr_val = $same_as->attr($p{to_attr}) ; |
127
|
0
|
0
|
|
0
|
|
|
if (first { $attr_val eq $_ } @{$p{excluding}}) { |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
128
|
0
|
0
|
|
|
|
|
warn "excluding $attr_val" if $p{debug} ; |
129
|
0
|
|
|
|
|
|
next; |
130
|
|
|
|
|
|
|
} |
131
|
0
|
0
|
|
|
|
|
warn "processing $attr_val" if $p{debug} ; |
132
|
0
|
|
|
|
|
|
$same_as->replace_content($p{hash}->{$attr_val}); |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub HTML::Element::hashmap { |
137
|
0
|
|
|
0
|
0
|
|
my ($container, $attr_name, $hashref, $excluding, $debug) = @_; |
138
|
|
|
|
|
|
|
|
139
|
0
|
|
0
|
|
|
|
$excluding ||= [] ; |
140
|
|
|
|
|
|
|
|
141
|
0
|
|
|
|
|
|
$container->hash_map( |
142
|
|
|
|
|
|
|
hash => $hashref, |
143
|
|
|
|
|
|
|
to_attr => $attr_name, |
144
|
|
|
|
|
|
|
excluding => $excluding, |
145
|
|
|
|
|
|
|
debug => $debug); |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
sub HTML::Element::passover { |
150
|
0
|
|
|
0
|
0
|
|
my ($tree, @to_preserve) = @_; |
151
|
|
|
|
|
|
|
|
152
|
0
|
0
|
|
|
|
|
warn "ARGS: my ($tree, @to_preserve)" if $DEBUG; |
153
|
0
|
0
|
|
|
|
|
warn $tree->as_HTML(undef, ' ') if $DEBUG; |
154
|
|
|
|
|
|
|
|
155
|
0
|
|
|
|
|
|
my $exodus = $tree->look_down(id => $to_preserve[0]); |
156
|
|
|
|
|
|
|
|
157
|
0
|
0
|
|
|
|
|
warn "E: $exodus" if $DEBUG; |
158
|
|
|
|
|
|
|
|
159
|
0
|
|
|
|
|
|
my @s = HTML::Element::siblings($exodus); |
160
|
|
|
|
|
|
|
|
161
|
0
|
|
|
|
|
|
for my $s (@s) { |
162
|
0
|
0
|
|
|
|
|
next unless ref $s; |
163
|
0
|
0
|
|
0
|
|
|
$s->delete unless first { $s->attr('id') eq $_ } @to_preserve; |
|
0
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
0
|
|
|
|
|
|
return $exodus; # Goodbye Egypt! http://en.wikipedia.org/wiki/Passover |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub HTML::Element::sibdex { |
170
|
0
|
|
|
0
|
0
|
|
my $element = shift; |
171
|
0
|
|
|
0
|
|
|
firstidx { $_ eq $element } $element->siblings |
|
0
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
0
|
|
|
0
|
0
|
|
sub HTML::Element::addr { goto &HTML::Element::sibdex } |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
sub HTML::Element::replace_content { |
177
|
0
|
|
|
0
|
0
|
|
my $elem = shift; |
178
|
0
|
|
|
|
|
|
$elem->delete_content; |
179
|
0
|
|
|
|
|
|
$elem->push_content(@_); |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
sub HTML::Element::wrap_content { |
183
|
0
|
|
|
0
|
0
|
|
my($self, $wrap) = @_; |
184
|
0
|
|
|
|
|
|
my $content = $self->content; |
185
|
0
|
0
|
|
|
|
|
if (ref $content) { |
186
|
0
|
|
|
|
|
|
$wrap->push_content(@$content); |
187
|
0
|
|
|
|
|
|
@$content = ($wrap); |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
else { |
190
|
0
|
|
|
|
|
|
$self->push_content($wrap); |
191
|
|
|
|
|
|
|
} |
192
|
0
|
|
|
|
|
|
$wrap; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
sub HTML::Element::Library::super_literal { |
196
|
0
|
|
|
0
|
1
|
|
my($text) = @_; |
197
|
0
|
|
|
|
|
|
HTML::Element->new('~literal', text => $text); |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
sub HTML::Element::position { |
201
|
|
|
|
|
|
|
# Report coordinates by chasing addr's up the |
202
|
|
|
|
|
|
|
# HTML::ElementSuper tree. We know we've reached |
203
|
|
|
|
|
|
|
# the top when a) there is no parent, or b) the |
204
|
|
|
|
|
|
|
# parent is some HTML::Element unable to report |
205
|
|
|
|
|
|
|
# it's position. |
206
|
0
|
|
|
0
|
0
|
|
my $p = shift; |
207
|
0
|
|
|
|
|
|
my @pos; |
208
|
0
|
|
|
|
|
|
while ($p) { |
209
|
0
|
|
|
|
|
|
my $a = $p->addr; |
210
|
0
|
0
|
|
|
|
|
unshift @pos, $a if defined $a; |
211
|
0
|
|
|
|
|
|
$p = $p->parent; |
212
|
|
|
|
|
|
|
} |
213
|
0
|
|
|
|
|
|
@pos; |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
sub HTML::Element::content_handler { |
217
|
0
|
|
|
0
|
0
|
|
my ($tree, %content_hash) = @_; |
218
|
|
|
|
|
|
|
|
219
|
0
|
|
|
|
|
|
for my $k (keys %content_hash) { |
220
|
0
|
|
|
|
|
|
$tree->set_child_content(id => $k, $content_hash{$k}); |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
0
|
|
|
0
|
0
|
|
sub HTML::Element::assign { goto &HTML::Element::content_handler } |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
sub make_counter { |
227
|
0
|
|
|
0
|
0
|
|
my $i = 1; |
228
|
|
|
|
|
|
|
sub { |
229
|
0
|
|
|
0
|
|
|
shift() . ':' . $i++ |
230
|
|
|
|
|
|
|
} |
231
|
0
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
sub HTML::Element::iter { |
234
|
0
|
|
|
0
|
0
|
|
my ($tree, $p, @data) = @_; |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# warn 'P: ' , $p->attr('id') ; |
237
|
|
|
|
|
|
|
# warn 'H: ' , $p->as_HTML; |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
# my $id_incr = make_counter; |
240
|
|
|
|
|
|
|
my @item = map { |
241
|
0
|
|
|
|
|
|
my $new_item = clone $p; |
|
0
|
|
|
|
|
|
|
242
|
0
|
|
|
|
|
|
$new_item->replace_content($_); |
243
|
0
|
|
|
|
|
|
$new_item; |
244
|
|
|
|
|
|
|
} @data; |
245
|
|
|
|
|
|
|
|
246
|
0
|
|
|
|
|
|
$p->replace_with(@item); |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
sub HTML::Element::itercb { |
250
|
0
|
|
|
0
|
0
|
|
my ($self, $data, $code) = @_; |
251
|
0
|
|
|
|
|
|
my $orig = $self; |
252
|
0
|
|
|
|
|
|
my $prev = $orig; |
253
|
0
|
|
|
|
|
|
for my $el (@$data) { |
254
|
0
|
|
|
|
|
|
my $current = $orig->clone; |
255
|
0
|
|
|
|
|
|
$code->($el, $current); |
256
|
0
|
|
|
|
|
|
$prev->postinsert($current); |
257
|
0
|
|
|
|
|
|
$prev = $current; |
258
|
|
|
|
|
|
|
} |
259
|
0
|
|
|
|
|
|
$orig->detach; |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
sub HTML::Element::iter2 { ## no critic (RequireArgUnpacking) |
263
|
0
|
|
|
0
|
0
|
|
my $tree = shift; |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
#warn "INPUT TO TABLE2: ", Dumper \@_; |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
my %p = validate( |
268
|
|
|
|
|
|
|
@_, { |
269
|
|
|
|
|
|
|
wrapper_ld => { default => ['_tag' => 'dl'] }, |
270
|
|
|
|
|
|
|
wrapper_data => 1, |
271
|
|
|
|
|
|
|
wrapper_proc => { default => undef }, |
272
|
|
|
|
|
|
|
item_ld => { |
273
|
|
|
|
|
|
|
default => sub { |
274
|
0
|
|
|
0
|
|
|
my $tr = shift; |
275
|
|
|
|
|
|
|
[ |
276
|
0
|
|
|
|
|
|
$tr->look_down('_tag' => 'dt'), |
277
|
|
|
|
|
|
|
$tr->look_down('_tag' => 'dd') |
278
|
|
|
|
|
|
|
]; |
279
|
|
|
|
|
|
|
}}, |
280
|
|
|
|
|
|
|
item_data => { |
281
|
|
|
|
|
|
|
default => sub { |
282
|
0
|
|
|
0
|
|
|
my ($wrapper_data) = @_; |
283
|
0
|
|
|
|
|
|
shift @{$wrapper_data}; |
|
0
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
}}, |
285
|
|
|
|
|
|
|
item_proc => { |
286
|
|
|
|
|
|
|
default => sub { |
287
|
0
|
|
|
0
|
|
|
my ($item_elems, $item_data, $row_count) = @_; |
288
|
0
|
|
|
|
|
|
$item_elems->[$_]->replace_content($item_data->[$_]) for (0,1) ; |
289
|
0
|
|
|
|
|
|
$item_elems; |
290
|
|
|
|
|
|
|
}}, |
291
|
|
|
|
|
|
|
splice => { |
292
|
|
|
|
|
|
|
default => sub { |
293
|
0
|
|
|
0
|
|
|
my ($container, @item_elems) = @_; |
294
|
0
|
|
|
|
|
|
$container->splice_content(0, 2, @item_elems); |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
}, |
297
|
0
|
|
|
|
|
|
debug => {default => 0} |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
); |
300
|
|
|
|
|
|
|
|
301
|
0
|
0
|
|
|
|
|
warn 'wrapper_data: ' . Dumper $p{wrapper_data} if $p{debug} ; |
302
|
|
|
|
|
|
|
|
303
|
0
|
|
|
|
|
|
my $container = ref_or_ld($tree, $p{wrapper_ld}); |
304
|
0
|
0
|
|
|
|
|
warn 'container: ' . $container if $p{debug} ; |
305
|
0
|
0
|
|
|
|
|
warn 'wrapper_(preproc): ' . $container->as_HTML if $p{debug} ; |
306
|
0
|
0
|
|
|
|
|
$p{wrapper_proc}->($container) if defined $p{wrapper_proc} ; |
307
|
0
|
0
|
|
|
|
|
warn 'wrapper_(postproc): ' . $container->as_HTML if $p{debug} ; |
308
|
|
|
|
|
|
|
|
309
|
0
|
|
|
|
|
|
my $_item_elems = $p{item_ld}->($container); |
310
|
|
|
|
|
|
|
|
311
|
0
|
|
|
|
|
|
my $row_count; |
312
|
|
|
|
|
|
|
my @item_elem; |
313
|
0
|
|
|
|
|
|
while(1){ |
314
|
0
|
|
|
|
|
|
my $item_data = $p{item_data}->($p{wrapper_data}); |
315
|
0
|
0
|
|
|
|
|
last unless defined $item_data; |
316
|
|
|
|
|
|
|
|
317
|
0
|
0
|
|
|
|
|
warn Dumper('item_data', $item_data) if $p{debug}; |
318
|
|
|
|
|
|
|
|
319
|
0
|
|
|
|
|
|
my $item_elems = [ map { $_->clone } @{$_item_elems} ] ; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
|
321
|
0
|
0
|
|
|
|
|
if ($p{debug}) { |
322
|
0
|
|
|
|
|
|
for (@{$item_elems}) { |
|
0
|
|
|
|
|
|
|
323
|
0
|
0
|
|
|
|
|
warn 'ITEM_ELEMS ', $_->as_HTML if $p{debug}; |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
} |
326
|
|
|
|
|
|
|
|
327
|
0
|
|
|
|
|
|
my $new_item_elems = $p{item_proc}->($item_elems, $item_data, ++$row_count); |
328
|
|
|
|
|
|
|
|
329
|
0
|
0
|
|
|
|
|
if ($p{debug}) { |
330
|
0
|
|
|
|
|
|
for (@{$new_item_elems}) { |
|
0
|
|
|
|
|
|
|
331
|
0
|
0
|
|
|
|
|
warn 'NEWITEM_ELEMS ', $_->as_HTML if $p{debug}; |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
|
335
|
0
|
|
|
|
|
|
push @item_elem, @{$new_item_elems} ; |
|
0
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
|
338
|
0
|
0
|
|
|
|
|
warn 'pushing ' . @item_elem . ' elems' if $p{debug} ; |
339
|
|
|
|
|
|
|
|
340
|
0
|
|
|
|
|
|
$p{splice}->($container, @item_elem); |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
sub HTML::Element::dual_iter { |
344
|
0
|
|
|
0
|
0
|
|
my ($parent, $data) = @_; |
345
|
|
|
|
|
|
|
|
346
|
0
|
|
|
|
|
|
my ($prototype_a, $prototype_b) = $parent->content_list; |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
# my $id_incr = make_counter; |
349
|
|
|
|
|
|
|
|
350
|
0
|
|
|
|
|
|
my $i; |
351
|
|
|
|
|
|
|
|
352
|
0
|
0
|
|
|
|
|
@$data %2 == 0 or confess 'dataset does not contain an even number of members'; |
353
|
|
|
|
|
|
|
|
354
|
0
|
|
|
|
|
|
my @iterable_data = ngroup 2 => @$data; |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
my @item = map { |
357
|
0
|
|
|
|
|
|
my ($new_a, $new_b) = map { clone $_ } ($prototype_a, $prototype_b) ; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
358
|
0
|
|
|
|
|
|
$new_a->splice_content(0,1, $_->[0]); |
359
|
0
|
|
|
|
|
|
$new_b->splice_content(0,1, $_->[1]); |
360
|
|
|
|
|
|
|
#$_->attr('id', $id_incr->($_->attr('id'))) for ($new_a, $new_b) ; |
361
|
0
|
|
|
|
|
|
($new_a, $new_b) |
362
|
|
|
|
|
|
|
} @iterable_data; |
363
|
|
|
|
|
|
|
|
364
|
0
|
|
|
|
|
|
$parent->splice_content(0, 2, @item); |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
sub HTML::Element::set_child_content { ## no critic (RequireArgUnpacking) |
368
|
0
|
|
|
0
|
0
|
|
my $tree = shift; |
369
|
0
|
|
|
|
|
|
my $content = pop; |
370
|
0
|
|
|
|
|
|
my @look_down = @_; |
371
|
|
|
|
|
|
|
|
372
|
0
|
|
|
|
|
|
my $content_tag = $tree->look_down(@look_down); |
373
|
|
|
|
|
|
|
|
374
|
0
|
0
|
|
|
|
|
unless ($content_tag) { |
375
|
0
|
|
|
|
|
|
warn "criteria [@look_down] not found"; |
376
|
0
|
|
|
|
|
|
return; |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
|
379
|
0
|
|
|
|
|
|
$content_tag->replace_content($content); |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
sub HTML::Element::highlander { |
383
|
0
|
|
|
0
|
0
|
|
my ($tree, $local_root_id, $aref, @arg) = @_; |
384
|
|
|
|
|
|
|
|
385
|
0
|
0
|
|
|
|
|
ref $aref eq 'ARRAY' or confess 'must supply array reference'; |
386
|
|
|
|
|
|
|
|
387
|
0
|
|
|
|
|
|
my @aref = @$aref; |
388
|
0
|
0
|
|
|
|
|
@aref % 2 == 0 or confess 'supplied array ref must have an even number of entries'; |
389
|
|
|
|
|
|
|
|
390
|
0
|
0
|
|
|
|
|
warn __PACKAGE__ if $DEBUG; |
391
|
|
|
|
|
|
|
|
392
|
0
|
|
|
|
|
|
my $survivor; |
393
|
0
|
|
|
|
|
|
while (my ($id, $test) = splice @aref, 0, 2) { |
394
|
0
|
0
|
|
|
|
|
warn $id if $DEBUG; |
395
|
0
|
0
|
|
|
|
|
if ($test->(@arg)) { |
396
|
0
|
|
|
|
|
|
$survivor = $id; |
397
|
0
|
|
|
|
|
|
last; |
398
|
|
|
|
|
|
|
} |
399
|
|
|
|
|
|
|
} |
400
|
|
|
|
|
|
|
|
401
|
0
|
|
|
|
|
|
my @id_survivor = (id => $survivor); |
402
|
0
|
|
|
|
|
|
my $survivor_node = $tree->look_down(@id_survivor); |
403
|
|
|
|
|
|
|
# warn $survivor; |
404
|
|
|
|
|
|
|
# warn $local_root_id; |
405
|
|
|
|
|
|
|
# warn $node; |
406
|
|
|
|
|
|
|
|
407
|
0
|
0
|
|
|
|
|
warn "survivor: $survivor" if $DEBUG; |
408
|
0
|
0
|
|
|
|
|
warn 'tree: ' . $tree->as_HTML if $DEBUG; |
409
|
|
|
|
|
|
|
|
410
|
0
|
0
|
|
|
|
|
$survivor_node or die "search for @id_survivor failed in tree($tree): " . $tree->as_HTML; |
411
|
|
|
|
|
|
|
|
412
|
0
|
|
|
|
|
|
my $survivor_node_parent = $survivor_node->parent; |
413
|
0
|
|
|
|
|
|
$survivor_node = $survivor_node->clone; |
414
|
0
|
|
|
|
|
|
$survivor_node_parent->replace_content($survivor_node); |
415
|
|
|
|
|
|
|
|
416
|
0
|
0
|
|
|
|
|
warn 'new tree: ' . $tree->as_HTML if $DEBUG; |
417
|
|
|
|
|
|
|
|
418
|
0
|
|
|
|
|
|
$survivor_node; |
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
sub HTML::Element::highlander2 { ## no critic (RequireArgUnpacking) |
422
|
0
|
|
|
0
|
0
|
|
my $tree = shift; |
423
|
|
|
|
|
|
|
|
424
|
0
|
|
|
|
|
|
my %p = validate(@_, { |
425
|
|
|
|
|
|
|
cond => { type => ARRAYREF }, |
426
|
|
|
|
|
|
|
cond_arg => { |
427
|
|
|
|
|
|
|
type => ARRAYREF, |
428
|
|
|
|
|
|
|
default => [] |
429
|
|
|
|
|
|
|
}, |
430
|
|
|
|
|
|
|
debug => { default => 0 } |
431
|
|
|
|
|
|
|
}); |
432
|
|
|
|
|
|
|
|
433
|
0
|
|
|
|
|
|
my @cond = @{$p{cond}}; |
|
0
|
|
|
|
|
|
|
434
|
0
|
0
|
|
|
|
|
@cond % 2 == 0 or confess 'supplied array ref must have an even number of entries'; |
435
|
|
|
|
|
|
|
|
436
|
0
|
0
|
|
|
|
|
warn __PACKAGE__ if $p{debug}; |
437
|
|
|
|
|
|
|
|
438
|
0
|
|
|
|
|
|
my @cond_arg = @{$p{cond_arg}}; |
|
0
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
|
440
|
0
|
|
|
|
|
|
my $survivor; my $then; |
441
|
0
|
|
|
|
|
|
while (my ($id, $if_then) = splice @cond, 0, 2) { |
442
|
0
|
0
|
|
|
|
|
warn $id if $p{debug}; |
443
|
0
|
|
|
|
|
|
my ($if, $_then); |
444
|
|
|
|
|
|
|
|
445
|
0
|
0
|
|
|
|
|
if (ref $if_then eq 'ARRAY') { |
446
|
0
|
|
|
|
|
|
($if, $_then) = @$if_then; |
447
|
|
|
|
|
|
|
} else { |
448
|
0
|
|
|
0
|
|
|
($if, $_then) = ($if_then, sub {}); |
449
|
|
|
|
|
|
|
} |
450
|
|
|
|
|
|
|
|
451
|
0
|
0
|
|
|
|
|
if ($if->(@cond_arg)) { |
452
|
0
|
|
|
|
|
|
$survivor = $id; |
453
|
0
|
|
|
|
|
|
$then = $_then; |
454
|
0
|
|
|
|
|
|
last; |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
} |
457
|
|
|
|
|
|
|
|
458
|
0
|
0
|
|
|
|
|
my @ld = (ref $survivor eq 'ARRAY') ? @$survivor : (id => $survivor); |
459
|
|
|
|
|
|
|
|
460
|
0
|
0
|
|
|
|
|
warn 'survivor: ', $survivor if $p{debug}; |
461
|
0
|
0
|
|
|
|
|
warn 'survivor_ld: ', Dumper \@ld if $p{debug}; |
462
|
|
|
|
|
|
|
|
463
|
0
|
|
|
|
|
|
my $survivor_node = $tree->look_down(@ld); |
464
|
|
|
|
|
|
|
|
465
|
0
|
0
|
|
|
|
|
$survivor_node or confess "search for @ld failed in tree($tree): " . $tree->as_HTML; |
466
|
|
|
|
|
|
|
|
467
|
0
|
|
|
|
|
|
my $survivor_node_parent = $survivor_node->parent; |
468
|
0
|
|
|
|
|
|
$survivor_node = $survivor_node->clone; |
469
|
0
|
|
|
|
|
|
$survivor_node_parent->replace_content($survivor_node); |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
# **************** NEW FUNCTIONALITY ******************* |
472
|
|
|
|
|
|
|
# apply transforms on survivor node |
473
|
|
|
|
|
|
|
|
474
|
0
|
0
|
|
|
|
|
warn 'SURV::pre_trans ' . $survivor_node->as_HTML if $p{debug}; |
475
|
0
|
|
|
|
|
|
$then->($survivor_node, @cond_arg); |
476
|
0
|
0
|
|
|
|
|
warn 'SURV::post_trans ' . $survivor_node->as_HTML if $p{debug}; |
477
|
|
|
|
|
|
|
# **************** NEW FUNCTIONALITY ******************* |
478
|
|
|
|
|
|
|
|
479
|
0
|
|
|
|
|
|
$survivor_node; |
480
|
|
|
|
|
|
|
} |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
sub overwrite_action { |
483
|
0
|
|
|
0
|
0
|
|
my ($mute_node, %X) = @_; |
484
|
|
|
|
|
|
|
|
485
|
0
|
|
|
|
|
|
$mute_node->attr($X{local_attr}{name} => $X{local_attr}{value}{new}); |
486
|
|
|
|
|
|
|
} |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
sub HTML::Element::overwrite_attr { |
489
|
0
|
|
|
0
|
0
|
|
my $tree = shift; |
490
|
|
|
|
|
|
|
|
491
|
0
|
|
|
|
|
|
$tree->mute_elem(@_, \&overwrite_action); |
492
|
|
|
|
|
|
|
} |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
sub HTML::Element::mute_elem { |
495
|
0
|
|
|
0
|
0
|
|
my ($tree, $mute_attr, $closures, $post_hook) = @_; |
496
|
|
|
|
|
|
|
|
497
|
0
|
|
|
|
|
|
my @mute_node = $tree->look_down($mute_attr => qr/.*/s) ; |
498
|
|
|
|
|
|
|
|
499
|
0
|
|
|
|
|
|
for my $mute_node (@mute_node) { |
500
|
0
|
|
|
|
|
|
my ($local_attr,$mute_key) = split /\s+/s, $mute_node->attr($mute_attr); |
501
|
0
|
|
|
|
|
|
my $local_attr_value_current = $mute_node->attr($local_attr); |
502
|
0
|
|
|
|
|
|
my $local_attr_value_new = $closures->{$mute_key}->($tree, $mute_node, $local_attr_value_current); |
503
|
0
|
0
|
|
|
|
|
$post_hook->( |
504
|
|
|
|
|
|
|
$mute_node, |
505
|
|
|
|
|
|
|
tree => $tree, |
506
|
|
|
|
|
|
|
local_attr => { |
507
|
|
|
|
|
|
|
name => $local_attr, |
508
|
|
|
|
|
|
|
value => { |
509
|
|
|
|
|
|
|
current => $local_attr_value_current, |
510
|
|
|
|
|
|
|
new => $local_attr_value_new |
511
|
|
|
|
|
|
|
} |
512
|
|
|
|
|
|
|
} |
513
|
|
|
|
|
|
|
) if ($post_hook) ; |
514
|
|
|
|
|
|
|
} |
515
|
|
|
|
|
|
|
} |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
sub HTML::Element::table { |
520
|
0
|
|
|
0
|
0
|
|
my ($s, %table) = @_; |
521
|
0
|
|
|
|
|
|
my $table = {}; |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
# Get the table element |
524
|
0
|
|
|
|
|
|
$table->{table_node} = $s->look_down(id => $table{gi_table}); |
525
|
0
|
0
|
|
|
|
|
$table->{table_node} or confess "table tag not found via (id => $table{gi_table}"; |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
# Get the prototype tr element(s) |
528
|
0
|
|
|
|
|
|
my @table_gi_tr = listify $table{gi_tr} ; |
529
|
|
|
|
|
|
|
my @iter_node = map { |
530
|
0
|
|
|
|
|
|
my $tr = $table->{table_node}->look_down(id => $_); |
|
0
|
|
|
|
|
|
|
531
|
0
|
0
|
|
|
|
|
$tr or confess "tr with id => $_ not found"; |
532
|
0
|
|
|
|
|
|
$tr; |
533
|
|
|
|
|
|
|
} @table_gi_tr; |
534
|
|
|
|
|
|
|
|
535
|
0
|
0
|
|
|
|
|
warn 'found ' . @iter_node . ' iter nodes ' if $DEBUG; |
536
|
0
|
|
|
|
|
|
my $iter_node = List::Rotation::Cycle->new(@iter_node); |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
# warn $iter_node; |
539
|
0
|
0
|
|
|
|
|
warn Dumper ($iter_node, \@iter_node) if $DEBUG; |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
# $table->{content} = $table{content}; |
542
|
|
|
|
|
|
|
# $table->{parent} = $table->{table_node}->parent; |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
# $table->{table_node}->detach; |
545
|
|
|
|
|
|
|
# $_->detach for @iter_node; |
546
|
|
|
|
|
|
|
|
547
|
0
|
|
|
|
|
|
my @table_rows; |
548
|
|
|
|
|
|
|
|
549
|
0
|
|
|
|
|
|
while (1) { |
550
|
0
|
|
|
|
|
|
my $row = $table{tr_data}->($table, $table{table_data}); |
551
|
0
|
0
|
|
|
|
|
last unless defined $row; |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
# get a sample table row and clone it. |
554
|
0
|
|
|
|
|
|
my $I = $iter_node->next; |
555
|
0
|
0
|
|
|
|
|
warn "I: $I" if $DEBUG; |
556
|
0
|
|
|
|
|
|
my $new_iter_node = $I->clone; |
557
|
|
|
|
|
|
|
|
558
|
0
|
|
|
|
|
|
$table{td_data}->($new_iter_node, $row); |
559
|
0
|
|
|
|
|
|
push @table_rows, $new_iter_node; |
560
|
|
|
|
|
|
|
} |
561
|
|
|
|
|
|
|
|
562
|
0
|
0
|
|
|
|
|
if (@table_rows) { |
563
|
0
|
|
|
|
|
|
my $replace_with_elem = $s->look_down(id => shift @table_gi_tr) ; |
564
|
0
|
|
|
|
|
|
$s->look_down(id => $_)->detach for @table_gi_tr; |
565
|
0
|
|
|
|
|
|
$replace_with_elem->replace_with(@table_rows); |
566
|
|
|
|
|
|
|
} |
567
|
|
|
|
|
|
|
} |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
sub ref_or_ld { |
570
|
0
|
|
|
0
|
0
|
|
my ($tree, $slot) = @_; |
571
|
|
|
|
|
|
|
|
572
|
0
|
0
|
|
|
|
|
if (ref($slot) eq 'CODE') { |
573
|
0
|
|
|
|
|
|
$slot->($tree); |
574
|
|
|
|
|
|
|
} else { |
575
|
0
|
|
|
|
|
|
$tree->look_down(@$slot); |
576
|
|
|
|
|
|
|
} |
577
|
|
|
|
|
|
|
} |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
sub HTML::Element::table2 { ## no critic (RequireArgUnpacking) |
580
|
0
|
|
|
0
|
0
|
|
my $tree = shift; |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
my %p = validate( |
583
|
|
|
|
|
|
|
@_, { |
584
|
|
|
|
|
|
|
table_ld => { default => ['_tag' => 'table'] }, |
585
|
|
|
|
|
|
|
table_data => 1, |
586
|
|
|
|
|
|
|
table_proc => { default => undef }, |
587
|
|
|
|
|
|
|
tr_ld => { default => ['_tag' => 'tr'] }, |
588
|
|
|
|
|
|
|
tr_data => { |
589
|
|
|
|
|
|
|
default => sub { |
590
|
0
|
|
|
0
|
|
|
my ($self, $data) = @_; |
591
|
0
|
|
|
|
|
|
shift @{$data}; |
|
0
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
}}, |
593
|
|
|
|
|
|
|
tr_base_id => { default => undef }, |
594
|
|
|
|
0
|
|
|
tr_proc => { default => sub {} }, |
595
|
0
|
|
|
|
|
|
td_proc => 1, |
596
|
|
|
|
|
|
|
debug => {default => 0} |
597
|
|
|
|
|
|
|
} |
598
|
|
|
|
|
|
|
); |
599
|
|
|
|
|
|
|
|
600
|
0
|
0
|
|
|
|
|
warn 'INPUT TO TABLE2: ', Dumper \@_ if $p{debug}; |
601
|
0
|
0
|
|
|
|
|
warn 'table_data: ' . Dumper $p{table_data} if $p{debug} ; |
602
|
|
|
|
|
|
|
|
603
|
0
|
|
|
|
|
|
my $table = {}; |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
# Get the table element |
606
|
0
|
|
|
|
|
|
$table->{table_node} = ref_or_ld( $tree, $p{table_ld} ) ; |
607
|
0
|
0
|
|
|
|
|
$table->{table_node} or confess 'table tag not found via ' . Dumper($p{table_ld}) ; |
608
|
|
|
|
|
|
|
|
609
|
0
|
0
|
|
|
|
|
warn 'table: ' . $table->{table_node}->as_HTML if $p{debug}; |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
# Get the prototype tr element(s) |
612
|
0
|
|
|
|
|
|
my @proto_tr = ref_or_ld( $table->{table_node}, $p{tr_ld} ) ; |
613
|
|
|
|
|
|
|
|
614
|
0
|
0
|
|
|
|
|
warn 'found ' . @proto_tr . ' iter nodes' if $p{debug}; |
615
|
|
|
|
|
|
|
|
616
|
0
|
0
|
|
|
|
|
return unless @proto_tr; |
617
|
|
|
|
|
|
|
|
618
|
0
|
0
|
|
|
|
|
if ($p{debug}) { |
619
|
0
|
|
|
|
|
|
warn $_->as_HTML for @proto_tr; |
620
|
|
|
|
|
|
|
} |
621
|
0
|
|
|
|
|
|
my $proto_tr = List::Rotation::Cycle->new(@proto_tr); |
622
|
|
|
|
|
|
|
|
623
|
0
|
|
|
|
|
|
my $tr_parent = $proto_tr[0]->parent; |
624
|
0
|
0
|
|
|
|
|
warn 'parent element of trs: ' . $tr_parent->as_HTML if $p{debug}; |
625
|
|
|
|
|
|
|
|
626
|
0
|
|
|
|
|
|
my $row_count; |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
my @table_rows; |
629
|
|
|
|
|
|
|
|
630
|
0
|
|
|
|
|
|
while(1) { |
631
|
0
|
|
|
|
|
|
my $row = $p{tr_data}->($table, $p{table_data}, $row_count); |
632
|
0
|
0
|
|
|
|
|
warn 'data row: ' . Dumper $row if $p{debug}; |
633
|
0
|
0
|
|
|
|
|
last unless defined $row; |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
# wont work: my $new_iter_node = $table->{iter_node}->clone; |
636
|
0
|
|
|
|
|
|
my $new_tr_node = $proto_tr->next->clone; |
637
|
0
|
0
|
|
|
|
|
warn "new_tr_node: $new_tr_node" if $p{debug}; |
638
|
|
|
|
|
|
|
|
639
|
0
|
0
|
|
|
|
|
$p{tr_proc}->($tree, $new_tr_node, $row, $p{tr_base_id}, ++$row_count) if defined $p{tr_proc}; |
640
|
|
|
|
|
|
|
|
641
|
0
|
0
|
|
|
|
|
warn 'data row redux: ' . Dumper $row if $p{debug}; |
642
|
|
|
|
|
|
|
|
643
|
0
|
|
|
|
|
|
$p{td_proc}->($new_tr_node, $row); |
644
|
0
|
|
|
|
|
|
push @table_rows, $new_tr_node; |
645
|
|
|
|
|
|
|
} |
646
|
|
|
|
|
|
|
|
647
|
0
|
|
|
|
|
|
$_->detach for @proto_tr; |
648
|
|
|
|
|
|
|
|
649
|
0
|
0
|
|
|
|
|
$tr_parent->push_content(@table_rows) if (@table_rows) ; |
650
|
|
|
|
|
|
|
} |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
sub HTML::Element::unroll_select { |
653
|
0
|
|
|
0
|
0
|
|
my ($s, %select) = @_; |
654
|
|
|
|
|
|
|
|
655
|
0
|
|
|
|
|
|
my $select = {}; |
656
|
0
|
0
|
|
|
|
|
warn 'Select Hash: ' . Dumper(\%select) if $select{debug}; |
657
|
|
|
|
|
|
|
|
658
|
0
|
|
|
|
|
|
my $select_node = $s->look_down(id => $select{select_label}); |
659
|
0
|
0
|
|
|
|
|
warn "Select Node: $select_node" if $select{debug}; |
660
|
|
|
|
|
|
|
|
661
|
0
|
0
|
|
|
|
|
unless ($select{append}) { |
662
|
0
|
|
|
|
|
|
for my $option ($select_node->look_down('_tag' => 'option')) { |
663
|
0
|
|
|
|
|
|
$option->delete; |
664
|
|
|
|
|
|
|
} |
665
|
|
|
|
|
|
|
} |
666
|
|
|
|
|
|
|
|
667
|
0
|
|
|
|
|
|
my $option = HTML::Element->new('option'); |
668
|
0
|
0
|
|
|
|
|
warn "Option Node: $option" if $select{debug}; |
669
|
|
|
|
|
|
|
|
670
|
0
|
|
|
|
|
|
$option->detach; |
671
|
|
|
|
|
|
|
|
672
|
0
|
|
|
|
|
|
while (my $row = $select{data_iter}->($select{data})) { |
673
|
0
|
0
|
|
|
|
|
warn 'Data Row: ' . Dumper($row) if $select{debug}; |
674
|
0
|
|
|
|
|
|
my $o = $option->clone; |
675
|
0
|
|
|
|
|
|
$o->attr('value', $select{option_value}->($row)); |
676
|
0
|
0
|
0
|
|
|
|
$o->attr('SELECTED', 1) if (exists $select{option_selected} and $select{option_selected}->($row)); |
677
|
|
|
|
|
|
|
|
678
|
0
|
|
|
|
|
|
$o->replace_content($select{option_content}->($row)); |
679
|
0
|
|
|
|
|
|
$select_node->push_content($o); |
680
|
0
|
0
|
|
|
|
|
warn $o->as_HTML if $select{debug}; |
681
|
|
|
|
|
|
|
} |
682
|
|
|
|
|
|
|
} |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
sub HTML::Element::set_sibling_content { |
685
|
0
|
|
|
0
|
0
|
|
my ($elt, $content) = @_; |
686
|
|
|
|
|
|
|
|
687
|
0
|
|
|
|
|
|
$elt->parent->splice_content($elt->pindex + 1, 1, $content); |
688
|
|
|
|
|
|
|
} |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
sub HTML::TreeBuilder::parse_string { |
691
|
0
|
|
|
0
|
0
|
|
my ($package, $string) = @_; |
692
|
|
|
|
|
|
|
|
693
|
0
|
|
|
|
|
|
my $h = HTML::TreeBuilder->new; |
694
|
0
|
|
|
|
|
|
HTML::TreeBuilder->parse($string); |
695
|
|
|
|
|
|
|
} |
696
|
|
|
|
|
|
|
|
697
|
0
|
|
|
0
|
0
|
|
sub HTML::Element::fid { shift->look_down(id => $_[0]) } |
698
|
0
|
|
|
0
|
0
|
|
sub HTML::Element::fclass { shift->look_down(class => qr/\b$_[0]\b/s) } |
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
1; |
701
|
|
|
|
|
|
|
__END__ |