Basic support for the CSS :not pseudo class
This does _not_ support element states such as DISABLED, nor does it support the special handling of namespaces (e.g. *|*:not(*)). Instead this selector basically acts as a negation, some examples: :not(foo) # All but any "foo" nodes :not(#foo) # Skips nodes with id="foo" :not(.foo) # Skips nodes with a class "foo" Fixes #125
This commit is contained in:
parent
b7b38255d3
commit
aef7c510c2
|
@ -230,6 +230,8 @@ module Oga
|
||||||
pseudo_args := |*
|
pseudo_args := |*
|
||||||
whitespace;
|
whitespace;
|
||||||
|
|
||||||
|
hash | dot | colon;
|
||||||
|
|
||||||
# NOTE: the priorities here are put in place to ensure that rules such
|
# NOTE: the priorities here are put in place to ensure that rules such
|
||||||
# as `nth` take precedence over `identifier`. The highest number has
|
# as `nth` take precedence over `identifier`. The highest number has
|
||||||
# the highest priority.
|
# the highest priority.
|
||||||
|
|
|
@ -497,6 +497,24 @@ even
|
||||||
s(:call, 'not', s(:axis, 'child', s(:type_test, 'node')))
|
s(:call, 'not', s(:axis, 'child', s(:type_test, 'node')))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Generates the AST for the `:not` selector.
|
||||||
|
#
|
||||||
|
# @param [AST::Node] arg
|
||||||
|
# @return [AST::Node]
|
||||||
|
def on_pseudo_class_not(arg)
|
||||||
|
# Unpacks (axis "descendant" (test nil "x")) into just (test nil "x") as
|
||||||
|
# in this case we want to wrap the (test) node in a (axis "self") node.
|
||||||
|
if arg.type == :axis
|
||||||
|
arg = s(:axis, 'self', arg.children[1])
|
||||||
|
|
||||||
|
# Unpack (predicate (eq ...)) into just (eq)
|
||||||
|
elsif arg.type == :predicate
|
||||||
|
arg = arg.children[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
s(:call, 'not', arg)
|
||||||
|
end
|
||||||
|
|
||||||
# Generates the AST for the `=` operator.
|
# Generates the AST for the `=` operator.
|
||||||
#
|
#
|
||||||
# @param [AST::Node] attr
|
# @param [AST::Node] attr
|
||||||
|
|
|
@ -126,5 +126,16 @@ describe Oga::CSS::Lexer do
|
||||||
[:T_RPAREN, nil]
|
[:T_RPAREN, nil]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'lexes the :not(#foo) pseudo class' do
|
||||||
|
lex_css(':not(#foo)').should == [
|
||||||
|
[:T_COLON, nil],
|
||||||
|
[:T_IDENT, 'not'],
|
||||||
|
[:T_LPAREN, nil],
|
||||||
|
[:T_HASH, nil],
|
||||||
|
[:T_IDENT, 'foo'],
|
||||||
|
[:T_RPAREN, nil]
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Oga::CSS::Parser do
|
||||||
|
describe ':not pseudo class' do
|
||||||
|
it 'parses the :not(x) pseudo class' do
|
||||||
|
parse_css(':not(x)').should == parse_xpath('descendant::*[not(self::x)]')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'parses the x:not(y) pseudo class' do
|
||||||
|
parse_css('x:not(y)').should == parse_xpath('descendant::x[not(self::y)]')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'parses the x:not(#foo) pseudo class' do
|
||||||
|
parse_css('x:not(#foo)').should ==
|
||||||
|
parse_xpath('descendant::x[not(@id="foo")]')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue