zafu 0.7.8 → 0.7.9

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ == 0.7.9 2011-05-26
2
+
3
+ * Enhancements
4
+ * Fixed bad ERB on 'klass' error.
5
+ * Should steal html params from [with] ("<r:with class='foo'>").
6
+ * Removed auto-transform of 'input', 'form' and other native tags.
7
+ * Added 'wrap_in_block' and 'add_block' helpers.
8
+ * Freezing RubyLess evaluated code (Ruby parser bug altering input string).
9
+
1
10
  == 0.7.8 2011-05-10
2
11
 
3
12
  * Enhancements
data/lib/zafu/info.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Zafu
2
- VERSION = '0.7.8'
2
+ VERSION = '0.7.9'
3
3
  end
4
4
 
data/lib/zafu/markup.rb CHANGED
@@ -7,7 +7,7 @@ module Zafu
7
7
  EMPTY_TAGS = %w{meta input link img}
8
8
  STEAL_PARAMS = {
9
9
  'link' => [:href, :charset, :rel, :type, :media, :rev, :target],
10
- 'a' => [:title, :onclick],
10
+ 'a' => [:title, :onclick, :target],
11
11
  'script' => [:type, :charset, :defer],
12
12
  :other => [:class, :id, :style],
13
13
  }
@@ -27,7 +27,10 @@ module Zafu
27
27
  @markup = Markup.new(@options.delete(:html_tag))
28
28
 
29
29
  # html_tag
30
- @markup.params = @options.delete(:html_tag_params)
30
+ if html_params = @options.delete(:html_tag_params)
31
+ # FIXME: make a better parser so that we do not have to worry with '>' at all.
32
+ @markup.params = html_params.gsub('&gt;', '>')
33
+ end
31
34
 
32
35
  # end_tag is used to know when to close parsing in sub-do
33
36
  # Example:
@@ -43,10 +46,6 @@ module Zafu
43
46
  # code indentation
44
47
  @markup.space_before = @options.delete(:space_before) # @space_before
45
48
 
46
- # form capture (input, select, textarea, form)
47
- # FIXME: what is this ???
48
- @options[:form] ||= true if @method == 'form'
49
-
50
49
  if @params =~ /\A([^>]*?)do\s*=('|")([^\2]*?[^\\])\2([^>]*)\Z/
51
50
  #puts $~.to_a.inspect
52
51
  # we have a sub 'do'
@@ -208,13 +207,6 @@ module Zafu
208
207
  opts.merge!(:method=> reg[4].gsub("\\#{reg[3]}", reg[3]), :html_tag=>reg[1], :html_tag_params=>reg[2], :params=>reg[5])
209
208
  opts.merge!(:text=>'') if reg[6] != ''
210
209
  make(:void, opts)
211
- elsif @options[:form] && @text =~ /\A<(input|select|textarea|form)([^>]*?)(\/?)>/
212
- eat $&
213
- method = $1 == 'form' ? 'form_tag' : $1 # <form> ==> r_form_tag, <r:form> ==> r_form
214
- opts.merge!(:method=>method, :params=>$2)
215
- opts.merge!(:text=>'') if $3 != ''
216
- opts.merge!(:end_tag=>'form') if method == 'form_tag'
217
- make(:void, opts)
218
210
  elsif @text =~ /\A<(\w+)(([^>]*?)\#\{([^>]*?))(\/?)>/
219
211
  # html tag with dynamic params
220
212
  #puts "OTHER_DYN:[#{$&}]"
@@ -316,5 +308,21 @@ module Zafu
316
308
  # Force descendants rebuild
317
309
  @all_descendants = nil
318
310
  end
311
+
312
+ # Helper during compilation to wrap current content in a new block
313
+ def wrap_in_block(text_or_opts)
314
+ # avoid wrapping objects in [void][/void]
315
+ bak = @blocks
316
+ @blocks = []
317
+ if text_or_opts.kind_of?(String)
318
+ wrapper = make(:void, :method => 'void', :text => text_or_opts)
319
+ else
320
+ wrapper = make(:void, text_or_opts)
321
+ end
322
+ wrapper.blocks = bak
323
+ @blocks = [wrapper]
324
+ # Force descendants rebuild
325
+ @all_descendants = nil
326
+ end
319
327
  end # ParsingRules
320
328
  end # Zafu
@@ -35,7 +35,7 @@ module Zafu
35
35
  # assign [] to var
36
36
  out "<% if (#{var} = #{finder[:method]}) || (#{node}.#{finder[:class].first <= Comment ? "can_comment?" : "can_write?"} && #{var}=[]) %>"
37
37
  # The list is not empty or we have enough rights to add new elements.
38
- set_dom_prefix
38
+ node.dom_prefix = dom_name
39
39
 
40
40
  # New node context.
41
41
  open_node_context(finder, :node => self.node.move_to(var, finder[:class])) do
@@ -58,9 +58,9 @@ module Zafu
58
58
 
59
59
  # Render 'else' clauses
60
60
  else_clauses = expand_with(
61
- :in_if => true,
62
- :only => ['elsif', 'else'],
63
- :markup => @markup
61
+ :in_if => true,
62
+ :only => ['elsif', 'else'],
63
+ :markup => @markup
64
64
  )
65
65
 
66
66
  # 2. Save 'each' template
@@ -124,7 +124,7 @@ module Zafu
124
124
  end
125
125
 
126
126
  # Since we are using ajax, we will need this object to have an ID set.
127
- set_dom_prefix
127
+ node.dom_prefix = dom_name
128
128
 
129
129
  @markup.done = false
130
130
 
@@ -224,7 +224,12 @@ module Zafu
224
224
  out wrap("#{expand_with(:onclick=>"[\"#{node.dom_prefix}_add\", \"#{node.dom_prefix}_form\"].each(Element.toggle);#{focus}return false;")}")
225
225
 
226
226
  if klass = @context[:klass]
227
- return parser_error("Invalid class '#{klass}'") unless klass = get_class(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
228
233
  else
229
234
  klass = Array(node.klass).first
230
235
  end
@@ -274,6 +279,7 @@ module Zafu
274
279
  def r_each
275
280
  if @context[:saved_template]
276
281
  # render to start a saved template
282
+ node.propagate_dom_scope!
277
283
  options = form_options
278
284
  @markup.set_id(options[:id]) if options[:id]
279
285
  @markup.set_param(:style, options[:style]) if options[:style]
@@ -308,14 +314,6 @@ module Zafu
308
314
  @context[:form] || descendant('unlink') || descendant('drop')
309
315
  end
310
316
 
311
- # Set a unique DOM prefix to build unique ids in the page.
312
- def set_dom_prefix(node = self.node)
313
- @name ||= unique_name
314
- # TODO: should rebuild descendants list in parents...
315
- #puts [parent.method, method, @context[:name], @name].inspect
316
- node.dom_prefix = @name
317
- end
318
-
319
317
  # Unique template_url, ending with dom_id
320
318
  def template_url(dom_prefix = node.dom_prefix)
321
319
  "#{root.options[:root]}/#{dom_prefix}"
@@ -325,9 +323,16 @@ module Zafu
325
323
  template_url(dom_prefix) + '_form'
326
324
  end
327
325
 
326
+ # Return object id (or name). Sets name when needed.
327
+ # Context is passed when the parent needs to set dom_name on a child
328
+ # before @context is passed down.
329
+ def dom_name(context = @context)
330
+ @name ||= unique_name(context)
331
+ end
332
+
328
333
  # Return a different name on each call
329
- def unique_name
330
- base = @name || @context[:name] || 'list'
334
+ def unique_name(context = @context)
335
+ base = @name || context[:name] || 'list'
331
336
  root.get_unique_name(base, base == @name).gsub(/[^\d\w\/]/,'_')
332
337
  end
333
338
 
@@ -379,10 +384,12 @@ module Zafu
379
384
 
380
385
  def store_block(block, cont = {})
381
386
  cont, prefix = context_for_partial(cont)
387
+ # Keep dom prefix
388
+ dom_prefix = node.dom_prefix
382
389
 
383
390
  # Create new node context
384
391
  node = cont[:node].as_main(ActiveRecord::Base)
385
- node.dom_prefix = @name
392
+ node.dom_prefix = dom_prefix
386
393
 
387
394
  cont[:template_url] = template_url(node.dom_prefix)
388
395
  cont[:node] = node
@@ -24,38 +24,26 @@ module Zafu
24
24
  end
25
25
 
26
26
  def r_form_tag(options = context[:form_options])
27
- if options.blank?
28
- # <form> not in <r:form>, just render all
29
- markup = Zafu::Markup.new('form')
30
- @params.each do |k, v|
31
- markup.set_param(k, v)
32
- end
33
- else
34
- # <form> inside <r:form>
35
- form_tag(options) do |opts|
36
- # Render error messages tag
37
- form_error_messages(opts[:form_helper])
38
-
39
- # Render form elements
40
- out expand_with(opts)
41
-
42
- # Render hidden fields (these must go after normal elements so that focusFirstElement works)
43
- hidden_fields = form_hidden_fields(options)
44
- out "<div class='hidden'>"
45
- hidden_fields.each do |k,v|
46
- if v.kind_of?(String)
47
- v = "'#{v}'" unless v.kind_of?(String) && ['"', "'"].include?(v[0..0])
48
- out "<input type='hidden' name='#{k}' value=#{v}/>"
49
- else
50
- # We use ['ffff'] to indicate that the content is already escaped and ready for ERB.
51
- out v.first
52
- end
27
+ form_tag(options) do |opts|
28
+ # Render error messages tag
29
+ form_error_messages(opts[:form_helper])
30
+
31
+ # Render form elements
32
+ out expand_with(opts)
33
+
34
+ # Render hidden fields (these must go after normal elements so that focusFirstElement works)
35
+ hidden_fields = form_hidden_fields(options)
36
+ out "<div class='hidden'>"
37
+ hidden_fields.each do |k,v|
38
+ if v.kind_of?(String)
39
+ v = "'#{v}'" unless v.kind_of?(String) && ['"', "'"].include?(v[0..0])
40
+ out "<input type='hidden' name='#{k}' value=#{v}/>"
41
+ else
42
+ # We use ['ffff'] to indicate that the content is already escaped and ready for ERB.
43
+ out v.first
53
44
  end
54
- out '</div>'
55
-
56
- # What is this ?
57
- #@blocks = opts[:blocks_bak] if opts[:blocks_bak]
58
45
  end
46
+ out '</div>'
59
47
  end
60
48
  end
61
49
 
@@ -11,6 +11,9 @@ module Zafu
11
11
  # [self = original_element]. Replace @markup with content of the new_obj (<ul do='with'>...)
12
12
  if new_obj.markup.tag
13
13
  @markup.tag = new_obj.markup.tag
14
+ else
15
+ # Steal 'class' param
16
+ @markup.steal_html_params_from(new_obj.params)
14
17
  end
15
18
 
16
19
  @markup.params.merge!(new_obj.markup.params)
@@ -60,16 +60,18 @@ module Zafu
60
60
  end
61
61
 
62
62
  # TEMPORARY METHOD DURING HACKING...
63
- def r_erb
64
- "<pre><%= @erb.gsub('<','&lt;').gsub('>','&gt;') %></pre>"
65
- end
63
+ # def r_erb
64
+ # "<pre><%= @erb.gsub('<','&lt;').gsub('>','&gt;') %></pre>"
65
+ # end
66
66
 
67
67
  def rubyless_render(method, params)
68
68
  # We need to set this here because we cannot pass options to RubyLess or get them back
69
69
  # when we evaluate the method to see if we can use blocks as arguments.
70
70
  @rendering_block_owner = true
71
71
  code = method_with_arguments(method, params)
72
- rubyless_expand RubyLess.translate(self, code)
72
+ # It is strange that we need to freeze code... But if we don't, we
73
+ # get double ##{} on some systems (Linux).
74
+ rubyless_expand RubyLess.translate(self, code.freeze)
73
75
  ensure
74
76
  @rendering_block_owner = false
75
77
  end
@@ -98,10 +100,18 @@ module Zafu
98
100
  elsif attribute = @params[:attr]
99
101
  code = "this.#{attribute}"
100
102
  elsif code = @params[:eval] || @params[:test]
103
+ elsif code = @params[:param]
104
+ code = "params[:#{code}]"
101
105
  elsif text = @params[:text]
102
106
  code = "%Q{#{text}}"
103
107
  elsif text = @params[:t]
104
108
  code = "t(%Q{#{text}})"
109
+ # elsif var = @params[:var]
110
+ # if code = get_context_var('set_var', var)
111
+ # return code
112
+ # else
113
+ # return parser_continue("Var #{var.inspect} not declared.")
114
+ # end
105
115
  elsif use_string_block && @blocks.size == 1 && @blocks.first.kind_of?(String)
106
116
  return RubyLess::TypedString.new(@blocks.first.inspect, :class => String, :literal => @blocks.first)
107
117
  else
@@ -262,6 +272,7 @@ module Zafu
262
272
  # Find a class or behavior based on a name. The returned class should implement
263
273
  # 'safe_method_type'.
264
274
  def get_class(class_name)
275
+ deb class_name
265
276
  Module.const_get(class_name)
266
277
  rescue
267
278
  nil
@@ -44,5 +44,21 @@ class ZafuRubyLessTest < Test::Unit::TestCase
44
44
  end
45
45
  end
46
46
  end
47
+
48
+ context 'With an invalid string' do
49
+ subject do
50
+ 'contact where id #{params[:foo]} in site'
51
+ end
52
+
53
+ should 'not alter string on error' do
54
+ str = subject.dup
55
+ begin
56
+ x = RubyLess.translate(self, str)
57
+ rescue RubyLess::Error => err
58
+ assert_equal subject, str
59
+ end
60
+ end
61
+ end # With an invalid string
62
+
47
63
 
48
64
  end
data/test/zafu/meta.yml CHANGED
@@ -13,6 +13,11 @@ include_with_part_change_class:
13
13
  src: "<r:include template='/some/template'><div class='foobar' do='with' part='b'>new b</div></r:include>"
14
14
  tem: "<div id='a'>a</div><div id='b' class='foobar'><%= make_link(@node) %></div>"
15
15
 
16
+ include_with_part_change_class_no_div:
17
+ # part 'a' is moved around
18
+ src: "<r:include template='/some/template'><r:with part='b' class='foo'>new b</div></r:include>"
19
+ tem: "<div id='a'>a</div><div id='b' class='foo'><%= make_link(@node) %></div>"
20
+
16
21
  include_missing_part:
17
22
  # part 'a' is moved around
18
23
  src: "<r:include template='/some/template' part='bad'/>"
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.8"
8
+ s.version = "0.7.9"
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-10}
12
+ s.date = %q{2011-05-26}
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: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 7
9
- - 8
10
- version: 0.7.8
9
+ - 9
10
+ version: 0.7.9
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-10 00:00:00 +02:00
18
+ date: 2011-05-26 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency