zafu 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,16 +6,54 @@ module Zafu
6
6
  module Context
7
7
  def r_each
8
8
  if node.klass.kind_of?(Array)
9
- out "<% #{node}.each do |#{var}| -%>"
10
- out render_html_tag(expand_with_node(var, node.klass.first))
9
+ if @params[:alt_class] || @params[:join]
10
+ out "<% #{var}_max_index = #{node}.size - 1 -%>" if @params[:alt_reverse]
11
+ out "<% #{node}.each_with_index do |#{var},#{var}_index| -%>"
12
+
13
+ if join = @params[:join]
14
+ join = RubyLess.translate_string(join, self)
15
+ #if join_clause = @params[:join_if]
16
+ # set_stored(Node, 'prev', "#{var}_prev")
17
+ # cond = get_test_condition(var, :test=>join_clause)
18
+ # out "<%= #{var}_prev = #{node}[#{var}_index - 1]; (#{var}_index > 0 && #{cond}) ? #{join.inspect} : '' %>"
19
+ #else
20
+ out "<%= #{var}_index > 0 ? #{join} : '' %>"
21
+ #end
22
+ end
23
+
24
+ if alt_class = @params[:alt_class]
25
+ alt_class = RubyLess.translate_string(alt_class, self)
26
+ alt_test = @params[:alt_reverse] == 'true' ? "(#{var}_max_index - #{var}_index) % 2 != 0" : "#{var}_index % 2 != 0"
27
+ @markup.append_dyn_param(:class, "<%= #{alt_test} ? #{alt_class} : '' %>")
28
+ @markup.tag ||= 'div'
29
+ end
30
+ else
31
+ out "<% #{node}.each do |#{var}| -%>"
32
+ end
33
+
34
+ with_context(:node => node.move_to(var, node.klass.first)) do
35
+ steal_and_eval_html_params_for(@markup, @params)
36
+ @markup.set_id(node.dom_id) if need_dom_id?
37
+ out @markup.wrap(expand_with)
38
+ end
11
39
  out "<% end -%>"
40
+ else
41
+ out expand_with
12
42
  end
43
+
44
+ # We need to return true for Ajax 'make_form'
45
+ true
13
46
  end
14
47
 
15
48
  def helper
16
49
  @context[:helper]
17
50
  end
18
51
 
52
+ # Return true if we need to insert the dom id for this element. This method is overwritten in Ajax.
53
+ def need_dom_id?
54
+ false
55
+ end
56
+
19
57
  # Return the node context for a given class (looks up into the hierarchy) or the
20
58
  # current node context if klass is nil.
21
59
  def node(klass = nil)
@@ -23,8 +61,33 @@ module Zafu
23
61
  @context[:node].get(klass)
24
62
  end
25
63
 
26
- def expand_with_node(name, klass)
27
- expand_with(:node => @context[:node].move_to(name, klass))
64
+ # Store some contextual value / variable inside a named group. This should be
65
+ # used to avoid key clashes between different types of elements to store.
66
+ def set_context_var(group, key, obj)
67
+ @context["#{group}::#{key}"] = obj
68
+ end
69
+
70
+ # Retrieve a value from a given contextual group. The value must have been
71
+ # previously set with 'set_context_var' somewhere in the hierarchy.
72
+ def get_context_var(group, key)
73
+ @context["#{group}::#{key}"]
74
+ end
75
+
76
+ # Expand blocks in a new context.
77
+ # This method is partly overwriten in Ajax
78
+ def expand_with_finder(finder)
79
+ if finder[:nil]
80
+ open_node_context(finder) do
81
+ expand_if("#{var} = #{finder[:method]}", node.move_to(var, finder[:class]))
82
+ end
83
+ else
84
+ res = ''
85
+ res << "<% #{var} = #{finder[:method]} -%>"
86
+ open_node_context(finder, :node => node.move_to(var, finder[:class])) do
87
+ res << @markup.wrap(expand_with)
88
+ end
89
+ res
90
+ end
28
91
  end
29
92
 
30
93
  # def context_with_node(name, klass)
@@ -40,6 +103,40 @@ module Zafu
40
103
  @var = "var1"
41
104
  end
42
105
  end
106
+
107
+ # This method is called when we enter a new node context
108
+ def node_context_vars(finder)
109
+ # do nothing (this is a hook for other modules like QueryBuilder and RubyLess)
110
+ {}
111
+ end
112
+
113
+ # Declare a variable that can be used later in the compilation. This method
114
+ # returns the variable name to use.
115
+ def set_var(var_list, var_name)
116
+ var_name = var_name.to_sym
117
+ out parser_error("'#{var_name}' already defined.") if @context[var_name] || var_list[var_name]
118
+ var_list[var_name] = "_z#{var_name}"
119
+ end
120
+
121
+ # Change context for a given scope.
122
+ def with_context(cont)
123
+ raise "Block missing" unless block_given?
124
+ cont_bak = @context.dup
125
+ @context.merge!(cont)
126
+ res = yield
127
+ @context = cont_bak
128
+ res
129
+ end
130
+
131
+ # This should be called when we enter a new node context so that the proper hooks are
132
+ # triggered (insertion of contextual variables).
133
+ def open_node_context(finder, cont = {})
134
+ sub_context = node_context_vars(finder).merge(cont)
135
+
136
+ with_context(sub_context) do
137
+ yield
138
+ end
139
+ end
43
140
  end # Context
44
141
  end # Process
45
142
  end # Zafu
@@ -0,0 +1,124 @@
1
+ module Zafu
2
+ module Process
3
+ module Forms
4
+ def self.included(base)
5
+ base.expander :make_form
6
+ end
7
+
8
+ def r_form
9
+ options = form_options
10
+
11
+ @markup.set_id(options[:id]) if options[:id]
12
+ @markup.set_param(:style, options[:style]) if options[:style]
13
+
14
+ if descendant('form_tag')
15
+ # We have a specific place to insert our form
16
+ out expand_with(:form_options => options)
17
+ else
18
+ r_form_tag(options)
19
+ end
20
+ end
21
+
22
+ def r_form_tag(options = context[:form_options])
23
+ if options.blank?
24
+ # <form> not in <r:form>, just render all
25
+ markup = Zafu::Markup.new('form')
26
+ @params.each do |k, v|
27
+ markup.set_param(k, v)
28
+ end
29
+ out markup.wrap(expand_with)
30
+ else
31
+ # <form> inside <r:form>
32
+ form_tag(options) do |opts|
33
+ # Render error messages tag
34
+ form_error_messages(opts[:form_helper])
35
+
36
+ # Render hidden fields
37
+ hidden_fields = form_hidden_fields(options)
38
+ out "<div class='hidden'>"
39
+ hidden_fields.each do |k,v|
40
+ if v.kind_of?(String)
41
+ v = "'#{v}'" unless v.kind_of?(String) && ['"', "'"].include?(v[0..0])
42
+ out "<input type='hidden' name='#{k}' value=#{v}/>"
43
+ else
44
+ # We use ['ffff'] to indicate that the content is already escaped and ready for ERB.
45
+ out v.first
46
+ end
47
+ end
48
+ out '</div>'
49
+
50
+ # Render form elements
51
+ out expand_with(opts)
52
+
53
+ # What is this ?
54
+ #@blocks = opts[:blocks_bak] if opts[:blocks_bak]
55
+ end
56
+ end
57
+ end
58
+
59
+ private
60
+ def make_form
61
+ return nil unless @context[:make_form]
62
+
63
+ if method == 'each'
64
+ r_form
65
+ else
66
+ nil
67
+ end
68
+ end
69
+
70
+ # Return id, style, form and cancel parts of the form.
71
+ def form_options
72
+ opts = {}
73
+ opts[:klass] = node.master_class(ActiveRecord::Base)
74
+ if @context[:in_add]
75
+ opts[:id] = "#{node.dom_prefix}_form"
76
+ opts[:style] = 'display:none;'
77
+ end
78
+
79
+ if @context[:template_url]
80
+ opts[:form_tag] = "<% remote_form_for(:#{node.form_name}, #{node}, :html => {:id => \"#{node.dom_prefix}_form_t\"}) do |f| %>"
81
+ opts[:form_helper] = 'f'
82
+ else
83
+ opts[:form_tag] = "<% form_for(:#{node.form_name}, #{node}, :html => {:id => \"#{node.dom_prefix}_form_t\"}) do |f| %>"
84
+ opts[:form_helper] = 'f'
85
+ end
86
+
87
+ opts
88
+ end
89
+
90
+ # Return hidden fields that need to be inserted in the form.
91
+ def form_hidden_fields(opts)
92
+ if t_url = @context[:template_url]
93
+ {'t_url' => t_url}
94
+ else
95
+ {}
96
+ end
97
+ end
98
+
99
+ # Render the 'form' tag and set expansion context.
100
+ def form_tag(options)
101
+ opts = options.dup
102
+
103
+ if descendant('cancel') || descendant('edit')
104
+ # Pass 'form_cancel' content to expand_with (already in options).
105
+ else
106
+ # Insert cancel before form
107
+ out opts.delete(:form_cancel).to_s
108
+ end
109
+
110
+ # form_for ... do |f|
111
+ out opts.delete(:form_tag)
112
+ # f.xxx
113
+ yield(opts.merge(:in_form => true))
114
+ # close form
115
+ out opts[:form_helper] ? "<% end -%>" : '</form>'
116
+ end
117
+
118
+ def form_error_messages(f)
119
+ out "<%= #{f}.error_messages %>"
120
+ end
121
+
122
+ end # Forms
123
+ end # Process
124
+ end # Zafu
@@ -1,30 +1,36 @@
1
1
  module Zafu
2
2
  module Process
3
3
  module HTML
4
- attr_accessor :html_tag, :html_tag_params, :name, :sub_do
4
+ def self.included(base)
5
+ base.wrap :wrap_html
6
+ end
5
7
 
6
8
  # Replace the 'original' element in the included template with our new version.
7
9
  def replace_with(new_obj)
8
10
  super
9
- html_tag_params = new_obj.html_tag_params
10
- [:class, :id].each do |sym|
11
- html_tag_params[sym] = new_obj.params[sym] if new_obj.params.include?(sym)
11
+ # [self = original_element]. Replace @markup with content of the new_obj (<ul do='with'>...)
12
+ if new_obj.markup.tag
13
+ @markup.tag = new_obj.markup.tag
12
14
  end
13
- @markup.tag = new_obj.html_tag || @markup.tag
14
- @markup.params.merge!(html_tag_params)
15
+
16
+ @markup.params.merge!(new_obj.markup.params)
17
+
18
+ # We do not have to merge dyn_params since these are compiled before processing (and we are in
19
+ # the pre-processor)
20
+
15
21
  if new_obj.params[:method]
16
- @method = new_obj.params[:method] if new_obj.params[:method]
22
+ @method = new_obj.params[:method]
17
23
  elsif new_obj.sub_do
18
24
  @method = 'void'
19
25
  end
20
26
  end
21
27
 
22
- # Pass the caller's 'html_tag' and 'html_tag_params' to the included part.
28
+ # Pass the caller's 'markup' to the included part.
23
29
  def include_part(obj)
24
- obj.html_tag = @markup.tag || obj.html_tag
25
- obj.html_tag_params = !@markup.params.empty? ? @markup.params : obj.html_tag_params
30
+ if @markup.tag
31
+ obj.markup = @markup.dup
32
+ end
26
33
  @markup.tag = nil
27
- @markup.params = {}
28
34
  super(obj)
29
35
  end
30
36
 
@@ -32,33 +38,29 @@ module Zafu
32
38
  super && @markup.params == {} && @markup.tag.nil?
33
39
  end
34
40
 
35
- def before_process
36
- return unless super
37
- @markup.done = false
41
+ def compile_html_params
42
+ return if @markup.done
38
43
  unless @markup.tag
39
44
  if @markup.tag = @params.delete(:tag)
40
- @markup.params = {}
41
- [:id, :class].each do |k|
42
- next unless @params[k]
43
- @markup.params[k] = @params.delete(k)
44
- end
45
+ @markup.steal_html_params_from(@params)
45
46
  end
46
47
  end
48
+
47
49
  # Translate dynamic params such as <tt>class='#{visitor.lang}'</tt> in the context
48
50
  # of the current parser
49
51
  @markup.compile_params(self)
50
-
51
- # [each] is run many times with different roles. Some of these change html_tag_params.
52
- @markup_bak = @markup.dup
53
- true
54
52
  end
55
53
 
56
- def after_process(text)
57
- res = @markup.wrap(super)
58
- @markup = @markup_bak
59
- res
54
+ def wrap_html(text)
55
+ compile_html_params
56
+ @markup.wrap(text)
60
57
  end
61
58
 
59
+ #def restore_markup
60
+ # # restore @markup
61
+ # @markup = @markup_bak
62
+ #end
63
+
62
64
  def inspect
63
65
  @markup.done = false
64
66
  res = super
@@ -66,7 +68,7 @@ module Zafu
66
68
  if res =~ /\A\[(\w+)(.*)\/\]\Z/m
67
69
  res = "[#{$1}#{$2}]<#{@markup.tag}/>[/#{$1}]"
68
70
  elsif res =~ /\A\[([^\]]+)\](.*)\[\/(\w+)\]\Z/m
69
- res = "[#{$1}]#{render_html_tag($2)}[/#{$3}]"
71
+ res = "[#{$1}]#{@markup.wrap($2)}[/#{$3}]"
70
72
  end
71
73
  end
72
74
  res
@@ -77,8 +79,6 @@ module Zafu
77
79
  ''
78
80
  end
79
81
 
80
- alias r_ r_ignore
81
-
82
82
  def r_rename_asset
83
83
  return expand_with unless @markup.tag
84
84
  case @markup.tag
@@ -105,64 +105,59 @@ module Zafu
105
105
  type = @markup.tag.to_sym
106
106
  end
107
107
 
108
- src = @params[key]
109
- if src && src[0..0] != '/' && src[0..6] != 'http://'
110
- @params[key] = helper.send(:template_url_for_asset, :src => src, :base_path => @options[:base_path], :type => type)
111
- end
112
-
113
- res = "<#{@markup.tag}#{params_to_html(@params)}"
114
- @markup.done = true
115
- inner = expand_with
116
- if inner == ''
117
- res + "/>"
118
- else
119
- res + ">#{inner}"
120
- end
121
- end
122
-
123
- def r_form
124
- res = "<#{@markup.tag}#{params_to_html(@params)}"
125
- @markup.done = true
126
- inner = expand_with
127
- if inner == ''
128
- res + "/>"
129
- else
130
- res + ">#{inner}"
108
+ src = @params.delete(key)
109
+ if src && src[0..6] != 'http://'
110
+ @markup.params[key] = helper.send(:template_url_for_asset, :src => src, :base_path => @options[:base_path], :type => type)
131
111
  end
132
- end
133
112
 
134
- def r_select
135
- res = "<#{@markup.tag}#{params_to_html(@params)}"
136
- @markup.done = true
137
- inner = expand_with
138
- if inner == ''
139
- res + "></#{@markup.tag}>"
140
- else
141
- res + ">#{inner}"
142
- end
143
- end
113
+ @markup.steal_html_params_from(@params)
144
114
 
145
- def r_input
146
- res = "<#{@markup.tag}#{params_to_html(@params)}"
147
- @markup.done = true
148
- inner = expand_with
149
- if inner == ''
150
- res + "/>"
151
- else
152
- res + ">#{inner}"
153
- end
115
+ expand_with
154
116
  end
155
117
 
156
- def r_textarea
157
- res = "<#{@markup.tag}#{params_to_html(@params)}"
158
- @markup.done = true
159
- inner = expand_with
160
- if inner == ''
161
- res + "/>"
162
- else
163
- res + ">#{inner}"
164
- end
165
- end
118
+ #def r_form
119
+ # res = "<#{@markup.tag}#{params_to_html(@params)}"
120
+ # @markup.done = true
121
+ # inner = expand_with
122
+ # if inner == ''
123
+ # res + "/>"
124
+ # else
125
+ # res + ">#{inner}"
126
+ # end
127
+ #end
128
+ #
129
+ #def r_select
130
+ # res = "<#{@markup.tag}#{params_to_html(@params)}"
131
+ # @markup.done = true
132
+ # inner = expand_with
133
+ # if inner == ''
134
+ # res + "></#{@markup.tag}>"
135
+ # else
136
+ # res + ">#{inner}"
137
+ # end
138
+ #end
139
+ #
140
+ #def r_input
141
+ # res = "<#{@markup.tag}#{params_to_html(@params)}"
142
+ # @markup.done = true
143
+ # inner = expand_with
144
+ # if inner == ''
145
+ # res + "/>"
146
+ # else
147
+ # res + ">#{inner}"
148
+ # end
149
+ #end
150
+ #
151
+ #def r_textarea
152
+ # res = "<#{@markup.tag}#{params_to_html(@params)}"
153
+ # @markup.done = true
154
+ # inner = expand_with
155
+ # if inner == ''
156
+ # res + "/>"
157
+ # else
158
+ # res + ">#{inner}"
159
+ # end
160
+ #end
166
161
  end # HTML
167
162
  end # Process
168
163
  end # Zafu