zena 0.15.2 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +20 -0
- data/CREDITS +27 -0
- data/Capfile +3 -0
- data/DEVELOPERS +46 -0
- data/History.txt +15 -0
- data/MIT-LICENSE +19 -0
- data/Rakefile +44 -0
- data/TODO +24 -0
- data/TODO_ZENA_1_0 +23 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/controllers/documents_controller.rb +22 -56
- data/app/controllers/nodes_controller.rb +42 -27
- data/app/controllers/pings_controller.rb +19 -0
- data/app/controllers/relations_controller.rb +5 -1
- data/app/controllers/sites_controller.rb +1 -46
- data/app/controllers/user_sessions_controller.rb +47 -0
- data/app/controllers/users_controller.rb +1 -0
- data/app/controllers/versions_controller.rb +25 -7
- data/app/controllers/virtual_classes_controller.rb +1 -1
- data/app/helpers/application_helper.rb +1 -1
- data/app/models/comment.rb +2 -1
- data/app/models/contact_content.rb +2 -2
- data/app/models/data_entry.rb +5 -6
- data/app/models/document.rb +14 -10
- data/app/models/document_content.rb +4 -6
- data/app/models/iformat.rb +2 -2
- data/app/models/image_content.rb +6 -9
- data/app/models/node.rb +106 -164
- data/app/models/page.rb +0 -20
- data/app/models/site.rb +42 -12
- data/app/models/template.rb +3 -8
- data/app/models/template_content.rb +2 -0
- data/app/models/text_document.rb +13 -8
- data/app/models/user.rb +47 -100
- data/app/models/user_session.rb +4 -0
- data/app/models/version.rb +1 -1
- data/app/views/comments/create.rjs +3 -3
- data/app/views/comments/edit.rjs +1 -1
- data/app/views/comments/update.rjs +1 -1
- data/app/views/nodes/_import_results.rhtml +1 -1
- data/app/views/nodes/create.rjs +3 -3
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -2
- data/app/views/templates/document_create_tabs/_import.rhtml +7 -2
- data/app/views/templates/edit_tabs/_document.rhtml +1 -3
- data/app/views/templates/edit_tabs/_image.rhtml +1 -3
- data/app/views/versions/_tr.rhtml +1 -1
- data/app/views/versions/edit.rhtml +2 -26
- data/bin/zena +6 -1
- data/bricks/delayed_job/README +18 -0
- data/bricks/delayed_job/migrate/20091104191643_create_delayed_jobs_table.rb +19 -0
- data/bricks/delayed_job/misc/init.rb +8 -0
- data/bricks/delayed_job/misc/tasks.rb +2 -0
- data/bricks/math/patch/application_helper.rb +1 -1
- data/bricks/sphinx/MIT-LICENSE +19 -0
- data/bricks/sphinx/README +19 -0
- data/bricks/sphinx/lib/use_sphinx.rb +78 -0
- data/bricks/sphinx/migrate/20091102171258_add_delta_for_sphinx.rb +9 -0
- data/bricks/sphinx/misc/deploy.rb +20 -0
- data/bricks/sphinx/misc/sphinx.yml +12 -0
- data/bricks/sphinx/misc/tasks.rb +21 -0
- data/bricks/sphinx/patch/node.rb +8 -0
- data/bricks/tags/lib/has_tags.rb +5 -3
- data/bricks/tags/test/zafu/tags.yml +13 -1
- data/config/bricks.yml +35 -0
- data/config/deploy.rb +8 -1
- data/config/environment.rb +1 -1
- data/config/environments/production.rb +1 -1
- data/config/gems.yml +28 -5
- data/config/sphinx.yml +12 -0
- data/db/init/base/skins/default/Node-+popupLayout.zafu +1 -16
- data/db/migrate/20091026161708_add_persistence_token.rb +13 -0
- data/db/migrate/20091101184952_add_session_table.rb +16 -0
- data/db/migrate/20091123175137_add_single_access_token.rb +9 -0
- data/db/migrate/20091124161608_rebuild_fullpath.rb +11 -0
- data/db/schema.rb +21 -8
- data/doc/README_FOR_APP +24 -0
- data/doc/fixtures.graffle +19568 -0
- data/doc/fixtures.pdf +0 -0
- data/doc/template/LICENSE +184 -0
- data/doc/template/README +37 -0
- data/doc/template/allison.css +283 -0
- data/doc/template/allison.js +307 -0
- data/doc/template/allison.rb +260 -0
- data/doc/template/cache/BODY +588 -0
- data/doc/template/cache/CLASS_INDEX +4 -0
- data/doc/template/cache/CLASS_PAGE +1 -0
- data/doc/template/cache/FILE_INDEX +4 -0
- data/doc/template/cache/FILE_PAGE +1 -0
- data/doc/template/cache/FONTS +1 -0
- data/doc/template/cache/FR_INDEX_BODY +1 -0
- data/doc/template/cache/IMGPATH +1 -0
- data/doc/template/cache/INDEX +1 -0
- data/doc/template/cache/JAVASCRIPT +307 -0
- data/doc/template/cache/METHOD_INDEX +4 -0
- data/doc/template/cache/METHOD_LIST +1 -0
- data/doc/template/cache/SRC_PAGE +1 -0
- data/doc/template/cache/STYLE +283 -0
- data/doc/template/cache/URL +1 -0
- data/doc/zafu_changes.yml +29 -0
- data/lib/base_additions.rb +1 -1
- data/lib/bricks.rb +9 -0
- data/lib/bricks/loader.rb +86 -0
- data/lib/bricks/requirements_validation.rb +71 -0
- data/lib/tasks/zena.rake +42 -4
- data/lib/zafu/action.rb +285 -0
- data/lib/zafu/ajax.rb +93 -0
- data/lib/zafu/attributes.rb +117 -0
- data/lib/zafu/calendar.rb +159 -0
- data/lib/zafu/context.rb +330 -0
- data/lib/zafu/core/html.rb +102 -0
- data/lib/zafu/core/move_to_parser.rb +167 -0
- data/lib/zafu/dates.rb +58 -0
- data/lib/zafu/display.rb +502 -0
- data/lib/zafu/eval.rb +66 -0
- data/lib/zafu/experimental.rb +66 -0
- data/lib/zafu/i18n.rb +64 -0
- data/lib/zafu/meta.rb +25 -0
- data/lib/zafu/refactor.rb +73 -0
- data/lib/zafu/support/context.rb +265 -0
- data/lib/zafu/support/dom.rb +145 -0
- data/lib/zafu/support/erb.rb +62 -0
- data/lib/zafu/support/flow.rb +401 -0
- data/lib/zafu/support/forms.rb +461 -0
- data/lib/zafu/support/links.rb +306 -0
- data/lib/zafu_parser.rb +26 -2
- data/lib/zena.rb +34 -15
- data/lib/zena/acts/multiversion.rb +2 -2
- data/lib/zena/acts/secure.rb +41 -30
- data/lib/zena/app.rb +7 -10
- data/lib/zena/controller/test_case.rb +12 -7
- data/lib/zena/crypto_provider/initial.rb +15 -0
- data/lib/zena/db.rb +6 -1
- data/lib/zena/deploy.rb +34 -6
- data/lib/zena/deploy/logrotate_app.rhtml +9 -0
- data/lib/zena/deploy/logrotate_host.rhtml +34 -0
- data/lib/zena/deploy/template.rb +1 -9
- data/lib/zena/foxy_parser.rb +1 -1
- data/lib/zena/info.rb +3 -1
- data/lib/zena/migrator.rb +1 -1
- data/lib/zena/parser.rb +12 -4
- data/lib/zena/parser/zazen_rules.rb +6 -6
- data/lib/zena/parser/zena_rules.rb +1 -7
- data/lib/zena/routes.rb +5 -5
- data/lib/zena/test_controller.rb +7 -2
- data/lib/zena/unit/test_case.rb +6 -8
- data/lib/zena/use/ajax.rb +10 -10
- data/lib/zena/use/authlogic.rb +93 -0
- data/lib/zena/use/dyn_attributes.rb +5 -0
- data/lib/zena/use/html_tags.rb +16 -34
- data/lib/zena/use/i18n.rb +4 -1
- data/lib/zena/use/node_query_finders.rb +8 -4
- data/lib/zena/use/refactor.rb +8 -20
- data/lib/zena/use/relations.rb +1 -0
- data/lib/zena/use/rendering.rb +4 -2
- data/lib/zena/use/search.rb +52 -0
- data/lib/zena/use/test_helper.rb +27 -28
- data/lib/zena/use/upload.rb +188 -0
- data/lib/zena/use/urls.rb +16 -14
- data/lib/zena/use/zafu.rb +16 -63
- data/lib/zena/use/zazen.rb +8 -8
- data/lib/zena/view/test_case.rb +8 -4
- data/locale/en/LC_MESSAGES/zena.mo +0 -0
- data/locale/en/zena.po +3 -3
- data/public/.htaccess +40 -0
- data/public/javascripts/upload-progress.js +17 -8
- data/public/javascripts/zena.js +8 -2
- data/public/stylesheets/popup.css +1 -0
- data/script/about +3 -0
- data/script/apache_logging +25 -0
- data/script/breakpointer +3 -0
- data/script/console +3 -0
- data/script/dbconsole +3 -0
- data/script/destroy +3 -0
- data/script/generate +3 -0
- data/script/performance/benchmarker +3 -0
- data/script/performance/profiler +3 -0
- data/script/plugin +3 -0
- data/script/process/inspector +3 -0
- data/script/process/reaper +3 -0
- data/script/process/spawner +3 -0
- data/script/runner +3 -0
- data/script/server +3 -0
- data/script/set_revision +29 -0
- data/spec/controllers/versions_controller_spec.rb +11 -0
- data/test/fixtures/files/Node-test.zafu +1 -1
- data/test/functional/nodes_controller_test.rb +25 -0
- data/test/functional/pings_controller_test.rb +8 -0
- data/test/functional/user_sessions_controller_test.rb +59 -0
- data/test/functional/users_controller_test.rb +81 -19
- data/test/helpers/node_query/filters.yml +5 -0
- data/test/helpers/node_query_test.rb +3 -3
- data/test/integration/multiple_hosts_test.rb +1 -1
- data/test/integration/navigation_test.rb +1 -1
- data/test/sites/complex/users.yml +1 -1
- data/test/sites/ocean/users.yml +3 -3
- data/test/sites/zena/users.yml +5 -4
- data/test/test_zena.rb +38 -38
- data/test/unit/cached_page_test.rb +2 -2
- data/test/unit/comment_test.rb +0 -1
- data/test/unit/document_test.rb +23 -11
- data/test/unit/helpers/ping_helper_test.rb +4 -0
- data/test/unit/multiversion_test.rb +24 -16
- data/test/unit/node_test.rb +32 -93
- data/test/unit/note_test.rb +9 -0
- data/test/unit/page_test.rb +2 -2
- data/test/unit/secure_test.rb +2 -12
- data/test/unit/site_test.rb +43 -24
- data/test/unit/template_test.rb +45 -3
- data/test/unit/text_document_test.rb +4 -3
- data/test/unit/user_test.rb +13 -33
- data/test/unit/zena/db_test.rb +8 -0
- data/test/unit/zena/parser/zazen.yml +4 -4
- data/test/unit/zena/use/dates_view_methods_test.rb +2 -1
- data/test/unit/zena/use/html_tags_test.rb +12 -4
- data/test/unit/zena/use/refactor_test.rb +4 -3
- data/test/unit/zena/use/rendering_test.rb +1 -0
- data/test/unit/zena/use/upload_test.rb +76 -0
- data/test/unit/zena/use/urls_test.rb +4 -0
- data/test/unit/zena/use/zafu_test.rb +8 -0
- data/test/unit/zena/workflow/status_version_test.rb +6 -0
- data/test/unit/zena/zena_tags/ajax.yml +4 -4
- data/test/unit/zena/zena_tags/basic.yml +21 -10
- data/test/unit/zena/zena_tags/relations.yml +0 -6
- data/test/unit/zena/zena_tags/rubyless.yml +35 -0
- data/test/unit/zena/zena_tags/zazen.yml +4 -4
- data/test/unit/zena/zena_tags_test.rb +36 -4
- data/vendor/TextMate/Zena.tmbundle/Commands/Run all yaml tests.tmCommand +1 -1
- data/vendor/TextMate/Zena.tmbundle/Commands/Run focused yaml test.tmCommand +2 -3
- data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/catch_exception.rb +39 -0
- data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/run_script.rb +102 -58
- data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/stdin_dialog.rb +14 -0
- data/vendor/TextMate/Zena.tmbundle/info.plist +2 -0
- data/zena.gemspec +2085 -0
- metadata +265 -90
- data/app/controllers/sessions_controller.rb +0 -41
- data/app/views/sites/zena_up.html.erb +0 -11
- data/config/database.yml +0 -40
- data/db/production.sqlite3 +0 -0
- data/lib/bricks/patcher.rb +0 -68
- data/lib/zena/parser/zena_tags.rb +0 -3562
- data/lib/zena/use/authentification.rb +0 -120
- data/public/images/ext/contact_pv.png +0 -0
- data/public/images/ext/other_pv.png +0 -0
- data/public/images/ext/page_pv.png +0 -0
- data/public/images/ext/page_tiny.png +0 -0
- data/public/images/ext/pdf_pv.png +0 -0
- data/public/images/ext/post_pv.png +0 -0
- data/public/images/ext/post_tiny.png +0 -0
- data/public/images/ext/project_pv.png +0 -0
- data/public/images/ext/project_tiny.png +0 -0
- data/public/images/ext/tag_pv.png +0 -0
- data/public/images/ext/zip_pv.png +0 -0
- data/tasks/ann.rake +0 -80
- data/tasks/bones.rake +0 -20
- data/tasks/gem.rake +0 -201
- data/tasks/git.rake +0 -40
- data/tasks/notes.rake +0 -27
- data/tasks/post_load.rake +0 -34
- data/tasks/rdoc.rake +0 -51
- data/tasks/rubyforge.rake +0 -55
- data/tasks/setup.rb +0 -292
- data/tasks/spec.rake +0 -54
- data/tasks/svn.rake +0 -47
- data/tasks/test.rake +0 -40
- data/tasks/zentest.rake +0 -36
- data/test/fixtures/comments.yml +0 -126
- data/test/fixtures/contact_contents.yml +0 -132
- data/test/fixtures/data_entries.yml +0 -65
- data/test/fixtures/discussions.yml +0 -48
- data/test/fixtures/document_contents.yml +0 -108
- data/test/fixtures/dyn_attributes.yml +0 -66
- data/test/fixtures/groups.yml +0 -86
- data/test/fixtures/groups_users.yml +0 -81
- data/test/fixtures/iformats.yml +0 -29
- data/test/fixtures/links.yml +0 -313
- data/test/fixtures/nodes.yml +0 -2592
- data/test/fixtures/relations.yml +0 -126
- data/test/fixtures/sites.yml +0 -58
- data/test/fixtures/template_contents.yml +0 -172
- data/test/fixtures/users.yml +0 -167
- data/test/fixtures/versions.yml +0 -1911
- data/test/fixtures/virtual_classes.yml +0 -87
- data/test/fixtures/zips.yml +0 -15
- data/test/functional/sessions_controller_test.rb +0 -73
@@ -0,0 +1,145 @@
|
|
1
|
+
module Zafu
|
2
|
+
module Support
|
3
|
+
module Dom
|
4
|
+
|
5
|
+
def start_node_s_param(type = :input)
|
6
|
+
if type == :input
|
7
|
+
"<input type='hidden' name='s' value='<%= params[:s] || @node[:zip] %>'/>"
|
8
|
+
elsif type == :erb
|
9
|
+
"s=<%= params[:s] || @node[:zip] %>"
|
10
|
+
elsif type == :value
|
11
|
+
"<%= params[:s] || @node[:zip] %>"
|
12
|
+
else
|
13
|
+
"s=\#{params[:s] || @node[:zip]}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def erb_node_id(obj = node)
|
18
|
+
if node_kind_of?(Version)
|
19
|
+
"<%= #{obj}.node.zip %>.<%= #{obj}.number %>"
|
20
|
+
else
|
21
|
+
"<%= #{node_id(obj)} %>"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def node_id(obj = node)
|
26
|
+
"#{obj}.zip"
|
27
|
+
end
|
28
|
+
|
29
|
+
# DOM id for the current context
|
30
|
+
def dom_id(suffix='')
|
31
|
+
return "\#{dom_id(#{node})}" if @context && (@context[:saved_template] && @context[:main_node])
|
32
|
+
if @context && scope_node = @context[:scope_node]
|
33
|
+
res = "#{dom_prefix}_\#{#{scope_node}.zip}"
|
34
|
+
else
|
35
|
+
res = dom_prefix
|
36
|
+
end
|
37
|
+
if (method == 'each' || method == 'each_group') && !@context[:make_form]
|
38
|
+
"#{res}_\#{#{var}.zip}"
|
39
|
+
elsif @context && @context[:in_calendar]
|
40
|
+
"#{res}_\#{#{current_date}.to_i}"
|
41
|
+
elsif method == 'unlink' || method == 'edit'
|
42
|
+
target = nil
|
43
|
+
parent = self.parent
|
44
|
+
while parent
|
45
|
+
if ['block', 'each', 'context', 'icon'].include?(parent.method)
|
46
|
+
target = parent
|
47
|
+
break
|
48
|
+
end
|
49
|
+
parent = parent.parent
|
50
|
+
end
|
51
|
+
target ? target.dom_id(suffix) : (res + suffix)
|
52
|
+
else
|
53
|
+
res + suffix
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def erb_dom_id(suffix='')
|
58
|
+
return "<%= dom_id(#{node}) %>" if @context && (@context[:saved_template] && @context[:main_node])
|
59
|
+
if @context && scope_node = @context[:scope_node]
|
60
|
+
res = "#{dom_prefix}_<%= #{scope_node}.zip %>"
|
61
|
+
else
|
62
|
+
res = dom_prefix
|
63
|
+
end
|
64
|
+
if (method == 'each' || method == 'each_group') && !@context[:make_form]
|
65
|
+
"#{res}_<%= #{var}.zip %>"
|
66
|
+
elsif method == 'draggable'
|
67
|
+
"#{res}_<%= #{node}.zip %>"
|
68
|
+
elsif @context && @context[:in_calendar]
|
69
|
+
"#{res}_<%= #{current_date}.to_i %>"
|
70
|
+
elsif method == 'unlink'
|
71
|
+
target = nil
|
72
|
+
parent = self.parent
|
73
|
+
while parent
|
74
|
+
if ['block', 'each', 'context', 'icon'].include?(parent.method)
|
75
|
+
target = parent
|
76
|
+
break
|
77
|
+
end
|
78
|
+
parent = parent.parent
|
79
|
+
end
|
80
|
+
target ? target.erb_dom_id(suffix) : (res + suffix)
|
81
|
+
else
|
82
|
+
res + suffix
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Unique template_url, ending with dom_id
|
87
|
+
def template_url
|
88
|
+
"#{@options[:root]}/#{dom_prefix}"
|
89
|
+
end
|
90
|
+
|
91
|
+
def form_url
|
92
|
+
template_url + '_form'
|
93
|
+
end
|
94
|
+
|
95
|
+
# prefix for DOM id
|
96
|
+
def dom_prefix
|
97
|
+
(@context ? @context[:dom_prefix] : nil) || (@dom_prefix ||= unique_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
# use our own scope
|
101
|
+
def clear_dom_scope
|
102
|
+
@context.delete(:make_form) # should not propagate
|
103
|
+
@context.delete(:main_node) # should not propagate
|
104
|
+
end
|
105
|
+
|
106
|
+
# create our own ajax DOM scope
|
107
|
+
def new_dom_scope
|
108
|
+
clear_dom_scope
|
109
|
+
@context.delete(:saved_template) # should not propagate on fresh template
|
110
|
+
@context.delete(:dom_prefix) # should not propagate on fresh template
|
111
|
+
@context[:main_node] = true # the current context will be rendered with a fresh '@node'
|
112
|
+
@context[:dom_prefix] = self.dom_prefix
|
113
|
+
end
|
114
|
+
|
115
|
+
# Return a different name on each call
|
116
|
+
def unique_name(base = context_name)
|
117
|
+
root.next_name_index(base, base == @name).gsub(/[^\d\w\/]/,'_')
|
118
|
+
end
|
119
|
+
|
120
|
+
def context_name
|
121
|
+
@name || if @context
|
122
|
+
@context[:name] || 'list'
|
123
|
+
elsif parent
|
124
|
+
parent.context_name
|
125
|
+
else
|
126
|
+
'root'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def next_name_index(key, own_id = false)
|
131
|
+
@next_name_index ||= {}
|
132
|
+
if @next_name_index[key]
|
133
|
+
@next_name_index[key] += 1
|
134
|
+
key + @next_name_index[key].to_s
|
135
|
+
elsif own_id
|
136
|
+
@next_name_index[key] = 0
|
137
|
+
key
|
138
|
+
else
|
139
|
+
@next_name_index[key] = 1
|
140
|
+
key + '1'
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end # Dom
|
144
|
+
end # Support
|
145
|
+
end # Zafu
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Zafu
|
2
|
+
module Support
|
3
|
+
module Erb
|
4
|
+
|
5
|
+
def params_to_erb(params, initial_comma = true)
|
6
|
+
res = initial_comma ? [""] : []
|
7
|
+
params.each do |k,v|
|
8
|
+
if v =~ /<%=/ && !(v =~ /"/)
|
9
|
+
# replace by #{}
|
10
|
+
val = v.gsub('#{', '# {').gsub(/<%=(.*?)%>/,'#{\1}')
|
11
|
+
res << "#{k.inspect}=>\"#{val}\""
|
12
|
+
else
|
13
|
+
res << "#{k.inspect}=>#{v.inspect}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
res.join(', ')
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_text_for_erb(params = @params, use_blocks = true, context = :erb)
|
20
|
+
string_context = context == :string
|
21
|
+
if params[:attr]
|
22
|
+
string_context ? "<%= #{node_attribute(params[:attr])} %>" : node_attribute(params[:attr])
|
23
|
+
elsif params[:tattr]
|
24
|
+
string_context ? "<%= _(#{node_attribute(params[:tattr])}) %>" : "_(#{node_attribute(params[:tattr])})"
|
25
|
+
elsif params[:trans]
|
26
|
+
string_context ? _(params[:trans]) : _(params[:trans]).inspect
|
27
|
+
elsif params[:text]
|
28
|
+
string_context ? params[:text] : params[:text].inspect
|
29
|
+
elsif use_blocks && @blocks != []
|
30
|
+
res = []
|
31
|
+
text = ""
|
32
|
+
static = true
|
33
|
+
@blocks.each do |b|
|
34
|
+
# FIXME: this is a little too hacky
|
35
|
+
if b.kind_of?(String)
|
36
|
+
res << b.inspect
|
37
|
+
text << b
|
38
|
+
elsif ['show', 'img'].include?(b.method)
|
39
|
+
res << expand_block(b, :trans=>true)
|
40
|
+
static = false
|
41
|
+
elsif ['rename_asset', 'trans'].include?(b.method)
|
42
|
+
# FIXME: if a trans contains non-static: static should become false
|
43
|
+
res << expand_block(b).inspect
|
44
|
+
text << expand_block(b)
|
45
|
+
else
|
46
|
+
# ignore
|
47
|
+
end
|
48
|
+
end
|
49
|
+
if static
|
50
|
+
# "just plain text"
|
51
|
+
string_context ? text : text.inspect
|
52
|
+
else
|
53
|
+
# function(...) + "blah" + function()
|
54
|
+
string_context ? "<%= #{res.join(' + ')} %>" : res.join(' + ')
|
55
|
+
end
|
56
|
+
else
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end # Erb
|
61
|
+
end # Support
|
62
|
+
end # Zafu
|
@@ -0,0 +1,401 @@
|
|
1
|
+
module Zafu
|
2
|
+
module Support
|
3
|
+
module Flow
|
4
|
+
|
5
|
+
def r_each_group
|
6
|
+
return parser_error("must be used inside a group context") unless group = @context[:group]
|
7
|
+
if join = @params[:join]
|
8
|
+
join = join.gsub(/<([^%])/, '<\1').gsub(/([^%])>/, '\1>')
|
9
|
+
out "<% #{group}.each_index do |#{list_var}_index| -%>"
|
10
|
+
out "<%= #{list_var}=#{group}[#{list_var}_index]; #{var} = #{list_var}[0]; #{list_var}_index > 0 ? #{join.inspect} : '' %>"
|
11
|
+
else
|
12
|
+
out "<% #{group}.each do |#{list_var}|; #{var} = #{list_var}[0]; -%>"
|
13
|
+
end
|
14
|
+
out render_html_tag(expand_with(:group => nil, :list => list_var, :node => var, :scope_node => var))
|
15
|
+
out "<% end -%>"
|
16
|
+
end
|
17
|
+
|
18
|
+
def r_each
|
19
|
+
is_draggable = @params[:draggable] == 'true' || @params[:drag_handle]
|
20
|
+
|
21
|
+
if descendant('edit') || descendant('unlink') || descendant('swap') || ['block', 'drop'].include?(single_child_method) || is_draggable
|
22
|
+
id_hash = {:id => erb_dom_id}
|
23
|
+
else
|
24
|
+
id_hash = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
if @context[:make_form]
|
29
|
+
# use the elements inside 'each' loop to produce the edit form
|
30
|
+
r_form
|
31
|
+
elsif @context[:list]
|
32
|
+
# normal rendering: not the start of a saved template
|
33
|
+
if is_draggable || descendant('unlink')
|
34
|
+
out "<% #{var}_dom_ids = [] -%>"
|
35
|
+
end
|
36
|
+
|
37
|
+
@params[:alt_class] ||= @html_tag_params.delete(:alt_class)
|
38
|
+
# FIXME: add alt_reverse='true' to start counting from bottom (if order last on top...)
|
39
|
+
if @params[:alt_class] || @params[:join]
|
40
|
+
join = @params[:join] || ''
|
41
|
+
join = join.gsub(/<([^%])/, '<\1').gsub(/([^%])>/, '\1>')
|
42
|
+
out "<% #{var}_max_index = #{list}.size - 1 -%>" if @params[:alt_reverse]
|
43
|
+
out "<% #{list}.each_with_index do |#{var},#{var}_index| -%>"
|
44
|
+
|
45
|
+
if join_clause = @params[:join_if]
|
46
|
+
set_stored(Node, 'prev', "#{var}_prev")
|
47
|
+
cond = get_test_condition(var, :test=>join_clause)
|
48
|
+
out "<%= #{var}_prev = #{list}[#{var}_index - 1]; (#{var}_index > 0 && #{cond}) ? #{join.inspect} : '' %>"
|
49
|
+
else
|
50
|
+
out "<%= #{var}_index > 0 ? #{join.inspect} : '' %>"
|
51
|
+
end
|
52
|
+
|
53
|
+
if alt_class = @params[:alt_class]
|
54
|
+
alt_test = @params[:alt_reverse] == 'true' ? "(#{var}_max_index - #{var}_index) % 2 != 0" : "#{var}_index % 2 != 0"
|
55
|
+
if html_class = @html_tag_params.delete(:class)
|
56
|
+
html_append = " class='#{html_class}<%= #{alt_test} ? #{(' ' + alt_class).inspect} : '' %>'"
|
57
|
+
else
|
58
|
+
html_append = "<%= #{alt_test} ? ' class=#{alt_class.inspect}' : '' %>"
|
59
|
+
end
|
60
|
+
else
|
61
|
+
html_append = nil
|
62
|
+
end
|
63
|
+
else
|
64
|
+
out "<% #{list}.each do |#{var}| -%>"
|
65
|
+
html_append = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
if is_draggable
|
69
|
+
out "<% #{var}_dom_ids << \"#{dom_id}\" -%>"
|
70
|
+
end
|
71
|
+
|
72
|
+
out r_anchor(var) if @anchor_param # insert anchor inside the each loop
|
73
|
+
@params[:anchor] = @anchor_param # set back in case we double render
|
74
|
+
@anchor_param = nil
|
75
|
+
|
76
|
+
res, drag_handle = set_drag_handle_and_id(expand_with(:node => var, :scope_node => var), @params, id_hash)
|
77
|
+
|
78
|
+
out render_html_tag(res, html_append)
|
79
|
+
|
80
|
+
out "<% end -%>"
|
81
|
+
|
82
|
+
if is_draggable
|
83
|
+
if drag_handle
|
84
|
+
out "<script type='text/javascript'>\n//<![CDATA[\n<%= #{var}_dom_ids.inspect %>.each(function(dom_id, index) {
|
85
|
+
new Draggable(dom_id, {ghosting:true, revert:true, handle:$(dom_id).select('.#{drag_handle}')[0]});
|
86
|
+
});\n//]]>\n</script>"
|
87
|
+
else
|
88
|
+
out "<script type='text/javascript'>\n//<![CDATA[\n<%= #{var}_dom_ids.inspect %>.each(Zena.draggable)\n//]]>\n</script>"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
elsif @context[:saved_template]
|
93
|
+
# render to start a saved template
|
94
|
+
res, drag_handle = set_drag_handle_and_id(expand_with(:scope_node => node), @params, id_hash)
|
95
|
+
|
96
|
+
out render_html_tag(res)
|
97
|
+
|
98
|
+
if is_draggable
|
99
|
+
if drag_handle
|
100
|
+
out "<script type='text/javascript'>\n//<![CDATA[\nnew Draggable('#{erb_dom_id}', {ghosting:true, revert:true, handle:$('#{erb_dom_id}').select('.#{drag_handle}')[0]});\n//]]>\n</script>"
|
101
|
+
else
|
102
|
+
out "<script type='text/javascript'>\n//<![CDATA[\nZena.draggable('#{erb_dom_id}')\n//]]>\n</script>"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
else
|
106
|
+
# TODO: make a single list ?
|
107
|
+
@context[:list] = "[#{node}]"
|
108
|
+
r_each
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def r_case
|
113
|
+
out "<% if false -%>"
|
114
|
+
out expand_with(:in_if=>true, :only=>['when', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
115
|
+
@html_tag_done = true
|
116
|
+
out "<% end -%>"
|
117
|
+
end
|
118
|
+
|
119
|
+
# TODO: test
|
120
|
+
def r_if
|
121
|
+
cond = get_test_condition
|
122
|
+
return parser_error("condition error") unless cond
|
123
|
+
|
124
|
+
if cond == 'true'
|
125
|
+
return expand_with(:in_if => false)
|
126
|
+
elsif cond == 'false'
|
127
|
+
if descendant('else') || descendant('elsif')
|
128
|
+
out "<% if false -%>"
|
129
|
+
out expand_with(:in_if=>true, :only=>['elsif', 'else'])
|
130
|
+
out "<% end -%>"
|
131
|
+
return
|
132
|
+
else
|
133
|
+
@html_tag_done = true
|
134
|
+
return ''
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
out "<% if #{cond} -%>"
|
139
|
+
out render_html_tag(expand_with(:in_if=>false))
|
140
|
+
out expand_with(:in_if=>true, :only=>['elsif', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
141
|
+
out "<% end -%>"
|
142
|
+
end
|
143
|
+
|
144
|
+
def r_else
|
145
|
+
if @context[:in_if]
|
146
|
+
@html_tag = @context[:html_tag]
|
147
|
+
@html_tag_params = @context[:html_tag_params] || {}
|
148
|
+
out "<% elsif true -%>"
|
149
|
+
if @params[:text]
|
150
|
+
out render_html_tag(@params[:text])
|
151
|
+
else
|
152
|
+
out render_html_tag(expand_with(:in_if=>false, :only => nil)) # do not propagate :only from ancestor 'if' clause
|
153
|
+
end
|
154
|
+
else
|
155
|
+
""
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def r_elsif
|
160
|
+
return '' unless @context[:in_if]
|
161
|
+
@html_tag = @context[:html_tag]
|
162
|
+
@html_tag_params = @context[:html_tag_params] || {}
|
163
|
+
cond = get_test_condition
|
164
|
+
return parser_error("condition error") unless cond
|
165
|
+
out "<% elsif #{cond} -%>"
|
166
|
+
out render_html_tag(expand_with(:in_if=>false, :only => nil)) # do not propagate :only from ancestor 'if' clause
|
167
|
+
end
|
168
|
+
|
169
|
+
def r_when
|
170
|
+
r_elsif
|
171
|
+
end
|
172
|
+
|
173
|
+
protected
|
174
|
+
|
175
|
+
# TODO: RUBYLESS
|
176
|
+
def get_test_condition(node = self.node, params = @params)
|
177
|
+
tests = []
|
178
|
+
params.each do |k,v|
|
179
|
+
if k.to_s =~ /^(or_|)([a-zA-Z_]+)(\d*)$/
|
180
|
+
k = $2.to_sym
|
181
|
+
end #tagged undocumented
|
182
|
+
if [:kind_of, :klass, :status, :lang, :can, :tagged, :node, :in, :visitor, :has].include?(k)
|
183
|
+
tests << [k, v]
|
184
|
+
elsif k == :test
|
185
|
+
if v =~ /\s/
|
186
|
+
tests << [:test, v]
|
187
|
+
else
|
188
|
+
tests << [:attribute, v]
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
tests.map! do |type,value|
|
195
|
+
case type
|
196
|
+
when :kind_of
|
197
|
+
"#{node}.vkind_of?(#{value.inspect})"
|
198
|
+
when :klass
|
199
|
+
klass = begin Module::const_get(value) rescue "NilClass" end
|
200
|
+
"#{node}.klass == #{value.inspect}"
|
201
|
+
when :status
|
202
|
+
"#{node}.version.status == #{Zena::Status[value.to_sym]}"
|
203
|
+
when :tagged
|
204
|
+
# TODO: undocumented: remove and use rubyless !
|
205
|
+
"#{node}.tagged[#{value.inspect}]"
|
206
|
+
when :lang
|
207
|
+
"#{node}.version.lang == #{value.inspect}"
|
208
|
+
when :can
|
209
|
+
# TODO: test
|
210
|
+
case value
|
211
|
+
when 'write', 'edit'
|
212
|
+
"#{node}.can_write?"
|
213
|
+
when 'drive', 'publish'
|
214
|
+
"#{node}.can_drive?"
|
215
|
+
else
|
216
|
+
nil
|
217
|
+
end
|
218
|
+
when :has
|
219
|
+
case value
|
220
|
+
when 'discussion'
|
221
|
+
"#{node}.discussion"
|
222
|
+
else
|
223
|
+
nil
|
224
|
+
end
|
225
|
+
when :test
|
226
|
+
parse_condition(value, node)
|
227
|
+
when :attribute
|
228
|
+
'!' + node_attribute(value, :node => node) + '.blank?'
|
229
|
+
when :node
|
230
|
+
if node_kind_of?(Node)
|
231
|
+
value, node_name = get_attribute_and_node(value)
|
232
|
+
node_name ||= '@node'
|
233
|
+
if value
|
234
|
+
case value
|
235
|
+
when 'main'
|
236
|
+
"#{node}[:id] == #{node_name}[:id]"
|
237
|
+
when 'start'
|
238
|
+
"#{node}[:zip] == (params[:s] || @node[:zip]).to_i"
|
239
|
+
when 'parent'
|
240
|
+
"#{node}[:id] == #{node_name}[:parent_id]"
|
241
|
+
when 'project'
|
242
|
+
"#{node}[:id] == #{node_name}[:project_id]"
|
243
|
+
when 'section'
|
244
|
+
"#{node}[:id] == #{node_name}[:section_id]"
|
245
|
+
when 'ancestor'
|
246
|
+
"#{node_name}.fullpath =~ /\\A\#{#{node}.fullpath}/"
|
247
|
+
else
|
248
|
+
if stored = find_stored(Node, value)
|
249
|
+
"#{node}[:id] == #{stored}[:id]"
|
250
|
+
else
|
251
|
+
nil
|
252
|
+
end
|
253
|
+
end
|
254
|
+
else
|
255
|
+
# bad node_name
|
256
|
+
nil
|
257
|
+
end
|
258
|
+
else
|
259
|
+
nil
|
260
|
+
end
|
261
|
+
when :in
|
262
|
+
if @context["in_#{value}".to_sym] # FIXME: || ancestors.include?(value) ==> ancestors is a list of zafu tags, not a list of names !
|
263
|
+
'true'
|
264
|
+
else
|
265
|
+
'false'
|
266
|
+
end
|
267
|
+
when :visitor
|
268
|
+
if value == 'anon'
|
269
|
+
"visitor.is_anon?"
|
270
|
+
else
|
271
|
+
nil
|
272
|
+
end
|
273
|
+
else
|
274
|
+
nil
|
275
|
+
end
|
276
|
+
end.compact!
|
277
|
+
tests == [] ? nil : tests.join(' || ')
|
278
|
+
end
|
279
|
+
|
280
|
+
def parse_condition_error(clause, rest, res)
|
281
|
+
out parser_error("invalid clause #{clause.inspect} near \"#{res[-2..-1]}#{rest[0..1]}\"")
|
282
|
+
end
|
283
|
+
|
284
|
+
def parse_condition(clause, node_name)
|
285
|
+
rest = clause.strip
|
286
|
+
types = [:par_open, :value, :bool_op, :op, :par_close]
|
287
|
+
allowed = [:par_open, :value]
|
288
|
+
par_count = 0
|
289
|
+
uses_bool_op = false
|
290
|
+
segment = [] # value op value
|
291
|
+
after_value = lambda { segment.size == 3 ? [:bool_op, :par_close] : [:op, :bool_op, :par_close]}
|
292
|
+
res = ""
|
293
|
+
while rest != ''
|
294
|
+
# puts rest.inspect
|
295
|
+
if rest =~ /\A\s+/
|
296
|
+
rest = rest[$&.size..-1]
|
297
|
+
elsif rest[0..0] == '('
|
298
|
+
unless allowed.include?(:par_open)
|
299
|
+
parse_condition_error(clause, rest, res)
|
300
|
+
return nil
|
301
|
+
end
|
302
|
+
res << '('
|
303
|
+
rest = rest[1..-1]
|
304
|
+
par_count += 1
|
305
|
+
elsif rest[0..0] == ')'
|
306
|
+
unless allowed.include?(:par_close)
|
307
|
+
parse_condition_error(clause, rest, res)
|
308
|
+
return nil
|
309
|
+
end
|
310
|
+
res << ')'
|
311
|
+
rest = rest[1..-1]
|
312
|
+
par_count -= 1
|
313
|
+
if par_count < 0
|
314
|
+
parse_condition_error(clause, rest, res)
|
315
|
+
return nil
|
316
|
+
end
|
317
|
+
allowed = [:bool_op]
|
318
|
+
elsif rest =~ /\A(lt|le|eq|ne|ge|gt)\s+/
|
319
|
+
unless allowed.include?(:op)
|
320
|
+
parse_condition_error(clause, rest, res)
|
321
|
+
return nil
|
322
|
+
end
|
323
|
+
op = $1.strip
|
324
|
+
rest = rest[op.size..-1]
|
325
|
+
op = {'lt' => '<', 'le' => '<=', 'eq' => '==', 'ne' => '!=', 'ge' => '>=', 'gt' => '>'}[op]
|
326
|
+
segment << [op, :op]
|
327
|
+
allowed = [:value]
|
328
|
+
elsif rest =~ /\A("|')([^\1]*?)\1/
|
329
|
+
# string
|
330
|
+
unless allowed.include?(:value)
|
331
|
+
parse_condition_error(clause, rest, res)
|
332
|
+
return nil
|
333
|
+
end
|
334
|
+
rest = rest[$&.size..-1]
|
335
|
+
segment << [$2.inspect, :string]
|
336
|
+
allowed = after_value.call
|
337
|
+
elsif rest =~ /\A(-?\d+)/
|
338
|
+
# number
|
339
|
+
unless allowed.include?(:value)
|
340
|
+
parse_condition_error(clause, rest, res)
|
341
|
+
return nil
|
342
|
+
end
|
343
|
+
rest = rest[$&.size..-1]
|
344
|
+
segment << [$1, :number]
|
345
|
+
allowed = after_value.call
|
346
|
+
elsif rest =~ /\A(and|or)/
|
347
|
+
unless allowed.include?(:bool_op)
|
348
|
+
parse_condition_error(clause, rest, res)
|
349
|
+
return nil
|
350
|
+
end
|
351
|
+
uses_bool_op = true
|
352
|
+
rest = rest[$&.size..-1]
|
353
|
+
res << " #{$1} "
|
354
|
+
allowed = [:par_open, :value]
|
355
|
+
elsif rest =~ /\A([\w:\.\-]+)/
|
356
|
+
# variable
|
357
|
+
unless allowed.include?(:value)
|
358
|
+
parse_condition_error(clause, rest, res)
|
359
|
+
return nil
|
360
|
+
end
|
361
|
+
rest = rest[$&.size..-1]
|
362
|
+
fld = $1
|
363
|
+
unless node_attr = node_attribute(fld, :node => node_name)
|
364
|
+
parser_error("invalid field #{fld.inspect}")
|
365
|
+
return nil
|
366
|
+
end
|
367
|
+
segment << [node_attr, :var]
|
368
|
+
allowed = after_value.call
|
369
|
+
else
|
370
|
+
parse_condition_error(clause, rest, res)
|
371
|
+
return nil
|
372
|
+
end
|
373
|
+
if segment.size == 3
|
374
|
+
toi = (segment[1][0] =~ /(>|<)/ || (segment[0][1] == :number || segment[2][1] == :number))
|
375
|
+
segment.map! do |part, type|
|
376
|
+
if type == :var
|
377
|
+
toi ? "#{part}.to_i" : part
|
378
|
+
elsif type == :string
|
379
|
+
toi ? part[1..-2].to_i : part
|
380
|
+
else
|
381
|
+
part
|
382
|
+
end
|
383
|
+
end
|
384
|
+
res << segment.join(" ")
|
385
|
+
segment = []
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
if par_count > 0
|
390
|
+
parser_error("invalid clause #{clause.inspect}: missing closing ')'")
|
391
|
+
return nil
|
392
|
+
elsif allowed.include?(:value)
|
393
|
+
parser_error("invalid clause #{clause.inspect}")
|
394
|
+
return nil
|
395
|
+
else
|
396
|
+
return uses_bool_op ? "(#{res})" : res
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end # Flow
|
400
|
+
end # Support
|
401
|
+
end # Zafu
|