Module: Banzai::Querying
- Defined in:
- lib/banzai/querying.rb
Class Method Summary collapse
-
.css(document, query, reference_options = {}) ⇒ Object
Searches a Nokogiri document using a CSS query, optionally optimizing it whenever possible.
- .filter_nodes(nodes, reference_options) ⇒ Object
-
.filter_nodes_at_beginning(nodes) ⇒ Object
Selects child nodes if they are present in the beginning among other siblings.
- .filter_nodes_at_beginning?(reference_options) ⇒ Boolean
- .restrict_to_p_nodes_at_root(xpath) ⇒ Object
Class Method Details
.css(document, query, reference_options = {}) ⇒ Object
Searches a Nokogiri document using a CSS query, optionally optimizing it whenever possible.
document - A document/element to search. query - The CSS query to use. reference_options - A hash with nodes filter options
Returns an array of Nokogiri::XML::Element objects if location is specified in reference_options. Otherwise it would a Nokogiri::XML::NodeSet.
16 17 18 19 20 21 22 23 24 |
# File 'lib/banzai/querying.rb', line 16 def css(document, query, = {}) # When using "a.foo" Nokogiri compiles this to "//a[...]" but # "descendant::a[...]" is quite a bit faster and achieves the same result. xpath = Nokogiri::CSS.xpath_for(query)[0].gsub(%r{^//}, 'descendant::') xpath = restrict_to_p_nodes_at_root(xpath) if filter_nodes_at_beginning?() nodes = document.xpath(xpath) filter_nodes(nodes, ) end |
.filter_nodes(nodes, reference_options) ⇒ Object
30 31 32 33 34 35 36 |
# File 'lib/banzai/querying.rb', line 30 def filter_nodes(nodes, ) if filter_nodes_at_beginning?() filter_nodes_at_beginning(nodes) else nodes end end |
.filter_nodes_at_beginning(nodes) ⇒ Object
Selects child nodes if they are present in the beginning among other siblings.
nodes - A Nokogiri::XML::NodeSet.
Returns an array of Nokogiri::XML::Element objects.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/banzai/querying.rb', line 47 def filter_nodes_at_beginning(nodes) parents_and_nodes = nodes.group_by(&:parent) filtered_nodes = [] parents_and_nodes.each do |parent, nodes| children = parent.children nodes = nodes.to_a children.each do |child| next if child.text.blank? node = nodes.shift break unless node == child filtered_nodes << node end end filtered_nodes end |
.filter_nodes_at_beginning?(reference_options) ⇒ Boolean
38 39 40 |
# File 'lib/banzai/querying.rb', line 38 def filter_nodes_at_beginning?() && [:location] == :beginning end |
.restrict_to_p_nodes_at_root(xpath) ⇒ Object
26 27 28 |
# File 'lib/banzai/querying.rb', line 26 def restrict_to_p_nodes_at_root(xpath) xpath.gsub('descendant::', './p/') end |