Mercurial > pub > Impl
comparison Lib/IMPL/DOM/Navigator.pm @ 36:1828103371d0
DOM in works
author | Sergey |
---|---|
date | Fri, 20 Nov 2009 16:48:08 +0300 |
parents | a8086f85a571 |
children | 16ada169ca75 |
comparison
equal
deleted
inserted
replaced
35:f25d021780b3 | 36:1828103371d0 |
---|---|
18 die IMPL::InvalidArgumentException("A starting node is a required paramater") unless $CurrentNode; | 18 die IMPL::InvalidArgumentException("A starting node is a required paramater") unless $CurrentNode; |
19 | 19 |
20 $this->{$_state} = { alternatives => [ $CurrentNode ], current => 0 }; | 20 $this->{$_state} = { alternatives => [ $CurrentNode ], current => 0 }; |
21 } | 21 } |
22 | 22 |
23 sub _initNavigator { | |
24 my ($this,$CurrentNode) = @_; | |
25 | |
26 die IMPL::InvalidArgumentException("A starting node is a required paramater") unless $CurrentNode; | |
27 | |
28 $this->{$_state} = { alternatives => [ $CurrentNode ], current => 0 }; | |
29 delete $this->{$_path}; | |
30 delete $this->{$_savedstates}; | |
31 } | |
32 | |
23 sub _getCurrent { | 33 sub _getCurrent { |
24 $_[0]->{$_state}{alternatives}[$_[0]->{$_state}{current}] | 34 $_[0]->{$_state}{alternatives}[$_[0]->{$_state}{current}] |
25 } | 35 } |
26 | 36 |
27 sub Navigate { | 37 sub Navigate { |
28 my ($this,@path) = @_; | 38 my ($this,@path) = @_; |
29 | 39 |
30 return unless @path; | 40 return unless @path; |
31 | 41 |
42 my $node; | |
43 | |
32 foreach my $query (@path) { | 44 foreach my $query (@path) { |
33 if (my $current = $this->Current) { | 45 if (my $current = $this->Current) { |
34 | 46 |
35 my @alternatives = $this->Current->selectNodes($query); | 47 my @alternatives = $current->selectNodes($query); |
36 | 48 |
37 unless (@alternatives) { | 49 unless (@alternatives) { |
38 $this->advanceNavigator or return undef; | 50 $current = $this->advanceNavigator or return undef; |
39 @alternatives = $this->Current->selectNodes($query); | 51 @alternatives = $current->selectNodes($query); |
40 } | 52 } |
41 | 53 |
42 push @{$this->{$_path}},$this->{$_state}; | 54 push @{$this->{$_path}},$this->{$_state}; |
43 $this->{$_state} = { | 55 $this->{$_state} = { |
44 alternatives => \@alternatives, | 56 alternatives => \@alternatives, |
45 current => 0, | 57 current => 0, |
46 query => $query | 58 query => $query |
47 } | 59 }; |
60 | |
61 $node = $alternatives[0]; | |
48 } else { | 62 } else { |
49 return undef; | 63 return undef; |
50 } | 64 } |
51 } | 65 } |
52 | 66 |
53 return $this->Current; | 67 $node; |
54 } | 68 } |
55 | 69 |
56 sub selectNodes { | 70 sub selectNodes { |
57 my ($this,@path) = @_; | 71 my ($this,@path) = @_; |
58 | 72 |
78 $this->{$_state} = { | 92 $this->{$_state} = { |
79 alternatives => \@nodeSet, | 93 alternatives => \@nodeSet, |
80 current => 0 | 94 current => 0 |
81 }; | 95 }; |
82 | 96 |
83 return $this->Current; | 97 $nodeSet[0]; |
84 } | 98 } |
85 | 99 |
86 sub fetch { | 100 sub fetch { |
87 my ($this) = @_; | 101 my ($this) = @_; |
88 | 102 |
98 | 112 |
99 if (@{$this->{$_state}{alternatives}} <= $this->{$_state}{current}) { | 113 if (@{$this->{$_state}{alternatives}} <= $this->{$_state}{current}) { |
100 if ( exists $this->{$_state}{query} ) { | 114 if ( exists $this->{$_state}{query} ) { |
101 my $query = $this->{$_state}{query}; | 115 my $query = $this->{$_state}{query}; |
102 | 116 |
103 $this->Back or return 0; # that meams the end of the history | 117 $this->Back or return undef; # that meams the end of the history |
104 | 118 |
105 undef while ( $this->advanceNavigator and not $this->Navigate($query)); | 119 undef while ( $this->advanceNavigator and not $this->Navigate($query)); |
106 | 120 |
107 return $this->Current ? 1 : 0; | 121 return $this->Current; |
108 } | 122 } |
109 return 0; | 123 return undef; |
110 } | 124 } |
111 | 125 |
112 return 1; | 126 return $this->Current; |
113 } | 127 } |
114 | 128 |
115 sub doeach { | 129 sub doeach { |
116 my ($this,$code) = @_; | 130 my ($this,$code) = @_; |
117 local $_; | 131 local $_; |
119 do { | 133 do { |
120 for (my $i = $this->{$_state}{current}; $i < @{$this->{$_state}{alternatives}}; $i++) { | 134 for (my $i = $this->{$_state}{current}; $i < @{$this->{$_state}{alternatives}}; $i++) { |
121 $_ = $this->{$_state}{alternatives}[$i]; | 135 $_ = $this->{$_state}{alternatives}[$i]; |
122 $code->(); | 136 $code->(); |
123 } | 137 } |
124 $this->{$_state}{current} = @{$this->{$_state}{alternatives}}; | 138 $this->{$_state}{current} = @{$this->{$_state}{alternatives}}; |
125 } while ($this->advanceNavigator); | 139 } while ($this->advanceNavigator); |
126 } | 140 } |
127 | 141 |
128 sub Back { | 142 sub Back { |
129 my ($this,$steps) = @_; | 143 my ($this,$steps) = @_; |
130 | |
131 $steps ||= 1; | |
132 | |
133 if ($this->{$_path} and @{$this->{$_path}}) { | 144 if ($this->{$_path} and @{$this->{$_path}}) { |
134 | 145 if ( (not $steps) || $steps == 1) { |
135 $steps = @{$this->{$_path}} - 1 if $steps >= @{$this->{$_path}}; | 146 $this->{$_state} = pop @{$this->{$_path}}; |
136 | 147 } else { |
137 ($this->{$_state}) = splice @{$this->{$_path}},-$steps; | 148 $steps ||= 1; |
138 | 149 |
139 $this->Current; | 150 $steps = @{$this->{$_path}} - 1 if $steps >= @{$this->{$_path}}; |
151 | |
152 $this->{$_state} = (splice @{$this->{$_path}},-$steps)[0]; | |
153 } | |
154 $this->Current if defined wantarray; | |
140 } else { | 155 } else { |
141 return undef; | 156 return undef; |
142 } | 157 } |
143 } | 158 } |
144 | 159 |