File Coverage

lib/HTML/Object/DOM/Element/TableSection.pm
Criterion Covered Total %
statement 72 102 70.5
branch 17 46 36.9
condition 9 26 34.6
subroutine 17 21 80.9
pod 8 8 100.0
total 123 203 60.5


line stmt bran cond sub pod time code
1             ##----------------------------------------------------------------------------
2             ## HTML Object - ~/lib/HTML/Object/DOM/Element/TableSection.pm
3             ## Version v0.2.0
4             ## Copyright(c) 2021 DEGUEST Pte. Ltd.
5             ## Author: Jacques Deguest <jack@deguest.jp>
6             ## Created 2021/12/23
7             ## Modified 2022/09/18
8             ## All rights reserved
9             ##
10             ##
11             ## This program is free software; you can redistribute it and/or modify it
12             ## under the same terms as Perl itself.
13             ##----------------------------------------------------------------------------
14             package HTML::Object::DOM::Element::TableSection;
15             BEGIN
16             {
17 2     2   2041 use strict;
  2         4  
  2         69  
18 2     2   13 use warnings;
  2         5  
  2         71  
19 2     2   13 use parent qw( HTML::Object::DOM::Element );
  2         5  
  2         12  
20 2     2   168 use vars qw( $VERSION );
  2         4  
  2         96  
21 2     2   12 use HTML::Object::DOM::Element::Shared qw( :tablesection );
  2         5  
  2         298  
22 2     2   42 our $VERSION = 'v0.2.0';
23             };
24              
25 2     2   16 use strict;
  2         4  
  2         65  
26 2     2   11 use warnings;
  2         6  
  2         2625  
27              
28             sub init
29             {
30 6     6 1 557 my $self = shift( @_ );
31             # could also be tbody o tfoot
32 6 50 33     185 $self->{tag} = 'thead' if( !defined( $self->{tag} ) || !CORE::length( "$self->{tag}" ) );
33 6         20 $self->{_init_strict_use_sub} = 1;
34 6 50       77 $self->SUPER::init( @_ ) || return( $self->pass_error );
35 6         22 $self->{_section_reset} = 1;
36             my $callback = sub
37             {
38 15     15   2183 my $def = shift( @_ );
39             # Our children were modified from outside our package.
40             # We need to check if it affects our rows and reset the cache accordingly
41 15 100 100     161 unless( $def->{caller}->[0] eq ref( $self ) ||
42             $def->{caller}->[0] eq 'HTML::Object::DOM::Element::Table' )
43             {
44 13         51 $self->reset(1);
45             }
46 15         101 return(1);
47 6         33 };
48 6         25 $self->children->callback( add => $callback );
49 6         891 $self->children->callback( remove => $callback );
50 6         663 return( $self );
51             }
52              
53             # Note: deprecated property align is inherited
54              
55             # Note: deprecated property ch
56 0     0 1 0 sub ch : lvalue { return( shift->_set_get_property( 'ch', @_ ) ); }
57              
58             # Note: deprecated property chOff
59 0     0 1 0 sub chOff : lvalue { return( shift->_set_get_property( 'choff', @_ ) ); }
60              
61             sub deleteRow
62             {
63 0     0 1 0 my $self = shift( @_ );
64 0         0 my $pos = shift( @_ );
65 0 0 0     0 return( $self->error({
      0        
66             message => "Value provided (" . overload::StrVal( $pos // '' ) . ") is not an integer.",
67             class => 'HTML::Object::IndexSizeError',
68             }) ) if( !defined( $pos ) || !$self->_is_integer( $pos ) );
69 0         0 my $rows = $self->rows;
70 0         0 my $size = $rows->size;
71 0 0       0 return( $self->error({
72             message => "Value provided ($pos) is greater than the zero-based number of rows available (" . $rows->size . ").",
73             class => 'HTML::Object::IndexSizeError',
74             }) ) if( $pos > $size );
75 0 0 0     0 return( $self->error({
76             message => "Value provided ($pos) is lower than the zero-based number of rows available (" . $rows->size . "). If you want to specify a negative index, it must be between -1 and -${size}",
77             class => 'HTML::Object::IndexSizeError',
78             }) ) if( $pos < 0 && abs( $pos ) > $size );
79 0 0       0 $pos = ( $rows->length + $pos ) if( $pos < 0 );
80 0         0 my $elem = $rows->index( $pos );
81 0         0 my $children = $self->children;
82 0         0 my $kid_pos = $children->pos( $elem );
83 0 0       0 return( $self->error({
84             message => "Unable to find the row element among this table children!",
85             class => 'HTML::Object::HierarchyRequestError',
86             }) ) if( !defined( $kid_pos ) );
87 0         0 $children->splice( $kid_pos, 1 );
88 0         0 $elem->parent( undef );
89 0         0 $self->reset(1);
90 0         0 return( $elem );
91             }
92              
93             sub insertRow
94             {
95 1     1 1 4 my $self = shift( @_ );
96 1         3 my $pos = shift( @_ );
97 1         6 my $rows = $self->rows;
98 1         8 my $size = $rows->size;
99 1 50       36950 if( defined( $pos ) )
100             {
101 0 0 0     0 return( $self->error({
102             message => "Value provided (" . overload::StrVal( $pos // '' ) . ") is not an integer.",
103             class => 'HTML::Object::IndexSizeError',
104             }) ) if( !$self->_is_integer( $pos ) );
105 0 0       0 return( $self->error({
106             message => "Value provided ($pos) is greater than the zero-based number of rows available (" . $rows->size . ").",
107             class => 'HTML::Object::IndexSizeError',
108             }) ) if( $pos > $size );
109 0 0 0     0 return( $self->error({
110             message => "Value provided ($pos) is lower than the zero-based number of rows available (" . $rows->size . "). If you want to specify a negative index, it must be between -1 and -${size}",
111             class => 'HTML::Object::IndexSizeError',
112             }) ) if( $pos < 0 && abs( $pos ) > $size );
113 0 0       0 $pos = ( $rows->length + $pos ) if( $pos < 0 );
114             }
115 1 50       7 $self->_load_class( 'HTML::Object::DOM::Element::TableRow' ) || return( $self->pass_error );
116 1         50 my $children = $self->children;
117 1   50     121 my $row = HTML::Object::DOM::Element::TableRow->new( @_ ) ||
118             return( $self->pass_error( HTML::Object::DOM::Element::TableRow->error ) );
119 1         22 $row->close;
120             # A position was provided
121 1 50       5 if( defined( $pos ) )
122             {
123             # ..., but there are no rows yet
124 0 0       0 if( $rows->is_empty )
125             {
126 0         0 $children->push( $row );
127             }
128             else
129             {
130 0         0 my $elem = $rows->index( $pos );
131 0         0 my $kid_pos = $children->pos( $elem );
132 0 0       0 if( !defined( $kid_pos ) )
133             {
134 0         0 return( $self->error({
135             message => "Could not find a value at offset $pos (translated to $kid_pos among the table children) amazingly enough.",
136             class => 'HTML::Object::HierarchyRequestError',
137             }) );
138             }
139 0         0 $children->splice( $kid_pos, 0, $row );
140             }
141             }
142             # otherwise, there are already other rows directly under <table> and the new row is just added at the end of the table, even if there is a <tfoot> element.
143             else
144             {
145 1         8 $children->push( $row );
146             }
147 1         16 $row->parent( $self );
148 1         47 $self->reset(1);
149 1         7 return( $row );
150             }
151              
152             sub reset
153             {
154 329     329 1 1025 my $self = shift( @_ );
155 329 100       727 if( scalar( @_ ) )
156             {
157 62         219 $self->_reset_section;
158 62         191 return( $self->SUPER::reset( @_ ) );
159             }
160 267         948 return( $self );
161             }
162              
163             # Note: property rows read-only
164             sub rows
165             {
166 142     142 1 6312 my $self = shift( @_ );
167 142 100 100     571 return( $self->{_section_rows} ) if( $self->{_section_rows} && !$self->_is_section_reset );
168 102     177   335 my $list = $self->children->grep(sub{ $self->_is_a( $_ => 'HTML::Object::DOM::Element::TableRow' ) });
  177         9948  
169 102 100       14523 unless( $self->{_section_rows} )
170             {
171 6 50       30 $self->_load_class( 'HTML::Object::DOM::Collection' ) || return( $self->pass_error );
172 6   50     239 $self->{_section_rows} = HTML::Object::DOM::Collection->new ||
173             return( $self->pass_error( HTML::Object::DOM::Collection->error ) );
174             }
175 102         383 $self->{_section_rows}->set( $list );
176 102         1501 $self->_remove_section_reset;
177 102         385 return( $self->{_section_rows} );
178             }
179              
180             # Note: deprecated property vAlign
181 0     0 1 0 sub vAlign : lvalue { return( shift->_set_get_property( 'valign', @_ ) ); }
182              
183 136     136   741 sub _is_section_reset { return( CORE::length( shift->{_section_reset} ) ); }
184              
185 102     102   265 sub _remove_section_reset { return( CORE::delete( shift->{_section_reset} ) ); }
186              
187             sub _reset_section
188             {
189 102     102   200 my $self = shift( @_ );
190 102         297 $self->{_section_reset}++;
191             # Force cells object update
192 102         315 $self->rows;
193 102 100       1930 if( my $parent = $self->parent )
194             {
195 78 50       2463 $parent->_reset_table( $self->{tag} ) if( $parent->can( '_reset_table' ) );
196             }
197 102         719 return( $self );
198             }
199              
200             1;
201             # NOTE: POD
202             __END__
203              
204             =encoding utf-8
205              
206             =head1 NAME
207              
208             HTML::Object::DOM::Element::TableSection - HTML Object DOM TableSection Class
209              
210             =head1 SYNOPSIS
211              
212             use HTML::Object::DOM::Element::TableSection;
213             my $section = HTML::Object::DOM::Element::TableSection->new ||
214             die( HTML::Object::DOM::Element::TableSection->error, "\n" );
215              
216             =head1 VERSION
217              
218             v0.2.0
219              
220             =head1 DESCRIPTION
221              
222             This interface provides special properties and methods (beyond the L<HTML::Object::DOM::Element> interface it also has available to it by inheritance) for manipulating the layout and presentation of sections, that is headers, footers and bodies, in an HTML table.
223              
224             =head1 INHERITANCE
225              
226             +-----------------------+ +---------------------------+ +-------------------------+ +----------------------------+ +------------------------------------------+
227             | HTML::Object::Element | --> | HTML::Object::EventTarget | --> | HTML::Object::DOM::Node | --> | HTML::Object::DOM::Element | --> | HTML::Object::DOM::Element::TableSection |
228             +-----------------------+ +---------------------------+ +-------------------------+ +----------------------------+ +------------------------------------------+
229              
230             =head1 PROPERTIES
231              
232             Inherits properties from its parent L<HTML::Object::DOM::Element>
233              
234             =head2 rows
235              
236             Read-only.
237              
238             Returns a live L<collection|HTML::Object::DOM::Collection> containing the rows in the section. The L<collection|HTML::Object::DOM::Collection> is live and is automatically updated when rows are added or removed.
239              
240             Note that for performance improvement, the collection is cached until changes are made that would affect the results.
241              
242             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableSectionElement/rows>
243              
244             =head1 METHODS
245              
246             Inherits methods from its parent L<HTML::Object::DOM::Element>
247              
248             =head2 deleteRow
249              
250             Removes the row, corresponding to the index given in parameter, in the section. If the index value is C<-1> the last row is removed; if it smaller than C<-1> or greater than the amount of rows in the collection, an C<HTML::Object::IndexSizeError> is returned.
251              
252             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableSectionElement/deleteRow>
253              
254             =head2 insertRow
255              
256             Returns an L<HTML::Object::DOM::Element::TableRow> representing a new row of the table. It inserts it in the rows collection immediately before the C<tr> element at the given index position, if any was provided.
257              
258             If the index is not given or is C<-1>, the new row is appended to the collection. If the index is smaller than C<-1>, it will start that far back from the end of the collection array. If index is greater than the number of rows in the collection, an C<HTML::Object::IndexSizeError> error is returned.
259              
260             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableSectionElement/insertRow>
261              
262             =head2 reset
263              
264             Reset the cache flag so that some data will be recomputed. The cache is design to avoid doing useless computing repeatedly when there is no change of data.
265              
266             =head1 DEPRECATED PROPERTIES
267              
268             =head2 align
269              
270             Is a string containing an enumerated value reflecting the align attribute. It indicates the alignment of the element's contents with respect to the surrounding context. The possible values are "left", "right", and "center".
271              
272             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableSectionElement/align>
273              
274             =head2 ch
275              
276             Is a string containing one single chararcter. This character is the one to align all the cell of a column on. It reflects the char and default to the decimal points associated with the language, e.g. '.' for English, or ',' for French. This property was optional and was not very well supported.
277              
278             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableSectionElement/ch>
279              
280             =head2 chOff
281              
282             Is a string containing a integer indicating how many characters must be left at the right (for left-to-right scripts; or at the left for right-to-left scripts) of the character defined by L<HTML::Object::DOM::Element::C<TableRow>>.ch. This property was optional and was not very well supported.
283              
284             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableSectionElement/chOff>
285              
286             =head2 vAlign
287              
288             Is a string representing an enumerated value indicating how the content of the cell must be vertically aligned. It reflects the valign attribute and can have one of the following values: "top", "middle", "bottom", or "baseline".
289              
290             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableSectionElement/vAlign>
291              
292             =head1 AUTHOR
293              
294             Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>
295              
296             =head1 SEE ALSO
297              
298             L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableSectionElement>, L<Mozilla documentation on tbody element|https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody>, L<Mozilla documentation on thead element|https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead>, L<Mozilla documentation on tfoot element|https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot>, L<W3C specifications|https://html.spec.whatwg.org/multipage/tables.html>
299              
300             =head1 COPYRIGHT & LICENSE
301              
302             Copyright(c) 2021 DEGUEST Pte. Ltd.
303              
304             All rights reserved
305              
306             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
307              
308             =cut