Mercurial > pub > Impl
view Lib/IMPL/DOM/Node.pm @ 7:94d47b388442
Улучшены тесты
Исправлены ошибки
Улучшена документация
Работа над схемой DOM
author | Sergey |
---|---|
date | Mon, 24 Aug 2009 01:05:34 +0400 |
parents | e2cd73ccc5bd |
children | 75980091813b |
line wrap: on
line source
package IMPL::DOM::Node; use strict; use warnings; use base qw(IMPL::Object IMPL::Object::Serializable IMPL::Object::Autofill); use IMPL::Object::List; use IMPL::Class::Property; use IMPL::Class::Property::Direct; use Scalar::Util qw(weaken); use IMPL::Exception; __PACKAGE__->PassThroughArgs; BEGIN { public _direct property nodeName => prop_get | owner_set; public _direct property isComplex => { get => \&_getIsComplex } ; public _direct property nodeValue => prop_all; public _direct property childNodes => { get => \&_getChildNodes }; public _direct property parentNode => prop_get ; private _direct property _propertyMap => prop_get ; } sub CTOR { my ($this,$name) = @_; $this->nodeName($name) or die new IMPL::InvalidArgumentException("A name is required"); } sub insertNode { my ($this,$node,$pos) = @_; die new IMPL::InvalidOperationException("You can't insert the node to itselft") if $this == $node; $node->{$parentNode}->removeNode($node) if ($node->{$parentNode}); $this->childNodes->InsertAt($pos,$node); $node->_setParent( $this ); return $node; } sub _getChildNodes { my ($this) = @_; $this->{$childNodes} = new IMPL::Object::List() unless $this->{$childNodes}; $this->{$childNodes}; } sub removeNode { my ($this,$node) = @_; if ($this == $node->{$parentNode}) { $this->childNodes->RemoveItem($node); $node->{$parentNode} = undef; return $this; } else { die new IMPL::InvalidOperationException("The specified node isn't belong to this node"); } } sub replaceNodeAt { my ($this,$index,$node) = @_; my $nodeOld = $this->childNodes->[$index]; die new IMPL::InvalidOperationException("You can't insert the node to itselft") if $this == $node; # unlink node from previous parent $node->{$parentNode}->removeNode($node) if ($node->{$parentNode}); # replace (or set) old node $this->childNodes->[$index] = $node; # save new parent $node->_setParent( $this ); # unlink old node if we have one $nodeOld->{$parentNode} = undef if $nodeOld; # return old node return $nodeOld; } sub removeAt { my ($this,$pos) = @_; if ( my $node = $this->childNodes->RemoveAt($pos) ) { $node->{$parentNode} = undef; return $node; } else { return undef; } } sub selectNodes { my ($this,$name) = @_; my @result = grep $_->nodeName eq $name, @{$this->childNodes}; return wantarray ? @result : \@result; } sub firstChild { @_ >=2 ? $_[0]->replaceNodeAt(0,$_[1]) : $_[0]->childNodes->[0]; } sub _getIsComplex { $_[0]->childNodes->Count ? 1 : 0; } sub _setParent { my ($this,$parentNode) = @_; $this->{$parentNode} = $parentNode; weaken($this->{$parentNode}); } sub text { my ($this) = @_; join '', $this->nodeValue, map $_->nodeValue, @{$this->childNodes}; } sub Property { my $this = shift; my $name = shift; if (@_) { # set return $this->{$_propertyMap}{$name} = shift; } else { return $this->{$_propertyMap}{$name}; } } 1;