line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package HTML::DOM::Element::Table; |
2
|
|
|
|
|
|
|
|
3
|
25
|
|
|
25
|
|
80
|
use strict; |
|
25
|
|
|
|
|
19
|
|
|
25
|
|
|
|
|
560
|
|
4
|
25
|
|
|
25
|
|
67
|
use warnings; |
|
25
|
|
|
|
|
21
|
|
|
25
|
|
|
|
|
542
|
|
5
|
|
|
|
|
|
|
|
6
|
25
|
|
|
25
|
|
78
|
use HTML::DOM::Exception qw 'HIERARCHY_REQUEST_ERR INDEX_SIZE_ERR'; |
|
25
|
|
|
|
|
23
|
|
|
25
|
|
|
|
|
53995
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
require HTML::DOM::Collection; |
9
|
|
|
|
|
|
|
require HTML::DOM::Element; |
10
|
|
|
|
|
|
|
#require HTML::DOM::NodeList::Magic; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
our @ISA = qw'HTML::DOM::Element'; |
13
|
|
|
|
|
|
|
our $VERSION = '0.056'; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub caption { |
16
|
13
|
|
|
13
|
1
|
48
|
my $old = ((my $self = shift)->content_list)[0]; |
17
|
13
|
100
|
100
|
|
|
120
|
undef $old unless $old and $old->tag eq 'caption'; |
18
|
13
|
100
|
|
|
|
23
|
if(@_) { |
19
|
4
|
|
|
|
|
5
|
my $new = shift; |
20
|
4
|
|
50
|
|
|
4
|
my $tag = (eval{$new->tag}||''); |
21
|
4
|
50
|
|
|
|
13
|
$tag eq 'caption' or die new HTML'DOM'Exception |
|
|
100
|
|
|
|
|
|
22
|
|
|
|
|
|
|
HIERARCHY_REQUEST_ERR, |
23
|
|
|
|
|
|
|
$tag ? "A $tag element cannot be a table caption" |
24
|
|
|
|
|
|
|
: "Not a valid table caption"; |
25
|
3
|
100
|
|
|
|
6
|
if ($old) { |
26
|
1
|
|
|
|
|
6
|
$self->replaceChild($new, $old); |
27
|
|
|
|
|
|
|
} else { |
28
|
2
|
|
|
|
|
8
|
$self->unshift_content($new) |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
} |
31
|
12
|
|
100
|
|
|
55
|
return $old || (); |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
sub tHead { |
34
|
32
|
|
|
32
|
1
|
35
|
my $self = shift; |
35
|
32
|
|
|
|
|
66
|
for($self->content_list) { |
36
|
42
|
|
|
|
|
67
|
(my $tag = tag $_); |
37
|
42
|
100
|
|
|
|
113
|
if($tag =~ /^t(?:head|body|foot)\z/) { |
38
|
28
|
100
|
|
|
|
41
|
if(@_) { |
39
|
3
|
|
|
|
|
2
|
my $new = shift; |
40
|
3
|
|
50
|
|
|
3
|
my $new_tag = (eval{$new->tag}||''); |
41
|
3
|
50
|
|
|
|
24
|
$new_tag eq 'thead' or die |
|
|
100
|
|
|
|
|
|
42
|
|
|
|
|
|
|
new HTML'DOM'Exception |
43
|
|
|
|
|
|
|
HIERARCHY_REQUEST_ERR, |
44
|
|
|
|
|
|
|
$tag |
45
|
|
|
|
|
|
|
? "A $new_tag element cannot be a table header" |
46
|
|
|
|
|
|
|
: "Not a valid table header"; |
47
|
2
|
|
|
|
|
2
|
$_->${\qw[preinsert replace_with][$tag eq 'thead']}( |
|
2
|
|
|
|
|
9
|
|
48
|
|
|
|
|
|
|
$new |
49
|
|
|
|
|
|
|
); |
50
|
2
|
|
|
|
|
4
|
$self->ownerDocument->_modified; |
51
|
|
|
|
|
|
|
} |
52
|
27
|
100
|
|
|
|
91
|
return $tag eq 'thead' ? $_:(); |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
} |
55
|
4
|
50
|
|
|
|
6
|
@_ and $self->appendChild(shift); |
56
|
4
|
|
|
|
|
9
|
return; |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
sub tFoot { |
59
|
32
|
|
|
32
|
1
|
37
|
my $self = shift; |
60
|
32
|
|
|
|
|
52
|
for($self->content_list) { |
61
|
56
|
|
|
|
|
74
|
(my $tag = tag $_); |
62
|
56
|
100
|
|
|
|
120
|
if($tag =~ /^t(?:body|foot)\z/) { |
63
|
28
|
100
|
|
|
|
37
|
if(@_) { |
64
|
3
|
|
|
|
|
2
|
my $new = shift; |
65
|
3
|
|
50
|
|
|
2
|
my $new_tag = (eval{$new->tag}||''); |
66
|
3
|
50
|
|
|
|
10
|
$new_tag eq 'tfoot' or die |
|
|
100
|
|
|
|
|
|
67
|
|
|
|
|
|
|
new HTML'DOM'Exception |
68
|
|
|
|
|
|
|
HIERARCHY_REQUEST_ERR, |
69
|
|
|
|
|
|
|
$tag |
70
|
|
|
|
|
|
|
? "A $new_tag element cannot be a table footer" |
71
|
|
|
|
|
|
|
: "Not a valid table footer"; |
72
|
2
|
|
|
|
|
2
|
$_->${\qw[preinsert replace_with][$tag eq 'tfoot']}( |
|
2
|
|
|
|
|
7
|
|
73
|
|
|
|
|
|
|
$new |
74
|
|
|
|
|
|
|
); |
75
|
2
|
|
|
|
|
5
|
$self->ownerDocument->_modified; |
76
|
|
|
|
|
|
|
} |
77
|
27
|
100
|
|
|
|
78
|
return $tag eq 'tfoot' ? $_ : (); |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
} |
80
|
4
|
50
|
|
|
|
7
|
@_ and $self->appendChild(shift); |
81
|
4
|
|
|
|
|
11
|
return; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
sub rows { # ~~~ I need to make this cache the resulting collection obj |
84
|
16
|
|
|
16
|
1
|
16
|
my $self = shift; |
85
|
16
|
100
|
|
|
|
25
|
if (wantarray) { |
86
|
|
|
|
|
|
|
# I need a grep in order to exclude text nodes. |
87
|
2
|
|
|
|
|
7
|
return grep tag $_ eq 'tr', map $_->content_list, |
88
|
|
|
|
|
|
|
map $self->$_, qw/ tHead tBodies tFoot /; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
else { |
91
|
|
|
|
|
|
|
my $collection = HTML::DOM::Collection->new( |
92
|
|
|
|
|
|
|
my $list = HTML::DOM::NodeList::Magic->new( |
93
|
18
|
|
|
18
|
|
41
|
sub { grep tag $_ eq 'tr', map $_->content_list, |
94
|
|
|
|
|
|
|
map $self->$_, qw/ tHead tBodies tFoot /; } |
95
|
14
|
|
|
|
|
66
|
)); |
96
|
14
|
|
|
|
|
35
|
$self->ownerDocument-> _register_magic_node_list($list); |
97
|
14
|
|
|
|
|
252
|
$collection; |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
sub tBodies { # ~~~ I need to make this cache the resulting collection obj |
101
|
26
|
|
|
26
|
1
|
25
|
my $self = shift; |
102
|
26
|
100
|
|
|
|
36
|
if (wantarray) { |
103
|
21
|
|
|
|
|
35
|
return grep tag $_ eq 'tbody', $self->content_list; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
else { |
106
|
|
|
|
|
|
|
my $collection = HTML::DOM::Collection->new( |
107
|
|
|
|
|
|
|
my $list = HTML::DOM::NodeList::Magic->new( |
108
|
5
|
|
|
5
|
|
11
|
sub { grep tag $_ eq 'tbody', $self->content_list } |
109
|
5
|
|
|
|
|
21
|
)); |
110
|
5
|
|
|
|
|
10
|
$self->ownerDocument-> _register_magic_node_list($list); |
111
|
5
|
|
|
|
|
71
|
$collection; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
} |
114
|
30
|
|
|
30
|
1
|
2522
|
sub align { lc shift->_attr('align' => @_) } |
115
|
15
|
|
|
15
|
1
|
2034
|
sub bgColor { shift->_attr('bgcolor' => @_) } |
116
|
5
|
|
|
5
|
1
|
691
|
sub border { shift->_attr( border => @_) } |
117
|
5
|
|
|
5
|
1
|
672
|
sub cellPadding { shift->_attr('cellpadding' => @_) } |
118
|
5
|
|
|
5
|
1
|
706
|
sub cellSpacing { shift->_attr('cellspacing' => @_) } |
119
|
5
|
|
|
5
|
1
|
675
|
sub frame { shift->_attr('frame' => @_) } |
120
|
5
|
|
|
5
|
1
|
676
|
sub rules { lc shift->_attr('rules' => @_) } |
121
|
5
|
|
|
5
|
1
|
718
|
sub summary { shift->_attr('summary' => @_) } |
122
|
10
|
|
|
10
|
1
|
1351
|
sub width { shift->_attr('width' => @_) } |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
sub createTHead { |
125
|
2
|
|
|
2
|
1
|
2
|
my $self = shift; |
126
|
2
|
|
|
|
|
3
|
my $th = $self->tHead; |
127
|
2
|
100
|
|
|
|
5
|
$th and return $th; |
128
|
|
|
|
|
|
|
|
129
|
1
|
|
|
|
|
2
|
my $inserted; |
130
|
1
|
|
|
|
|
2
|
$th = $self->ownerDocument->createElement('thead'); |
131
|
1
|
|
|
|
|
2
|
for($self->content_list) { |
132
|
1
|
50
|
|
|
|
2
|
next if tag $_ =~ /^c(?:aption|ol(?:group)?)\z/; |
133
|
1
|
|
|
|
|
3
|
$_->preinsert($th), ++$inserted, |
134
|
|
|
|
|
|
|
$self->ownerDocument->_modified, last |
135
|
|
|
|
|
|
|
} |
136
|
1
|
50
|
|
|
|
3
|
$self->appendChild($th) unless $inserted; |
137
|
|
|
|
|
|
|
|
138
|
1
|
|
|
|
|
5
|
$th |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub deleteTHead { |
142
|
1
|
|
|
1
|
1
|
1
|
my $self = shift; |
143
|
1
|
|
50
|
|
|
2
|
($self->tHead||return)->delete; # ~~~ once I weaken upward refs, should I make this less destructive? |
144
|
1
|
|
|
|
|
8
|
$self->ownerDocument->_modified; |
145
|
1
|
|
|
|
|
3
|
return; |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
sub createTFoot { |
149
|
2
|
|
|
2
|
1
|
3
|
my $self = shift; |
150
|
2
|
|
|
|
|
4
|
my $tf = $self->tFoot; |
151
|
2
|
100
|
|
|
|
6
|
$tf and return $tf; |
152
|
|
|
|
|
|
|
|
153
|
1
|
|
|
|
|
1
|
my $inserted; |
154
|
1
|
|
|
|
|
3
|
$tf = $self->ownerDocument->createElement('tfoot'); |
155
|
1
|
|
|
|
|
3
|
for($self->content_list) { |
156
|
2
|
100
|
|
|
|
4
|
next if tag $_ =~ /^(?:c(?:aption|ol(?:group)?)|thead)\z/; |
157
|
1
|
|
|
|
|
3
|
$_->preinsert($tf), ++$inserted, |
158
|
|
|
|
|
|
|
$self->ownerDocument->_modified, last |
159
|
|
|
|
|
|
|
} |
160
|
1
|
50
|
|
|
|
2
|
$self->appendChild($tf) unless $inserted; |
161
|
|
|
|
|
|
|
|
162
|
1
|
|
|
|
|
3
|
$tf |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub deleteTFoot { |
166
|
1
|
|
|
1
|
1
|
2
|
my $self = shift; |
167
|
1
|
|
50
|
|
|
2
|
($self->tFoot||return)->delete; # ~~~ once I weaken upward refs, should I make this less destructive? |
168
|
1
|
|
|
|
|
3
|
$self->ownerDocument->_modified; |
169
|
1
|
|
|
|
|
3
|
return; |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
sub createCaption { |
173
|
2
|
|
|
2
|
1
|
2
|
my $self = shift; my $th; |
|
2
|
|
|
|
|
2
|
|
174
|
2
|
100
|
|
|
|
3
|
$self->caption or |
175
|
|
|
|
|
|
|
$self->unshift_content($th = |
176
|
|
|
|
|
|
|
$self->ownerDocument->createElement('caption')), |
177
|
|
|
|
|
|
|
$self->ownerDocument->_modified, |
178
|
|
|
|
|
|
|
$th; |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
sub deleteCaption { |
182
|
1
|
|
|
1
|
1
|
2
|
my $self = shift; |
183
|
1
|
|
50
|
|
|
2
|
($self->caption||return)->delete; # ~~~ once I weaken upward refs, should I make this less destructive? |
184
|
1
|
|
|
|
|
6
|
$self->ownerDocument->_modified; |
185
|
1
|
|
|
|
|
3
|
return; |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
sub insertRow { |
189
|
9
|
|
|
9
|
1
|
15
|
my $self = shift; |
190
|
9
|
|
|
|
|
9
|
my $ix = shift; |
191
|
9
|
|
|
|
|
12
|
my $len = (my $rows = $self->rows)->length; |
192
|
9
|
|
|
|
|
21
|
my $row = $self->ownerDocument->createElement('tr'); |
193
|
9
|
100
|
100
|
|
|
43
|
if(!$len) { # worst case |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
|
|
|
|
|
194
|
2
|
50
|
|
|
|
4
|
if(my $tb = $self->tBodies->item(0)) { |
195
|
0
|
|
|
|
|
0
|
$tb->appendChild($row); |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
else { |
198
|
2
|
|
|
|
|
5
|
(my $tb = $self->ownerDocument |
199
|
|
|
|
|
|
|
->createElement('tbody')) |
200
|
|
|
|
|
|
|
->appendChild($row); |
201
|
2
|
|
|
|
|
5
|
$self->appendChild($tb); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
elsif($ix == -1 || $ix == $len) { |
205
|
2
|
|
|
|
|
39
|
$rows->item(-1)->postinsert( |
206
|
|
|
|
|
|
|
$row |
207
|
|
|
|
|
|
|
); |
208
|
2
|
|
|
|
|
3
|
$self->ownerDocument->_modified; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
elsif($ix < $len && $ix >= 0) { |
211
|
3
|
|
|
|
|
59
|
$rows->item($ix)->preinsert($row); |
212
|
3
|
|
|
|
|
6
|
$self->ownerDocument->_modified |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
else { |
215
|
2
|
|
|
|
|
11
|
die new HTML::DOM::Exception INDEX_SIZE_ERR, |
216
|
|
|
|
|
|
|
"Index $ix is out of range" |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
|
219
|
7
|
|
|
|
|
39
|
return $row; |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
sub deleteRow { |
223
|
2
|
|
|
2
|
1
|
8
|
my $self = shift; |
224
|
2
|
|
50
|
|
|
3
|
($self->rows->item(shift)||return)->delete; # ~~~ once I weaken upward refs, should I make this less destructive? |
225
|
2
|
|
|
|
|
10
|
$self->ownerDocument->_modified; |
226
|
2
|
|
|
|
|
7
|
return; |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
=head1 NAME |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
HTML::DOM::Element::Table - A Perl class for representing 'table' elements in an HTML DOM tree |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=head1 VERSION |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
Version 0.056 |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
=head1 SYNOPSIS |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
use HTML::DOM; |
241
|
|
|
|
|
|
|
$doc = HTML::DOM->new; |
242
|
|
|
|
|
|
|
$elem = $doc->createElement('table'); |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
$elem->tHead; |
245
|
|
|
|
|
|
|
$elem->tBodies->[0]; |
246
|
|
|
|
|
|
|
$elem->createTFoot; |
247
|
|
|
|
|
|
|
# etc |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=head1 DESCRIPTION |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
This class represents 'table' elements in an HTML::DOM tree. It implements the HTMLTableElement DOM interface and inherits from L |
252
|
|
|
|
|
|
|
(q.v.). |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
=head1 METHODS |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
In addition to those inherited from HTML::DOM::Element and its |
257
|
|
|
|
|
|
|
superclasses, this class implements the following DOM methods: |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=over 4 |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
=item caption |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=item tHead |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
=item tFoot |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
Each of these returns the table's corresponding element, if it exists, or |
268
|
|
|
|
|
|
|
an empty list otherwise. |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=item rows |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
Returns a collection of all table row elements, or a list in list context. |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=item tBodies |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
Returns a collection of all 'tbody' elements, or a list in list context. |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
=item align |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=item bgColor |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=item border |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=item cellPadding |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
=item cellSpacing |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=item frame |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=item rules |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=item summary |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=item width |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
These get (optionally set) the corresponding HTML attributes. |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=item createTHead |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
Returns the table's 'thead' element, creating it if it doesn't exist. |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=item deleteTHead |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
Deletes the table's 'thead' element. |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=item createTFoot |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
Returns the table's 'tfoot' element, creating it if it doesn't exist. |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=item deleteTFoot |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
Does what you would think. |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=item createCaption |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
Returns the table's 'caption' element, creating it if it doesn't exist. |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=item deleteCaption |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
Deletes the caption. |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=item insertRow |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
Insert a new 'tr' element at the index specified by the first argument, and |
325
|
|
|
|
|
|
|
returns that new row. |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
=item deleteRow |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
Deletes the row at the index specified by the first arg. |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=back |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=head1 SEE ALSO |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
L |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
L |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
L |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
L |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
L |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
L |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
L |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=cut |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
# ------- HTMLTableCaptionElement interface ---------- # |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
package HTML::DOM::Element::Caption; |
355
|
|
|
|
|
|
|
our $VERSION = '0.056'; |
356
|
|
|
|
|
|
|
our @ISA = 'HTML::DOM::Element'; |
357
|
|
|
|
|
|
|
*align = \&HTML::DOM::Element::Table::align; |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
# ------- HTMLTableColElement interface ---------- # |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
package HTML::DOM::Element::TableColumn; |
362
|
|
|
|
|
|
|
our $VERSION = '0.056'; |
363
|
|
|
|
|
|
|
our @ISA = 'HTML::DOM::Element'; |
364
|
|
|
|
|
|
|
*align = \&HTML::DOM::Element::Table::align; |
365
|
20
|
|
|
20
|
|
3196
|
sub ch { shift->_attr('char' => @_) } |
366
|
20
|
|
|
20
|
|
3250
|
sub chOff { shift->_attr( charoff => @_) } |
367
|
5
|
|
|
5
|
|
924
|
sub span { shift->_attr('span' => @_) } |
368
|
20
|
|
|
20
|
|
3542
|
sub vAlign { lc shift->_attr('valign' => @_) } |
369
|
5
|
|
|
5
|
|
925
|
sub width { shift->_attr('width' => @_) } |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
# ------- HTMLTableSectionElement interface ---------- # |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
package HTML::DOM::Element::TableSection; |
374
|
|
|
|
|
|
|
our $VERSION = '0.056'; |
375
|
|
|
|
|
|
|
our @ISA = 'HTML::DOM::Element'; |
376
|
|
|
|
|
|
|
*align = \&HTML::DOM::Element::Table::align; |
377
|
|
|
|
|
|
|
*ch = \&HTML::DOM::Element::TableColumn::ch; |
378
|
|
|
|
|
|
|
*chOff = \&HTML::DOM::Element::TableColumn::chOff; |
379
|
|
|
|
|
|
|
*vAlign = \&HTML::DOM::Element::TableColumn::vAlign; |
380
|
|
|
|
|
|
|
sub rows { # ~~~ I need to make this cache the resulting collection obj |
381
|
15
|
|
|
15
|
|
254
|
my $self = shift; |
382
|
15
|
100
|
|
|
|
21
|
if (wantarray) { |
383
|
|
|
|
|
|
|
# I need a grep in order to exclude text nodes. |
384
|
3
|
|
|
|
|
8
|
return grep tag $_ eq 'tr', $self->content_list, |
385
|
|
|
|
|
|
|
} |
386
|
|
|
|
|
|
|
else { |
387
|
|
|
|
|
|
|
my $collection = HTML::DOM::Collection->new( |
388
|
|
|
|
|
|
|
my $list = HTML::DOM::NodeList::Magic->new( |
389
|
16
|
|
|
16
|
|
35
|
sub { grep tag $_ eq 'tr', $self->content_list; } |
390
|
12
|
|
|
|
|
51
|
)); |
391
|
12
|
|
|
|
|
24
|
$self->ownerDocument-> _register_magic_node_list($list); |
392
|
12
|
|
|
|
|
207
|
$collection; |
393
|
|
|
|
|
|
|
} |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
sub insertRow { |
396
|
7
|
|
|
7
|
|
12
|
my $self = shift; |
397
|
7
|
|
100
|
|
|
17
|
my $ix = shift||0; |
398
|
7
|
|
|
|
|
9
|
my $len = (my $rows = $self->rows)->length; |
399
|
7
|
|
|
|
|
14
|
my $row = $self->ownerDocument->createElement('tr'); |
400
|
7
|
100
|
100
|
|
|
35
|
if(!$len) { |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
|
|
|
|
|
401
|
1
|
|
|
|
|
3
|
$self->appendChild($row); |
402
|
|
|
|
|
|
|
} |
403
|
|
|
|
|
|
|
elsif($ix == -1 || $ix == $len) { |
404
|
2
|
|
|
|
|
38
|
$rows->item(-1)->postinsert( |
405
|
|
|
|
|
|
|
$row |
406
|
|
|
|
|
|
|
); |
407
|
2
|
|
|
|
|
5
|
$self->ownerDocument->_modified; |
408
|
|
|
|
|
|
|
} |
409
|
|
|
|
|
|
|
elsif($ix < $len && $ix >= 0) { |
410
|
2
|
|
|
|
|
39
|
$rows->item($ix)->preinsert($row); |
411
|
2
|
|
|
|
|
3
|
$self->ownerDocument->_modified; |
412
|
|
|
|
|
|
|
} |
413
|
|
|
|
|
|
|
else { |
414
|
2
|
|
|
|
|
8
|
die new HTML::DOM::Exception |
415
|
|
|
|
|
|
|
HTML::DOM::Exception::INDEX_SIZE_ERR, |
416
|
|
|
|
|
|
|
"Index $ix is out of range" |
417
|
|
|
|
|
|
|
} |
418
|
|
|
|
|
|
|
|
419
|
5
|
|
|
|
|
25
|
return $row; |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
*deleteRow = \&HTML::DOM::Element::Table::deleteRow; |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
# ------- HTMLTableRowElement interface ---------- # |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
package HTML::DOM::Element::TR; |
427
|
|
|
|
|
|
|
our $VERSION = '0.056'; |
428
|
|
|
|
|
|
|
our @ISA = 'HTML::DOM::Element'; |
429
|
|
|
|
|
|
|
sub rowIndex { |
430
|
1
|
|
|
1
|
|
1
|
my $self = shift; |
431
|
1
|
|
|
|
|
1
|
my $ix = 0; |
432
|
1
|
|
|
|
|
7
|
for($self->look_up(_tag => 'table')->rows){ |
433
|
2
|
100
|
|
|
|
6
|
return $ix if $self == $_; |
434
|
1
|
|
|
|
|
1
|
$ix++ |
435
|
|
|
|
|
|
|
} |
436
|
0
|
|
|
|
|
0
|
die "Internal error in HTML::DOM::Element::TR::rowIndex: " . |
437
|
|
|
|
|
|
|
"This table row is not inside the table it is inside. " . |
438
|
|
|
|
|
|
|
"Please report this bug." |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
sub sectionRowIndex { |
441
|
1
|
|
|
1
|
|
1
|
my $self = shift; |
442
|
1
|
|
|
|
|
3
|
my $parent = $self->parent; |
443
|
1
|
|
|
|
|
5
|
while(!$parent->isa('HTML::DOM::Element::TableSection')) { |
444
|
|
|
|
|
|
|
# If we get here, there is probably something wrong, should |
445
|
|
|
|
|
|
|
# I just throw an error instead? |
446
|
0
|
|
|
|
|
0
|
$parent = $parent->parent; |
447
|
|
|
|
|
|
|
} |
448
|
1
|
|
|
|
|
1
|
my $ix = 0; |
449
|
1
|
|
|
|
|
2
|
for($parent->rows){ |
450
|
1
|
50
|
|
|
|
5
|
return $ix if $self == $_; |
451
|
0
|
|
|
|
|
0
|
$ix++ |
452
|
|
|
|
|
|
|
} |
453
|
0
|
|
|
|
|
0
|
die "Internal error in HTML::DOM::Element::TR::sectionRowIndex: " . |
454
|
|
|
|
|
|
|
"This table row is not inside the table section it is " . |
455
|
|
|
|
|
|
|
"inside. Please report this bug." |
456
|
|
|
|
|
|
|
} |
457
|
|
|
|
|
|
|
sub cells { # ~~~ I need to make this cache the resulting collection obj |
458
|
11
|
|
|
11
|
|
11
|
my $self = shift; |
459
|
11
|
100
|
|
|
|
14
|
if (wantarray) { |
460
|
|
|
|
|
|
|
# I need a grep in order to exclude text nodes. |
461
|
3
|
|
|
|
|
8
|
return grep tag $_ =~ /^t[hd]\z/, $self->content_list, |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
else { |
464
|
|
|
|
|
|
|
my $collection = HTML::DOM::Collection->new( |
465
|
|
|
|
|
|
|
my $list = HTML::DOM::NodeList::Magic->new( |
466
|
14
|
|
|
14
|
|
32
|
sub { grep tag $_ =~ /^t[hd]\z/, $self->content_list; } |
467
|
8
|
|
|
|
|
38
|
)); |
468
|
8
|
|
|
|
|
20
|
$self->ownerDocument-> _register_magic_node_list($list); |
469
|
8
|
|
|
|
|
170
|
$collection; |
470
|
|
|
|
|
|
|
} |
471
|
|
|
|
|
|
|
} |
472
|
|
|
|
|
|
|
*align = \&HTML::DOM::Element::Table::align; |
473
|
|
|
|
|
|
|
*bgColor = \&HTML::DOM::Element::Table::bgColor; |
474
|
|
|
|
|
|
|
*ch = \&HTML::DOM::Element::TableColumn::ch; |
475
|
|
|
|
|
|
|
*chOff = \&HTML::DOM::Element::TableColumn::chOff; |
476
|
|
|
|
|
|
|
*vAlign = \&HTML::DOM::Element::TableColumn::vAlign; |
477
|
|
|
|
|
|
|
sub insertCell { |
478
|
6
|
|
|
6
|
|
7
|
my $self = shift; |
479
|
6
|
|
100
|
|
|
15
|
my $ix = shift||0; |
480
|
6
|
|
|
|
|
9
|
my $len = (my $cels = $self->cells)->length; |
481
|
6
|
|
|
|
|
13
|
my $cel = $self->ownerDocument->createElement('td'); |
482
|
6
|
50
|
100
|
|
|
35
|
if(!$len) { |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
|
|
|
|
|
483
|
0
|
|
|
|
|
0
|
$self->appendChild($cel); |
484
|
|
|
|
|
|
|
} |
485
|
|
|
|
|
|
|
elsif($ix == -1 || $ix == $len) { |
486
|
2
|
|
|
|
|
38
|
$cels->item(-1)->postinsert( |
487
|
|
|
|
|
|
|
$cel |
488
|
|
|
|
|
|
|
); |
489
|
2
|
|
|
|
|
5
|
$self->ownerDocument->_modified; |
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
elsif($ix < $len && $ix >= 0) { |
492
|
2
|
|
|
|
|
40
|
$cels->item($ix)->preinsert($cel); |
493
|
2
|
|
|
|
|
4
|
$self->ownerDocument->_modified; |
494
|
|
|
|
|
|
|
} |
495
|
|
|
|
|
|
|
else { |
496
|
2
|
|
|
|
|
8
|
die new HTML::DOM::Exception |
497
|
|
|
|
|
|
|
HTML::DOM::Exception::INDEX_SIZE_ERR, |
498
|
|
|
|
|
|
|
"Index $ix is out of range" |
499
|
|
|
|
|
|
|
} |
500
|
|
|
|
|
|
|
|
501
|
4
|
|
|
|
|
23
|
return $cel; |
502
|
|
|
|
|
|
|
} |
503
|
|
|
|
|
|
|
sub deleteCell { |
504
|
1
|
|
|
1
|
|
4
|
my $self = shift; |
505
|
1
|
|
50
|
|
|
3
|
($self->cells->item(shift)||return)->delete; # ~~~ once I weaken upward refs, should I make this less destructive? |
506
|
1
|
|
|
|
|
6
|
$self->ownerDocument->_modified; |
507
|
1
|
|
|
|
|
4
|
return; |
508
|
|
|
|
|
|
|
} |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
# ------- HTMLTableCellElement interface ---------- # |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
package HTML::DOM::Element::TableCell; |
513
|
|
|
|
|
|
|
our $VERSION = '0.056'; |
514
|
|
|
|
|
|
|
our @ISA = 'HTML::DOM::Element'; |
515
|
|
|
|
|
|
|
sub cellIndex { |
516
|
1
|
|
|
1
|
|
4
|
my $self = shift; |
517
|
1
|
|
|
|
|
2
|
my $ix = 0; |
518
|
1
|
|
|
|
|
3
|
for($self->parent->cells){ |
519
|
1
|
50
|
|
|
|
6
|
return $ix if $self == $_; |
520
|
0
|
|
|
|
|
0
|
$ix++ |
521
|
|
|
|
|
|
|
} |
522
|
0
|
|
|
|
|
0
|
die "Internal error in HTML::DOM::Element::TR::rowIndex: " . |
523
|
|
|
|
|
|
|
"This table row is not inside the table it is inside. " . |
524
|
|
|
|
|
|
|
"Please report this bug." |
525
|
|
|
|
|
|
|
} |
526
|
5
|
|
|
5
|
|
357
|
sub abbr { shift->_attr('abbr' => @_) } |
527
|
|
|
|
|
|
|
*align = \&HTML::DOM::Element::Table::align; |
528
|
5
|
|
|
5
|
|
723
|
sub axis { shift->_attr('axis' => @_) } |
529
|
|
|
|
|
|
|
*bgColor = \&HTML::DOM::Element::Table::bgColor; |
530
|
|
|
|
|
|
|
*ch = \&HTML::DOM::Element::TableColumn::ch; |
531
|
|
|
|
|
|
|
*chOff = \&HTML::DOM::Element::TableColumn::chOff; |
532
|
5
|
|
|
5
|
|
676
|
sub colSpan { shift->_attr('colspan' => @_) } |
533
|
5
|
|
|
5
|
|
678
|
sub headers { shift->_attr('headers' => @_) } |
534
|
5
|
|
|
5
|
|
672
|
sub height { shift->_attr('height' => @_) } |
535
|
6
|
100
|
|
6
|
|
51
|
sub noWrap { shift->_attr(nowrap => @_ ? $_[0] ? 'nowrap' : undef : ()) } |
|
|
100
|
|
|
|
|
|
536
|
5
|
|
|
5
|
|
672
|
sub rowSpan { shift->_attr('rowspan' => @_) } |
537
|
5
|
|
|
5
|
|
679
|
sub scope { lc shift->_attr('scope' => @_) } |
538
|
|
|
|
|
|
|
*vAlign = \&HTML::DOM::Element::TableColumn::vAlign; |
539
|
|
|
|
|
|
|
*width = \&HTML::DOM::Element::Table::width; |
540
|
|
|
|
|
|
|
|