Use nested node stacks for predicates.

This ensures the current context node is set correctly when using the "self"
axis inside a path that's inside a predicate, e.g.

    foo/bar[baz/. = "something"]

Here the "self" axis should refer to foo/bar/baz, _not_ foo/bar.
This commit is contained in:
Yorick Peterse 2014-09-03 19:54:16 +02:00
parent 2b96d65103
commit e858b54c58
1 changed files with 35 additions and 8 deletions

View File

@ -66,7 +66,7 @@ module Oga
# #
def initialize(document, variables = {}) def initialize(document, variables = {})
@document = document @document = document
@nodes = [] @nodes = [[]]
@variables = variables @variables = variables
end end
@ -147,6 +147,7 @@ module Oga
def on_path(ast_node, context) def on_path(ast_node, context)
nodes = XML::NodeSet.new nodes = XML::NodeSet.new
with_node_stack do
ast_node.children.each do |test| ast_node.children.each do |test|
nodes = process(test, context) nodes = process(test, context)
@ -156,6 +157,7 @@ module Oga
context = nodes context = nodes
end end
end end
end
return nodes return nodes
end end
@ -1733,7 +1735,25 @@ module Oga
# @return [Mixed] # @return [Mixed]
# #
def with_node(node) def with_node(node)
@nodes << node node_stack << node
retval = yield
node_stack.pop
return retval
end
##
# Adds a new stack for storing context nodes and yields the supplied
# block.
#
# The return value of this method is whatever the supplied block returns.
#
# @return [Mixed]
#
def with_node_stack
@nodes << []
retval = yield retval = yield
@ -1748,6 +1768,13 @@ module Oga
# @return [Oga::XML::Node] # @return [Oga::XML::Node]
# #
def current_node def current_node
return node_stack.last
end
##
# @return [Array]
#
def node_stack
return @nodes.last return @nodes.last
end end
end # Evaluator end # Evaluator