Module: Zafu::Process::Context

Defined in:
lib/zafu/process/context.rb

Overview

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).

Instance Method Summary collapse

Instance Method Details

#context_without_varsObject

Return a new context without contextual variables.



125
126
127
128
129
130
131
# File 'lib/zafu/process/context.rb', line 125

def context_without_vars
  context = @context.dup
  context.keys.each do |k|
    context.delete(k) if k.kind_of?(String)
  end
  context
end

#expand_with_finder(finder) ⇒ Object

Expand blocks in a new context. This method is partly overwriten in Ajax



135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/zafu/process/context.rb', line 135

def expand_with_finder(finder)
  if finder[:nil]
    open_node_context(finder, :form => nil) do # do not propagate :form
      expand_if("#{var} = #{finder[:method]}", node.move_to(var, finder[:class], finder.merge(:nil => false)))
    end
  else
    res = ''
    res << "<% #{var} = #{finder[:method]} %>"
    open_node_context(finder, :node => node.move_to(var, finder[:class], finder), :form => nil) do
      res << wrap(expand_with)
    end
    res
  end
end

#get_context_var(group, key, context = @context) ⇒ Object

Retrieve a value from a given contextual group. The value must have been previously set with ‘set_context_var’ somewhere in the hierarchy.



120
121
122
# File 'lib/zafu/process/context.rb', line 120

def get_context_var(group, key, context = @context)
  context["#{group}::#{key}"]
end

#get_var_name(group_name, wanted_name, context = @context) ⇒ Object

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



178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/zafu/process/context.rb', line 178

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

#helperObject



96
97
98
# File 'lib/zafu/process/context.rb', line 96

def helper
  @context[:helper]
end

#need_dom_id?Boolean

Return true if we need to insert the dom id for this element. This method is overwritten in Ajax.

Returns:

  • (Boolean)


101
102
103
# File 'lib/zafu/process/context.rb', line 101

def need_dom_id?
  false
end

#node(klass = nil) ⇒ Object

Return the node context for a given class (looks up into the hierarchy) or the current node context if klass is nil.



107
108
109
110
# File 'lib/zafu/process/context.rb', line 107

def node(klass = nil)
  return @context[:node] if !klass
  @context[:node].get(klass)
end

#node_context_vars(finder) ⇒ Object

This method is called when we enter a new node context



165
166
167
168
# File 'lib/zafu/process/context.rb', line 165

def node_context_vars(finder)
  # do nothing (this is a hook for other modules like QueryBuilder and RubyLess)
  {}
end

#open_node_context(finder, cont = {}) ⇒ Object

This should be called when we enter a new node context so that the proper hooks are triggered (insertion of contextual variables).



207
208
209
210
211
212
213
# File 'lib/zafu/process/context.rb', line 207

def open_node_context(finder, cont = {})
  sub_context = node_context_vars(finder).merge(cont)

  with_context(sub_context) do
    yield
  end
end

#r_eachObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/zafu/process/context.rb', line 7

def r_each
  if node.list_context?
    
    if @params[:alt_class] || @params[:join] || @params[:sortable]
      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(self, join)
        out "<%= #{var}_index > 0 ? #{join} : '' %>"
      end

      if alt_class = @params[:alt_class]
        alt_class = RubyLess.translate_string(self, alt_class)
        alt_test = @params[:alt_reverse] == 'true' ? "(#{var}_max_index - #{var}_index) % 2 != 0" : "#{var}_index % 2 != 0"

        alt_var = get_var_name('set_var', 'alt_class')
        set_context_var('set_var', 'alt_class', RubyLess::TypedString.new(alt_var, :class => String))
        out "<% #{alt_var} = #{alt_test} ? #{alt_class} : '' %>"

        if @markup.tag
          @markup.append_dyn_param(:class, "<%= #{alt_var} %>")
        else
          # Just declare 'alt_class'
        end
      end
    else
      out "<% #{node}.each do |#{var}| %>"
    end

    raw_dom_prefix = node.raw_dom_prefix
    query = node.opts[:query]

    with_context(:node => node.move_to(var, node.klass.first, :query => node.opts[:query])) do
      # We pass the :query option for RubyLess resolution by using the QueryBuilder finder
      
      before_wrap = ''

      steal_and_eval_html_params_for(@markup, @params)
      if s = @params[:sortable]
        unless sort_attr = @params.delete(:sort_attr)
          if query
            sort_attr = query.select_keys.include?('l_status') ? 'l_status' : 'position'
          else
            sort_attr = 'position'
          end
        end
        @markup.set_param(:'data-a', sort_attr)
        @markup.set_dyn_param(:'data-p', "<%= #{node}.#{RubyLess.translate(node.klass, sort_attr)} %>")
        s = 'drag_handle' if s == 'true'
        unless s == 'all' || @blocks.detect{|b| b.kind_of?(String) ? b =~ /class=.#{s}/ : (b.params[:class] == s || (b.markup && b.markup.params[:class] == s))}
          before_wrap << "<span class='#{s}'>&nbsp;</span>"
        end
      end
      
      # The id set here should be used as prefix for sub-nodes to ensure uniqueness of generated DOM ids
      if node.list_context?
        # we are still in a list (example: previous context was [[Node]], current is [Node])
      else
        # Change dom_prefix if it isn't our own (inherited).
        node.dom_prefix = dom_name unless raw_dom_prefix
        node.propagate_dom_scope!

        if need_dom_id? || @params[:sortable]
          @markup.set_id(node.dom_id)
        end
      end
      
      if s = @params[:sortable]
        if s == 'all'
          # drag full element
          before_wrap << %Q{<% if #{var}_index == 0; js_data << "Zena.sortable('#{node.dom_id(:erb => false)}')" end %>}
        else
          # drag element with given class
          s = 'drag_handle' if s == 'true'
          before_wrap << %Q{<% if #{var}_index == 0; js_data << "Zena.sortable('#{node.dom_id(:erb => false)}', {handle:'#{s}'})" end %>}
        end
      end
      out wrap(before_wrap + expand_with)
    end
    out "<% end %>"
  else
    out expand_with
  end

  # We need to return true for Ajax 'make_form'
  true
end

#set_context_var(group, key, obj, context = @context) ⇒ Object

Store some contextual value / variable inside a named group. This should be used to avoid key clashes between different types of elements to store.



114
115
116
# File 'lib/zafu/process/context.rb', line 114

def set_context_var(group, key, obj, context = @context)
  context["#{group}::#{key}"] = obj
end

#varObject

def context_with_node(name, klass)

context = @context.dup
context[:node] = context[:node].move_to(name, klass)

end



155
156
157
158
159
160
161
162
# File 'lib/zafu/process/context.rb', line 155

def var
  return @var if @var
  if node.name =~ /^var(\d+)$/
    @var = "var#{$1.to_i + 1}"
  else
    @var = "var1"
  end
end

#with_context(cont, merge = true) ⇒ Object

Change context for a given scope.



192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/zafu/process/context.rb', line 192

def with_context(cont, merge = true)
  raise "Block missing" unless block_given?
  cont_bak = @context
    if merge
      @context = @context.merge(cont)
    else
      @context = cont
    end
    res = yield
  @context = cont_bak
  res
end