114 |
return ${$_[0]}->{prefix}; |
return ${$_[0]}->{prefix}; |
115 |
} # prefix |
} # prefix |
116 |
|
|
117 |
|
## |Node| methods |
118 |
|
|
119 |
|
sub append_child ($$) { |
120 |
|
my $self = $_[0]; |
121 |
|
|
122 |
|
## NOTE: Depends on $self->node_type: |
123 |
|
my $self_od = $$self->{owner_document}; |
124 |
|
|
125 |
|
## -- Node Type check |
126 |
|
my @new_child; |
127 |
|
my $new_child_parent; |
128 |
|
if ($_[1]->node_type == 11) { # DOCUMENT_FRAGMENT_NODE |
129 |
|
push @new_child, @{$_[1]->child_nodes}; |
130 |
|
$new_child_parent = $_[1]; |
131 |
|
} else { |
132 |
|
@new_child = ($_[1]); |
133 |
|
$new_child_parent = $_[1]->parent_node; |
134 |
|
} |
135 |
|
|
136 |
|
## NOTE: Depends on $self->node_type: |
137 |
|
if ($$self_od->{strict_error_checking}) { |
138 |
|
my $child_od = $_[1]->owner_document || $_[1]; # might be DocumentType |
139 |
|
if ($self_od ne $child_od and $child_od->node_type != 10) { |
140 |
|
report Message::DOM::DOMException # DOCUMENT_TYPE_NODE |
141 |
|
-object => $self, |
142 |
|
-type => 'WRONG_DOCUMENT_ERR', |
143 |
|
-subtype => 'EXTERNAL_OBJECT_ERR'; |
144 |
|
} |
145 |
|
|
146 |
|
if ($$self->{manakai_read_only} or |
147 |
|
(@new_child and defined $new_child_parent and |
148 |
|
$$new_child_parent->{manakai_read_only})) { |
149 |
|
report Message::DOM::DOMException |
150 |
|
-object => $self, |
151 |
|
-type => 'NO_MODIFICATION_ALLOWED_ERR', |
152 |
|
-subtype => 'READ_ONLY_NODE_ERR'; |
153 |
|
} |
154 |
|
|
155 |
|
## NOTE: |Document| has children order check here. |
156 |
|
|
157 |
|
for my $cn (@new_child) { |
158 |
|
unless ({ |
159 |
|
3, 1, 5, 1, # TEXT_NODE, ENTITY_REFERENCE_NODE |
160 |
|
}->{$cn->node_type}) { |
161 |
|
report Message::DOM::DOMException |
162 |
|
-object => $self, |
163 |
|
-type => 'HIERARCHY_REQUEST_ERR', |
164 |
|
-subtype => 'CHILD_NODE_TYPE_ERR'; |
165 |
|
} |
166 |
|
} |
167 |
|
|
168 |
|
## NOTE: Ancestor check here in |Node|. |
169 |
|
} |
170 |
|
|
171 |
|
## NOTE: "Insert at" code only in insert_before and replace_child |
172 |
|
|
173 |
|
## -- Removes from parent |
174 |
|
if ($new_child_parent) { |
175 |
|
if (@new_child == 1) { |
176 |
|
my $v = $$new_child_parent->{child_nodes}; |
177 |
|
RP: for my $i (0..$#$v) { |
178 |
|
if ($v->[$i] eq $new_child[0]) { |
179 |
|
splice @$v, $i, 1, (); |
180 |
|
last RP; |
181 |
|
} |
182 |
|
} # RP |
183 |
|
} else { |
184 |
|
@{$$new_child_parent->{child_nodes}} = (); |
185 |
|
} |
186 |
|
} |
187 |
|
|
188 |
|
## -- Rewrite the |parentNode| properties |
189 |
|
for my $nc (@new_child) { |
190 |
|
$$nc->{parent_node} = $self; |
191 |
|
Scalar::Util::weaken ($$nc->{parent_node}); |
192 |
|
} |
193 |
|
|
194 |
|
## NOTE: Depends on method: |
195 |
|
push @{$$self->{child_nodes}}, @new_child; |
196 |
|
|
197 |
|
## NOTE: Setting |owner_document| in |Document|. |
198 |
|
|
199 |
|
return $_[1]; |
200 |
|
} # apepnd_child |
201 |
|
|
202 |
|
sub insert_before ($$) { |
203 |
|
my $self = $_[0]; |
204 |
|
|
205 |
|
## NOTE: Depends on $self->node_type: |
206 |
|
my $self_od = $$self->{owner_document}; |
207 |
|
|
208 |
|
## -- Node Type check |
209 |
|
my @new_child; |
210 |
|
my $new_child_parent; |
211 |
|
if ($_[1]->node_type == 11) { # DOCUMENT_FRAGMENT_NODE |
212 |
|
push @new_child, @{$_[1]->child_nodes}; |
213 |
|
$new_child_parent = $_[1]; |
214 |
|
} else { |
215 |
|
@new_child = ($_[1]); |
216 |
|
$new_child_parent = $_[1]->parent_node; |
217 |
|
} |
218 |
|
|
219 |
|
## NOTE: Depends on $self->node_type: |
220 |
|
if ($$self_od->{strict_error_checking}) { |
221 |
|
my $child_od = $_[1]->owner_document || $_[1]; # might be DocumentType |
222 |
|
if ($self_od ne $child_od and $child_od->node_type != 10) { |
223 |
|
report Message::DOM::DOMException # DOCUMENT_TYPE_NODE |
224 |
|
-object => $self, |
225 |
|
-type => 'WRONG_DOCUMENT_ERR', |
226 |
|
-subtype => 'EXTERNAL_OBJECT_ERR'; |
227 |
|
} |
228 |
|
|
229 |
|
if ($$self->{manakai_read_only} or |
230 |
|
(@new_child and defined $new_child_parent and |
231 |
|
$$new_child_parent->{manakai_read_only})) { |
232 |
|
report Message::DOM::DOMException |
233 |
|
-object => $self, |
234 |
|
-type => 'NO_MODIFICATION_ALLOWED_ERR', |
235 |
|
-subtype => 'READ_ONLY_NODE_ERR'; |
236 |
|
} |
237 |
|
|
238 |
|
## NOTE: |Document| has children order check here. |
239 |
|
|
240 |
|
for my $cn (@new_child) { |
241 |
|
unless ({ |
242 |
|
3, 1, 5, 1, # TEXT_NODE, ENTITY_REFERENCE_NODE |
243 |
|
}->{$cn->node_type}) { |
244 |
|
report Message::DOM::DOMException |
245 |
|
-object => $self, |
246 |
|
-type => 'HIERARCHY_REQUEST_ERR', |
247 |
|
-subtype => 'CHILD_NODE_TYPE_ERR'; |
248 |
|
} |
249 |
|
} |
250 |
|
|
251 |
|
## NOTE: Ancestor check here in |Node|. |
252 |
|
} |
253 |
|
|
254 |
|
## -- Insert at... ## NOTE: Only in insert_before and replace_child |
255 |
|
my $index = -1; # last |
256 |
|
if (defined $_[2]) { |
257 |
|
## error if $_[1] eq $_[2]; |
258 |
|
|
259 |
|
my $cns = $self->child_nodes; |
260 |
|
my $cnsl = @$cns; |
261 |
|
C: { |
262 |
|
$index = 0; |
263 |
|
for my $i (0..($cnsl-1)) { |
264 |
|
my $cn = $cns->[$i]; |
265 |
|
if ($cn eq $_[2]) { |
266 |
|
$index += $i; |
267 |
|
last C; |
268 |
|
} elsif ($cn eq $_[1]) { |
269 |
|
$index = -1; # offset |
270 |
|
} |
271 |
|
} |
272 |
|
|
273 |
|
report Message::DOM::DOMException |
274 |
|
-object => $self, |
275 |
|
-type => 'NOT_FOUND_ERR', |
276 |
|
-subtype => 'NOT_CHILD_ERR'; |
277 |
|
} # C |
278 |
|
} |
279 |
|
## NOTE: "else" only in replace_child |
280 |
|
|
281 |
|
## -- Removes from parent |
282 |
|
if ($new_child_parent) { |
283 |
|
if (@new_child == 1) { |
284 |
|
my $v = $$new_child_parent->{child_nodes}; |
285 |
|
RP: for my $i (0..$#$v) { |
286 |
|
if ($v->[$i] eq $new_child[0]) { |
287 |
|
splice @$v, $i, 1, (); |
288 |
|
last RP; |
289 |
|
} |
290 |
|
} # RP |
291 |
|
} else { |
292 |
|
@{$$new_child_parent->{child_nodes}} = (); |
293 |
|
} |
294 |
|
} |
295 |
|
|
296 |
|
## -- Rewrite the |parentNode| properties |
297 |
|
for my $nc (@new_child) { |
298 |
|
$$nc->{parent_node} = $self; |
299 |
|
Scalar::Util::weaken ($$nc->{parent_node}); |
300 |
|
} |
301 |
|
|
302 |
|
## NOTE: Depends on method: |
303 |
|
if ($index == -1) { |
304 |
|
push @{$$self->{child_nodes}}, @new_child; |
305 |
|
} else { |
306 |
|
splice @{$$self->{child_nodes}}, $index, 0, @new_child; |
307 |
|
} |
308 |
|
|
309 |
|
## NOTE: Setting |owner_document| in |Document|. |
310 |
|
|
311 |
|
return $_[1]; |
312 |
|
} # insert_before |
313 |
|
|
314 |
|
sub replace_child ($$) { |
315 |
|
my $self = $_[0]; |
316 |
|
|
317 |
|
## NOTE: Depends on $self->node_type: |
318 |
|
my $self_od = $$self->{owner_document}; |
319 |
|
|
320 |
|
## -- Node Type check |
321 |
|
my @new_child; |
322 |
|
my $new_child_parent; |
323 |
|
if ($_[1]->node_type == 11) { # DOCUMENT_FRAGMENT_NODE |
324 |
|
push @new_child, @{$_[1]->child_nodes}; |
325 |
|
$new_child_parent = $_[1]; |
326 |
|
} else { |
327 |
|
@new_child = ($_[1]); |
328 |
|
$new_child_parent = $_[1]->parent_node; |
329 |
|
} |
330 |
|
|
331 |
|
## NOTE: Depends on $self->node_type: |
332 |
|
if ($$self_od->{strict_error_checking}) { |
333 |
|
my $child_od = $_[1]->owner_document || $_[1]; # might be DocumentType |
334 |
|
if ($self_od ne $child_od and $child_od->node_type != 10) { |
335 |
|
report Message::DOM::DOMException # DOCUMENT_TYPE_NODE |
336 |
|
-object => $self, |
337 |
|
-type => 'WRONG_DOCUMENT_ERR', |
338 |
|
-subtype => 'EXTERNAL_OBJECT_ERR'; |
339 |
|
} |
340 |
|
|
341 |
|
if ($$self->{manakai_read_only} or |
342 |
|
(@new_child and defined $new_child_parent and |
343 |
|
$$new_child_parent->{manakai_read_only})) { |
344 |
|
report Message::DOM::DOMException |
345 |
|
-object => $self, |
346 |
|
-type => 'NO_MODIFICATION_ALLOWED_ERR', |
347 |
|
-subtype => 'READ_ONLY_NODE_ERR'; |
348 |
|
} |
349 |
|
|
350 |
|
## NOTE: |Document| has children order check here. |
351 |
|
|
352 |
|
for my $cn (@new_child) { |
353 |
|
unless ({ |
354 |
|
3, 1, 5, 1, # TEXT_NODE, ENTITY_REFERENCE_NODE |
355 |
|
}->{$cn->node_type}) { |
356 |
|
report Message::DOM::DOMException |
357 |
|
-object => $self, |
358 |
|
-type => 'HIERARCHY_REQUEST_ERR', |
359 |
|
-subtype => 'CHILD_NODE_TYPE_ERR'; |
360 |
|
} |
361 |
|
} |
362 |
|
|
363 |
|
## NOTE: Ancestor check here in |Node|. |
364 |
|
} |
365 |
|
|
366 |
|
## -- Insert at... ## NOTE: Only in insertBefore and replaceChild |
367 |
|
my $index = -1; # last |
368 |
|
if (defined $_[2]) { |
369 |
|
## error if $_[1] eq $_[2]; |
370 |
|
|
371 |
|
my $cns = $self->child_nodes; |
372 |
|
my $cnsl = @$cns; |
373 |
|
C: { |
374 |
|
$index = 0; |
375 |
|
for my $i (0..($cnsl-1)) { |
376 |
|
my $cn = $cns->[$i]; |
377 |
|
if ($cn eq $_[2]) { |
378 |
|
$index += $i; |
379 |
|
last C; |
380 |
|
} elsif ($cn eq $_[1]) { |
381 |
|
$index = -1; # offset |
382 |
|
} |
383 |
|
} |
384 |
|
|
385 |
|
report Message::DOM::DOMException |
386 |
|
-object => $self, |
387 |
|
-type => 'NOT_FOUND_ERR', |
388 |
|
-subtype => 'NOT_CHILD_ERR'; |
389 |
|
} # C |
390 |
|
} else { |
391 |
|
## NOTE: Only in replaceChild |
392 |
|
report Message::DOM::DOMException |
393 |
|
-object => $self, |
394 |
|
-type => 'NOT_FOUND_ERR', |
395 |
|
-subtype => 'NOT_CHILD_ERR'; |
396 |
|
} |
397 |
|
|
398 |
|
## -- Removes from parent |
399 |
|
if ($new_child_parent) { |
400 |
|
if (@new_child == 1) { |
401 |
|
my $v = $$new_child_parent->{child_nodes}; |
402 |
|
RP: for my $i (0..$#$v) { |
403 |
|
if ($v->[$i] eq $new_child[0]) { |
404 |
|
splice @$v, $i, 1, (); |
405 |
|
last RP; |
406 |
|
} |
407 |
|
} # RP |
408 |
|
} else { |
409 |
|
@{$$new_child_parent->{child_nodes}} = (); |
410 |
|
} |
411 |
|
} |
412 |
|
|
413 |
|
## -- Rewrite the |parentNode| properties |
414 |
|
for my $nc (@new_child) { |
415 |
|
$$nc->{parent_node} = $self; |
416 |
|
Scalar::Util::weaken ($$nc->{parent_node}); |
417 |
|
} |
418 |
|
|
419 |
|
## NOTE: Depends on method: |
420 |
|
splice @{$$self->{child_nodes}}, $index, 1, @new_child; |
421 |
|
delete ${$_[2]}->{parent_node}; |
422 |
|
|
423 |
|
## NOTE: Setting |owner_document| in |Document|. |
424 |
|
|
425 |
|
return $_[2]; |
426 |
|
} # replace_child |
427 |
|
|
428 |
## |Attr| attributes |
## |Attr| attributes |
429 |
|
|
430 |
sub manakai_attribute_type ($;$) { |
sub manakai_attribute_type ($;$) { |