From 71960fff87da633dcab863002a461fbf7d4c5738 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Mon, 29 Jun 2015 20:51:38 +0200 Subject: [PATCH] Added CSS :nth() pseudo class This is a Nokogiri extension (as far as I'm aware) but it's useful enough to also include in Oga. Selectors such as "foo:nth(2)" are simply compiled to XPath "descendant::foo[position() = 2]". Fixes #123 --- lib/oga/css/parser.rll | 10 +++++++++ .../css/evaluator/pseudo_classes/nth_spec.rb | 21 +++++++++++++++++++ .../oga/css/parser/pseudo_classes/nth_spec.rb | 15 +++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 spec/oga/css/evaluator/pseudo_classes/nth_spec.rb create mode 100644 spec/oga/css/parser/pseudo_classes/nth_spec.rb diff --git a/lib/oga/css/parser.rll b/lib/oga/css/parser.rll index b85587d..cc0aae6 100644 --- a/lib/oga/css/parser.rll +++ b/lib/oga/css/parser.rll @@ -473,6 +473,16 @@ even generate_nth_child('following-sibling', arg, current_element) end + ## + # Generates the AST for the `nth` pseudo class. + # + # @param [AST::Node] arg + # @return [AST::Node] + # + def on_pseudo_class_nth(arg) + s(:eq, s(:call, 'position'), arg) + end + ## # Generates the AST for the `:first-child` selector. # diff --git a/spec/oga/css/evaluator/pseudo_classes/nth_spec.rb b/spec/oga/css/evaluator/pseudo_classes/nth_spec.rb new file mode 100644 index 0000000..407a3ea --- /dev/null +++ b/spec/oga/css/evaluator/pseudo_classes/nth_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe 'CSS selector evaluation' do + describe ':nth pseudo class' do + before do + @document = parse('') + + @root = @document.children[0] + @a1 = @root.children[0] + @a2 = @root.children[1] + end + + it 'returns a node set containing the first node' do + evaluate_css(@document, 'root a:nth(1)').should == node_set(@a1) + end + + it 'returns a node set containing the second node' do + evaluate_css(@document, 'root a:nth(2)').should == node_set(@a2) + end + end +end diff --git a/spec/oga/css/parser/pseudo_classes/nth_spec.rb b/spec/oga/css/parser/pseudo_classes/nth_spec.rb new file mode 100644 index 0000000..2e42020 --- /dev/null +++ b/spec/oga/css/parser/pseudo_classes/nth_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe Oga::CSS::Parser do + describe ':nth pseudo class' do + it 'parses the :nth(1) pseudo class' do + parse_css(':nth(1)') + .should == parse_xpath('descendant::*[position() = 1]') + end + + it 'parses the :nth(2) pseudo class' do + parse_css(':nth(2)') + .should == parse_xpath('descendant::*[position() = 2]') + end + end +end