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.
104 105 106 107 108 109 |
# File 'lib/dommy/tree_walker.rb', line 104 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.
102 103 104 |
# File 'lib/dommy/tree_walker.rb', line 102 def current_node @current_node end |
#filter ⇒ Object (readonly)
Returns the value of attribute filter.
101 102 103 |
# File 'lib/dommy/tree_walker.rb', line 101 def filter @filter end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
101 102 103 |
# File 'lib/dommy/tree_walker.rb', line 101 def root @root end |
#what_to_show ⇒ Object (readonly)
Returns the value of attribute what_to_show.
101 102 103 |
# File 'lib/dommy/tree_walker.rb', line 101 def what_to_show @what_to_show end |
Instance Method Details
#__js_call__(method, _args) ⇒ Object
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/dommy/tree_walker.rb', line 218 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
193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/dommy/tree_walker.rb', line 193 def __js_get__(key) case key when "root" @root when "whatToShow" @what_to_show when "filter" @filter when "currentNode" @current_node end end |
#__js_set__(key, value) ⇒ Object
206 207 208 209 210 211 212 213 214 |
# File 'lib/dommy/tree_walker.rb', line 206 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
177 178 179 |
# File 'lib/dommy/tree_walker.rb', line 177 def first_child traverse_children(:first_wrapped_child, :next_sibling_wrapped) end |
#last_child ⇒ Object
181 182 183 |
# File 'lib/dommy/tree_walker.rb', line 181 def last_child traverse_children(:last_wrapped_child, :previous_sibling_wrapped) end |
#next_node ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/dommy/tree_walker.rb', line 111 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
185 186 187 |
# File 'lib/dommy/tree_walker.rb', line 185 def next_sibling traverse_siblings(:next_sibling_wrapped, :first_wrapped_child) end |
#parent_node ⇒ Object
166 167 168 169 170 171 172 173 174 175 |
# File 'lib/dommy/tree_walker.rb', line 166 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
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/dommy/tree_walker.rb', line 140 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
189 190 191 |
# File 'lib/dommy/tree_walker.rb', line 189 def previous_sibling traverse_siblings(:previous_sibling_wrapped, :last_wrapped_child) end |