3 |
our $VERSION=do{my @r=(q$Revision$=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; |
our $VERSION=do{my @r=(q$Revision$=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; |
4 |
push our @ISA, 'Message::IF::Node'; |
push our @ISA, 'Message::IF::Node'; |
5 |
require Scalar::Util; |
require Scalar::Util; |
6 |
|
require Message::DOM::DOMException; |
7 |
|
|
8 |
## NOTE: |
## NOTE: |
9 |
## Node |
## Node |
74 |
return $self; |
return $self; |
75 |
} # ____new |
} # ____new |
76 |
|
|
77 |
|
sub ___report_error ($$) { |
78 |
|
$_[1]->throw; |
79 |
|
} # ___report_error |
80 |
|
|
81 |
sub AUTOLOAD { |
sub AUTOLOAD { |
82 |
my $method_name = our $AUTOLOAD; |
my $method_name = our $AUTOLOAD; |
83 |
$method_name =~ s/.*:://; |
$method_name =~ s/.*:://; |
115 |
} |
} |
116 |
} # AUTOLOAD |
} # AUTOLOAD |
117 |
|
|
118 |
## The |Node| interface - attribute |
## |Node| attributes |
119 |
|
|
120 |
sub attributes ($) { |
## NOTE: Overridden by |Element|. |
121 |
## NOTE: Overloaded by |Message::DOM::Element|. |
sub attributes () { undef } |
|
return undef; |
|
|
} # attributes |
|
122 |
|
|
123 |
## TODO: baseURI |
## TODO: baseURI |
124 |
|
|
125 |
sub child_nodes ($) { |
sub child_nodes ($) { |
126 |
|
## NOTE: Overridden by |CharacterData|, |ElementTypeDefinition|, |
127 |
|
## |Notation|, and |ProcessingInstruction|. |
128 |
require Message::DOM::NodeList; |
require Message::DOM::NodeList; |
129 |
return bless \\($_[0]), 'Message::DOM::NodeList::ChildNodeList'; |
return bless \\($_[0]), 'Message::DOM::NodeList::ChildNodeList'; |
130 |
} # child_nodes |
} # child_nodes |
140 |
? $$self->{child_nodes}->[-1] : undef; |
? $$self->{child_nodes}->[-1] : undef; |
141 |
} # last_child |
} # last_child |
142 |
|
|
143 |
sub local_name ($) { undef } |
sub local_name { undef } |
|
sub manakai_local_name ($) { undef } |
|
144 |
|
|
145 |
sub namespace_uri ($) { undef } |
sub manakai_local_name { undef } |
146 |
|
|
147 |
|
sub namespace_uri { undef } |
148 |
|
|
149 |
sub next_sibling ($) { |
sub next_sibling ($) { |
150 |
my $self = shift; |
my $self = shift; |
161 |
return undef; |
return undef; |
162 |
} # next_sibling |
} # next_sibling |
163 |
|
|
164 |
sub node_name ($) { |
## NOTE: Overridden by subclasses. |
165 |
## NOTE: Overloaded by subclasses. |
sub node_name () { undef } |
|
return undef; |
|
|
} # node_name |
|
|
|
|
|
sub node_type ($) { |
|
|
## NOTE: Overloaded by subclasses. |
|
|
die "Node->node_type is not defined"; |
|
|
} # node_type |
|
166 |
|
|
167 |
sub node_value ($;$) { |
## NOTE: Overridden by subclasses. |
168 |
## NOTE: Overloaded by subclasses. |
sub node_type () { } |
|
return undef; |
|
|
} # node_value |
|
169 |
|
|
170 |
## TODO: node_value setter |
## NOTE: Overridden by |Attr|, |AttributeDefinition|, |
171 |
|
## |CharacterData|, and |ProcessingInstruction|. |
172 |
|
sub node_value () { undef } |
173 |
|
|
174 |
sub owner_document ($); |
sub owner_document ($); |
175 |
|
|
176 |
sub parent_node ($); |
sub parent_node ($); |
177 |
|
|
178 |
|
## NOTE: Overridden by |Element| and |Attr|. |
179 |
sub prefix ($;$) { undef } |
sub prefix ($;$) { undef } |
180 |
|
|
181 |
sub previous_sibling ($) { |
sub previous_sibling ($) { |
196 |
sub manakai_read_only ($); |
sub manakai_read_only ($); |
197 |
|
|
198 |
sub text_content ($;$) { |
sub text_content ($;$) { |
199 |
## TODO: |
## NOTE: For |Element|, |Attr|, |Entity|, |EntityReference|, |
200 |
|
## |DocumentFragment|, and |AttributeDefinition|. In addition, |
201 |
|
## |Document|'s |text_content| might call this attribute. |
202 |
|
|
203 |
|
## NOTE: Overridden by |Document|, |DocumentType|, |Notation|, |
204 |
|
## |CharacterData|, |ProcessingInstruction|, and |ElementTypeDefinition|. |
205 |
|
|
206 |
|
my $self = $_[0]; |
207 |
|
|
208 |
|
if (@_ > 1) { |
209 |
|
if ($$self->{manakai_read_only}) { |
210 |
|
report Message::DOM::DOMException |
211 |
|
-object => $self, |
212 |
|
-type => 'NO_MODIFICATION_ALLOWED_ERR', |
213 |
|
-subtype => 'READ_ONLY_NODE_ERR'; |
214 |
|
} |
215 |
|
|
216 |
|
local $Error::Depth = $Error::Depth + 1; |
217 |
|
@{$self->child_nodes} = (); |
218 |
|
if (defined $_[1] and length $_[1]) { |
219 |
|
## NOTE: |DocumentType| don't use this code. |
220 |
|
my $text = ($$self->{owner_document} || $self)->create_text_node ($_[1]); |
221 |
|
$self->append_child ($text); |
222 |
|
} |
223 |
|
} |
224 |
|
|
225 |
|
if (defined wantarray) { |
226 |
|
local $Error::Depth = $Error::Depth + 1; |
227 |
|
my $r = ''; |
228 |
|
my @node = @{$self->child_nodes}; |
229 |
|
while (@node) { |
230 |
|
my $child = shift @node; |
231 |
|
my $child_nt = $child->node_type; |
232 |
|
if ($child_nt == TEXT_NODE or $child_nt == CDATA_SECTION_NODE) { |
233 |
|
$r .= $child->node_value unless $child->is_element_content_whitespace; |
234 |
|
} elsif ($child_nt == COMMENT_NODE or |
235 |
|
$child_nt == PROCESSING_INSTRUCTION_NODE or |
236 |
|
$child_nt == DOCUMENT_TYPE_NODE) { |
237 |
|
# |
238 |
|
} else { |
239 |
|
unshift @node, @{$child->child_nodes}; |
240 |
|
} |
241 |
|
} |
242 |
|
return $r; |
243 |
|
} |
244 |
} # text_content |
} # text_content |
245 |
|
|
246 |
## TODO: |
## TODO: |
310 |
return $new_child; |
return $new_child; |
311 |
} # insert_before |
} # insert_before |
312 |
|
|
313 |
|
## NOTE: For nodeTypes with childNodes |
314 |
|
sub manakai_append_text ($$) { |
315 |
|
my $self = shift; |
316 |
|
local $Error::Depth = $Error::Depth + 1; |
317 |
|
if (@{$$self->{child_nodes}} and |
318 |
|
$$self->{child_nodes}->[-1]->node_type == 3) { |
319 |
|
$$self->{child_nodes}->[-1]->manakai_append_text (shift); |
320 |
|
} else { |
321 |
|
my $text = $$self->{owner_document}->create_text_node ($_[0]); |
322 |
|
$self->append_child ($text); |
323 |
|
} |
324 |
|
} # manakai_append_text |
325 |
|
|
326 |
## NOTE: Only applied to Elements and Documents |
## NOTE: Only applied to Elements and Documents |
327 |
sub remove_child ($$) { |
sub remove_child ($$) { |
328 |
my ($self, $old_child) = @_; |
my ($self, $old_child) = @_; |