diff 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
line wrap: on
line diff
--- a/Lib/IMPL/DOM/Node.pm	Fri Nov 20 16:48:08 2009 +0300
+++ b/Lib/IMPL/DOM/Node.pm	Mon Nov 23 00:59:06 2009 +0300
@@ -12,20 +12,24 @@
 use IMPL::Exception;
 
 BEGIN {
-    public _direct property nodeName => prop_get | owner_set;
+    public _direct property nodeName => prop_get;
+    public _direct property document => prop_get;
     public _direct property isComplex => { get => \&_getIsComplex } ;
     public _direct property nodeValue => prop_all;
     public _direct property childNodes => { get => \&_getChildNodes };
     public _direct property parentNode => prop_get ;
-    public _direct property rootNode => { get => \&_getRootNode};
     private _direct property _propertyMap => prop_all ;
 }
 
 sub CTOR {
     my ($this,%args) = @_;
     
-    $this->nodeName(delete $args{nodeName}) or die new IMPL::InvalidArgumentException("A name is required");
-    $this->nodeValue(delete $args{nodeValue});
+    $this->{$nodeName} = delete $args{nodeName} or die new IMPL::InvalidArgumentException("A name is required");
+    $this->{$nodeValue} = delete $args{nodeValue} if exists $args{nodeValue};
+    if ( exists $args{document} ) {
+        $this->{$document} = delete $args{document};
+        weaken($this->{$document});
+    }
     
     $this->{$_propertyMap} = \%args;
 }
@@ -198,25 +202,16 @@
     $_[0]->childNodes->Count ? 1 : 0;
 }
 
-sub _getRootNode {
-    $_[0]->{$rootNode} || $_[0];
-}
-
-sub _updateRootRefs {
+sub _updateDocRefs {
     my ($this) = @_;
     
-    if ( my $newRoot = $this->{$parentNode} ? $this->{$parentNode}->rootNode : undef) {
-        if ($this->{$rootNode} ? $this->{$rootNode} != $newRoot : 1 ) {
-            $this->{$rootNode} = $newRoot;
-            weaken($this->{$rootNode});
-        }
-    } elsif($this->{$rootNode}) {
-        delete $this->{$rootNode};
-    }
+    # this method is called by the parent node on his children, so we need no to check parent
+    $this->{$document} = $this->{$parentNode}->document;
     
-    if ($this->{$childNodes}) {
-        $_->_updateRootRefs foreach @{$this->{$childNodes}};
-    }
+    # prevetn ciclyc
+    weaken($this->{$document}) if $this->{$document};
+    
+    $_->_updateDocRefs foreach @{$this->{$childNodes}};
 }
 
 sub _setParent {
@@ -224,21 +219,31 @@
     
    
     if (($node || 0) != ($this->{$parentNode} || 0)) {
+        my $newOwner;
         if ($node) {
             $this->{$parentNode} = $node;
+            $newOwner = $node->document || 0;
+            
             # prevent from creating cyclicreferences
             weaken($this->{$parentNode});
+
         } else {
             delete $this->{$parentNode};
+            $newOwner = 0;
         }
-        $this->_updateRootRefs;
+        
+        if (($this->{$document}||0) != $newOwner) {
+            $this->{$document} = $newOwner;
+            weaken($this->{$document}) if $newOwner;
+            $_->_updateDocRefs foreach @{$this->childNodes};
+        }
     }
 }
 
 sub text {
     my ($this) = @_;
     
-    join '', $this->nodeValue || '', map $_->nodeValue || '', @{$this->childNodes};
+    join ('', $this->nodeValue || '', map ($_->text || '', @{$this->childNodes}));
 }
 
 sub nodeProperty {