| 24 |
## + ProcessingInstruction (7) |
## + ProcessingInstruction (7) |
| 25 |
|
|
| 26 |
use overload |
use overload |
| 27 |
'==' => sub { |
'==' => 'is_equal_node', |
|
return 0 unless UNIVERSAL::isa ($_[0], 'Message::IF::Node'); |
|
|
## TODO: implement is_equal_node |
|
|
return $_[0]->is_equal_node ($_[1]); |
|
|
}, |
|
| 28 |
'!=' => sub { |
'!=' => sub { |
| 29 |
return not ($_[0] == $_[1]); |
return not ($_[0] == $_[1]); |
| 30 |
}, |
}, |
| 31 |
|
#eq => sub { $_[0] eq $_[1] }, ## is_same_node |
| 32 |
|
#ne => sub { $_[0] ne $_[1] }, ## not is_same_node |
| 33 |
fallback => 1; |
fallback => 1; |
| 34 |
|
|
| 35 |
## The |Node| interface - constants |
## The |Node| interface - constants |
| 576 |
die "compare_document_position: Something wrong (2)"; |
die "compare_document_position: Something wrong (2)"; |
| 577 |
} # compare_document_position |
} # compare_document_position |
| 578 |
|
|
| 579 |
|
sub get_feature ($$;$) { |
| 580 |
|
my $feature = lc $_[1]; ## TODO: |lc|? |
| 581 |
|
$feature =~ s/^\+//; |
| 582 |
|
my $version = defined $_[2] ? $_[2] : ''; |
| 583 |
|
if ($Message::DOM::DOMImplementation::HasFeature->{$feature}->{$version}) { |
| 584 |
|
return $_[0]; |
| 585 |
|
} else { |
| 586 |
|
return undef; |
| 587 |
|
} |
| 588 |
|
} # get_feature |
| 589 |
|
|
| 590 |
|
sub get_user_data ($$) { |
| 591 |
|
if (${$_[0]}->{user_data}->{$_[1]}) { |
| 592 |
|
return ${$_[0]}->{user_data}->{$_[1]}->[0]; |
| 593 |
|
} else { |
| 594 |
|
return undef; |
| 595 |
|
} |
| 596 |
|
} # get_user_data |
| 597 |
|
|
| 598 |
sub has_attributes ($) { |
sub has_attributes ($) { |
| 599 |
for (values %{${$_[0]}->{attributes} or {}}) { |
for (values %{${$_[0]}->{attributes} or {}}) { |
| 600 |
return 1 if keys %$_; |
return 1 if keys %$_; |
| 606 |
return (@{${$_[0]}->{child_nodes} or []} > 0); |
return (@{${$_[0]}->{child_nodes} or []} > 0); |
| 607 |
} # has_child_nodes |
} # has_child_nodes |
| 608 |
|
|
|
## TODO: |
|
|
sub is_same_node ($$) { |
|
|
return $_[0] eq $_[1]; |
|
|
} # is_same_node |
|
|
|
|
|
## TODO: |
|
| 609 |
sub is_equal_node ($$) { |
sub is_equal_node ($$) { |
| 610 |
return $_[0]->node_name eq $_[1]->node_name && |
local $Error::Depth = $Error::Depth + 1; |
| 611 |
$_[0]->node_value eq $_[1]->node_value; |
|
| 612 |
|
return 0 unless UNIVERSAL::isa ($_[1], 'Message::IF::Node'); |
| 613 |
|
|
| 614 |
|
my $nt = $_[0]->node_type; |
| 615 |
|
return 0 unless $nt == $_[1]->node_type; |
| 616 |
|
|
| 617 |
|
my @str_attr = qw/node_name local_name namespace_uri |
| 618 |
|
prefix node_value/; |
| 619 |
|
push @str_attr, qw/public_id system_id internal_subset/ |
| 620 |
|
if $nt == DOCUMENT_TYPE_NODE; |
| 621 |
|
for my $attr_name (@str_attr) { |
| 622 |
|
my $v1 = $_[0]->can ($attr_name) ? $_[0]->$attr_name : undef; |
| 623 |
|
my $v2 = $_[1]->can ($attr_name) ? $_[1]->$attr_name : undef; |
| 624 |
|
if (defined $v1 and defined $v2) { |
| 625 |
|
return 0 unless ''.$v1 eq ''.$v2; |
| 626 |
|
} elsif (defined $v1 or defined $v2) { |
| 627 |
|
return 0; |
| 628 |
|
} |
| 629 |
|
} |
| 630 |
|
|
| 631 |
|
my @num_eq_attr = qw/child_nodes attributes/; |
| 632 |
|
push @num_eq_attr, qw/entities notations element_types/ |
| 633 |
|
if $nt == DOCUMENT_TYPE_NODE; |
| 634 |
|
push @num_eq_attr, qw/attribute_definitions/ |
| 635 |
|
if $nt == ELEMENT_TYPE_DEFINITION_NODE; |
| 636 |
|
push @num_eq_attr, qw/declared_type default_type allowed_tokens/ |
| 637 |
|
if $nt == ATTRIBUTE_DEFINITION_NODE; |
| 638 |
|
for my $attr_name (@num_eq_attr) { |
| 639 |
|
my $v1 = $_[0]->can ($attr_name) ? $_[0]->$attr_name : undef; |
| 640 |
|
my $v2 = $_[1]->can ($attr_name) ? $_[1]->$attr_name : undef; |
| 641 |
|
if (defined $v1 and defined $v2) { |
| 642 |
|
return 0 unless $v1 == $v2; |
| 643 |
|
} elsif (defined $v1 or defined $v2) { |
| 644 |
|
return 0; |
| 645 |
|
} |
| 646 |
|
} |
| 647 |
|
|
| 648 |
|
return 1; |
| 649 |
} # is_equal_node |
} # is_equal_node |
| 650 |
|
|
| 651 |
|
sub is_same_node ($$) { $_[0] eq $_[1] } |
| 652 |
|
|
| 653 |
|
sub is_supported ($$;$) { |
| 654 |
|
my $feature = lc $_[1]; ## TODO: |lc|? |
| 655 |
|
my $plus = ($feature =~ s/^\+//); |
| 656 |
|
my $version = defined $_[2] ? $_[2] : ''; |
| 657 |
|
return $Message::DOM::DOMImplementation::HasFeature->{$feature}->{$version}; |
| 658 |
|
} # is_supported; |
| 659 |
|
|
| 660 |
## NOTE: Only applied to Elements and Documents |
## NOTE: Only applied to Elements and Documents |
| 661 |
sub append_child ($$) { |
sub append_child ($$) { |
| 662 |
my ($self, $new_child) = @_; |
my ($self, $new_child) = @_; |
| 696 |
} |
} |
| 697 |
} # manakai_append_text |
} # manakai_append_text |
| 698 |
|
|
|
sub get_feature { |
|
|
## TODO: |
|
|
return $_[0]; |
|
|
} |
|
|
|
|
| 699 |
## NOTE: Only applied to Elements and Documents |
## NOTE: Only applied to Elements and Documents |
| 700 |
sub insert_before ($$;$) { |
sub insert_before ($$;$) { |
| 701 |
my ($self, $new_child, $ref_child) = @_; |
my ($self, $new_child, $ref_child) = @_; |
| 980 |
} |
} |
| 981 |
} # manakai_set_read_only |
} # manakai_set_read_only |
| 982 |
|
|
| 983 |
|
# {NOTE:: Perl application developers are advised to be careful |
| 984 |
|
# to include direct or indirect references to the node |
| 985 |
|
# itself as user data or in user data handlers. |
| 986 |
|
# They would result in memory leak problems unless |
| 987 |
|
# the circular references are removed later. |
| 988 |
|
# |
| 989 |
|
# It would be a good practive to eusure that every user data |
| 990 |
|
# registered to a node is later unregistered by setting |
| 991 |
|
# <DOM::null> as a data for the same key. |
| 992 |
|
# |
| 993 |
sub set_user_data ($$$;$) { |
sub set_user_data ($$$;$) { |
| 994 |
my ($self, $key, $data, $handler) = @_; |
my ($self, $key, $data, $handler) = @_; |
| 995 |
|
|
| 1000 |
$v->{$key} = [$data, $handler]; |
$v->{$key} = [$data, $handler]; |
| 1001 |
|
|
| 1002 |
if (defined $handler) { |
if (defined $handler) { |
| 1003 |
$$self->{manakai_onunload} = sub { |
eval q{ |
| 1004 |
my $node = $_[0]; |
sub DESTROY { |
| 1005 |
my $uds = $$node->{user_data}; |
my $uds = ${$_[0]}->{user_data}; |
| 1006 |
for my $key (keys %$uds) { |
for my $key (keys %$uds) { |
| 1007 |
if (defined $uds->{$key}->[1]) { |
if (defined $uds->{$key}->[1]) { |
| 1008 |
$uds->{$key}->[1]->(3, $key, $uds->{$key}->[0]); # NODE_DELETED |
local $Error::Depth = $Error::Depth + 1; |
| 1009 |
|
$uds->{$key}->[1]->(3, $key, $uds->{$key}->[0]); # NODE_DELETED |
| 1010 |
|
} |
| 1011 |
} |
} |
| 1012 |
} |
} |
| 1013 |
}; |
}; |