diff --git a/lib/oga.rb b/lib/oga.rb
index 8498725..aadd7fc 100644
--- a/lib/oga.rb
+++ b/lib/oga.rb
@@ -20,6 +20,7 @@ end
#:nocov:
require_relative 'oga/xml/querying'
+require_relative 'oga/xml/traversal'
require_relative 'oga/xml/node'
require_relative 'oga/xml/document'
require_relative 'oga/xml/character_node'
diff --git a/lib/oga/xml/document.rb b/lib/oga/xml/document.rb
index 2c9fb33..1a56c39 100644
--- a/lib/oga/xml/document.rb
+++ b/lib/oga/xml/document.rb
@@ -14,6 +14,7 @@ module Oga
#
class Document
include Querying
+ include Traversal
attr_accessor :doctype, :xml_declaration
@@ -51,46 +52,6 @@ module Oga
end
end
- ##
- # Traverses through the document and yields every node to the supplied
- # block.
- #
- # The block's body can also determine whether or not to traverse child
- # nodes. Preventing a node's children from being traversed can be done by
- # using `throw :skip_children`
- #
- # This method uses a combination of breadth-first and depth-first
- # traversal to traverse the entire XML tree in document order. See
- # http://en.wikipedia.org/wiki/Breadth-first_search for more information.
- #
- # @example
- # document.each_node do |node|
- # p node.class
- # end
- #
- # @example Skipping the children of a certain node
- # document.each_node do |node|
- # if node.is_a?(Oga::XML::Element) and node.name == 'book'
- # throw :skip_children
- # end
- # end
- #
- # @yieldparam [Oga::XML::Node] The current node.
- #
- def each_node
- visit = children.to_a.dup # copy it since we're modifying the array
-
- until visit.empty?
- current = visit.shift
-
- catch :skip_children do
- yield current
-
- visit = current.children.to_a + visit
- end
- end
- end
-
##
# Converts the document and its child nodes to XML.
#
diff --git a/lib/oga/xml/node.rb b/lib/oga/xml/node.rb
index 0cabf6d..1d6d76b 100644
--- a/lib/oga/xml/node.rb
+++ b/lib/oga/xml/node.rb
@@ -9,6 +9,8 @@ module Oga
# @return [Oga::XML::NodeSet]
#
class Node
+ include Traversal
+
attr_accessor :node_set
##
diff --git a/lib/oga/xml/traversal.rb b/lib/oga/xml/traversal.rb
new file mode 100644
index 0000000..4903e07
--- /dev/null
+++ b/lib/oga/xml/traversal.rb
@@ -0,0 +1,48 @@
+module Oga
+ module XML
+ ##
+ # Module that provides methods to traverse DOM trees.
+ #
+ module Traversal
+ ##
+ # Traverses through the node and yields every child node to the supplied
+ # block.
+ #
+ # The block's body can also determine whether or not to traverse child
+ # nodes. Preventing a node's children from being traversed can be done by
+ # using `throw :skip_children`
+ #
+ # This method uses a combination of breadth-first and depth-first
+ # traversal to traverse the entire XML tree in document order. See
+ # http://en.wikipedia.org/wiki/Breadth-first_search for more information.
+ #
+ # @example
+ # document.each_node do |node|
+ # p node.class
+ # end
+ #
+ # @example Skipping the children of a certain node
+ # document.each_node do |node|
+ # if node.is_a?(Oga::XML::Element) and node.name == 'book'
+ # throw :skip_children
+ # end
+ # end
+ #
+ # @yieldparam [Oga::XML::Node] The current node.
+ #
+ def each_node
+ visit = children.to_a.dup # copy it since we're modifying the array
+
+ until visit.empty?
+ current = visit.shift
+
+ catch :skip_children do
+ yield current
+
+ visit = current.children.to_a + visit
+ end
+ end
+ end
+ end # Traversal
+ end # XML
+end # Oga
diff --git a/spec/oga/xml/document_spec.rb b/spec/oga/xml/document_spec.rb
index 5c68e5c..62df667 100644
--- a/spec/oga/xml/document_spec.rb
+++ b/spec/oga/xml/document_spec.rb
@@ -30,47 +30,6 @@ describe Oga::XML::Document do
end
end
- context '#each_node' do
- before do
- @document = parse(<<-EOF.strip.gsub(/\s+/m, ''))
-
-
- Foo
-
-
- Bar
-
-
- EOF
- end
-
- example 'yield the nodes in document order' do
- names = []
-
- @document.each_node do |node|
- names << (node.is_a?(Oga::XML::Element) ? node.name : node.text)
- end
-
- names.should == %w{books book1 title1 Foo book2 title2 Bar}
- end
-
- example 'skip child nodes when skip_children is thrown' do
- names = []
-
- @document.each_node do |node|
- if node.is_a?(Oga::XML::Element)
- if node.name == 'book1'
- throw :skip_children
- else
- names << node.name
- end
- end
- end
-
- names.should == %w{books book2 title2}
- end
- end
-
context '#to_xml' do
before do
child = Oga::XML::Comment.new(:text => 'foo')
diff --git a/spec/oga/xml/traversal_spec.rb b/spec/oga/xml/traversal_spec.rb
new file mode 100644
index 0000000..23b16c9
--- /dev/null
+++ b/spec/oga/xml/traversal_spec.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+describe Oga::XML::Traversal do
+ context '#each_node' do
+ before do
+ @document = parse(<<-EOF.strip.gsub(/\s+/m, ''))
+
+
+ Foo
+
+
+ Bar
+
+
+ EOF
+ end
+
+ example 'yield the nodes in document order' do
+ names = []
+
+ @document.each_node do |node|
+ names << (node.is_a?(Oga::XML::Element) ? node.name : node.text)
+ end
+
+ names.should == %w{books book1 title1 Foo book2 title2 Bar}
+ end
+
+ example 'skip child nodes when skip_children is thrown' do
+ names = []
+
+ @document.each_node do |node|
+ if node.is_a?(Oga::XML::Element)
+ if node.name == 'book1'
+ throw :skip_children
+ else
+ names << node.name
+ end
+ end
+ end
+
+ names.should == %w{books book2 title2}
+ end
+ end
+end