Class: Dommy::TreeWalker
- Inherits:
-
Object
- Object
- Dommy::TreeWalker
- Includes:
- Bridge::Methods, TreeTraversalCore
- Defined in:
- lib/dommy/tree_walker.rb
Overview
TreeWalker — stateful traversal with next_node / previous_node
/ parent_node / first_child / last_child / next_sibling /
previous_sibling and a mutable current_node cursor.
Wraps Nokogiri descent; doesn't snapshot the tree, so mutations during traversal are visible (matches DOM spec).
Instance Attribute Summary collapse
-
#current_node ⇒ Object
Returns the value of attribute current_node.
-
#filter ⇒ Object
readonly
Returns the value of attribute filter.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
-
#what_to_show ⇒ Object
readonly
Returns the value of attribute what_to_show.
Instance Method Summary collapse
- #__js_call__(method, _args) ⇒ Object
- #__js_get__(key) ⇒ Object
- #__js_set__(key, value) ⇒ Object
- #first_child ⇒ Object
-
#initialize(root, what_to_show = NodeFilter::SHOW_ALL, filter = nil) ⇒ TreeWalker
constructor
A new instance of TreeWalker.
- #last_child ⇒ Object
- #next_node ⇒ Object
- #next_sibling ⇒ Object
- #parent_node ⇒ Object
- #previous_node ⇒ Object
- #previous_sibling ⇒ Object
Methods included from Bridge::Methods
Constructor Details
#initialize(root, what_to_show = NodeFilter::SHOW_ALL, filter = nil) ⇒ TreeWalker
Returns a new instance of TreeWalker.
122 123 124 125 126 127 |
# File 'lib/dommy/tree_walker.rb', line 122 def initialize(root, what_to_show = NodeFilter::SHOW_ALL, filter = nil) @root = root @what_to_show = what_to_show.to_i @filter = filter @current_node = root end |
Instance Attribute Details
#current_node ⇒ Object
Returns the value of attribute current_node.
120 121 122 |
# File 'lib/dommy/tree_walker.rb', line 120 def current_node @current_node end |
#filter ⇒ Object (readonly)
Returns the value of attribute filter.
119 120 121 |
# File 'lib/dommy/tree_walker.rb', line 119 def filter @filter end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
119 120 121 |
# File 'lib/dommy/tree_walker.rb', line 119 def root @root end |
#what_to_show ⇒ Object (readonly)
Returns the value of attribute what_to_show.
119 120 121 |
# File 'lib/dommy/tree_walker.rb', line 119 def what_to_show @what_to_show end |
Instance Method Details
#__js_call__(method, _args) ⇒ Object
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/dommy/tree_walker.rb', line 238 def __js_call__(method, _args) case method when "nextNode" next_node when "previousNode" previous_node when "parentNode" parent_node when "firstChild" first_child when "lastChild" last_child when "nextSibling" next_sibling when "previousSibling" previous_sibling end end |
#__js_get__(key) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/dommy/tree_walker.rb', line 211 def __js_get__(key) case key when "root" @root when "whatToShow" @what_to_show when "filter" @filter when "currentNode" @current_node else Bridge::ABSENT end end |
#__js_set__(key, value) ⇒ Object
226 227 228 229 230 231 232 233 234 |
# File 'lib/dommy/tree_walker.rb', line 226 def __js_set__(key, value) return Bridge::UNHANDLED unless key == "currentNode" # currentNode is a non-null `Node`; non-Node values are a TypeError. raise Bridge::TypeError, "currentNode must be a Node" unless value.is_a?(Dommy::Node) @current_node = value nil end |
#first_child ⇒ Object
195 196 197 |
# File 'lib/dommy/tree_walker.rb', line 195 def first_child traverse_children(:first_wrapped_child, :next_sibling_wrapped) end |
#last_child ⇒ Object
199 200 201 |
# File 'lib/dommy/tree_walker.rb', line 199 def last_child traverse_children(:last_wrapped_child, :previous_sibling_wrapped) end |
#next_node ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/dommy/tree_walker.rb', line 129 def next_node node = @current_node result = NodeFilter::FILTER_ACCEPT loop do while result != NodeFilter::FILTER_REJECT && (child = first_wrapped_child(node)) node = child result = accept(node) return @current_node = node if result == NodeFilter::FILTER_ACCEPT end sibling = nil temp = node while temp return nil if temp == @root sibling = next_sibling_wrapped(temp) if sibling node = sibling break end temp = wrapped_parent(temp) end return nil unless sibling result = accept(node) return @current_node = node if result == NodeFilter::FILTER_ACCEPT end end |
#next_sibling ⇒ Object
203 204 205 |
# File 'lib/dommy/tree_walker.rb', line 203 def next_sibling traverse_siblings(:next_sibling_wrapped, :first_wrapped_child) end |
#parent_node ⇒ Object
184 185 186 187 188 189 190 191 192 193 |
# File 'lib/dommy/tree_walker.rb', line 184 def parent_node node = wrapped_parent(@current_node) while node && reachable_from_root?(node) return @current_node = node if accept(node) == NodeFilter::FILTER_ACCEPT node = wrapped_parent(node) end nil end |
#previous_node ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/dommy/tree_walker.rb', line 158 def previous_node node = @current_node while node != @root sibling = previous_sibling_wrapped(node) while sibling node = sibling result = accept(node) while result != NodeFilter::FILTER_REJECT && (child = last_wrapped_child(node)) node = child result = accept(node) end return @current_node = node if result == NodeFilter::FILTER_ACCEPT sibling = previous_sibling_wrapped(node) end parent = wrapped_parent(node) return nil if node == @root || parent.nil? node = parent return @current_node = node if accept(node) == NodeFilter::FILTER_ACCEPT end nil end |
#previous_sibling ⇒ Object
207 208 209 |
# File 'lib/dommy/tree_walker.rb', line 207 def previous_sibling traverse_siblings(:previous_sibling_wrapped, :last_wrapped_child) end |