Mercurial > pub > Impl
comparison Lib/IMPL/DOM/Node.pm @ 18:818c74b038ae
DOM Schema + tests
author | Sergey |
---|---|
date | Thu, 10 Sep 2009 17:42:47 +0400 |
parents | 75d55f4ee263 |
children | fafe56cfcd69 |
comparison
equal
deleted
inserted
replaced
17:7f88e01b58f8 | 18:818c74b038ae |
---|---|
15 public _direct property nodeName => prop_get | owner_set; | 15 public _direct property nodeName => prop_get | owner_set; |
16 public _direct property isComplex => { get => \&_getIsComplex } ; | 16 public _direct property isComplex => { get => \&_getIsComplex } ; |
17 public _direct property nodeValue => prop_all; | 17 public _direct property nodeValue => prop_all; |
18 public _direct property childNodes => { get => \&_getChildNodes }; | 18 public _direct property childNodes => { get => \&_getChildNodes }; |
19 public _direct property parentNode => prop_get ; | 19 public _direct property parentNode => prop_get ; |
20 private _direct property _propertyMap => prop_get ; | 20 public _direct property rootNode => { get => \&_getRootNode}; |
21 private _direct property _propertyMap => prop_all ; | |
21 } | 22 } |
22 | 23 |
23 sub CTOR { | 24 sub CTOR { |
24 my ($this,%args) = @_; | 25 my ($this,%args) = @_; |
25 | 26 |
26 $this->nodeName($args{nodeName}) or die new IMPL::InvalidArgumentException("A name is required"); | 27 $this->nodeName($args{nodeName}) or die new IMPL::InvalidArgumentException("A name is required"); |
28 $this->nodeValue($args{nodeValue}); | |
27 } | 29 } |
28 | 30 |
29 sub insertNode { | 31 sub insertNode { |
30 my ($this,$node,$pos) = @_; | 32 my ($this,$node,$pos) = @_; |
31 | 33 |
45 | 47 |
46 die new IMPL::InvalidOperationException("You can't insert the node to itselft") if $this == $node; | 48 die new IMPL::InvalidOperationException("You can't insert the node to itselft") if $this == $node; |
47 | 49 |
48 $node->{$parentNode}->removeNode($node) if ($node->{$parentNode}); | 50 $node->{$parentNode}->removeNode($node) if ($node->{$parentNode}); |
49 | 51 |
50 $this->childNodes->Append($node); | 52 my $children = $this->childNodes; |
53 $children->Append($node); | |
51 | 54 |
52 $node->_setParent( $this ); | 55 $node->_setParent( $this ); |
53 | 56 |
54 return $node; | 57 return $node; |
55 } | 58 } |
71 | 74 |
72 sub _getChildNodes { | 75 sub _getChildNodes { |
73 my ($this) = @_; | 76 my ($this) = @_; |
74 | 77 |
75 $this->{$childNodes} = new IMPL::Object::List() unless $this->{$childNodes}; | 78 $this->{$childNodes} = new IMPL::Object::List() unless $this->{$childNodes}; |
76 $this->{$childNodes}; | 79 return $this->{$childNodes}; |
77 } | 80 } |
78 | 81 |
79 sub removeNode { | 82 sub removeNode { |
80 my ($this,$node) = @_; | 83 my ($this,$node) = @_; |
81 | 84 |
82 if ($this == $node->{$parentNode}) { | 85 if ($this == $node->{$parentNode}) { |
83 $this->childNodes->RemoveItem($node); | 86 $this->childNodes->RemoveItem($node); |
84 $node->{$parentNode} = undef; | 87 $node->_setParent(undef); |
85 return $this; | 88 return $node; |
86 } else { | 89 } else { |
87 die new IMPL::InvalidOperationException("The specified node isn't belong to this node"); | 90 die new IMPL::InvalidOperationException("The specified node isn't belong to this node"); |
88 } | 91 } |
89 } | 92 } |
90 | 93 |
99 $node->{$parentNode}->removeNode($node) if ($node->{$parentNode}); | 102 $node->{$parentNode}->removeNode($node) if ($node->{$parentNode}); |
100 | 103 |
101 # replace (or set) old node | 104 # replace (or set) old node |
102 $this->childNodes->[$index] = $node; | 105 $this->childNodes->[$index] = $node; |
103 | 106 |
104 # save new parent | 107 # set new parent |
105 $node->_setParent( $this ); | 108 $node->_setParent( $this ); |
106 | 109 |
107 # unlink old node if we have one | 110 # unlink old node if we have one |
108 $nodeOld->{$parentNode} = undef if $nodeOld; | 111 $nodeOld->_setParent(undef) if $nodeOld; |
109 | 112 |
110 # return old node | 113 # return old node |
111 return $nodeOld; | 114 return $nodeOld; |
112 } | 115 } |
113 | 116 |
114 sub removeAt { | 117 sub removeAt { |
115 my ($this,$pos) = @_; | 118 my ($this,$pos) = @_; |
116 | 119 |
117 if ( my $node = $this->childNodes->RemoveAt($pos) ) { | 120 if ( my $node = $this->childNodes->RemoveAt($pos) ) { |
118 $node->{$parentNode} = undef; | 121 $node->_setParent(undef); |
119 return $node; | 122 return $node; |
120 } else { | 123 } else { |
121 return undef; | 124 return undef; |
122 } | 125 } |
126 } | |
127 | |
128 sub removeLast { | |
129 my ($this) = @_; | |
130 | |
131 if ( my $node = $this->{$childNodes} ? $this->{$childNodes}->RemoveLast() : undef) { | |
132 $node->_setParent(undef); | |
133 return $node; | |
134 } else { | |
135 return undef; | |
136 } | |
137 } | |
138 | |
139 sub removeSelected { | |
140 my ($this,$query) = @_; | |
141 | |
142 my @newSet; | |
143 my @result; | |
144 | |
145 if (ref $query eq 'CODE') { | |
146 &$query($_) ? push @result, $_ : push @newSet, $_ foreach @{$this->childNodes}; | |
147 } elsif (defined $query) { | |
148 $_->nodeName eq $query ? push @result, $_ : push @newSet, $_ foreach @{$this->childNodes}; | |
149 } else { | |
150 my $children = $this->childNodes; | |
151 $_->_setParent(undef) foreach @$children; | |
152 delete $this->{$childNodes}; | |
153 return wantarray ? @$children : $children; | |
154 } | |
155 | |
156 $_->_setParent(undef) foreach @result; | |
157 | |
158 $this->{$childNodes} = @newSet ? bless \@newSet ,'IMPL::Object::List' : undef; | |
159 | |
160 return wantarray ? @result : \@result; | |
123 } | 161 } |
124 | 162 |
125 sub selectNodes { | 163 sub selectNodes { |
126 my ($this,$query) = @_; | 164 my ($this,$query) = @_; |
165 | |
127 my @result; | 166 my @result; |
128 | 167 |
129 if (ref $query eq 'CODE') { | 168 if (ref $query eq 'CODE') { |
130 @result = grep &$query($_), @{$this->childNodes}; | 169 @result = grep &$query($_), @{$this->childNodes}; |
131 } else { | 170 } elsif (defined $query) { |
132 @result = grep $_->nodeName eq $query, @{$this->childNodes}; | 171 @result = grep $_->nodeName eq $query, @{$this->childNodes}; |
172 } else { | |
173 if (wantarray) { | |
174 return @{$this->childNodes}; | |
175 } else { | |
176 @result = $this->childNodes; | |
177 return \@result; | |
178 } | |
133 } | 179 } |
134 | 180 |
135 return wantarray ? @result : \@result; | 181 return wantarray ? @result : \@result; |
136 } | 182 } |
137 | 183 |
141 | 187 |
142 sub _getIsComplex { | 188 sub _getIsComplex { |
143 $_[0]->childNodes->Count ? 1 : 0; | 189 $_[0]->childNodes->Count ? 1 : 0; |
144 } | 190 } |
145 | 191 |
192 sub _getRootNode { | |
193 $_[0]->{$rootNode} || $_[0]; | |
194 } | |
195 | |
196 sub _updateRootRefs { | |
197 my ($this) = @_; | |
198 | |
199 if ( my $newRoot = $this->{$parentNode} ? $this->{$parentNode}->rootNode : undef) { | |
200 if ($this->{$rootNode} ? $this->{$rootNode} != $newRoot : 1 ) { | |
201 $this->{$rootNode} = $newRoot; | |
202 weaken($this->{$rootNode}); | |
203 if ($this->{$childNodes}) { | |
204 $_->_updateRootRefs foreach @{$this->{$childNodes}}; | |
205 } | |
206 } | |
207 } elsif($this->{$rootNode}) { | |
208 delete $this->{$rootNode}; | |
209 if ($this->{$childNodes}) { | |
210 $_->_updateRootRefs foreach @{$this->{$childNodes}}; | |
211 } | |
212 } | |
213 } | |
214 | |
146 sub _setParent { | 215 sub _setParent { |
147 my ($this,$node) = @_; | 216 my ($this,$node) = @_; |
148 | 217 |
149 $this->{$parentNode} = $node; | 218 |
150 # prevent from creating cyclicreferences | 219 if (($node || 0) != ($this->{$parentNode} || 0)) { |
151 weaken($this->{$parentNode}); | 220 if ($node) { |
221 $this->{$parentNode} = $node; | |
222 # prevent from creating cyclicreferences | |
223 weaken($this->{$parentNode}); | |
224 } else { | |
225 delete $this->{$parentNode}; | |
226 } | |
227 $this->_updateRootRefs; | |
228 } | |
152 } | 229 } |
153 | 230 |
154 sub text { | 231 sub text { |
155 my ($this) = @_; | 232 my ($this) = @_; |
156 | 233 |
157 join '', $this->nodeValue, map $_->nodeValue, @{$this->childNodes}; | 234 join '', $this->nodeValue || '', map $_->nodeValue || '', @{$this->childNodes}; |
158 } | 235 } |
159 | 236 |
160 sub Property { | 237 sub Property { |
161 my $this = shift; | 238 my $this = shift; |
162 my $name = shift; | 239 my $name = shift; |