zafu 0.7.9 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -0
- data/lib/zafu/info.rb +1 -1
- data/lib/zafu/node_context.rb +27 -11
- data/lib/zafu/ordered_hash.rb +6 -0
- data/lib/zafu/parsing_rules.rb +19 -3
- data/lib/zafu/process/ajax.rb +29 -21
- data/lib/zafu/process/conditional.rb +24 -14
- data/lib/zafu/process/forms.rb +2 -0
- data/lib/zafu/process/html.rb +8 -1
- data/lib/zafu/process/ruby_less_processing.rb +2 -3
- data/test/mock/params.rb +5 -0
- data/test/zafu/basic.yml +16 -0
- data/zafu.gemspec +2 -2
- metadata +5 -5
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
data/lib/zafu/node_context.rb
CHANGED
@@ -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
|
-
|
83
|
+
code = $1
|
75
84
|
elsif dom =~ /#\{/
|
76
|
-
"
|
85
|
+
code = "%Q{#{dom}}"
|
77
86
|
else
|
78
|
-
dom
|
87
|
+
str = dom
|
88
|
+
code = dom.inspect
|
79
89
|
end
|
80
|
-
|
81
|
-
if
|
82
|
-
|
90
|
+
|
91
|
+
if options[:code]
|
92
|
+
code
|
83
93
|
else
|
84
|
-
|
85
|
-
end
|
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
|
|
data/lib/zafu/ordered_hash.rb
CHANGED
data/lib/zafu/parsing_rules.rb
CHANGED
@@ -93,9 +93,10 @@ module Zafu
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def extract_name
|
96
|
-
|
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 =~
|
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_]+\??)([^>]*?)(\/?)>/
|
data/lib/zafu/process/ajax.rb
CHANGED
@@ -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
|
-
|
29
|
-
|
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
|
-
#
|
178
|
-
# removed so
|
179
|
-
@params.delete(
|
180
|
-
@params.delete(
|
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
|
-
|
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
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/zafu/process/forms.rb
CHANGED
data/lib/zafu/process/html.rb
CHANGED
@@ -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..
|
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>
|
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
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'>function foo(a); print(a); end</code>\"/>"
|
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.
|
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-
|
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:
|
4
|
+
hash: 63
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
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-
|
18
|
+
date: 2011-06-15 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|