diff --git a/lib/oga/xml/node.rb b/lib/oga/xml/node.rb index 201feb0..751edd3 100644 --- a/lib/oga/xml/node.rb +++ b/lib/oga/xml/node.rb @@ -214,6 +214,26 @@ module Oga def xml? !html? end + + ## + # Yields all ancestor elements of the current node. + # + # @example + # some_element.each_ancestor do |node| + # # ... + # end + # + # @yieldparam [Oga::XML::Node] + # + def each_ancestor + node = parent + + while node.is_a?(XML::Element) + yield node + + node = node.parent + end + end end # Element end # XML end # Oga diff --git a/spec/oga/xml/node_spec.rb b/spec/oga/xml/node_spec.rb index 34cb5ba..6d33f4d 100644 --- a/spec/oga/xml/node_spec.rb +++ b/spec/oga/xml/node_spec.rb @@ -276,4 +276,18 @@ describe Oga::XML::Node do node.xml?.should == false end end + + describe '#each_ancestor' do + before do + @child2 = Oga::XML::Element.new(:name => 'c') + @child1 = Oga::XML::Element.new(:name => 'b', :children => [@child2]) + @root = Oga::XML::Element.new(:name => 'a', :children => [@child1]) + @document = Oga::XML::Document.new(:children => [@root]) + end + + it 'yields all the ancestor elements' do + expect { |b| @child2.each_ancestor(&b) } + .to yield_successive_args(@child1, @root) + end + end end