File Coverage

blib/lib/HTML/DOM/CharacterData.pm
Criterion Covered Total %
statement 107 107 100.0
branch 50 58 86.2
condition 15 21 71.4
subroutine 23 23 100.0
pod 12 15 80.0
total 207 224 92.4


line stmt bran cond sub pod time code
1             package HTML::DOM::CharacterData;
2              
3             # This contains those methods that are shared both by comments and text
4             # nodes.
5              
6 25     25   80 use warnings;
  25         27  
  25         617  
7 25     25   92 use strict;
  25         25  
  25         409  
8              
9 25     25   84 use HTML::DOM::Exception qw'INDEX_SIZE_ERR';
  25         24  
  25         871  
10 25     25   86 use Scalar::Util qw'blessed weaken';
  25         24  
  25         14236  
11              
12             require HTML::DOM::Node;
13              
14             our @ISA = 'HTML::DOM::Node';
15             our $VERSION = '0.056';
16              
17              
18             sub surrogify($);
19             sub desurrogify($);
20              
21              
22             # ~comment and ~text pseudo-elements (see HTML::Element) store the
23             # character data in the 'text' attribute.
24             sub data {
25 151     151 1 1315 my $old = (my $self = shift)->attr('text');
26 151 100       257 if(@_) {
27 20         57 $self->attr(text => my $strung = "$_[0]");
28 20         62 $self->_modified($old,$strung);
29             }
30             $old
31 151         675 }
32              
33             sub length {
34 1     1 1 3 length $_[0]->attr('text');
35             }
36              
37             sub length16 {
38 1     1 1 4 CORE::length surrogify $_[0]->attr('text');
39             }
40              
41             sub substringData { # obj, offset, length
42             # Throwing exceptions in these cases is really dumb, but what can I
43             # do? I'm trying to follow standards.
44 7     7 1 278 my($self,$off,$len) = @_;
45 7 100       28 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
46             'substringData cannot take a negative offset')
47             if $off <0;
48 5 50 66     17 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
49             'substringData cannot take a negative substring length')
50             if $len && $len <0;
51 5         15 my $text = $self->attr('text');
52 5 100       17 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
53             "substringData: $off is greater than the length of the text")
54             if $off > CORE::length $text;
55 3 100       16 defined $len ? substr( $text, $off, $len) : substr $text, $off, ;
56             }
57              
58             sub substringData16 { # obj, offset, length
59 8     8 1 281 my($self,$off,$len) = @_;
60 8 100       23 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
61             'substringData cannot take a negative offset')
62             if $off <0;
63 6 50 66     19 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
64             'substringData cannot take a negative substring length')
65             if $len && $len<0;
66 6         14 my $text = surrogify $self->attr('text');
67 6 100       21 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
68             "substringData: $off is greater than the length of the text")
69             if $off > CORE::length $text;
70 4 100       6 desurrogify defined $len
71             ? substr($text, $off, $len)
72             : substr $text, $off, ;
73             }
74              
75             sub appendData {
76 2     2 1 658 my $old = $_[0]->attr(text => my $new = $_[0]->attr('text').$_[1]);
77 2         6 $_[0]->_modified($old, $new);
78             return # nothing
79 2         6 }
80              
81             sub insertData { # obj, offset, string to insert
82 4     4 1 623 my ($self,$off,$insert) = @_;
83 4 100       15 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
84             'insertData cannot take a negative offset')
85             if $off <0;
86 3         10 my $text = $self->attr('text');
87 3 100       13 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
88             "insertData: $off is greater than the length of the text")
89             if $off > CORE::length $text;
90 2         6 substr($text, $off, 0) = $insert;
91 2         15 my $old = $self->attr(text => $text);
92 2         5 $self->_modified($old,$text);
93             return # nothing
94 2         6 }
95              
96             sub insertData16 { # obj, offset, string to insert
97 4     4 1 892 my ($self,$off,$insert) = @_;
98 4 100       13 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
99             'insertData cannot take a negative offset')
100             if $off <0;
101 3         9 my $text = surrogify $self->attr('text');
102 3 100       13 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
103             "insertData: $off is greater than the length of the text")
104             if $off > CORE::length $text;
105 2         6 substr($text, $off, 0) = $insert;
106 2         5 my $old = $self->attr(text => desurrogify $text);
107 2         4 $self->_modified($old,$text);
108             return # nothing
109 2         6 }
110              
111             sub deleteData { # obj, offset, length
112 5     5 1 891 my ($self,$off,$len) = @_;
113 5 100       18 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
114             'deleteData cannot take a negative offset')
115             if $off <0;
116 4 50 66     15 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
117             'deleteData cannot take a negative substring length')
118             if $len && $len <0;
119 4         12 my $text = $self->attr('text');
120 4 100       13 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
121             "deleteData: $off is greater than the length of the text")
122             if $off > CORE::length $text;
123 25     25   106 no warnings; # Silence nonsensical warnings
  25         27  
  25         3211  
124 3 100       15 undef(defined $len
125             ? substr( $text, $off, $len)
126             : substr $text, $off, );
127 3         8 my $old = $_[0]->attr(text => $text);
128 3         24 $self->_modified($old,$text);
129             return # nothing
130 3         9 }
131              
132             sub deleteData16 { # obj, offset, length
133 5     5 1 902 my ($self,$off,$len) = @_;
134 5 100       29 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
135             'deleteData cannot take a negative offset')
136             if $off <0;
137 4 50 66     31 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
138             'deleteData cannot take a negative substring length')
139             if $len && $len <0;
140 4         15 my $text = surrogify $self->attr('text');
141 4 100       22 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
142             "deleteData: $off is greater than the length of the text")
143             if $off > CORE::length $text;
144 25     25   89 no warnings; # Silence nonsensical warnings
  25         23  
  25         6892  
145 3 100       14 undef( defined $len
146             ? substr( $text, $off, $len)
147             : substr $text, $off, );
148 3         8 my $old = $self->attr(text => desurrogify $text);
149 3         9 $self->_modified($old,$text);
150             return # nothing
151 3         8 }
152              
153             sub replaceData { # obj, offset, length, replacement
154 4     4 1 897 my ($self,$off,$len,$subst) = @_;
155 4 100       12 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
156             'replaceData cannot take a negative offset')
157             if $off <0;
158 3 50       7 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
159             'replaceData cannot take a negative substring length')
160             if $len <0;
161 3         8 my $text = $self->attr('text');
162 3 100       12 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
163             "replaceData: $off is greater than the length of the text")
164             if $off > CORE::length $text;
165 2         4 substr($text, $off, $len) = $subst;
166 2         5 my $old = $self->attr(text => $text);
167 2         5 $self->_modified($old,$text);
168             return # nothing
169 2         7 }
170              
171             sub replaceData16 { # obj, offset, length, replacement
172 4     4 0 820 my ($self,$off,$len,$subst) = @_;
173 4 100       18 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
174             'replaceData cannot take a negative offset')
175             if $off <0;
176 3 50       5 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
177             'replaceData cannot take a negative substring length')
178             if $len <0;
179 3         10 my $text = surrogify $self->attr('text');
180 3 100       16 die HTML::DOM::Exception->new(INDEX_SIZE_ERR,
181             "replaceData: $off is greater than the length of the text")
182             if $off > CORE::length $text;
183 2         5 substr($text, $off, $len) = $subst;
184 2         4 my $old = $self->attr(text => desurrogify $text);
185 2         5 $self->_modified($old,$text);
186             return # nothing
187 2         7 }
188              
189             sub _modified {
190 36     36   39 my $self = shift;
191 36 50       145 $_[0] eq $_[1] or $self->trigger_event(
192             'DOMCharacterDataModified',
193             prev_value => $_[0],
194             new_value => $_[1],
195             );
196             };
197              
198             #------- UTILITY FUNCTIONS ---------#
199              
200             # ~~~ Should these be exported?
201              
202             sub surrogify($) { # copied straight from JE::String
203 17     17 0 16 my $ret = shift;
204              
205 25     25   101 no warnings 'utf8';
  25         27  
  25         4312  
206              
207 17         83 $ret =~ s<([^\0-\x{ffff}])><
208 13         88 chr((ord($1) - 0x10000) / 0x400 + 0xD800)
209             . chr((ord($1) - 0x10000) % 0x400 + 0xDC00)
210             >eg;
211 17         29 $ret;
212             }
213              
214             sub desurrogify($) { # copied straight from JE::String (with length changed
215             # to CORE::length)
216 11     11 0 18 my $ret = shift;
217 11         10 my($ord1, $ord2);
218 11         26 for(my $n = 0; $n < CORE::length $ret; ++$n) { # really slow
219 56 50 100     158 ($ord1 = ord substr $ret,$n,1) >= 0xd800 and
      66        
      66        
220             $ord1 <= 0xdbff and
221             ($ord2 = ord substr $ret,$n+1,1) >= 0xdc00 and
222             $ord2 <= 0xdfff and
223             substr($ret,$n,2) =
224             chr 0x10000 + ($ord1 - 0xD800) * 0x400 + ($ord2 - 0xDC00);
225             }
226              
227             # In perl 5.8.8, if there is a sub on the call stack that was
228             # triggered by the overloading mechanism when the object with the
229             # overloaded operator was passed as the only argument to 'die',
230             # then the following substitution magically calls that subroutine
231             # again with the same arguments, thereby causing infinite
232             # recursion:
233             #
234             # $ret =~ s/([\x{d800}-\x{dbff}])([\x{dc00}-\x{dfff}])/
235             # chr 0x10000 + (ord($1) - 0xD800) * 0x400 +
236             # (ord($2) - 0xDC00)
237             # /ge;
238             #
239             # 5.9.4 still has this bug.
240             # (fixed in 5.9.5--don't know which patch)
241              
242 11         42 $ret;
243             }
244              
245 5     5 1 23 sub nodeValue { $_[0]->data(@_[1..$#_]); }
246              
247              
248             1 __END__ 1
249              
250              
251             =head1 NAME
252              
253             HTML::DOM::CharacterData - A base class shared by HTML::DOM::Text and ::Comment
254              
255             =head1 VERSION
256              
257             Version 0.056
258              
259             =head1 DESCRIPTION
260              
261             This class provides those methods that are shared both by comments and text
262             nodes in an HTML DOM tree.
263              
264             =head1 METHODS
265              
266             =head2 Attributes
267              
268             The following DOM attributes are supported:
269              
270             =over 4
271              
272             =item data
273              
274             The textual data that the node contains.
275              
276             =item length
277              
278             The number of characters in C.
279              
280             =item length16
281              
282             A standards-compliant version of C that counts UTF-16 bytes instead
283             of characters.
284              
285             =back
286              
287             =head2 Other Methods
288              
289             =over 4
290              
291             =item substringData ( $offset, $length )
292              
293             Returns a substring of the data. If C<$length> is omitted, all characters
294             from C<$offset> to the end of the data are returned.
295              
296             =item substringData16
297              
298             A UTF-16 version of C.
299              
300             =item appendData ( $str )
301              
302             Appends C<$str> to the node's data.
303              
304             =item insertData ( $offset, $str )
305              
306             Inserts C<$str> at the given C<$offset>, which is understood to be the
307             number of Unicode characters from the beginning of the node's data.
308              
309             =item insertData16
310              
311             Like C, but C<$offset> is taken to be the number of UTF-16
312             (16-bit) bytes.
313              
314             =item deleteData ( $offset, $length )
315              
316             Deletes the specified data. If C<$length> is omitted, all characters from
317             C<$offset> to the end of the node's data are deleted.
318              
319             =item deleteData16
320              
321             A UTF-16 version of the above.
322              
323             =item replaceData ( $offset, $length, $str )
324              
325             This replaces the substring specified by C<$offset> and C<$length> with
326             C<$str>.
327              
328             =back
329              
330             =head1 SEE ALSO
331              
332             L
333              
334             L
335              
336             L