zena 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +38 -1
- data/app/controllers/documents_controller.rb +7 -5
- data/app/controllers/nodes_controller.rb +47 -6
- data/app/controllers/user_sessions_controller.rb +12 -3
- data/app/controllers/virtual_classes_controller.rb +8 -2
- data/app/models/acl.rb +5 -2
- data/app/models/cached_page.rb +5 -5
- data/app/models/column.rb +27 -4
- data/app/models/group.rb +1 -1
- data/app/models/node.rb +106 -24
- data/app/models/note.rb +2 -1
- data/app/models/relation.rb +9 -4
- data/app/models/relation_proxy.rb +2 -2
- data/app/models/role.rb +12 -5
- data/app/models/site.rb +10 -9
- data/app/models/skin.rb +8 -0
- data/app/models/string_hash.rb +65 -0
- data/app/models/text_document.rb +1 -1
- data/app/models/user.rb +2 -0
- data/app/models/virtual_class.rb +43 -10
- data/app/views/comments/create.rjs +1 -32
- data/app/views/comments/edit.rjs +1 -1
- data/app/views/comments/update.rjs +1 -1
- data/app/views/documents/show.rhtml +1 -1
- data/app/views/groups/_form.rhtml +7 -0
- data/app/views/groups/_li.rhtml +1 -1
- data/app/views/nodes/500.html +2 -1
- data/app/views/nodes/destroy.rjs +2 -0
- data/app/views/sites/jobs.erb +2 -3
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_import.rhtml +4 -1
- data/app/views/templates/document_create_tabs/_template.rhtml +3 -0
- data/app/views/templates/document_create_tabs/_text_document.rhtml +3 -0
- data/app/views/versions/custom_tab.rhtml +1 -1
- data/app/views/versions/edit.rhtml +1 -1
- data/bricks/acls/lib/bricks/acls.rb +3 -3
- data/bricks/acls/zena/test/unit/acl_test.rb +15 -0
- data/bricks/fs_skin/lib/bricks/fs_skin.rb +190 -0
- data/bricks/fs_skin/zena/init.rb +1 -0
- data/bricks/fs_skin/zena/migrate/20110702010330_add_fs_skin_to_idx_templates.rb +12 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Image-edit.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Image.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Node-+index.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Node-+notFound.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Node-+search.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Node.zafu +1 -1
- data/bricks/{static → fs_skin}/zena/skins/blog/Post.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Project--kml.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Project.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/comments.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/dict.yml +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/dateBg.jpg +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/header.png +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/mapPin.png +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/menu.gif +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/menuover.gif +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/style.css +0 -0
- data/bricks/fs_skin/zena/tasks.rb +26 -0
- data/bricks/{static/zena/test/integration/static_integration_test.rb → fs_skin/zena/test/integration/fs_skin_integration_test.rb} +6 -6
- data/bricks/fs_skin/zena/test/unit/fs_skin_test.rb +33 -0
- data/bricks/grid/lib/bricks/grid.rb +4 -3
- data/bricks/tags/lib/bricks/tags.rb +1 -7
- data/bricks/zena/zena/migrate/20120605091558_add_ssl_login_to_site.rb +7 -0
- data/bricks/zena/zena/migrate/20120630123551_add_auto_publish_to_group.rb +9 -0
- data/config/bricks.yml +3 -3
- data/config/gems.yml +2 -3
- data/lib/tasks/zena.rake +7 -3
- data/lib/zafu.rb +7 -0
- data/lib/zafu/all.rb +21 -0
- data/lib/zafu/compiler.rb +7 -0
- data/lib/zafu/controller_methods.rb +58 -0
- data/lib/zafu/handler.rb +57 -0
- data/lib/zafu/info.rb +4 -0
- data/lib/zafu/markup.rb +309 -0
- data/lib/zafu/mock_helper.rb +42 -0
- data/lib/zafu/node_context.rb +203 -0
- data/lib/zafu/ordered_hash.rb +53 -0
- data/lib/zafu/parser.rb +676 -0
- data/lib/zafu/parsing_rules.rb +382 -0
- data/lib/zafu/process/ajax.rb +530 -0
- data/lib/zafu/process/conditional.rb +92 -0
- data/lib/zafu/process/context.rb +186 -0
- data/lib/zafu/process/forms.rb +143 -0
- data/lib/zafu/process/html.rb +186 -0
- data/lib/zafu/process/ruby_less_processing.rb +321 -0
- data/lib/zafu/security.rb +15 -0
- data/lib/zafu/template.rb +25 -0
- data/lib/zafu/test_helper.rb +19 -0
- data/lib/zafu/view_methods.rb +6 -0
- data/lib/zena.rb +1 -1
- data/lib/zena/acts/enrollable.rb +1 -1
- data/lib/zena/app.rb +4 -17
- data/lib/zena/console.rb +18 -1
- data/lib/zena/core_ext/file_utils.rb +13 -1
- data/lib/zena/core_ext/fixnum.rb +4 -0
- data/lib/zena/core_ext/float.rb +7 -0
- data/lib/zena/deploy.rb +4 -2
- data/lib/zena/deploy/app_init.rhtml +2 -1
- data/lib/zena/deploy/database.rhtml +1 -1
- data/lib/zena/info.rb +1 -1
- data/lib/zena/parser/zazen_rules.rb +4 -4
- data/lib/zena/routes.rb +1 -1
- data/lib/zena/test_controller.rb +1 -1
- data/lib/zena/use.rb +14 -1
- data/lib/zena/use/action.rb +4 -2
- data/lib/zena/use/ajax.rb +86 -38
- data/lib/zena/use/authlogic.rb +16 -1
- data/lib/zena/use/calendar.rb +37 -17
- data/lib/zena/use/conditional.rb +2 -2
- data/lib/zena/use/context.rb +30 -9
- data/lib/zena/use/dates.rb +39 -3
- data/lib/zena/use/display.rb +6 -19
- data/lib/zena/use/forms.rb +100 -79
- data/lib/zena/use/i18n.rb +40 -16
- data/lib/zena/use/query_builder.rb +0 -6
- data/lib/zena/use/query_node.rb +17 -4
- data/lib/zena/use/relations.rb +1 -3
- data/lib/zena/use/rendering.rb +10 -8
- data/lib/zena/use/scope_index.rb +5 -1
- data/lib/zena/use/search.rb +2 -1
- data/lib/zena/use/urls.rb +82 -77
- data/lib/zena/use/workflow.rb +12 -4
- data/lib/zena/use/zafu_safe_definitions.rb +37 -9
- data/lib/zena/use/zafu_templates.rb +49 -20
- data/lib/zena/use/zazen.rb +6 -2
- data/locale/it/LC_MESSAGES/zena.mo +0 -0
- data/locale/it/zena.mo +0 -0
- data/locale/it/zena.po +1982 -0
- data/public/images/arrow_back.png +0 -0
- data/public/images/remove_tag.png +0 -0
- data/public/javascripts/grid.js +800 -199
- data/public/javascripts/window.js +1 -1
- data/public/javascripts/zena.js +130 -21
- data/public/stylesheets/grid.css +11 -2
- data/public/stylesheets/zena.css +2 -1
- data/test/custom_queries/complex.host.yml +5 -0
- data/test/fixtures/files/TestNode.zafu +36 -0
- data/test/functional/nodes_controller_test.rb +18 -1
- data/test/integration/zafu_compiler/action.yml +2 -2
- data/test/integration/zafu_compiler/ajax.yml +44 -26
- data/test/integration/zafu_compiler/asset.yml +12 -2
- data/test/integration/zafu_compiler/basic.yml +0 -16
- data/test/integration/zafu_compiler/calendar.yml +6 -6
- data/test/integration/zafu_compiler/complex_ok.yml +23 -1
- data/test/integration/zafu_compiler/conditional.yml +5 -5
- data/test/integration/zafu_compiler/context.yml +6 -5
- data/test/integration/zafu_compiler/dates.yml +23 -2
- data/test/integration/zafu_compiler/display.yml +46 -2
- data/test/integration/zafu_compiler/errors.yml +2 -2
- data/test/integration/zafu_compiler/eval.yml +35 -7
- data/test/integration/zafu_compiler/forms.yml +47 -13
- data/test/integration/zafu_compiler/i18n.yml +2 -2
- data/test/integration/zafu_compiler/meta.yml +35 -1
- data/test/integration/zafu_compiler/query.yml +23 -4
- data/test/integration/zafu_compiler/relations.yml +10 -6
- data/test/integration/zafu_compiler/roles.yml +4 -4
- data/test/integration/zafu_compiler/rubyless.yml +11 -1
- data/test/integration/zafu_compiler/safe_definitions.yml +23 -5
- data/test/integration/zafu_compiler/security.yml +10 -6
- data/test/integration/zafu_compiler/urls.yml +23 -6
- data/test/integration/zafu_compiler/zafu_attributes.yml +1 -1
- data/test/integration/zafu_compiler/zazen.yml +14 -0
- data/test/selenium/Add/add3.rsel +8 -8
- data/test/selenium/Destroy/0setup.rsel +12 -0
- data/test/selenium/Destroy/destroy1.rsel +16 -0
- data/test/selenium/Edit/edit2.rsel +9 -9
- data/test/selenium/Edit/edit5.rsel +9 -9
- data/test/selenium/Edit/edit6.rsel +9 -9
- data/test/selenium/Form/form4.rsel +17 -0
- data/test/selenium/Toggle/toggle1.rsel +2 -0
- data/test/selenium/Toggle/toggle2.rsel +18 -0
- data/test/sites/zena/columns.yml +3 -0
- data/test/sites/zena/versions.yml +7 -0
- data/test/unit/cached_page_test.rb +13 -13
- data/test/unit/column_test.rb +26 -0
- data/test/unit/node_test.rb +16 -1
- data/test/unit/project_test.rb +6 -1
- data/test/unit/relation_test.rb +1 -1
- data/test/unit/role_test.rb +1 -1
- data/test/unit/string_hash_test.rb +30 -0
- data/test/unit/virtual_class_test.rb +31 -17
- data/test/unit/zafu_markup_test.rb +414 -0
- data/test/unit/zafu_node_context_test.rb +375 -0
- data/test/unit/zafu_ordered_hash_test.rb +69 -0
- data/test/unit/zena/acts/enrollable_test.rb +1 -1
- data/test/unit/zena/parser/zafu_asset.yml +0 -10
- data/test/unit/zena/parser/zazen.yml +1 -1
- data/test/unit/zena/parser_test.rb +1 -72
- data/test/unit/zena/use/dates_test.rb +1 -1
- data/test/unit/zena/use/rendering_test.rb +24 -7
- data/test/unit/zena/use/scope_index_test.rb +17 -0
- data/test/unit/zena/use/zazen_test.rb +2 -1
- data/zena.gemspec +71 -37
- metadata +104 -83
- data/app/views/nodes/destroy.erb +0 -0
- data/bricks/static/lib/bricks/static.rb +0 -151
- data/bricks/static/zena/init.rb +0 -1
- data/bricks/static/zena/migrate/20110702010330_add_static_to_idx_templates.rb +0 -12
- data/bricks/static/zena/test/unit/static_test.rb +0 -33
- data/lib/zena/parser/zafu_rules.rb +0 -244
- data/lib/zena/parser/zafu_tags.rb +0 -198
- data/lib/zena/parser/zena_rules.rb +0 -23
@@ -0,0 +1,92 @@
|
|
1
|
+
module Zafu
|
2
|
+
module Process
|
3
|
+
# This module manages conditional rendering (if, else, elsif, case, when).
|
4
|
+
module Conditional
|
5
|
+
def r_if(cond = nil)
|
6
|
+
cond ||= get_condition
|
7
|
+
return unless cond
|
8
|
+
expand_if(cond)
|
9
|
+
end
|
10
|
+
|
11
|
+
def r_case
|
12
|
+
r_if('false')
|
13
|
+
end
|
14
|
+
|
15
|
+
def r_else
|
16
|
+
r_elsif('true')
|
17
|
+
end
|
18
|
+
|
19
|
+
def r_when
|
20
|
+
r_elsif
|
21
|
+
end
|
22
|
+
|
23
|
+
def r_elsif(cond = nil)
|
24
|
+
return '' unless @context[:in_if]
|
25
|
+
cond ||= get_condition
|
26
|
+
return unless cond
|
27
|
+
|
28
|
+
res = expand_with(:in_if => false, :markup => nil)
|
29
|
+
|
30
|
+
# We use 'elsif' just in case there are more then one 'else' clause
|
31
|
+
if markup = @context[:markup]
|
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
|
40
|
+
|
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))
|
50
|
+
end
|
51
|
+
out "<% elsif #{cond} %>#{inner}" # do not propagate
|
52
|
+
else
|
53
|
+
#@markup.done = true # never wrap else/elsif clause
|
54
|
+
out "<% elsif #{cond} %>#{res}" # do not propagate
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Expand blocks with conditional processing enabled (else, elsif, etc).
|
59
|
+
#
|
60
|
+
# ==== Parameters
|
61
|
+
#
|
62
|
+
# * +condition+ - ruby condition for the conditional execution.
|
63
|
+
# * +new_node_context+ - (optional) new node context to enter if the clause succeeds.
|
64
|
+
# * +alt_markup+ - (optional) alternative markup to use for the 'else', 'elsif' clauses.
|
65
|
+
def expand_if(condition, new_node_context = self.node, alt_markup = @markup)
|
66
|
+
res = ""
|
67
|
+
res << "<% if #{condition} %>"
|
68
|
+
with_context(:node => new_node_context) do
|
69
|
+
res << wrap(expand_with)
|
70
|
+
end
|
71
|
+
|
72
|
+
only = method == 'case' ? %r{^[A-Z]|else|elsif|when} : %w{else elsif when}
|
73
|
+
res << expand_with(:in_if => true, :only => only, :markup => alt_markup)
|
74
|
+
res << "<% end %>"
|
75
|
+
res
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def get_condition
|
80
|
+
if in_tag = @params[:in]
|
81
|
+
if in_tag == 'form' && @context[:make_form]
|
82
|
+
'true'
|
83
|
+
else
|
84
|
+
ancestor(in_tag) ? 'true' : 'false'
|
85
|
+
end
|
86
|
+
else
|
87
|
+
get_attribute_or_eval(false)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end # Context
|
91
|
+
end # Process
|
92
|
+
end # Zafu
|
@@ -0,0 +1,186 @@
|
|
1
|
+
module Zafu
|
2
|
+
module Process
|
3
|
+
# This module manages the change of contexts by opening (each) or moving into the NodeContext.
|
4
|
+
# The '@context' holds many information on the current compilation environment. Inside this
|
5
|
+
# context, the "node" context holds information on the type of "this" (first responder).
|
6
|
+
module Context
|
7
|
+
def r_each
|
8
|
+
if node.list_context?
|
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(self, join)
|
15
|
+
out "<%= #{var}_index > 0 ? #{join} : '' %>"
|
16
|
+
end
|
17
|
+
|
18
|
+
if alt_class = @params[:alt_class]
|
19
|
+
alt_class = RubyLess.translate_string(self, alt_class)
|
20
|
+
alt_test = @params[:alt_reverse] == 'true' ? "(#{var}_max_index - #{var}_index) % 2 != 0" : "#{var}_index % 2 != 0"
|
21
|
+
|
22
|
+
alt_var = get_var_name('set_var', 'alt_class')
|
23
|
+
set_context_var('set_var', 'alt_class', RubyLess::TypedString.new(alt_var, :class => String))
|
24
|
+
out "<% #{alt_var} = #{alt_test} ? #{alt_class} : '' %>"
|
25
|
+
|
26
|
+
if @markup.tag
|
27
|
+
@markup.append_dyn_param(:class, "<%= #{alt_var} %>")
|
28
|
+
else
|
29
|
+
# Just declare 'alt_class'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
else
|
33
|
+
out "<% #{node}.each do |#{var}| %>"
|
34
|
+
end
|
35
|
+
|
36
|
+
raw_dom_prefix = node.raw_dom_prefix
|
37
|
+
|
38
|
+
with_context(:node => node.move_to(var, node.klass.first, :query => node.opts[:query])) do
|
39
|
+
# We pass the :query option for RubyLess resolution by using the QueryBuilder finder
|
40
|
+
|
41
|
+
steal_and_eval_html_params_for(@markup, @params)
|
42
|
+
# The id set here should be used as prefix for sub-nodes to ensure uniqueness of generated DOM ids
|
43
|
+
if node.list_context?
|
44
|
+
# we are still in a list (example: previous context was [[Node]], current is [Node])
|
45
|
+
else
|
46
|
+
# Change dom_prefix if it isn't our own (inherited).
|
47
|
+
node.dom_prefix = dom_name unless raw_dom_prefix
|
48
|
+
node.propagate_dom_scope!
|
49
|
+
|
50
|
+
if need_dom_id?
|
51
|
+
@markup.set_id(node.dom_id)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
out wrap(expand_with)
|
56
|
+
end
|
57
|
+
out "<% end %>"
|
58
|
+
else
|
59
|
+
out expand_with
|
60
|
+
end
|
61
|
+
|
62
|
+
# We need to return true for Ajax 'make_form'
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
def helper
|
67
|
+
@context[:helper]
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return true if we need to insert the dom id for this element. This method is overwritten in Ajax.
|
71
|
+
def need_dom_id?
|
72
|
+
false
|
73
|
+
end
|
74
|
+
|
75
|
+
# Return the node context for a given class (looks up into the hierarchy) or the
|
76
|
+
# current node context if klass is nil.
|
77
|
+
def node(klass = nil)
|
78
|
+
return @context[:node] if !klass
|
79
|
+
@context[:node].get(klass)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Store some contextual value / variable inside a named group. This should be
|
83
|
+
# used to avoid key clashes between different types of elements to store.
|
84
|
+
def set_context_var(group, key, obj, context = @context)
|
85
|
+
context["#{group}::#{key}"] = obj
|
86
|
+
end
|
87
|
+
|
88
|
+
# Retrieve a value from a given contextual group. The value must have been
|
89
|
+
# previously set with 'set_context_var' somewhere in the hierarchy.
|
90
|
+
def get_context_var(group, key, context = @context)
|
91
|
+
context["#{group}::#{key}"]
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return a new context without contextual variables.
|
95
|
+
def context_without_vars
|
96
|
+
context = @context.dup
|
97
|
+
context.keys.each do |k|
|
98
|
+
context.delete(k) if k.kind_of?(String)
|
99
|
+
end
|
100
|
+
context
|
101
|
+
end
|
102
|
+
|
103
|
+
# Expand blocks in a new context.
|
104
|
+
# This method is partly overwriten in Ajax
|
105
|
+
def expand_with_finder(finder)
|
106
|
+
if finder[:nil]
|
107
|
+
open_node_context(finder, :form => nil) do # do not propagate :form
|
108
|
+
expand_if("#{var} = #{finder[:method]}", node.move_to(var, finder[:class], finder.merge(:nil => false)))
|
109
|
+
end
|
110
|
+
else
|
111
|
+
res = ''
|
112
|
+
res << "<% #{var} = #{finder[:method]} %>"
|
113
|
+
open_node_context(finder, :node => node.move_to(var, finder[:class], finder), :form => nil) do
|
114
|
+
res << wrap(expand_with)
|
115
|
+
end
|
116
|
+
res
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# def context_with_node(name, klass)
|
121
|
+
# context = @context.dup
|
122
|
+
# context[:node] = context[:node].move_to(name, klass)
|
123
|
+
# end
|
124
|
+
|
125
|
+
def var
|
126
|
+
return @var if @var
|
127
|
+
if node.name =~ /^var(\d+)$/
|
128
|
+
@var = "var#{$1.to_i + 1}"
|
129
|
+
else
|
130
|
+
@var = "var1"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# This method is called when we enter a new node context
|
135
|
+
def node_context_vars(finder)
|
136
|
+
# do nothing (this is a hook for other modules like QueryBuilder and RubyLess)
|
137
|
+
{}
|
138
|
+
end
|
139
|
+
|
140
|
+
# Get a variable name and store the name in context variables for the given group.
|
141
|
+
#
|
142
|
+
# ==== Parameters
|
143
|
+
#
|
144
|
+
# * +group_name+ - name of the variable context group
|
145
|
+
# * +wanted_name+ - wanted variable name (used as key to get real var back later with #get_context_var)
|
146
|
+
# * +context+ - (optional) can be used if we do not want to store the variable definition in the current context
|
147
|
+
#
|
148
|
+
def get_var_name(group_name, wanted_name, context = @context)
|
149
|
+
secure_name = wanted_name.gsub(/[^a-zA-Z0-9]/,'')
|
150
|
+
name = "_z#{secure_name}"
|
151
|
+
i = 0
|
152
|
+
while get_context_var('var', name, context)
|
153
|
+
i += 1
|
154
|
+
name = "_z#{secure_name}#{i}"
|
155
|
+
end
|
156
|
+
set_context_var('var', name, true)
|
157
|
+
set_context_var(group_name, wanted_name, name)
|
158
|
+
name
|
159
|
+
end
|
160
|
+
|
161
|
+
# Change context for a given scope.
|
162
|
+
def with_context(cont, merge = true)
|
163
|
+
raise "Block missing" unless block_given?
|
164
|
+
cont_bak = @context
|
165
|
+
if merge
|
166
|
+
@context = @context.merge(cont)
|
167
|
+
else
|
168
|
+
@context = cont
|
169
|
+
end
|
170
|
+
res = yield
|
171
|
+
@context = cont_bak
|
172
|
+
res
|
173
|
+
end
|
174
|
+
|
175
|
+
# This should be called when we enter a new node context so that the proper hooks are
|
176
|
+
# triggered (insertion of contextual variables).
|
177
|
+
def open_node_context(finder, cont = {})
|
178
|
+
sub_context = node_context_vars(finder).merge(cont)
|
179
|
+
|
180
|
+
with_context(sub_context) do
|
181
|
+
yield
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end # Context
|
185
|
+
end # Process
|
186
|
+
end # Zafu
|
@@ -0,0 +1,143 @@
|
|
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
|
+
if node.dom_prefix
|
10
|
+
fnode = node
|
11
|
+
else
|
12
|
+
fnode = node.dup
|
13
|
+
fnode.dom_prefix = dom_name
|
14
|
+
end
|
15
|
+
with_context(:node => fnode) do
|
16
|
+
|
17
|
+
unless @params[:on].nil? || @params[:on].split(',').include?(@context[:ajax_action])
|
18
|
+
return ''
|
19
|
+
end
|
20
|
+
|
21
|
+
return parser_error('Cannot render update form in list context.') if node.list_context?
|
22
|
+
|
23
|
+
options = form_options
|
24
|
+
|
25
|
+
@markup.set_id(options[:id]) if options[:id]
|
26
|
+
@markup.set_param(:style, options[:style]) if options[:style]
|
27
|
+
|
28
|
+
if descendant('form_tag')
|
29
|
+
# We have a specific place to insert our form
|
30
|
+
out expand_with(:form_options => options, :form => self)
|
31
|
+
else
|
32
|
+
r_form_tag(options)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def r_form_tag(options = @context[:form_options])
|
38
|
+
form_tag(options) do |opts|
|
39
|
+
# Render error messages tag
|
40
|
+
form_error_messages(opts[:form_helper])
|
41
|
+
|
42
|
+
# Render form elements
|
43
|
+
out expand_with(opts)
|
44
|
+
|
45
|
+
# Render hidden fields (these must go after normal elements so that focusFirstElement works)
|
46
|
+
hidden_fields = form_hidden_fields(options)
|
47
|
+
|
48
|
+
out "<div class='hidden'>"
|
49
|
+
hidden_fields.each do |k,v|
|
50
|
+
if v.kind_of?(String)
|
51
|
+
v = "'#{v}'" unless v.kind_of?(String) && ['"', "'"].include?(v[0..0])
|
52
|
+
out "<input type='hidden' name='#{k}' value=#{v}/>"
|
53
|
+
elsif v.kind_of?(Array)
|
54
|
+
# We use ['ffff'] to indicate that the content is already escaped and ready for ERB.
|
55
|
+
out v.first
|
56
|
+
end
|
57
|
+
end
|
58
|
+
out '</div>'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def make_form
|
64
|
+
return nil unless @context[:make_form]
|
65
|
+
|
66
|
+
if method == 'each' || method == 'block'
|
67
|
+
r_form
|
68
|
+
else
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return id, style, form and cancel parts of the form.
|
74
|
+
def form_options
|
75
|
+
opts = {}
|
76
|
+
|
77
|
+
# Do we need this ?
|
78
|
+
# opts[:klass] = node.master_class(ActiveRecord::Base).to_s
|
79
|
+
|
80
|
+
if @context[:in_add]
|
81
|
+
opts[:id] = "#{node.dom_prefix}_add"
|
82
|
+
opts[:style] = 'display:none;'
|
83
|
+
elsif @markup.tag == 'table'
|
84
|
+
# the normal id goes to the form wrapping the table
|
85
|
+
opts[:id] = "#{node.dom_prefix}_tbl"
|
86
|
+
form_id = node.dom_prefix
|
87
|
+
end
|
88
|
+
|
89
|
+
form_id ||= "#{node.dom_prefix}_form_t"
|
90
|
+
if @context[:template_url]
|
91
|
+
opts[:form_tag] = "<% remote_form_for(:#{node.form_name}, #{node}, :html => {:id => #{form_id.inspect}}) do |f| %>"
|
92
|
+
opts[:form_helper] = 'f'
|
93
|
+
else
|
94
|
+
opts[:form_tag] = "<% form_for(:#{node.form_name}, #{node}, :html => {:id => #{form_id.inspect}}) do |f| %>"
|
95
|
+
opts[:form_helper] = 'f'
|
96
|
+
end
|
97
|
+
opts[:form_prefix] = node.dom_prefix || dom_name
|
98
|
+
opts
|
99
|
+
end
|
100
|
+
|
101
|
+
# Return hidden fields that need to be inserted in the form.
|
102
|
+
def form_hidden_fields(opts)
|
103
|
+
if t_url = @context[:template_url]
|
104
|
+
{'t_url' => t_url}
|
105
|
+
else
|
106
|
+
{}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Render the 'form' tag and set expansion context.
|
111
|
+
def form_tag(options)
|
112
|
+
opts = options.dup
|
113
|
+
|
114
|
+
if descendant('cancel') || descendant('edit')
|
115
|
+
# Pass 'form_cancel' content to expand_with (already in options).
|
116
|
+
else
|
117
|
+
# Insert cancel before form
|
118
|
+
out opts.delete(:form_cancel).to_s
|
119
|
+
end
|
120
|
+
|
121
|
+
# form_for ... do |f|
|
122
|
+
out opts.delete(:form_tag)
|
123
|
+
# f.xxx
|
124
|
+
if markup.tag == 'table'
|
125
|
+
# Avoid <table><form> (invalid HTML)
|
126
|
+
bak = @result
|
127
|
+
@result = ''
|
128
|
+
yield(opts.merge(:in_form => true))
|
129
|
+
@result = bak + markup.wrap(@result)
|
130
|
+
else
|
131
|
+
yield(opts.merge(:in_form => true))
|
132
|
+
end
|
133
|
+
# close form
|
134
|
+
out opts[:form_helper] ? "<% end %>" : '</form>'
|
135
|
+
end
|
136
|
+
|
137
|
+
def form_error_messages(f)
|
138
|
+
out "<%= #{f}.error_messages %>"
|
139
|
+
end
|
140
|
+
|
141
|
+
end # Forms
|
142
|
+
end # Process
|
143
|
+
end # Zafu
|
@@ -0,0 +1,186 @@
|
|
1
|
+
module Zafu
|
2
|
+
module Process
|
3
|
+
module HTML
|
4
|
+
SAFE_SRC_REGEX = %r{\A/[^\.]+\.[a-zA-Z]+\Z}
|
5
|
+
def self.included(base)
|
6
|
+
base.wrap :wrap_html
|
7
|
+
end
|
8
|
+
|
9
|
+
# Replace the 'original' element in the included template with our new version.
|
10
|
+
def replace_with(new_obj)
|
11
|
+
super
|
12
|
+
# [self = original_element]. Replace @markup with content of the new_obj (<ul do='with'>...)
|
13
|
+
if new_obj.markup.tag
|
14
|
+
@markup.tag = new_obj.markup.tag
|
15
|
+
else
|
16
|
+
# Steal 'class' param
|
17
|
+
@markup.steal_html_params_from(new_obj.params)
|
18
|
+
end
|
19
|
+
|
20
|
+
@markup.params.merge!(new_obj.markup.params)
|
21
|
+
|
22
|
+
# We do not have to merge dyn_params since these are compiled before processing (and we are in
|
23
|
+
# the pre-processor)
|
24
|
+
|
25
|
+
if new_obj.params[:method]
|
26
|
+
@method = new_obj.params[:method]
|
27
|
+
elsif new_obj.sub_do
|
28
|
+
@method = 'void'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Pass the caller's 'markup' to the included part.
|
33
|
+
def include_part(obj)
|
34
|
+
if @markup.tag
|
35
|
+
obj.markup = @markup.dup
|
36
|
+
end
|
37
|
+
@markup.tag = nil
|
38
|
+
|
39
|
+
if sub_do
|
40
|
+
obj.method = @blocks.first.method
|
41
|
+
obj.params = @blocks.first.params
|
42
|
+
elsif params[:method]
|
43
|
+
obj.method = params[:method]
|
44
|
+
end
|
45
|
+
super(obj)
|
46
|
+
end
|
47
|
+
|
48
|
+
def empty?
|
49
|
+
super && @markup.params == {} && @markup.tag.nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
def compile_html_params
|
53
|
+
return if @markup.done
|
54
|
+
unless @markup.tag
|
55
|
+
if @markup.tag = @params.delete(:tag)
|
56
|
+
@markup.steal_html_params_from(@params)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Translate dynamic params such as <tt>class='#{visitor.lang}'</tt> in the context
|
61
|
+
# of the current parser
|
62
|
+
@markup.compile_params(self)
|
63
|
+
end
|
64
|
+
|
65
|
+
def wrap_html(text)
|
66
|
+
compile_html_params
|
67
|
+
@markup.wrap(text)
|
68
|
+
end
|
69
|
+
|
70
|
+
#def restore_markup
|
71
|
+
# # restore @markup
|
72
|
+
# @markup = @markup_bak
|
73
|
+
#end
|
74
|
+
|
75
|
+
def inspect
|
76
|
+
@markup.done = false
|
77
|
+
res = super
|
78
|
+
if @markup.tag
|
79
|
+
if res =~ /\A\[(\w+)(.*)\/\]\Z/m
|
80
|
+
res = "[#{$1}#{$2}]<#{@markup.tag}/>[/#{$1}]"
|
81
|
+
elsif res =~ /\A\[([^\]]+)\](.*)\[\/(\w+)\]\Z/m
|
82
|
+
res = "[#{$1}]#{@markup.wrap($2)}[/#{$3}]"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
res
|
86
|
+
end
|
87
|
+
|
88
|
+
def r_ignore
|
89
|
+
@markup.done = true
|
90
|
+
''
|
91
|
+
end
|
92
|
+
|
93
|
+
def r_rename_asset
|
94
|
+
return expand_with unless @markup.tag
|
95
|
+
case @markup.tag
|
96
|
+
when 'link'
|
97
|
+
key = :href
|
98
|
+
return parser_error("Missing 'rel' parameter.") unless rel = @params[:rel]
|
99
|
+
return parser_error("Missing 'href' parameter.") unless @params[:href]
|
100
|
+
if rel.downcase == 'stylesheet'
|
101
|
+
type = :stylesheet
|
102
|
+
else
|
103
|
+
type = :link
|
104
|
+
end
|
105
|
+
when 'style'
|
106
|
+
return expand_with.gsub(/url\(('|")(.*?)\1\)/) do
|
107
|
+
if $2[0..6] == 'http://'
|
108
|
+
$&
|
109
|
+
else
|
110
|
+
quote = $1
|
111
|
+
new_src = helper.send(:template_url_for_asset, :base_path=>@options[:base_path], :src => $2)
|
112
|
+
"url(#{quote}#{new_src}#{quote})"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
else
|
116
|
+
key = :src
|
117
|
+
type = @markup.tag.to_sym
|
118
|
+
end
|
119
|
+
|
120
|
+
src = @params.delete(key)
|
121
|
+
if src && src[0..7] != 'http://'
|
122
|
+
if new_value = helper.send(:template_url_for_asset, :src => src, :base_path => @options[:base_path], :type => type)
|
123
|
+
elsif src =~ SAFE_SRC_REGEX
|
124
|
+
fullpath = "#{SITES_ROOT}#{current_site.public_path}#{src}"
|
125
|
+
if File.exist?(fullpath) && File.stat(fullpath)
|
126
|
+
src = "#{src}?#{File.mtime(fullpath).to_i}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
@markup.params[key] = new_value.blank? ? src : new_value
|
130
|
+
end
|
131
|
+
|
132
|
+
expand_with
|
133
|
+
end
|
134
|
+
|
135
|
+
def steal_and_eval_html_params_for(markup, params)
|
136
|
+
markup.steal_keys.each do |key|
|
137
|
+
next unless value = params.delete(key)
|
138
|
+
append_markup_attr(markup, key, value)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
#def r_form
|
142
|
+
# res = "<#{@markup.tag}#{params_to_html(@params)}"
|
143
|
+
# @markup.done = true
|
144
|
+
# inner = expand_with
|
145
|
+
# if inner == ''
|
146
|
+
# res + "/>"
|
147
|
+
# else
|
148
|
+
# res + ">#{inner}"
|
149
|
+
# end
|
150
|
+
#end
|
151
|
+
#
|
152
|
+
#def r_select
|
153
|
+
# res = "<#{@markup.tag}#{params_to_html(@params)}"
|
154
|
+
# @markup.done = true
|
155
|
+
# inner = expand_with
|
156
|
+
# if inner == ''
|
157
|
+
# res + "></#{@markup.tag}>"
|
158
|
+
# else
|
159
|
+
# res + ">#{inner}"
|
160
|
+
# end
|
161
|
+
#end
|
162
|
+
#
|
163
|
+
#def r_input
|
164
|
+
# res = "<#{@markup.tag}#{params_to_html(@params)}"
|
165
|
+
# @markup.done = true
|
166
|
+
# inner = expand_with
|
167
|
+
# if inner == ''
|
168
|
+
# res + "/>"
|
169
|
+
# else
|
170
|
+
# res + ">#{inner}"
|
171
|
+
# end
|
172
|
+
#end
|
173
|
+
#
|
174
|
+
#def r_textarea
|
175
|
+
# res = "<#{@markup.tag}#{params_to_html(@params)}"
|
176
|
+
# @markup.done = true
|
177
|
+
# inner = expand_with
|
178
|
+
# if inner == ''
|
179
|
+
# res + "/>"
|
180
|
+
# else
|
181
|
+
# res + ">#{inner}"
|
182
|
+
# end
|
183
|
+
#end
|
184
|
+
end # HTML
|
185
|
+
end # Process
|
186
|
+
end # Zafu
|