From a0cc23d99faa929a9ad4fe424aa4d4adcaa086e3 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 19 Jun 2024 14:02:34 -0400 Subject: [PATCH] css: handle relative selectors --- lib/nokogiri/css/selectors/xpath_visitor.rb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/nokogiri/css/selectors/xpath_visitor.rb b/lib/nokogiri/css/selectors/xpath_visitor.rb index e5f4ea471dc..9ba38f0046e 100644 --- a/lib/nokogiri/css/selectors/xpath_visitor.rb +++ b/lib/nokogiri/css/selectors/xpath_visitor.rb @@ -16,6 +16,11 @@ def xpath(ast) # else # visitor.prefix # end + prefix = if RelativeSelector === ast + "." + else + self.prefix + end prefix + accept(ast) end @@ -27,6 +32,10 @@ def visit_complex_selector(node) "#{accept(node.left)}#{accept(node.combinator)}#{accept(node.right)}" end + def visit_relative_selector(node) + "#{accept(node.combinator)}#{accept(node.complex_selector)}" + end + def visit_compound_selector(node) type_selector = node.type.nil? ? "*" : accept(node.type) @@ -142,8 +151,13 @@ def visit_pseudo_class_function(node) "position()>3" # TODO: OBVIOUSLY WRONG # when "only-child" # # TODO - # when "has" - # # TODO + when "has" + case node.arguments.first + when RelativeSelector + ".#{accept(node.arguments.first)}" + else + ".//#{accept(node.arguments.first)}" + end else # custom xpath function call # TODO ""