lib/zafu/process/context.rb in zafu-0.5.0 vs lib/zafu/process/context.rb in zafu-0.6.0
- old
+ new
@@ -4,31 +4,94 @@
# 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)
- out "<% #{node}.each do |#{var}| -%>"
- out render_html_tag(expand_with_node(var, node.klass.first))
+ 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]
+ join = RubyLess.translate_string(join, self)
+ #if join_clause = @params[:join_if]
+ # set_stored(Node, 'prev', "#{var}_prev")
+ # cond = get_test_condition(var, :test=>join_clause)
+ # out "<%= #{var}_prev = #{node}[#{var}_index - 1]; (#{var}_index > 0 && #{cond}) ? #{join.inspect} : '' %>"
+ #else
+ out "<%= #{var}_index > 0 ? #{join} : '' %>"
+ #end
+ end
+
+ if alt_class = @params[:alt_class]
+ alt_class = RubyLess.translate_string(alt_class, self)
+ alt_test = @params[:alt_reverse] == 'true' ? "(#{var}_max_index - #{var}_index) % 2 != 0" : "#{var}_index % 2 != 0"
+ @markup.append_dyn_param(:class, "<%= #{alt_test} ? #{alt_class} : '' %>")
+ @markup.tag ||= 'div'
+ end
+ else
+ out "<% #{node}.each do |#{var}| -%>"
+ end
+
+ with_context(:node => node.move_to(var, node.klass.first)) do
+ steal_and_eval_html_params_for(@markup, @params)
+ @markup.set_id(node.dom_id) if need_dom_id?
+ out @markup.wrap(expand_with)
+ end
out "<% end -%>"
+ else
+ out expand_with
end
+
+ # We need to return true for Ajax 'make_form'
+ true
end
def helper
@context[:helper]
end
+ # Return true if we need to insert the dom id for this element. This method is overwritten in Ajax.
+ def need_dom_id?
+ false
+ end
+
# Return the node context for a given class (looks up into the hierarchy) or the
# current node context if klass is nil.
def node(klass = nil)
return @context[:node] if !klass
@context[:node].get(klass)
end
- def expand_with_node(name, klass)
- expand_with(:node => @context[:node].move_to(name, klass))
+ # 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
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}"]
+ 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
+ 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)
+ end
+ res
+ end
+ end
+
# def context_with_node(name, klass)
# context = @context.dup
# context[:node] = context[:node].move_to(name, klass)
# end
@@ -36,9 +99,43 @@
return @var if @var
if node.name =~ /^var(\d+)$/
@var = "var#{$1.to_i + 1}"
else
@var = "var1"
+ end
+ end
+
+ # This method is called when we enter a new node context
+ 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}"
+ end
+
+ # Change context for a given scope.
+ def with_context(cont)
+ raise "Block missing" unless block_given?
+ cont_bak = @context.dup
+ @context.merge!(cont)
+ res = yield
+ @context = cont_bak
+ res
+ end
+
+ # This should be called when we enter a new node context so that the proper hooks are
+ # triggered (insertion of contextual variables).
+ def open_node_context(finder, cont = {})
+ sub_context = node_context_vars(finder).merge(cont)
+
+ with_context(sub_context) do
+ yield
end
end
end # Context
end # Process
end # Zafu