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 := |*
|
||||
whitespace;
|
||||
|
||||
hash | dot | colon;
|
||||
|
||||
# NOTE: the priorities here are put in place to ensure that rules such
|
||||
# as `nth` take precedence over `identifier`. The highest number has
|
||||
# the highest priority.
|
||||
|
|
|
@ -497,6 +497,24 @@ even
|
|||
s(:call, 'not', s(:axis, 'child', s(:type_test, 'node')))
|
||||
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.
|
||||
#
|
||||
# @param [AST::Node] attr
|
||||
|
|
|
@ -126,5 +126,16 @@ describe Oga::CSS::Lexer do
|
|||
[:T_RPAREN, nil]
|
||||
]
|
||||
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
|
||||
|
|
|
@ -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