zafu 0.7.9 → 0.8.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.
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.8.0 2011-06-15
2
+
3
+ * Enhancements
4
+ * Include with 'part' can now replace method.
5
+ * Fixed 'merge' for OrderedHash.
6
+ * Fixed dom_scope from block in each (was not using propagated dom scope).
7
+ * Added support for comments (started with '//!').
8
+
1
9
  == 0.7.9 2011-05-26
2
10
 
3
11
  * Enhancements
data/lib/zafu/info.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Zafu
2
- VERSION = '0.7.9'
2
+ VERSION = '0.8.0'
3
3
  end
4
4
 
@@ -13,6 +13,9 @@ module Zafu
13
13
  # it has a name or dom id defined ('main', 'related', 'list', etc).
14
14
  attr_writer :dom_prefix
15
15
 
16
+ # This is used to force a given dom_id (in saved templates for example).
17
+ attr_accessor :saved_dom_id
18
+
16
19
  # Any kind of information that the compiler might need to use (QueryBuilder query used
17
20
  # to fetch the node for example).
18
21
  attr_reader :opts
@@ -48,7 +51,9 @@ module Zafu
48
51
  # ivar name (see #master_class).
49
52
  def as_main(after_class = nil)
50
53
  klass = after_class ? master_class(after_class) : single_class
51
- self.class.new("@#{klass.to_s.underscore}", single_class)
54
+ res = self.class.new("@#{klass.to_s.underscore}", single_class, nil, :new_record => @opts[:new_record])
55
+ res.dom_prefix = self.dom_prefix
56
+ res
52
57
  end
53
58
 
54
59
  # Find the class just afer 'after_class' in the class hierarchy.
@@ -64,25 +69,36 @@ module Zafu
64
69
  end
65
70
 
66
71
  # Generate a unique DOM id for this element based on dom_scopes defined in parent contexts.
72
+ # :code option returns ruby
73
+ # :erb option returns either string content or "<%= ... %>"
74
+ # default returns something to insert in interpolated string such as '#{xxx}'
67
75
  def dom_id(opts = {})
68
76
  dom_prefix = opts[:dom_prefix] || self.dom_prefix
69
77
  options = {:list => true, :erb => true}.merge(opts)
70
78
 
71
- if options[:erb]
72
- dom = dom_id(options.merge(:erb => false))
79
+ if options[:erb] || options[:code]
80
+ dom = dom_id(options.merge(:erb => false, :code => false))
81
+
73
82
  if dom =~ /^#\{([^\{]+)\}$/
74
- "<%= #{$1} %>"
83
+ code = $1
75
84
  elsif dom =~ /#\{/
76
- "<%= %Q{#{dom}} %>"
85
+ code = "%Q{#{dom}}"
77
86
  else
78
- dom
87
+ str = dom
88
+ code = dom.inspect
79
89
  end
80
- else
81
- if @up
82
- [dom_prefix] + @up.dom_scopes + (options[:list] ? [make_scope_id] : [])
90
+
91
+ if options[:code]
92
+ code
83
93
  else
84
- [dom_prefix] + (options[:list] ? [make_scope_id] : [])
85
- end.compact.uniq.join('_')
94
+ str || "<%= #{code} %>"
95
+ end
96
+ else
97
+ @saved_dom_id || (
98
+ [dom_prefix] +
99
+ dom_scopes +
100
+ (options[:list] ? [make_scope_id] : [])
101
+ ).compact.uniq.join('_')
86
102
  end
87
103
  end
88
104
 
@@ -17,6 +17,12 @@ module Zafu
17
17
  super
18
18
  end
19
19
 
20
+ def merge(hash)
21
+ res = dup
22
+ res.merge!(hash)
23
+ res
24
+ end
25
+
20
26
  alias o_keys keys
21
27
  def get_keys
22
28
  @keys ||= o_keys
@@ -93,9 +93,10 @@ module Zafu
93
93
  end
94
94
 
95
95
  def extract_name
96
- super ||
96
+ @options[:name] ||
97
97
  (%w{input select textarea}.include?(@method) ? nil : @params[:name]) ||
98
- @markup.params[:id]
98
+ @markup.params[:id] ||
99
+ @params[:id]
99
100
  end
100
101
 
101
102
  def remove_erb(text)
@@ -125,7 +126,12 @@ module Zafu
125
126
  # scan rules
126
127
  def scan
127
128
  # puts "SCAN(#{@method}): [#{@text}]"
128
- if @text =~ /\A([^<]*?)(^ *|)</m
129
+ if @text =~ %r{\A([^<]*?)(\s*)//!}m
130
+ # comment
131
+ flush $1
132
+ eat $2
133
+ scan_comment
134
+ elsif @text =~ /\A([^<]*?)(^ *|)</m
129
135
  flush $1
130
136
  eat $2
131
137
  if @text[1..1] == '/'
@@ -191,6 +197,16 @@ module Zafu
191
197
  end
192
198
  end
193
199
 
200
+ def scan_comment
201
+ if @text =~ %r{\A//!.*(\n|\Z)}
202
+ # zafu html escaped
203
+ eat $&
204
+ else
205
+ # error
206
+ flush
207
+ end
208
+ end
209
+
194
210
  def scan_tag(opts={})
195
211
  #puts "TAG(#{@method}): [#{@text}]"
196
212
  if @text =~ /\A<r:([\w_]+\??)([^>]*?)(\/?)>/
@@ -8,6 +8,7 @@ module Zafu
8
8
 
9
9
  # This method process a list and handles building the necessary templates for ajax 'add'.
10
10
  def expand_with_finder(finder)
11
+ @context.delete(:make_form) # Do not propagate.
11
12
  return super unless finder[:class].kind_of?(Array)
12
13
 
13
14
  # reset scope
@@ -25,8 +26,14 @@ module Zafu
25
26
  (edit_block && edit_block.params[:publish])
26
27
 
27
28
  # class name for create form
28
- klass = (add_block && add_block.params[:klass]) ||
29
- (form_block && form_block.params[:klass])
29
+ if class_name = (add_block && add_block.params[:klass]) ||
30
+ (form_block && form_block.params[:klass])
31
+ unless klass = get_class(class_name)
32
+ return parser_error("Invalid class '#{class_name}'")
33
+ end
34
+ else
35
+ klass = finder[:class].first
36
+ end
30
37
 
31
38
  if need_ajax?(each_block)
32
39
  # We need to build the templates for ajax rendering.
@@ -35,6 +42,7 @@ module Zafu
35
42
  # assign [] to var
36
43
  out "<% if (#{var} = #{finder[:method]}) || (#{node}.#{finder[:class].first <= Comment ? "can_comment?" : "can_write?"} && #{var}=[]) %>"
37
44
  # The list is not empty or we have enough rights to add new elements.
45
+
38
46
  node.dom_prefix = dom_name
39
47
 
40
48
  # New node context.
@@ -71,7 +79,10 @@ module Zafu
71
79
  :saved_template => form_url(node.dom_prefix),
72
80
  :klass => klass,
73
81
  :make_form => each_block == form_block,
82
+ # Used to get parameters like 'publish', 'done', 'after'
83
+ :add => add_block,
74
84
  :publish_after_save => publish_after_save,
85
+ :node => node.move_to("@node", klass, :new_record => true)
75
86
  }
76
87
 
77
88
  store_block(form_block, cont)
@@ -174,10 +185,11 @@ module Zafu
174
185
  # TODO: show 'reply' instead of 'edit' in comments if visitor != author
175
186
  block = ancestor(%w{each block})
176
187
 
177
- # 'publish' is detected by r_block and set in form.
178
- # removed so it does not polute link
179
- @params.delete('publish')
180
- @params.delete('cancel')
188
+ # These parameters are detected by r_block and set in form.
189
+ # removed so they do not polute link
190
+ @params.delete(:publish)
191
+ @params.delete(:cancel)
192
+ @params.delete(:tcancel)
181
193
 
182
194
  link = wrap(make_link(:default_text => _('edit'), :update => block, :action => 'edit'))
183
195
 
@@ -223,16 +235,7 @@ module Zafu
223
235
  # Expand 'add' block
224
236
  out wrap("#{expand_with(:onclick=>"[\"#{node.dom_prefix}_add\", \"#{node.dom_prefix}_form\"].each(Element.toggle);#{focus}return false;")}")
225
237
 
226
- if klass = @context[:klass]
227
- unless klass = get_class(klass)
228
- out parser_error("Invalid class '#{@context[:klass]}'")
229
- # Clean close ERB
230
- out "<% end -%>"
231
- return
232
- end
233
- else
234
- klass = Array(node.klass).first
235
- end
238
+ klass = @context[:klass] || node.single_class
236
239
 
237
240
  # New object to render form.
238
241
  new_node = node.move_to("#{var}_new", klass, :new_record => true)
@@ -252,7 +255,10 @@ module Zafu
252
255
  out expand_block(form_block,
253
256
  # Needed in form to be able to return the result
254
257
  :template_url => template_url(node.dom_prefix),
255
- # ??
258
+ # Used to avoid wrong dom_id in hidden form. Should not be
259
+ # necessary but it's hard to fix when node changes a lot (drop in add).
260
+ :dom_prefix => node.dom_prefix,
261
+ # Used to add needed hidden fields in form
256
262
  :in_add => true,
257
263
  # Used to get parameters like 'publish' or 'klass'
258
264
  :add => self,
@@ -279,9 +285,11 @@ module Zafu
279
285
  def r_each
280
286
  if @context[:saved_template]
281
287
  # render to start a saved template
288
+ node.saved_dom_id = "\#{ndom_id(#{node})}"
282
289
  node.propagate_dom_scope!
290
+ @markup.set_id(node.dom_id)
291
+
283
292
  options = form_options
284
- @markup.set_id(options[:id]) if options[:id]
285
293
  @markup.set_param(:style, options[:style]) if options[:style]
286
294
 
287
295
  out wrap(expand_with)
@@ -384,12 +392,12 @@ module Zafu
384
392
 
385
393
  def store_block(block, cont = {})
386
394
  cont, prefix = context_for_partial(cont)
387
- # Keep dom prefix
388
- dom_prefix = node.dom_prefix
389
395
 
390
396
  # Create new node context
391
397
  node = cont[:node].as_main(ActiveRecord::Base)
392
- node.dom_prefix = dom_prefix
398
+
399
+ # The dom_id will be calculated from the Ajax params in the view.
400
+ node.saved_dom_id = "\#{ndom_id(#{node})}"
393
401
 
394
402
  cont[:template_url] = template_url(node.dom_prefix)
395
403
  cont[:node] = node
@@ -29,22 +29,28 @@ module Zafu
29
29
 
30
30
  # We use 'elsif' just in case there are more then one 'else' clause
31
31
  if markup = @context[:markup]
32
- # Copy markup tag
33
- @markup.tag ||= markup.tag
34
- @markup.steal_html_params_from(@params)
35
- markup.params.each do |k, v|
36
- next if @markup.params[k]
37
- @markup.set_param(k, v)
38
- end
32
+ if @markup.tag.blank?
33
+ # Copy markup tag
34
+ @markup.tag = markup.tag
35
+ @markup.steal_html_params_from(@params)
36
+ markup.params.each do |k, v|
37
+ next if @markup.params[k]
38
+ @markup.set_param(k, v)
39
+ end
39
40
 
40
- markup.dyn_params.each do |k, v|
41
- next if @markup.params[k] || @markup.dyn_params[k]
42
- @markup.set_dyn_param(k, v)
41
+ markup.dyn_params.each do |k, v|
42
+ next if @markup.params[k] || @markup.dyn_params[k]
43
+ @markup.set_dyn_param(k, v)
44
+ end
45
+ inner = wrap(res)
46
+ else
47
+ markup.done = false
48
+ # Wrap with both markup (ours and the else/elsif clause).
49
+ inner = markup.wrap(wrap(res))
43
50
  end
44
-
45
- out "<% elsif #{cond} %>#{wrap(res)}" # do not propagate
51
+ out "<% elsif #{cond} %>#{inner}" # do not propagate
46
52
  else
47
- @markup.done = true # never wrap else/elsif clause
53
+ #@markup.done = true # never wrap else/elsif clause
48
54
  out "<% elsif #{cond} %>#{res}" # do not propagate
49
55
  end
50
56
  end
@@ -72,7 +78,11 @@ module Zafu
72
78
  private
73
79
  def get_condition
74
80
  if in_tag = @params[:in]
75
- ancestor(in_tag) ? 'true' : 'false'
81
+ if in_tag == 'form' && @context[:make_form]
82
+ 'true'
83
+ else
84
+ ancestor(in_tag) ? 'true' : 'false'
85
+ end
76
86
  else
77
87
  get_attribute_or_eval(false)
78
88
  end
@@ -10,6 +10,8 @@ module Zafu
10
10
  return ''
11
11
  end
12
12
 
13
+ return parser_error('Cannot render update form in list context.') if node.list_context?
14
+
13
15
  options = form_options
14
16
 
15
17
  @markup.set_id(options[:id]) if options[:id]
@@ -34,6 +34,13 @@ module Zafu
34
34
  obj.markup = @markup.dup
35
35
  end
36
36
  @markup.tag = nil
37
+
38
+ if sub_do
39
+ obj.method = @blocks.first.method
40
+ obj.params = @blocks.first.params
41
+ elsif params[:method]
42
+ obj.method = params[:method]
43
+ end
37
44
  super(obj)
38
45
  end
39
46
 
@@ -111,7 +118,7 @@ module Zafu
111
118
  end
112
119
 
113
120
  src = @params.delete(key)
114
- if src && src[0..6] != 'http://'
121
+ if src && src[0..7] != 'http://'
115
122
  new_value = helper.send(:template_url_for_asset, :src => src, :base_path => @options[:base_path], :type => type)
116
123
  @markup.params[key] = new_value.blank? ? src : new_value
117
124
  end
@@ -33,7 +33,7 @@ module Zafu
33
33
 
34
34
  rubyless_render(@method, params)
35
35
  rescue RubyLess::NoMethodError => err
36
- parser_continue("#{err.error_message} <span class='type'>#{err.method_with_arguments}</span> for #{err.receiver_with_class}")
36
+ parser_continue("#{err.error_message} <span class='type'>#{err.method_with_arguments}</span> (#{node.klass} context)")
37
37
  rescue RubyLess::Error => err
38
38
  parser_continue(err.message)
39
39
  end
@@ -133,7 +133,7 @@ module Zafu
133
133
  end
134
134
 
135
135
  private
136
- # Extract arguments from params
136
+ # Extract arguments from params (evaluates params as RubyLess strings).
137
137
  def extract_from_params(*keys)
138
138
  res = []
139
139
 
@@ -272,7 +272,6 @@ module Zafu
272
272
  # Find a class or behavior based on a name. The returned class should implement
273
273
  # 'safe_method_type'.
274
274
  def get_class(class_name)
275
- deb class_name
276
275
  Module.const_get(class_name)
277
276
  rescue
278
277
  nil
data/test/mock/params.rb CHANGED
@@ -9,5 +9,10 @@ module Mock
9
9
  out_post str
10
10
  end
11
11
  end
12
+
13
+
14
+ def r_inspect
15
+ out "#{@params.inspect}"
16
+ end
12
17
  end
13
18
  end
data/test/zafu/basic.yml CHANGED
@@ -13,3 +13,19 @@ empty_do:
13
13
  do_with_escaped_quote:
14
14
  src: "<li do='raw(\'blah\')'>blah</li>"
15
15
  tem: "<li><%= raw(\"blah\") %></li>"
16
+
17
+ quotes_in_quotes:
18
+ src: "<r:inspect line_numbers='true' text=\"<code lang='lua'&gt;function foo(a); print(a); end</code&gt;\"/>"
19
+ tem: "/:text=>\"<code lang='lua'>function foo\(a\); print\(a\); end</code>\"/"
20
+
21
+ comment:
22
+ src: "<r:raw>hello</r:raw> //! This is a comment that will be removed"
23
+ tem: "<%= raw(\"hello\") %>"
24
+
25
+ line_comment:
26
+ src: "<r:raw>hello</r:raw>\n//! This is a comment that will be removed\nabc"
27
+ tem: "<%= raw(\"hello\") %>\nabc"
28
+
29
+ do_not_touch_js_comment:
30
+ src: "<r:raw>hello</r:raw> // This is a comment that will not be removed"
31
+ tem: "<%= raw(\"hello\") %> // This is a comment that will not be removed"
data/zafu.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{zafu}
8
- s.version = "0.7.9"
8
+ s.version = "0.8.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Gaspard Bucher"]
12
- s.date = %q{2011-05-26}
12
+ s.date = %q{2011-06-15}
13
13
  s.description = %q{Provides a powerful templating language based on xhtml for rails}
14
14
  s.email = %q{gaspard@teti.ch}
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zafu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 63
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 7
9
- - 9
10
- version: 0.7.9
8
+ - 8
9
+ - 0
10
+ version: 0.8.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gaspard Bucher
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-26 00:00:00 +02:00
18
+ date: 2011-06-15 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency