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