From 39c0f7147c4523c6ab1aa149395fdb3a7ef2e764 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Sun, 26 Oct 2014 22:20:23 +0100 Subject: [PATCH] Support for parsing the :root pseudo class. --- lib/oga/css/parser.y | 48 ++++++++++++++++++---- spec/oga/css/parser/pseudo_classes_spec.rb | 8 +++- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/lib/oga/css/parser.y b/lib/oga/css/parser.y index bdfc1f1..c59e321 100644 --- a/lib/oga/css/parser.y +++ b/lib/oga/css/parser.y @@ -237,10 +237,10 @@ rule pseudo_class # :root - : pseudo_name { s(:pseudo, nil, val[0]) } + : pseudo_name { on_pseudo_class(val[0]) } # :nth-child(2) - | pseudo_name pseudo_args { s(:pseudo, nil, val[0], val[1]) } + | pseudo_name pseudo_args { on_pseudo_class(val[0], val[1]) } ; pseudo_name @@ -253,19 +253,34 @@ rule pseudo_arg : integer - #| odd - #| even - #| nth + | odd + | even + | nth | selector ; + nth + : T_NTH { s(:nth) } + | T_MINUS T_NTH { s(:nth) } + | integer T_NTH { s(:nth, val[0]) } + | integer T_NTH integer { s(:nth, val[0], val[2]) } + ; + + odd + : T_ODD { s(:nth, s(:int, 2), s(:int, 1)) } + ; + + even + : T_EVEN { s(:nth, s(:int, 2)) } + ; + string : T_STRING { s(:string, val[0]) } ; integer - : T_INT { s(:int, val[0].to_i) } - ; + : T_INT { s(:int, val[0].to_i) } + ; end ---- inner @@ -313,4 +328,23 @@ end return ast end + ## + # @param [String] name + # @param [AST::Node] arg + # @return [AST::Node] + # + def on_pseudo_class(name, arg = nil) + handler = "on_pseudo_class_#{name.gsub('-', '_')}" + + return arg ? send(handler, arg) : send(handler) + end + + ## + # Generates the AST for the `root` pseudo class. + # + # @return [AST::Node] + # + def on_pseudo_class_root + return s(:call, 'not', s(:axis, 'parent', s(:test, nil, '*'))) + end # vim: set ft=racc: diff --git a/spec/oga/css/parser/pseudo_classes_spec.rb b/spec/oga/css/parser/pseudo_classes_spec.rb index 81ab4e5..146a6de 100644 --- a/spec/oga/css/parser/pseudo_classes_spec.rb +++ b/spec/oga/css/parser/pseudo_classes_spec.rb @@ -3,11 +3,15 @@ require 'spec_helper' describe Oga::CSS::Parser do context 'pseudo classes' do example 'parse the x:root pseudo class' do - parse_css('x:root').should == s(:pseudo, s(:test, nil, 'x'), 'root') + parse_css('x:root').should == parse_xpath( + 'descendant-or-self::x[not(parent::*)]' + ) end example 'parse the :root pseudo class' do - parse_css(':root').should == s(:pseudo, nil, 'root') + parse_css(':root').should == parse_xpath( + 'descendant-or-self::*[not(parent::*)]' + ) end example 'parse the x:nth-child(1) pseudo class' do