comparison Lib/IMPL/DOM/Node.pm @ 37:c2e7f7c96bcd

performance improvements, DOM reworked (a little)
author Sergey
date Mon, 23 Nov 2009 00:59:06 +0300
parents 1828103371d0
children d660fb38b7cc
comparison
equal deleted inserted replaced
36:1828103371d0 37:c2e7f7c96bcd
10 use Scalar::Util qw(weaken); 10 use Scalar::Util qw(weaken);
11 11
12 use IMPL::Exception; 12 use IMPL::Exception;
13 13
14 BEGIN { 14 BEGIN {
15 public _direct property nodeName => prop_get | owner_set; 15 public _direct property nodeName => prop_get;
16 public _direct property document => prop_get;
16 public _direct property isComplex => { get => \&_getIsComplex } ; 17 public _direct property isComplex => { get => \&_getIsComplex } ;
17 public _direct property nodeValue => prop_all; 18 public _direct property nodeValue => prop_all;
18 public _direct property childNodes => { get => \&_getChildNodes }; 19 public _direct property childNodes => { get => \&_getChildNodes };
19 public _direct property parentNode => prop_get ; 20 public _direct property parentNode => prop_get ;
20 public _direct property rootNode => { get => \&_getRootNode};
21 private _direct property _propertyMap => prop_all ; 21 private _direct property _propertyMap => prop_all ;
22 } 22 }
23 23
24 sub CTOR { 24 sub CTOR {
25 my ($this,%args) = @_; 25 my ($this,%args) = @_;
26 26
27 $this->nodeName(delete $args{nodeName}) or die new IMPL::InvalidArgumentException("A name is required"); 27 $this->{$nodeName} = delete $args{nodeName} or die new IMPL::InvalidArgumentException("A name is required");
28 $this->nodeValue(delete $args{nodeValue}); 28 $this->{$nodeValue} = delete $args{nodeValue} if exists $args{nodeValue};
29 if ( exists $args{document} ) {
30 $this->{$document} = delete $args{document};
31 weaken($this->{$document});
32 }
29 33
30 $this->{$_propertyMap} = \%args; 34 $this->{$_propertyMap} = \%args;
31 } 35 }
32 36
33 sub insertNode { 37 sub insertNode {
196 200
197 sub _getIsComplex { 201 sub _getIsComplex {
198 $_[0]->childNodes->Count ? 1 : 0; 202 $_[0]->childNodes->Count ? 1 : 0;
199 } 203 }
200 204
201 sub _getRootNode { 205 sub _updateDocRefs {
202 $_[0]->{$rootNode} || $_[0]; 206 my ($this) = @_;
203 } 207
204 208 # this method is called by the parent node on his children, so we need no to check parent
205 sub _updateRootRefs { 209 $this->{$document} = $this->{$parentNode}->document;
206 my ($this) = @_; 210
207 211 # prevetn ciclyc
208 if ( my $newRoot = $this->{$parentNode} ? $this->{$parentNode}->rootNode : undef) { 212 weaken($this->{$document}) if $this->{$document};
209 if ($this->{$rootNode} ? $this->{$rootNode} != $newRoot : 1 ) { 213
210 $this->{$rootNode} = $newRoot; 214 $_->_updateDocRefs foreach @{$this->{$childNodes}};
211 weaken($this->{$rootNode});
212 }
213 } elsif($this->{$rootNode}) {
214 delete $this->{$rootNode};
215 }
216
217 if ($this->{$childNodes}) {
218 $_->_updateRootRefs foreach @{$this->{$childNodes}};
219 }
220 } 215 }
221 216
222 sub _setParent { 217 sub _setParent {
223 my ($this,$node) = @_; 218 my ($this,$node) = @_;
224 219
225 220
226 if (($node || 0) != ($this->{$parentNode} || 0)) { 221 if (($node || 0) != ($this->{$parentNode} || 0)) {
222 my $newOwner;
227 if ($node) { 223 if ($node) {
228 $this->{$parentNode} = $node; 224 $this->{$parentNode} = $node;
225 $newOwner = $node->document || 0;
226
229 # prevent from creating cyclicreferences 227 # prevent from creating cyclicreferences
230 weaken($this->{$parentNode}); 228 weaken($this->{$parentNode});
229
231 } else { 230 } else {
232 delete $this->{$parentNode}; 231 delete $this->{$parentNode};
232 $newOwner = 0;
233 } 233 }
234 $this->_updateRootRefs; 234
235 if (($this->{$document}||0) != $newOwner) {
236 $this->{$document} = $newOwner;
237 weaken($this->{$document}) if $newOwner;
238 $_->_updateDocRefs foreach @{$this->childNodes};
239 }
235 } 240 }
236 } 241 }
237 242
238 sub text { 243 sub text {
239 my ($this) = @_; 244 my ($this) = @_;
240 245
241 join '', $this->nodeValue || '', map $_->nodeValue || '', @{$this->childNodes}; 246 join ('', $this->nodeValue || '', map ($_->text || '', @{$this->childNodes}));
242 } 247 }
243 248
244 sub nodeProperty { 249 sub nodeProperty {
245 my $this = shift; 250 my $this = shift;
246 my $name = shift; 251 my $name = shift;