lib/zafu/process/context.rb in zafu-0.6.0 vs lib/zafu/process/context.rb in zafu-0.6.1
- old
+ new
@@ -3,11 +3,11 @@
# This module manages the change of contexts by opening (each) or moving into the NodeContext.
# The '@context' holds many information on the current compilation environment. Inside this
# context, the "node" context holds information on the type of "this" (first responder).
module Context
def r_each
- if node.klass.kind_of?(Array)
+ if node.list_context?
if @params[:alt_class] || @params[:join]
out "<% #{var}_max_index = #{node}.size - 1 -%>" if @params[:alt_reverse]
out "<% #{node}.each_with_index do |#{var},#{var}_index| -%>"
if join = @params[:join]
@@ -29,14 +29,23 @@
end
else
out "<% #{node}.each do |#{var}| -%>"
end
+
with_context(:node => node.move_to(var, node.klass.first)) do
+ # The id set here should be used as prefix for sub-nodes to ensure uniqueness of generated DOM ids
+ node.propagate_dom_scope!
+
steal_and_eval_html_params_for(@markup, @params)
- @markup.set_id(node.dom_id) if need_dom_id?
- out @markup.wrap(expand_with)
+
+ if need_dom_id?
+ set_dom_prefix
+ @markup.set_id(node.dom_id)
+ end
+
+ out wrap(expand_with)
end
out "<% end -%>"
else
out expand_with
end
@@ -61,32 +70,41 @@
@context[:node].get(klass)
end
# Store some contextual value / variable inside a named group. This should be
# used to avoid key clashes between different types of elements to store.
- def set_context_var(group, key, obj)
- @context["#{group}::#{key}"] = obj
+ def set_context_var(group, key, obj, context = @context)
+ context["#{group}::#{key}"] = obj
end
# Retrieve a value from a given contextual group. The value must have been
# previously set with 'set_context_var' somewhere in the hierarchy.
- def get_context_var(group, key)
- @context["#{group}::#{key}"]
+ def get_context_var(group, key, context = @context)
+ context["#{group}::#{key}"]
end
+ # Return a new context without contextual variables.
+ def context_without_vars
+ context = @context.dup
+ context.keys.each do |k|
+ context.delete(k) if k.kind_of?(String)
+ end
+ context
+ end
+
# Expand blocks in a new context.
# This method is partly overwriten in Ajax
def expand_with_finder(finder)
if finder[:nil]
- open_node_context(finder) do
+ open_node_context(finder, :form => nil) do # do not propagate :form
expand_if("#{var} = #{finder[:method]}", node.move_to(var, finder[:class]))
end
else
res = ''
res << "<% #{var} = #{finder[:method]} -%>"
- open_node_context(finder, :node => node.move_to(var, finder[:class])) do
- res << @markup.wrap(expand_with)
+ open_node_context(finder, :node => node.move_to(var, finder[:class]), :form => nil) do
+ res << wrap(expand_with)
end
res
end
end
@@ -108,22 +126,39 @@
def node_context_vars(finder)
# do nothing (this is a hook for other modules like QueryBuilder and RubyLess)
{}
end
- # Declare a variable that can be used later in the compilation. This method
- # returns the variable name to use.
- def set_var(var_list, var_name)
- var_name = var_name.to_sym
- out parser_error("'#{var_name}' already defined.") if @context[var_name] || var_list[var_name]
- var_list[var_name] = "_z#{var_name}"
+ # Get a variable name and store the name in context variables for the given group.
+ #
+ # ==== Parameters
+ #
+ # * +group_name+ - name of the variable context group
+ # * +wanted_name+ - wanted variable name (used as key to get real var back later with #get_context_var)
+ # * +context+ - (optional) can be used if we do not want to store the variable definition in the current context
+ #
+ def get_var_name(group_name, wanted_name, context = @context)
+ secure_name = wanted_name.gsub(/[^a-zA-Z0-9]/,'')
+ name = "_z#{secure_name}"
+ i = 0
+ while get_context_var('var', name, context)
+ i += 1
+ name = "_z#{secure_name}#{i}"
+ end
+ set_context_var('var', name, true)
+ set_context_var(group_name, wanted_name, name)
+ name
end
# Change context for a given scope.
- def with_context(cont)
+ def with_context(cont, merge = true)
raise "Block missing" unless block_given?
cont_bak = @context.dup
- @context.merge!(cont)
+ if merge
+ @context.merge!(cont)
+ else
+ @context = cont
+ end
res = yield
@context = cont_bak
res
end