zena 1.2.1 → 1.2.2

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.
Files changed (202) hide show
  1. data/History.txt +38 -1
  2. data/app/controllers/documents_controller.rb +7 -5
  3. data/app/controllers/nodes_controller.rb +47 -6
  4. data/app/controllers/user_sessions_controller.rb +12 -3
  5. data/app/controllers/virtual_classes_controller.rb +8 -2
  6. data/app/models/acl.rb +5 -2
  7. data/app/models/cached_page.rb +5 -5
  8. data/app/models/column.rb +27 -4
  9. data/app/models/group.rb +1 -1
  10. data/app/models/node.rb +106 -24
  11. data/app/models/note.rb +2 -1
  12. data/app/models/relation.rb +9 -4
  13. data/app/models/relation_proxy.rb +2 -2
  14. data/app/models/role.rb +12 -5
  15. data/app/models/site.rb +10 -9
  16. data/app/models/skin.rb +8 -0
  17. data/app/models/string_hash.rb +65 -0
  18. data/app/models/text_document.rb +1 -1
  19. data/app/models/user.rb +2 -0
  20. data/app/models/virtual_class.rb +43 -10
  21. data/app/views/comments/create.rjs +1 -32
  22. data/app/views/comments/edit.rjs +1 -1
  23. data/app/views/comments/update.rjs +1 -1
  24. data/app/views/documents/show.rhtml +1 -1
  25. data/app/views/groups/_form.rhtml +7 -0
  26. data/app/views/groups/_li.rhtml +1 -1
  27. data/app/views/nodes/500.html +2 -1
  28. data/app/views/nodes/destroy.rjs +2 -0
  29. data/app/views/sites/jobs.erb +2 -3
  30. data/app/views/templates/document_create_tabs/_file.rhtml +1 -1
  31. data/app/views/templates/document_create_tabs/_import.rhtml +4 -1
  32. data/app/views/templates/document_create_tabs/_template.rhtml +3 -0
  33. data/app/views/templates/document_create_tabs/_text_document.rhtml +3 -0
  34. data/app/views/versions/custom_tab.rhtml +1 -1
  35. data/app/views/versions/edit.rhtml +1 -1
  36. data/bricks/acls/lib/bricks/acls.rb +3 -3
  37. data/bricks/acls/zena/test/unit/acl_test.rb +15 -0
  38. data/bricks/fs_skin/lib/bricks/fs_skin.rb +190 -0
  39. data/bricks/fs_skin/zena/init.rb +1 -0
  40. data/bricks/fs_skin/zena/migrate/20110702010330_add_fs_skin_to_idx_templates.rb +12 -0
  41. data/bricks/{static → fs_skin}/zena/skins/blog/Image-edit.zafu +0 -0
  42. data/bricks/{static → fs_skin}/zena/skins/blog/Image.zafu +0 -0
  43. data/bricks/{static → fs_skin}/zena/skins/blog/Node-+index.zafu +0 -0
  44. data/bricks/{static → fs_skin}/zena/skins/blog/Node-+notFound.zafu +0 -0
  45. data/bricks/{static → fs_skin}/zena/skins/blog/Node-+search.zafu +0 -0
  46. data/bricks/{static → fs_skin}/zena/skins/blog/Node.zafu +1 -1
  47. data/bricks/{static → fs_skin}/zena/skins/blog/Post.zafu +0 -0
  48. data/bricks/{static → fs_skin}/zena/skins/blog/Project--kml.zafu +0 -0
  49. data/bricks/{static → fs_skin}/zena/skins/blog/Project.zafu +0 -0
  50. data/bricks/{static → fs_skin}/zena/skins/blog/comments.zafu +0 -0
  51. data/bricks/{static → fs_skin}/zena/skins/blog/dict.yml +0 -0
  52. data/bricks/{static → fs_skin}/zena/skins/blog/img/dateBg.jpg +0 -0
  53. data/bricks/{static → fs_skin}/zena/skins/blog/img/header.png +0 -0
  54. data/bricks/{static → fs_skin}/zena/skins/blog/img/mapPin.png +0 -0
  55. data/bricks/{static → fs_skin}/zena/skins/blog/img/menu.gif +0 -0
  56. data/bricks/{static → fs_skin}/zena/skins/blog/img/menuover.gif +0 -0
  57. data/bricks/{static → fs_skin}/zena/skins/blog/img/style.css +0 -0
  58. data/bricks/fs_skin/zena/tasks.rb +26 -0
  59. data/bricks/{static/zena/test/integration/static_integration_test.rb → fs_skin/zena/test/integration/fs_skin_integration_test.rb} +6 -6
  60. data/bricks/fs_skin/zena/test/unit/fs_skin_test.rb +33 -0
  61. data/bricks/grid/lib/bricks/grid.rb +4 -3
  62. data/bricks/tags/lib/bricks/tags.rb +1 -7
  63. data/bricks/zena/zena/migrate/20120605091558_add_ssl_login_to_site.rb +7 -0
  64. data/bricks/zena/zena/migrate/20120630123551_add_auto_publish_to_group.rb +9 -0
  65. data/config/bricks.yml +3 -3
  66. data/config/gems.yml +2 -3
  67. data/lib/tasks/zena.rake +7 -3
  68. data/lib/zafu.rb +7 -0
  69. data/lib/zafu/all.rb +21 -0
  70. data/lib/zafu/compiler.rb +7 -0
  71. data/lib/zafu/controller_methods.rb +58 -0
  72. data/lib/zafu/handler.rb +57 -0
  73. data/lib/zafu/info.rb +4 -0
  74. data/lib/zafu/markup.rb +309 -0
  75. data/lib/zafu/mock_helper.rb +42 -0
  76. data/lib/zafu/node_context.rb +203 -0
  77. data/lib/zafu/ordered_hash.rb +53 -0
  78. data/lib/zafu/parser.rb +676 -0
  79. data/lib/zafu/parsing_rules.rb +382 -0
  80. data/lib/zafu/process/ajax.rb +530 -0
  81. data/lib/zafu/process/conditional.rb +92 -0
  82. data/lib/zafu/process/context.rb +186 -0
  83. data/lib/zafu/process/forms.rb +143 -0
  84. data/lib/zafu/process/html.rb +186 -0
  85. data/lib/zafu/process/ruby_less_processing.rb +321 -0
  86. data/lib/zafu/security.rb +15 -0
  87. data/lib/zafu/template.rb +25 -0
  88. data/lib/zafu/test_helper.rb +19 -0
  89. data/lib/zafu/view_methods.rb +6 -0
  90. data/lib/zena.rb +1 -1
  91. data/lib/zena/acts/enrollable.rb +1 -1
  92. data/lib/zena/app.rb +4 -17
  93. data/lib/zena/console.rb +18 -1
  94. data/lib/zena/core_ext/file_utils.rb +13 -1
  95. data/lib/zena/core_ext/fixnum.rb +4 -0
  96. data/lib/zena/core_ext/float.rb +7 -0
  97. data/lib/zena/deploy.rb +4 -2
  98. data/lib/zena/deploy/app_init.rhtml +2 -1
  99. data/lib/zena/deploy/database.rhtml +1 -1
  100. data/lib/zena/info.rb +1 -1
  101. data/lib/zena/parser/zazen_rules.rb +4 -4
  102. data/lib/zena/routes.rb +1 -1
  103. data/lib/zena/test_controller.rb +1 -1
  104. data/lib/zena/use.rb +14 -1
  105. data/lib/zena/use/action.rb +4 -2
  106. data/lib/zena/use/ajax.rb +86 -38
  107. data/lib/zena/use/authlogic.rb +16 -1
  108. data/lib/zena/use/calendar.rb +37 -17
  109. data/lib/zena/use/conditional.rb +2 -2
  110. data/lib/zena/use/context.rb +30 -9
  111. data/lib/zena/use/dates.rb +39 -3
  112. data/lib/zena/use/display.rb +6 -19
  113. data/lib/zena/use/forms.rb +100 -79
  114. data/lib/zena/use/i18n.rb +40 -16
  115. data/lib/zena/use/query_builder.rb +0 -6
  116. data/lib/zena/use/query_node.rb +17 -4
  117. data/lib/zena/use/relations.rb +1 -3
  118. data/lib/zena/use/rendering.rb +10 -8
  119. data/lib/zena/use/scope_index.rb +5 -1
  120. data/lib/zena/use/search.rb +2 -1
  121. data/lib/zena/use/urls.rb +82 -77
  122. data/lib/zena/use/workflow.rb +12 -4
  123. data/lib/zena/use/zafu_safe_definitions.rb +37 -9
  124. data/lib/zena/use/zafu_templates.rb +49 -20
  125. data/lib/zena/use/zazen.rb +6 -2
  126. data/locale/it/LC_MESSAGES/zena.mo +0 -0
  127. data/locale/it/zena.mo +0 -0
  128. data/locale/it/zena.po +1982 -0
  129. data/public/images/arrow_back.png +0 -0
  130. data/public/images/remove_tag.png +0 -0
  131. data/public/javascripts/grid.js +800 -199
  132. data/public/javascripts/window.js +1 -1
  133. data/public/javascripts/zena.js +130 -21
  134. data/public/stylesheets/grid.css +11 -2
  135. data/public/stylesheets/zena.css +2 -1
  136. data/test/custom_queries/complex.host.yml +5 -0
  137. data/test/fixtures/files/TestNode.zafu +36 -0
  138. data/test/functional/nodes_controller_test.rb +18 -1
  139. data/test/integration/zafu_compiler/action.yml +2 -2
  140. data/test/integration/zafu_compiler/ajax.yml +44 -26
  141. data/test/integration/zafu_compiler/asset.yml +12 -2
  142. data/test/integration/zafu_compiler/basic.yml +0 -16
  143. data/test/integration/zafu_compiler/calendar.yml +6 -6
  144. data/test/integration/zafu_compiler/complex_ok.yml +23 -1
  145. data/test/integration/zafu_compiler/conditional.yml +5 -5
  146. data/test/integration/zafu_compiler/context.yml +6 -5
  147. data/test/integration/zafu_compiler/dates.yml +23 -2
  148. data/test/integration/zafu_compiler/display.yml +46 -2
  149. data/test/integration/zafu_compiler/errors.yml +2 -2
  150. data/test/integration/zafu_compiler/eval.yml +35 -7
  151. data/test/integration/zafu_compiler/forms.yml +47 -13
  152. data/test/integration/zafu_compiler/i18n.yml +2 -2
  153. data/test/integration/zafu_compiler/meta.yml +35 -1
  154. data/test/integration/zafu_compiler/query.yml +23 -4
  155. data/test/integration/zafu_compiler/relations.yml +10 -6
  156. data/test/integration/zafu_compiler/roles.yml +4 -4
  157. data/test/integration/zafu_compiler/rubyless.yml +11 -1
  158. data/test/integration/zafu_compiler/safe_definitions.yml +23 -5
  159. data/test/integration/zafu_compiler/security.yml +10 -6
  160. data/test/integration/zafu_compiler/urls.yml +23 -6
  161. data/test/integration/zafu_compiler/zafu_attributes.yml +1 -1
  162. data/test/integration/zafu_compiler/zazen.yml +14 -0
  163. data/test/selenium/Add/add3.rsel +8 -8
  164. data/test/selenium/Destroy/0setup.rsel +12 -0
  165. data/test/selenium/Destroy/destroy1.rsel +16 -0
  166. data/test/selenium/Edit/edit2.rsel +9 -9
  167. data/test/selenium/Edit/edit5.rsel +9 -9
  168. data/test/selenium/Edit/edit6.rsel +9 -9
  169. data/test/selenium/Form/form4.rsel +17 -0
  170. data/test/selenium/Toggle/toggle1.rsel +2 -0
  171. data/test/selenium/Toggle/toggle2.rsel +18 -0
  172. data/test/sites/zena/columns.yml +3 -0
  173. data/test/sites/zena/versions.yml +7 -0
  174. data/test/unit/cached_page_test.rb +13 -13
  175. data/test/unit/column_test.rb +26 -0
  176. data/test/unit/node_test.rb +16 -1
  177. data/test/unit/project_test.rb +6 -1
  178. data/test/unit/relation_test.rb +1 -1
  179. data/test/unit/role_test.rb +1 -1
  180. data/test/unit/string_hash_test.rb +30 -0
  181. data/test/unit/virtual_class_test.rb +31 -17
  182. data/test/unit/zafu_markup_test.rb +414 -0
  183. data/test/unit/zafu_node_context_test.rb +375 -0
  184. data/test/unit/zafu_ordered_hash_test.rb +69 -0
  185. data/test/unit/zena/acts/enrollable_test.rb +1 -1
  186. data/test/unit/zena/parser/zafu_asset.yml +0 -10
  187. data/test/unit/zena/parser/zazen.yml +1 -1
  188. data/test/unit/zena/parser_test.rb +1 -72
  189. data/test/unit/zena/use/dates_test.rb +1 -1
  190. data/test/unit/zena/use/rendering_test.rb +24 -7
  191. data/test/unit/zena/use/scope_index_test.rb +17 -0
  192. data/test/unit/zena/use/zazen_test.rb +2 -1
  193. data/zena.gemspec +71 -37
  194. metadata +104 -83
  195. data/app/views/nodes/destroy.erb +0 -0
  196. data/bricks/static/lib/bricks/static.rb +0 -151
  197. data/bricks/static/zena/init.rb +0 -1
  198. data/bricks/static/zena/migrate/20110702010330_add_static_to_idx_templates.rb +0 -12
  199. data/bricks/static/zena/test/unit/static_test.rb +0 -33
  200. data/lib/zena/parser/zafu_rules.rb +0 -244
  201. data/lib/zena/parser/zafu_tags.rb +0 -198
  202. data/lib/zena/parser/zena_rules.rb +0 -23
@@ -10,4 +10,16 @@ else
10
10
  class << FileUtils
11
11
  alias symlink_or_copy cp_r
12
12
  end
13
- end
13
+ end
14
+
15
+ =begin
16
+ class << FileUtils
17
+ def symlink_or_copy(from, to)
18
+ if File.directory?(from)
19
+ cp_r(from, to)
20
+ else
21
+ ln(from, to)
22
+ end
23
+ end
24
+ end
25
+ =end
@@ -17,4 +17,8 @@ class Fixnum
17
17
  res << "#{seconds} second#{seconds == 1 ? '' : 's'}" if seconds != 0
18
18
  res == [] ? '0' : res.join(' ')
19
19
  end
20
+
21
+ def fmt(format)
22
+ # TODO: Better strftime with thousand separator
23
+ end
20
24
  end
@@ -0,0 +1,7 @@
1
+ class Float
2
+ # Format a float with thousand separator and decimal positions.
3
+ def fmt(pos=2,sep="'")
4
+ i = self.to_i.to_s.reverse
5
+ i.gsub(/(\d\d\d)(?=\d)(?!\d*\.)/,'\1'+sep).reverse
6
+ end
7
+ end
@@ -40,6 +40,7 @@ Capistrano::Configuration.instance(:must_exist).load do
40
40
 
41
41
  self[:balancer] ||= db_name
42
42
  self[:db_user] ||= db_name
43
+ self[:db_socket] ||= "/var/run/mysqld/mysqld.sock"
43
44
  self[:runner] ||= 'root'
44
45
  self[:on_stop] = []
45
46
  self[:on_start] = []
@@ -341,7 +342,8 @@ Capistrano::Configuration.instance(:must_exist).load do
341
342
  db_app_config = render("#{templates}/database.rhtml",
342
343
  :db_name => db_name,
343
344
  :db_user => db_user,
344
- :db_password => db_password
345
+ :db_password => db_password,
346
+ :db_socket => db_socket
345
347
  )
346
348
  put(db_app_config, "#{deploy_to}/current/config/database.yml")
347
349
  end
@@ -403,7 +405,7 @@ Capistrano::Configuration.instance(:must_exist).load do
403
405
  else
404
406
  init_name = db_name
405
407
  end
406
- run "cd /usr/local/bin && test -e /usr/local/bin/#{init_name}"
408
+ run "cd /usr/local/bin && test -e /usr/local/bin/#{init_name} || ln -sf /usr/local/bin/zena_#{db_name} /usr/local/bin/#{init_name}"
407
409
 
408
410
  if self[:rvm_ruby_string]
409
411
  run "rvm wrapper #{self[:rvm_ruby_string]} init zena_#{db_name}"
@@ -24,7 +24,8 @@ operations = [
24
24
  # 'rake sphinx:',
25
25
  ]
26
26
 
27
- if %w{stop restart}.include?(cmd)
27
+ # Allways make a clean start
28
+ if %w{stop restart start}.include?(cmd)
28
29
  puts "Stopping #{APP_ROOT}..."
29
30
  operations.each do |op|
30
31
  run "cd #{APP_ROOT} && #{op}stop"
@@ -18,7 +18,7 @@ test:
18
18
 
19
19
  production:
20
20
  adapter: mysql
21
- socket: /var/run/mysqld/mysqld.sock
21
+ socket: <%= db_socket %>
22
22
  database: <%= db_name %>
23
23
  encoding: utf8
24
24
  username: <%= db_user %>
@@ -1,4 +1,4 @@
1
1
  module Zena
2
- VERSION = '1.2.1'
2
+ VERSION = '1.2.2'
3
3
  ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
4
4
  end
@@ -134,7 +134,7 @@ module Zena
134
134
  end
135
135
  else
136
136
  if node.kind_of?(Document)
137
- store @helper.make_image(:style=>style, :id=>node[:zip].to_s, :node=>node, :mode=>mode, :title=>title, :link=>link, :images=>@context[:images], :host => @context[:host])
137
+ store @helper.make_image(:style=>style, :id=>node[:zip].to_s, :node=>node, :mode=>mode, :title=>title, :link=>link, :images=>@context[:images], :host => @context[:host],:target=>@context[:target])
138
138
  else
139
139
  store "[#{node.fullpath_as_title.join('/')} is not a document]"
140
140
  end
@@ -162,7 +162,7 @@ module Zena
162
162
  end
163
163
  store "!#{style}#{id}#{other_opts}#{title_opts}!#{link ? ':' + link : ''}"
164
164
  else
165
- store @helper.make_image(:style=>style, :id=>id, :mode=>mode, :title=>title, :link=>link, :images=>@context[:images], :host => @context[:host])
165
+ store @helper.make_image(:style=>style, :id=>id, :mode=>mode, :title=>title, :link=>link, :images=>@context[:images], :host => @context[:host],:target=>@context[:target])
166
166
  end
167
167
  else
168
168
  #puts "EAT:[#{$&}]"
@@ -190,7 +190,7 @@ module Zena
190
190
  id, anchor = $1, $2
191
191
  anchor = 'true' if anchor == ''
192
192
  end
193
- store @helper.make_link(:title=>title,:id=>id,:anchor=>anchor,:host=>@context[:host])
193
+ store @helper.make_link(:title=>title,:id=>id,:anchor=>anchor,:host=>@context[:host],:target=>@context[:target])
194
194
  end
195
195
  elsif @text =~ /\A"([^"]*)":(#{PSEUDO_ID_REGEXP})((_[a-z]+|)(\.[a-z]+|)(#[a-z_\/\[\]]*|))/m
196
196
  #puts "SHORTCUT_LINK:[#{$&}]"
@@ -212,7 +212,7 @@ module Zena
212
212
  id, anchor = $1, $2
213
213
  anchor = 'true' if anchor == ''
214
214
  end
215
- store @helper.make_link(:title=>title,:id=>id,:anchor=>anchor,:node=>node,:host=>@context[:host])
215
+ store @helper.make_link(:title=>title,:id=>id,:anchor=>anchor,:node=>node,:host=>@context[:host],:target=>@context[:target])
216
216
  end
217
217
  elsif @translate_ids
218
218
  store $&
@@ -39,7 +39,7 @@ module Zena
39
39
  :refuse => :put,
40
40
  :remove => :put,
41
41
  :redit => :put,
42
- :preview => :get,
42
+ :preview => :any,
43
43
  :link => :any }
44
44
 
45
45
  nodes.resources :links
@@ -109,7 +109,7 @@ module Zena
109
109
  end
110
110
  end
111
111
 
112
- def get_template_text(path, base_path)
112
+ def get_template_text(path, base_path, opts={})
113
113
  folder = base_path.blank? ? [] : base_path[1..-1].split('/')
114
114
  if path[0..0] == '/'
115
115
  # just ignore the 'relative' or 'absolute' tricks.
@@ -7,7 +7,7 @@ module Zena
7
7
  MODULE_NAME = Hash[*MODULE_NAMES.map {|n| [n, "#{n}#{SUFFIX_NAME}"]}.flatten]
8
8
 
9
9
  class << self
10
- attr_accessor :modules, :extra_routes
10
+ attr_accessor :modules, :extra_routes, :upgraded_classes
11
11
 
12
12
  # Declare a module (or list of modules) that should be used in Zena. The module should implement
13
13
  # sub-modules named ControllerMethods, ViewMethods or ZafuMethods in order to add features to
@@ -37,6 +37,19 @@ module Zena
37
37
  create_module_hash
38
38
  self.modules[name] || []
39
39
  end
40
+
41
+ def upgrade_class(class_name)
42
+ self.upgraded_classes ||= {}
43
+ if !self.upgraded_classes[class_name]
44
+ self.upgraded_classes[class_name] = true
45
+ klass = eval "::#{class_name}"
46
+ klass.class_eval do
47
+ Zena::Use.each_module_for(class_name) do |mod|
48
+ include mod
49
+ end
50
+ end
51
+ end
52
+ end
40
53
 
41
54
  def routes(rez)
42
55
  if self.extra_routes.nil?
@@ -2,7 +2,9 @@ module Zena
2
2
  module Use
3
3
  module Action
4
4
  module Common
5
-
5
+ def win_id(node_zip, action)
6
+ "#{current_site.host.gsub('.', '_')}_#{node_zip}_#{action}"
7
+ end
6
8
  # This method renders an action link without using Rails actions so that we can feed it with
7
9
  # erb from Zafu.
8
10
  def node_action_link(action, node_zip, opts={})
@@ -25,7 +27,7 @@ module Zena
25
27
  url = "/documents/new"
26
28
  query << "parent_id=#{node_zip}"
27
29
  end
28
- id = "#{current_site.host.gsub('.', '_')}_#{node_zip}_#{action}"
30
+ id = win_id(node_zip, action)
29
31
 
30
32
  url = query.empty? ? url : "#{url}?#{query.join('&')}"
31
33
  tag = "<a href='#{url}' target='_blank' title='#{title}' onclick=\"Zena.open_window('#{url}', '#{id}', event);return false;\">"
@@ -44,10 +44,10 @@ module Zena
44
44
 
45
45
  if obj.new_record?
46
46
  # A. could not create object: show form with errors
47
- page.replace ndom_id, :file => template_path_from_template_url + "_form.erb"
47
+ page.replace ndom_id, :file => template_path_from_template_url('_form')
48
48
  elsif @errors || !obj.errors.empty?
49
49
  # B. could not update/delete: show errors
50
- form_file = template_path_from_template_url + "_form.erb"
50
+ form_file = template_path_from_template_url('_form')
51
51
  if File.exist?(form_file)
52
52
  page.replace ndom_id, :file => form_file
53
53
  else
@@ -68,10 +68,10 @@ module Zena
68
68
  end
69
69
  end
70
70
  end
71
- page.replace params[:udom_id], :file => template_path_from_template_url(params[:u_url]) + ".erb"
71
+ page.replace params[:udom_id], :file => template_path_from_template_url('', params[:u_url])
72
72
  if params[:upd_both]
73
73
  @dom_id = params[:dom_id]
74
- page.replace params[:dom_id], :file => template_path_from_template_url + ".erb"
74
+ page.replace params[:dom_id], :file => template_path_from_template_url
75
75
  end
76
76
  if params[:done] && params[:zadd]
77
77
  page.toggle "#{params[:dom_id]}_0", "#{params[:dom_id]}_add"
@@ -89,25 +89,25 @@ module Zena
89
89
 
90
90
  case params[:action]
91
91
  when 'edit'
92
- page.replace params[:dom_id], :file => template_path_from_template_url + ".erb"
92
+ page.replace params[:dom_id], :file => template_path_from_template_url
93
93
  page << "$('#{params[:dom_id]}_form_t').focusFirstElement();"
94
94
  when 'create'
95
95
  pos = params[:position] || :before
96
96
  ref = params[:reference] || "#{params[:dom_id]}_add"
97
- page.insert_html pos.to_sym, ref, :file => template_path_from_template_url + ".erb"
97
+ page.insert_html pos.to_sym, ref, :file => template_path_from_template_url
98
98
  if obj.kind_of?(Node)
99
99
  @node = obj.parent.new_child(:class => obj.class)
100
100
  else
101
101
  instance_variable_set("@#{base_class.to_s.underscore}", obj.clone)
102
102
  end
103
- page.replace ndom_id, :file => template_path_from_template_url + "_form.erb"
103
+ page.replace ndom_id, :file => template_path_from_template_url('_form')
104
104
  if params[:done]
105
105
  page << params[:done]
106
106
  elsif params[:zadd]
107
107
  page.toggle "#{params[:dom_id]}_0", "#{params[:dom_id]}_add"
108
108
  end
109
109
  when 'update'
110
- page.replace ndom_id, :file => template_path_from_template_url + ".erb"
110
+ page.replace ndom_id, :file => template_path_from_template_url
111
111
  page << params[:done] if params[:done]
112
112
  when 'destroy'
113
113
  page << %Q{
@@ -129,18 +129,21 @@ module Zena
129
129
  page.visual_effect :highlight, params[:drop], :duration => 0.3
130
130
  page.visual_effect :fade, params[:drop], :duration => 0.3
131
131
  end
132
- page.replace params[:dom_id], :file => template_path_from_template_url + ".erb"
132
+ page.replace params[:dom_id], :file => template_path_from_template_url
133
133
  else
134
134
  if position = params[:insert]
135
- page.call 'Zena.insert_inner', params[:dom_id], position, render(:file => template_path_from_template_url + ".erb")
135
+ page.call 'Zena.insert_inner', params[:dom_id], position, render(:file => template_path_from_template_url)
136
136
  else
137
- page.replace params[:dom_id], :file => template_path_from_template_url + ".erb"
137
+ page.replace params[:dom_id], :file => template_path_from_template_url
138
138
  end
139
139
  end
140
140
  end
141
141
  if params[:redir]
142
142
  page << "window.location.href = '#{params[:redir]}';"
143
143
  end
144
+ if params[:reload]
145
+ page << "Zena.reload(#{params[:reload].inspect});"
146
+ end
144
147
  page << render_js(false)
145
148
  end
146
149
 
@@ -157,7 +160,12 @@ module Zena
157
160
  }});"
158
161
  end
159
162
 
160
- def add_toggle_id(dom_id, group_name, role)
163
+ def add_toggle_id(dom_id, group_name, role, opts = {})
164
+ arity = opts[:arity] || 'many'
165
+ if js = opts[:js]
166
+ js = ", js:function(e) { #{js} }"
167
+ end
168
+
161
169
  @toggle_ids ||= {}
162
170
  unless list = @toggle_ids[group_name]
163
171
  list = @toggle_ids[group_name] = []
@@ -168,13 +176,20 @@ module Zena
168
176
  found = []
169
177
  end
170
178
  url = "/nodes/#{other.zip}"
171
- js_data << "#{group_name} = {\"list\":#{found.inspect}, \"url\":#{url.inspect}, \"role\":#{role.inspect}};"
179
+ js_data << "#{group_name} = {list:#{found.inspect}, url:#{url.inspect}, role:#{role.inspect}, arity:#{arity.inspect}#{js}};"
172
180
  end
173
181
  list << dom_id
174
182
  end
175
183
 
176
- def filter_form(node, dom_id)
177
- js_data << %Q{new Form.Observer('#{dom_id}', 0.3, function(element, value) {new Ajax.Request('#{zafu_node_path(node)}', {asynchronous:true, evalScripts:true, method:'get', parameters:Form.serialize('#{dom_id}')})});}
184
+ def filter_form(node, dom_id, loading, upd)
185
+ if loading
186
+ loading = "\n#{loading}($('#{upd}'));"
187
+ else
188
+ loading = ''
189
+ end
190
+ js_data << %Q{new Form.Observer('#{dom_id}', 0.3, function(element, value) {#{loading}
191
+ new Ajax.Request('#{zafu_node_path(node)}', {asynchronous:true, evalScripts:true, method:'get', parameters:Form.serialize('#{dom_id}')})
192
+ });}
178
193
  end
179
194
 
180
195
  # Include draggable ids in bottom of page Javascript.
@@ -285,28 +300,35 @@ module Zena
285
300
 
286
301
  # Move up in case we are in a list.
287
302
  if self.node.list_context?
288
- node = self.node.up(Node)
289
- else
290
- node = self.node
291
- end
292
- node.dom_prefix = dom_name
293
- dom_id = node.dom_id(:erb => false)
294
-
295
- out %Q{<%= form_remote_tag(:url => zafu_node_path(#{node}), :method => :get, :html => {:id => \"#{dom_id}_f\"}) %>
296
- <div class='hidden'>
297
- <input type='hidden' name='t_url' value='#{template_url(upd)}'/>
298
- <input type='hidden' name='dom_id' value='#{upd}'/>
299
- <input type='hidden' name='s' value='<%= start_node_zip %>'/>
300
- </div><div class='wrapper'>
301
- }
302
- if @blocks == []
303
- out "<input type='text' name='#{@params[:key] || 'f'}' value='<%= params[#{(@params[:key] || 'f').to_sym.inspect}] %>'/>"
303
+ base_node = self.node.up(Node)
304
304
  else
305
- out expand_with(:in_filter => true)
305
+ base_node = self.node
306
306
  end
307
- out "</div></form>"
308
- if @params[:live] || @params[:update]
309
- out "<% filter_form(#{node}, \"#{dom_id}_f\") %>"
307
+
308
+ # Do not alter current node, create our own
309
+ with_context(:node => base_node.dup) do
310
+ node.dom_prefix = dom_name
311
+ dom_id = node.dom_id(:erb => false)
312
+
313
+ # TODO: add 'encode_params' and x='"foobar"' to add any value in the request
314
+ out %Q{<%= form_remote_tag(:url => zafu_node_path(#{node}), :method => :get, :html => {:id => \"#{dom_id}_f\"}) %>
315
+ <div class='hidden'>
316
+ <input type='hidden' name='t_url' value='#{template_url(upd)}'/>
317
+ <input type='hidden' name='dom_id' value='#{upd}'/>
318
+ <input type='hidden' name='s' value='<%= start_node_zip %>'/>
319
+ </div><div class='wrapper'>
320
+ }
321
+ if @blocks == []
322
+ out "<input type='text' name='#{@params[:key] || 'f'}' value='<%= params[#{(@params[:key] || 'f').to_sym.inspect}] %>'/>"
323
+ else
324
+ out expand_with(:in_filter => true)
325
+ end
326
+ out "</div></form>"
327
+ loading = @params[:loading]
328
+ loading = 'Zena.loading' if loading == 'true'
329
+ if @params[:live] || @params[:update]
330
+ out "<% filter_form(#{node}, \"#{dom_id}_f\", #{loading.inspect}, '#{upd}') %>"
331
+ end
310
332
  end
311
333
  end
312
334
 
@@ -370,7 +392,16 @@ module Zena
370
392
  dom_id = node.dom_id(:erb => false)
371
393
  markup.set_id(node.dom_id)
372
394
  markup.append_param(:class, 'toggle')
373
- out "<% add_toggle_id(\"#{dom_id}\", #{var.inspect}, #{RubyLess.translate_string(self, role)}) { #{finder} } %>#{expand_with}"
395
+ opts = {}
396
+ if arity = @params.delete(:arity)
397
+ opts[:arity] = arity
398
+ end
399
+
400
+ if js = @params.delete(:js)
401
+ opts[:js] = js
402
+ end
403
+
404
+ out "<% add_toggle_id(\"#{dom_id}\", #{var.inspect}, #{RubyLess.translate_string(self, role)},#{opts.inspect}) { #{finder} } %>#{expand_with}"
374
405
  end
375
406
 
376
407
  def process_toggle
@@ -400,7 +431,17 @@ module Zena
400
431
  markup.tag ||= 'div'
401
432
 
402
433
  markup.append_param(:class, 'toggle')
403
- markup.pre_wrap[:toggle] = "<% add_toggle_id(\"#{dom_id}\", #{"#{var}_tog".inspect}, #{RubyLess.translate_string(self, role)}) { #{finder} } %>"
434
+
435
+ opts = {}
436
+ if arity = @params.delete(:arity)
437
+ opts[:arity] = arity
438
+ end
439
+
440
+ if js = @params.delete(:js)
441
+ opts[:js] = js
442
+ end
443
+
444
+ markup.pre_wrap[:toggle] = "<% add_toggle_id(\"#{dom_id}\", #{"#{var}_tog".inspect}, #{RubyLess.translate_string(self, role)},#{opts.inspect}) { #{finder} } %>"
404
445
  end
405
446
 
406
447
  def r_unlink
@@ -453,7 +494,7 @@ module Zena
453
494
  #end
454
495
  end
455
496
 
456
- # Add some js at end of document/partial
497
+ # Execute javascript after page/partial load.
457
498
  def r_js
458
499
  if @blocks.detect {|b| !b.kind_of?(String)}
459
500
  out "<% js_data << capture do %>"
@@ -464,6 +505,13 @@ module Zena
464
505
  out "<% js_data << #{txt.inspect} %>"
465
506
  end
466
507
  end
508
+
509
+ # Only execute javascript on ajax.
510
+ def r_ajs
511
+ out "<% if params[:s] %>"
512
+ r_js
513
+ out "<% end %>"
514
+ end
467
515
 
468
516
  def r_ajax?
469
517
  r_if(RubyLess.translate(self, 'ajax?'))
@@ -16,10 +16,14 @@ module Zena
16
16
  module ControllerMethods
17
17
 
18
18
  def self.included(base)
19
- base.before_filter :set_visitor, :force_authentication?
19
+ base.before_filter :set_visitor, :force_authentication?, :redirect_to_https
20
20
  end
21
21
 
22
22
  include Common
23
+
24
+ def ssl_request?
25
+ request.ssl? || request.headers['X_FORWARDED_PROTO'] == 'https'
26
+ end
23
27
 
24
28
  private
25
29
 
@@ -132,6 +136,17 @@ module Zena
132
136
  end
133
137
  end
134
138
  end
139
+
140
+ # Force https if ssl_on_auth is enabled. This method is overwriten in UserSessionsController.
141
+ def redirect_to_https
142
+ if current_site.ssl_on_auth
143
+ if !ssl_request? && !visitor.is_anon? && !local_request?
144
+ redirect_to :protocol => "https://"
145
+ elsif ssl_request? && visitor.is_anon?
146
+ redirect_to :protocol => "http://"
147
+ end
148
+ end
149
+ end
135
150
  end
136
151
 
137
152
  module ViewMethods