imagine_cms 3.0.0.beta6 → 3.0.0.beta7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (278) hide show
  1. data/README.rdoc +1 -1
  2. data/app/assets/images/codepress/line-numbers.png +0 -0
  3. data/app/assets/images/cropper/marqueeHoriz.gif +0 -0
  4. data/app/assets/images/cropper/marqueeVert.gif +0 -0
  5. data/app/assets/images/management/btn_add.gif +0 -0
  6. data/app/assets/images/management/btn_archive.gif +0 -0
  7. data/app/assets/images/management/btn_delete.gif +0 -0
  8. data/app/assets/images/management/btn_duplicate.gif +0 -0
  9. data/app/assets/images/management/btn_edit.gif +0 -0
  10. data/app/assets/images/management/btn_help.gif +0 -0
  11. data/app/assets/images/management/btn_new_page.gif +0 -0
  12. data/app/assets/images/management/btn_preview.gif +0 -0
  13. data/app/assets/images/management/btn_properties.gif +0 -0
  14. data/app/assets/images/management/btn_restore.gif +0 -0
  15. data/app/assets/images/management/btn_top_delete.gif +0 -0
  16. data/app/assets/images/management/btn_top_duplicate.gif +0 -0
  17. data/app/assets/images/management/btn_top_edit.gif +0 -0
  18. data/app/assets/images/management/btn_top_new.gif +0 -0
  19. data/app/assets/images/management/btn_top_preview.gif +0 -0
  20. data/app/assets/images/management/btn_top_properties.gif +0 -0
  21. data/app/assets/{manage → images/management}/bullet.gif +0 -0
  22. data/app/assets/images/management/cvv2_graphic.gif +0 -0
  23. data/app/assets/images/management/error.gif +0 -0
  24. data/app/assets/images/management/gallery_index.gif +0 -0
  25. data/app/assets/images/management/gallery_preview_overlay.png +0 -0
  26. data/app/assets/images/management/gallery_small_drag_overlay.png +0 -0
  27. data/app/assets/images/management/gallery_small_overlay.png +0 -0
  28. data/app/assets/images/management/gallery_sort.gif +0 -0
  29. data/app/assets/images/management/icon_download.gif +0 -0
  30. data/app/assets/images/management/icon_locked.png +0 -0
  31. data/app/assets/images/management/icon_page.gif +0 -0
  32. data/app/assets/images/management/icon_time.gif +0 -0
  33. data/app/assets/images/management/icon_unlocked.png +0 -0
  34. data/app/assets/images/management/page_loading.gif +0 -0
  35. data/app/assets/{manage → images/management}/start.gif +0 -0
  36. data/app/assets/images/management/vcard.gif +0 -0
  37. data/app/assets/javascripts/builder.js +101 -0
  38. data/app/assets/javascripts/codepress/codepress.html +36 -0
  39. data/app/assets/javascripts/codepress/codepress.js +130 -0
  40. data/app/assets/javascripts/codepress/engines/gecko.js +240 -0
  41. data/{vendor/gems/acts_as_tree/test/abstract_unit.rb → app/assets/javascripts/codepress/engines/khtml.js} +0 -0
  42. data/app/assets/javascripts/codepress/engines/msie.js +263 -0
  43. data/{vendor/gems/acts_as_tree/test/database.yml → app/assets/javascripts/codepress/engines/older.js} +0 -0
  44. data/app/assets/javascripts/codepress/engines/opera.js +259 -0
  45. data/app/assets/javascripts/codepress/languages/css.js +23 -0
  46. data/app/assets/javascripts/codepress/languages/generic.js +25 -0
  47. data/app/assets/javascripts/codepress/languages/html.js +63 -0
  48. data/app/assets/javascripts/codepress/languages/java.js +24 -0
  49. data/app/assets/javascripts/codepress/languages/javascript.js +30 -0
  50. data/app/assets/javascripts/codepress/languages/perl.js +27 -0
  51. data/app/assets/javascripts/codepress/languages/php.js +60 -0
  52. data/app/assets/javascripts/codepress/languages/ruby.js +26 -0
  53. data/app/assets/javascripts/codepress/languages/sql.js +30 -0
  54. data/app/assets/javascripts/codepress/languages/text.js +9 -0
  55. data/app/assets/javascripts/cropper.js +568 -0
  56. data/app/assets/javascripts/dojo/dojo.js +14155 -0
  57. data/app/assets/javascripts/dojo/src/html/images/shadowB.png +0 -0
  58. data/app/assets/javascripts/dojo/src/html/images/shadowBL.png +0 -0
  59. data/app/assets/javascripts/dojo/src/html/images/shadowBR.png +0 -0
  60. data/app/assets/javascripts/dojo/src/html/images/shadowL.png +0 -0
  61. data/app/assets/javascripts/dojo/src/html/images/shadowR.png +0 -0
  62. data/app/assets/javascripts/dojo/src/html/images/shadowT.png +0 -0
  63. data/app/assets/javascripts/dojo/src/html/images/shadowTL.png +0 -0
  64. data/app/assets/javascripts/dojo/src/html/images/shadowTR.png +0 -0
  65. data/app/assets/javascripts/dojo/src/widget/templates/Editor2/showtableborder_gecko.css +19 -0
  66. data/app/assets/javascripts/dojo/src/widget/templates/HslColorPicker.svg +30 -0
  67. data/app/assets/javascripts/dojo/src/widget/templates/buttons/aggregate.gif +0 -0
  68. data/app/assets/javascripts/dojo/src/widget/templates/buttons/aggregate.psd +0 -0
  69. data/app/assets/javascripts/dojo/src/widget/templates/buttons/backcolor.gif +0 -0
  70. data/app/assets/javascripts/dojo/src/widget/templates/buttons/bg-fade.png +0 -0
  71. data/app/assets/javascripts/dojo/src/widget/templates/buttons/bold.gif +0 -0
  72. data/app/assets/javascripts/dojo/src/widget/templates/buttons/cancel.gif +0 -0
  73. data/app/assets/javascripts/dojo/src/widget/templates/buttons/copy.gif +0 -0
  74. data/app/assets/javascripts/dojo/src/widget/templates/buttons/createlink.gif +0 -0
  75. data/app/assets/javascripts/dojo/src/widget/templates/buttons/cut.gif +0 -0
  76. data/app/assets/javascripts/dojo/src/widget/templates/buttons/delete.gif +0 -0
  77. data/app/assets/javascripts/dojo/src/widget/templates/buttons/forecolor.gif +0 -0
  78. data/app/assets/javascripts/dojo/src/widget/templates/buttons/hilitecolor.gif +0 -0
  79. data/app/assets/javascripts/dojo/src/widget/templates/buttons/indent.gif +0 -0
  80. data/app/assets/javascripts/dojo/src/widget/templates/buttons/inserthorizontalrule.gif +0 -0
  81. data/app/assets/javascripts/dojo/src/widget/templates/buttons/insertimage.gif +0 -0
  82. data/app/assets/javascripts/dojo/src/widget/templates/buttons/insertorderedlist.gif +0 -0
  83. data/app/assets/javascripts/dojo/src/widget/templates/buttons/inserttable.gif +0 -0
  84. data/app/assets/javascripts/dojo/src/widget/templates/buttons/insertunorderedlist.gif +0 -0
  85. data/app/assets/javascripts/dojo/src/widget/templates/buttons/italic.gif +0 -0
  86. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifycenter.gif +0 -0
  87. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifyfull.gif +0 -0
  88. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifyleft.gif +0 -0
  89. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifyright.gif +0 -0
  90. data/app/assets/javascripts/dojo/src/widget/templates/buttons/left_to_right.gif +0 -0
  91. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_bullet_indent.gif +0 -0
  92. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_bullet_outdent.gif +0 -0
  93. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_num_indent.gif +0 -0
  94. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_num_outdent.gif +0 -0
  95. data/app/assets/javascripts/dojo/src/widget/templates/buttons/outdent.gif +0 -0
  96. data/app/assets/javascripts/dojo/src/widget/templates/buttons/paste.gif +0 -0
  97. data/app/assets/javascripts/dojo/src/widget/templates/buttons/redo.gif +0 -0
  98. data/app/assets/javascripts/dojo/src/widget/templates/buttons/removeformat.gif +0 -0
  99. data/app/assets/javascripts/dojo/src/widget/templates/buttons/right_to_left.gif +0 -0
  100. data/app/assets/javascripts/dojo/src/widget/templates/buttons/save.gif +0 -0
  101. data/app/assets/javascripts/dojo/src/widget/templates/buttons/sep.gif +0 -0
  102. data/app/assets/javascripts/dojo/src/widget/templates/buttons/space.gif +0 -0
  103. data/app/assets/javascripts/dojo/src/widget/templates/buttons/strikethrough.gif +0 -0
  104. data/app/assets/javascripts/dojo/src/widget/templates/buttons/subscript.gif +0 -0
  105. data/app/assets/javascripts/dojo/src/widget/templates/buttons/superscript.gif +0 -0
  106. data/app/assets/javascripts/dojo/src/widget/templates/buttons/underline.gif +0 -0
  107. data/app/assets/javascripts/dojo/src/widget/templates/buttons/undo.gif +0 -0
  108. data/app/assets/javascripts/dojo/src/widget/templates/buttons/wikiword.gif +0 -0
  109. data/app/assets/javascripts/dojo/src/widget/templates/check.gif +0 -0
  110. data/app/assets/javascripts/dojo/src/widget/templates/decrementMonth.gif +0 -0
  111. data/app/assets/javascripts/dojo/src/widget/templates/decrementWeek.gif +0 -0
  112. data/app/assets/javascripts/dojo/src/widget/templates/grabCorner.gif +0 -0
  113. data/app/assets/javascripts/dojo/src/widget/templates/images/floatingPaneClose.gif +0 -0
  114. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaAccordionOff.gif +0 -0
  115. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaAccordionSelected.gif +0 -0
  116. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaActive-c.gif +0 -0
  117. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaActive-l.gif +0 -0
  118. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaActive-r.gif +0 -0
  119. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaBarBg.gif +0 -0
  120. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaButton-c.gif +0 -0
  121. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaButton-l.gif +0 -0
  122. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaButton-r.gif +0 -0
  123. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaDisabled-c.gif +0 -0
  124. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaDisabled-l.gif +0 -0
  125. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaDisabled-r.gif +0 -0
  126. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaMenuBg.gif +0 -0
  127. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaPressed-c.gif +0 -0
  128. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaPressed-l.gif +0 -0
  129. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaPressed-r.gif +0 -0
  130. data/app/assets/javascripts/dojo/src/widget/templates/images/tab_close.gif +0 -0
  131. data/app/assets/javascripts/dojo/src/widget/templates/images/toolbar-bg.gif +0 -0
  132. data/app/assets/javascripts/dojo/src/widget/templates/incrementMonth.gif +0 -0
  133. data/app/assets/javascripts/dojo/src/widget/templates/incrementWeek.gif +0 -0
  134. data/app/assets/javascripts/dojo/src/widget/templates/richtextframe.html +24 -0
  135. data/app/assets/javascripts/imagine.js +1385 -0
  136. data/app/assets/javascripts/jquery_no_conflict.js +9405 -0
  137. data/app/assets/stylesheets/codepress/codepress.css +7 -0
  138. data/app/assets/stylesheets/codepress/languages/css.css +10 -0
  139. data/app/assets/stylesheets/codepress/languages/generic.css +9 -0
  140. data/app/assets/stylesheets/codepress/languages/html.css +18 -0
  141. data/app/assets/stylesheets/codepress/languages/java.css +7 -0
  142. data/app/assets/stylesheets/codepress/languages/javascript.css +8 -0
  143. data/app/assets/stylesheets/codepress/languages/perl.css +11 -0
  144. data/app/assets/stylesheets/codepress/languages/php.css +12 -0
  145. data/app/assets/stylesheets/codepress/languages/ruby.css +10 -0
  146. data/app/assets/stylesheets/codepress/languages/sql.css +10 -0
  147. data/app/assets/stylesheets/codepress/languages/text.css +5 -0
  148. data/app/assets/stylesheets/cropper.css +182 -0
  149. data/app/assets/stylesheets/management.css +96 -0
  150. data/app/assets/stylesheets/reset.css +58 -0
  151. data/app/controllers/cms/content_controller.rb +318 -2
  152. data/app/controllers/management/cms_controller.rb +1669 -0
  153. data/app/controllers/management/user_controller.rb +4 -4
  154. data/app/controllers/management/users_controller.rb +18 -4
  155. data/app/controllers/util_controller.rb +45 -0
  156. data/app/helpers/cms_application_helper.rb +662 -15
  157. data/app/models/cms_content_sweeper.rb +21 -0
  158. data/app/models/cms_page.rb +126 -0
  159. data/app/models/cms_page_object.rb +23 -0
  160. data/app/models/cms_page_tag.rb +5 -0
  161. data/app/models/cms_page_version.rb +3 -0
  162. data/app/models/cms_snippet.rb +16 -0
  163. data/app/models/cms_template.rb +29 -0
  164. data/app/models/user.rb +6 -3
  165. data/app/views/management/cms/_complete_gallery.html.erb +5 -0
  166. data/app/views/management/cms/_create_file_link.html.erb +21 -0
  167. data/app/views/management/cms/_crop_feature_image.html.erb +188 -0
  168. data/app/views/management/cms/_crop_image.html.erb +188 -0
  169. data/app/views/management/cms/_crop_results.html.erb +1 -0
  170. data/app/views/management/cms/_crop_results_feature_image.html.erb +1 -0
  171. data/app/views/management/cms/_crop_results_thumb.html.erb +1 -0
  172. data/app/views/management/cms/_crop_thumb.html.erb +188 -0
  173. data/app/views/management/cms/_dialogs.html.erb +39 -0
  174. data/app/views/management/cms/_edit_page.html.erb +176 -0
  175. data/app/views/management/cms/_gallery_index.html.erb +10 -0
  176. data/app/views/management/cms/_gallery_setup.html.erb +22 -0
  177. data/app/views/management/cms/_image.html.erb +3 -0
  178. data/app/views/management/cms/_image_details.html.erb +26 -0
  179. data/app/views/management/cms/_image_draggable.html.erb +4 -0
  180. data/app/views/management/cms/_list_page.html.erb +8 -0
  181. data/app/views/management/cms/_list_page_select.html.erb +8 -0
  182. data/app/views/management/cms/_list_pages.html.erb +1 -0
  183. data/app/views/management/cms/_list_pages_select.html.erb +1 -0
  184. data/app/views/management/cms/_page_attribute.html.erb +6 -0
  185. data/app/views/management/cms/_page_list.html.erb +171 -0
  186. data/app/views/management/cms/_page_list_source_folder.html.erb +20 -0
  187. data/app/views/management/cms/_page_list_source_tag.html.erb +18 -0
  188. data/app/views/management/cms/_select_gallery.html.erb +117 -0
  189. data/app/views/management/cms/_snippet.html.erb +3 -0
  190. data/app/views/management/cms/_sort_images.html.erb +15 -0
  191. data/app/views/management/cms/_temp.html.erb +3 -0
  192. data/app/views/management/cms/_template_options.html.erb +21 -0
  193. data/app/views/management/cms/_template_reference.html.erb +42 -0
  194. data/app/views/management/cms/_upload_feature_image.html.erb +35 -0
  195. data/app/views/management/cms/_upload_file.html.erb +31 -0
  196. data/app/views/management/cms/_upload_image.html.erb +74 -0
  197. data/app/views/management/cms/_upload_thumb.html.erb +35 -0
  198. data/app/views/management/cms/edit_master.html.erb +48 -0
  199. data/app/views/management/cms/edit_page_content.html.erb +4 -0
  200. data/app/views/management/cms/edit_snippet.html.erb +47 -0
  201. data/app/views/management/cms/edit_template.html.erb +48 -0
  202. data/app/views/management/cms/gallery_management.html.erb +108 -0
  203. data/app/views/management/cms/index.html.erb +20 -0
  204. data/app/views/management/cms/page_tags_for_lookup.html.erb +5 -0
  205. data/app/views/management/cms/pages.html.erb +99 -0
  206. data/app/views/management/cms/permission_denied.html.erb +1 -0
  207. data/app/views/management/cms/select_page.html.erb +57 -0
  208. data/app/views/management/cms/snippets.html.erb +14 -0
  209. data/app/views/management/cms/templates.html.erb +14 -0
  210. data/app/views/management/cms/toolbar_edit.html.erb +269 -0
  211. data/app/views/management/cms/toolbar_preview.html.erb +109 -0
  212. data/app/views/util/_calendar_days.html.erb +72 -0
  213. data/app/views/util/_calendar_month_year.html.erb +1 -0
  214. data/app/views/util/_date_picker.html.erb +56 -0
  215. data/app/views/util/_message.html.erb +1 -0
  216. data/app/views/util/_show_message.js.erb +6 -0
  217. data/app/views/util/_tab.html.erb +4 -0
  218. data/config/routes.rb +4 -1
  219. data/imagine_cms.gemspec +4 -0
  220. data/{vendor/gems → lib}/acts_as_versioned/.document +0 -0
  221. data/{vendor/gems → lib}/acts_as_versioned/.gitignore +2 -0
  222. data/{vendor/gems → lib}/acts_as_versioned/CHANGELOG +0 -0
  223. data/lib/acts_as_versioned/Gemfile +7 -0
  224. data/{vendor/gems → lib}/acts_as_versioned/MIT-LICENSE +0 -0
  225. data/{vendor/gems → lib}/acts_as_versioned/README +0 -0
  226. data/{vendor/gems → lib}/acts_as_versioned/RUNNING_UNIT_TESTS +0 -0
  227. data/{vendor/gems → lib}/acts_as_versioned/Rakefile +1 -1
  228. data/{vendor/gems → lib}/acts_as_versioned/acts_as_versioned.gemspec +4 -4
  229. data/{vendor/gems → lib}/acts_as_versioned/init.rb +0 -0
  230. data/{vendor/gems → lib}/acts_as_versioned/lib/acts_as_versioned.rb +109 -107
  231. data/{vendor/gems → lib}/acts_as_versioned/test/abstract_unit.rb +0 -0
  232. data/{vendor/gems → lib}/acts_as_versioned/test/database.yml +0 -0
  233. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/authors.yml +0 -0
  234. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/landmark.rb +0 -0
  235. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/landmark_versions.yml +0 -0
  236. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/landmarks.yml +0 -0
  237. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/locked_pages.yml +0 -0
  238. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/locked_pages_revisions.yml +0 -0
  239. data/{vendor/gems/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb → lib/acts_as_versioned/test/fixtures/migrations/2_add_versioned_tables.rb} +0 -0
  240. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/page.rb +0 -0
  241. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/page_versions.yml +0 -0
  242. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/pages.yml +0 -0
  243. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/widget.rb +0 -0
  244. data/{vendor/gems → lib}/acts_as_versioned/test/migration_test.rb +0 -1
  245. data/{vendor/gems → lib}/acts_as_versioned/test/schema.rb +0 -0
  246. data/{vendor/gems → lib}/acts_as_versioned/test/versioned_test.rb +0 -0
  247. data/lib/extensions/action_controller.rb +154 -143
  248. data/lib/imagine_cms/engine.rb +33 -12
  249. data/lib/imagine_cms/version.rb +1 -1
  250. data/lib/imagine_cms.rb +30 -6
  251. data/lib/prototype_legacy_helper/README.markdown +13 -0
  252. data/lib/prototype_legacy_helper/init.rb +1 -0
  253. data/lib/prototype_legacy_helper/lib/prototype_legacy_helper.rb +430 -0
  254. data/lib/prototype_legacy_helper/test/test_prototype_helper.rb +297 -0
  255. data/lib/upload_progress/CHANGELOG +5 -0
  256. data/lib/upload_progress/MIT-LICENSE +20 -0
  257. data/lib/upload_progress/README +45 -0
  258. data/{vendor/gems/acts_as_tree → lib/upload_progress}/Rakefile +6 -5
  259. data/lib/upload_progress/init.rb +7 -0
  260. data/lib/upload_progress/lib/multipart_progress.rb +176 -0
  261. data/lib/upload_progress/lib/progress.rb +145 -0
  262. data/lib/upload_progress/lib/upload_progress.rb +303 -0
  263. data/lib/upload_progress/lib/upload_progress_helper.rb +425 -0
  264. data/lib/upload_progress/public/stylesheets/upload_progress.css +21 -0
  265. data/lib/upload_progress/test/multipart_progress_testx.rb +364 -0
  266. data/lib/upload_progress/test/upload_progress_helper_testx.rb +134 -0
  267. data/lib/upload_progress/test/upload_progress_testx.rb +88 -0
  268. metadata +305 -43
  269. data/app/assets/manage/btn_delete.gif +0 -0
  270. data/vendor/gems/.DS_Store +0 -0
  271. data/vendor/gems/acts_as_tree/README +0 -26
  272. data/vendor/gems/acts_as_tree/init.rb +0 -1
  273. data/vendor/gems/acts_as_tree/lib/active_record/acts/tree.rb +0 -96
  274. data/vendor/gems/acts_as_tree/test/acts_as_tree_test.rb +0 -219
  275. data/vendor/gems/acts_as_tree/test/fixtures/mixin.rb +0 -0
  276. data/vendor/gems/acts_as_tree/test/fixtures/mixins.yml +0 -0
  277. data/vendor/gems/acts_as_tree/test/schema.rb +0 -0
  278. data/vendor/gems/acts_as_versioned/Gemfile +0 -7
@@ -6,10 +6,30 @@ module ImagineCms
6
6
  config.app_root = root
7
7
  middleware.use ::ActionDispatch::Static, "#{root}/public"
8
8
 
9
+ initializer :assets do |config|
10
+ Rails.application.config.assets.precompile += %w( codepress/** dojo/** manage.css )
11
+ end
12
+
9
13
  #
10
- # load unusual gems
14
+ # activate gems as needed
11
15
  #
16
+ require 'prototype-rails'
17
+ # require 'redactor-rails'
18
+ require 'mini_magick'
19
+ require 'rails_rinku'
12
20
  require 'net/dns'
21
+ require 'acts_as_tree'
22
+
23
+ #
24
+ # rails plugins
25
+ #
26
+ require 'acts_as_versioned/lib/acts_as_versioned'
27
+ require 'prototype_legacy_helper/lib/prototype_legacy_helper'
28
+
29
+ require 'upload_progress/lib/multipart_progress'
30
+ require 'upload_progress/lib/progress'
31
+ require 'upload_progress/lib/upload_progress'
32
+ require 'upload_progress/lib/upload_progress_helper'
13
33
 
14
34
  #
15
35
  # load provided classes
@@ -27,20 +47,21 @@ module ImagineCms
27
47
  extend ActionControllerExtensions::ClassMethods
28
48
  include ActionControllerExtensions::InstanceMethods
29
49
 
50
+ include UploadProgress
51
+ helper UploadProgress::UploadProgressHelper
52
+
53
+ # include + helper: allow use both in controllers and views
54
+
55
+ include PrototypeHelper # from prototype_legacy_helper
56
+ helper PrototypeHelper
57
+
58
+ include CmsApplicationHelper
30
59
  helper CmsApplicationHelper
31
- helper_method :user_has_permission?
32
- helper_method :user_has_permissions?
33
- helper_method :template_exists?
34
- helper_method :url_for_current
35
- helper_method :gm_to_local
36
- helper_method :local_to_gm
37
- helper_method :ts_to_str
38
- helper_method :ts_to_time_str
39
- helper_method :time_to_str
40
- helper_method :date_to_str
60
+
61
+ helper_method :insert_object
41
62
 
42
63
  # before_filter :create_settings_object, :set_default_session_values, :check_ssl_requirement, :expire_session_data
43
- # after_filter :compress_output
64
+ before_filter :expire_session_data
44
65
  end
45
66
  end
46
67
 
@@ -1,3 +1,3 @@
1
1
  module ImagineCms
2
- VERSION = "3.0.0.beta6"
2
+ VERSION = "3.0.0.beta7"
3
3
  end
data/lib/imagine_cms.rb CHANGED
@@ -16,9 +16,33 @@ end
16
16
  require "imagine_cms/engine"
17
17
 
18
18
 
19
- # Require vendored gems
20
- # $:.push File.expand_path("../../vendor/gems", __FILE__)
21
- # $:.push File.expand_path("../../vendor/gems/acts_as_tree/lib", __FILE__)
22
- # require "acts_as_tree/init"
23
- # $:.push File.expand_path("../../vendor/gems/acts_as_versioned/lib", __FILE__)
24
- # require "acts_as_versioned/init"
19
+ #
20
+ # define constants related to configurable behaviors (change to proper config.imagine_cms.X later)
21
+ #
22
+
23
+ # Shouldn't need to adjust these
24
+ ContentIgnoreDirectories = [ '.svn', 'CVS' ] unless defined? ContentIgnoreDirectories
25
+ ContentIgnoreFilesRE = /^\./ unless defined? ContentIgnoreFilesRE
26
+ ContentExcludeFiles = [ 'index' ] unless defined? ContentExcludeFiles
27
+ UseCmsPageCaching = false unless defined? UseCmsPageCaching
28
+ # UseCmsPageDatabase = CmsPage.table_exists? unless defined? UseCmsPageDatabase
29
+ UseCmsAccessLevels = false unless defined? UseCmsAccessLevels
30
+ EnableAssetTimestamping = true unless defined? EnableAssetTimestamping
31
+
32
+ # CMS gallery setup
33
+ GalleryMaxWidth = 586 unless defined? GalleryMaxWidth
34
+ GalleryMaxHeight = 400 unless defined? GalleryMaxHeight
35
+ GalleryThumbWidth = 50 unless defined? GalleryThumbWidth
36
+ GalleryThumbHeight = 50 unless defined? GalleryThumbHeight
37
+
38
+ # SSL settings
39
+ SSL_REDIRECTS_ON = false unless defined?(SSL_REDIRECTS_ON)
40
+ SSL_STANDARD_HOST = 'localhost' unless defined?(SSL_STANDARD_HOST)
41
+ SSL_SECURE_HOST = '127.0.0.1' unless defined?(SSL_SECURE_HOST)
42
+ # if using non-standard ports, also set these:
43
+ # SSL_STANDARD_PORT = 80
44
+ # SSL_SECURE_PORT = 443
45
+
46
+ # Member component
47
+ Member_AllowEmailAsLogin = true unless defined? Member_AllowEmailAsLogin
48
+ Member_RequireMembername = false unless defined? Member_RequireMembername
@@ -0,0 +1,13 @@
1
+ # Prototype Legacy Helper
2
+
3
+ This plugin adds support for `form_remote_tag`, etc from Rails 2 to Rails 3.
4
+
5
+ ## Installation
6
+
7
+ Either add the following to your `Gemfile` and run `bundle`:
8
+
9
+ gem 'prototype_legacy_helper', '0.0.0', :git => 'git://github.com/rails/prototype_legacy_helper.git'
10
+
11
+ or run the following command to vendor the plugin within your app:
12
+
13
+ rails plugin install git://github.com/rails/prototype_legacy_helper.git
@@ -0,0 +1 @@
1
+ require 'prototype_legacy_helper'
@@ -0,0 +1,430 @@
1
+ module PrototypeHelper
2
+ # Creates a button with an onclick event which calls a remote action
3
+ # via XMLHttpRequest
4
+ # The options for specifying the target with :url
5
+ # and defining callbacks is the same as link_to_remote.
6
+ def button_to_remote(name, options = {}, html_options = {})
7
+ button_to_function(name, remote_function(options), html_options)
8
+ end
9
+
10
+ # Returns a button input tag with the element name of +name+ and a value (i.e., display text) of +value+
11
+ # that will submit form using XMLHttpRequest in the background instead of a regular POST request that
12
+ # reloads the page.
13
+ #
14
+ # # Create a button that submits to the create action
15
+ # #
16
+ # # Generates: <input name="create_btn" onclick="new Ajax.Request('/testing/create',
17
+ # # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
18
+ # # return false;" type="button" value="Create" />
19
+ # <%= submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' } %>
20
+ #
21
+ # # Submit to the remote action update and update the DIV succeed or fail based
22
+ # # on the success or failure of the request
23
+ # #
24
+ # # Generates: <input name="update_btn" onclick="new Ajax.Updater({success:'succeed',failure:'fail'},
25
+ # # '/testing/update', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
26
+ # # return false;" type="button" value="Update" />
27
+ # <%= submit_to_remote 'update_btn', 'Update', :url => { :action => 'update' },
28
+ # :update => { :success => "succeed", :failure => "fail" }
29
+ #
30
+ # <tt>options</tt> argument is the same as in form_remote_tag.
31
+ def submit_to_remote(name, value, options = {})
32
+ options[:with] ||= 'Form.serialize(this.form)'
33
+
34
+ html_options = options.delete(:html) || {}
35
+ html_options[:name] = name
36
+
37
+ button_to_remote(value, options, html_options)
38
+ end
39
+
40
+ # Returns a link to a remote action defined by <tt>options[:url]</tt>
41
+ # (using the url_for format) that's called in the background using
42
+ # XMLHttpRequest. The result of that request can then be inserted into a
43
+ # DOM object whose id can be specified with <tt>options[:update]</tt>.
44
+ # Usually, the result would be a partial prepared by the controller with
45
+ # render :partial.
46
+ #
47
+ # Examples:
48
+ # # Generates: <a href="#" onclick="new Ajax.Updater('posts', '/blog/destroy/3', {asynchronous:true, evalScripts:true});
49
+ # # return false;">Delete this post</a>
50
+ # link_to_remote "Delete this post", :update => "posts",
51
+ # :url => { :action => "destroy", :id => post.id }
52
+ #
53
+ # # Generates: <a href="#" onclick="new Ajax.Updater('emails', '/mail/list_emails', {asynchronous:true, evalScripts:true});
54
+ # # return false;"><img alt="Refresh" src="/assets/refresh.png?" /></a>
55
+ # link_to_remote(image_tag("refresh"), :update => "emails",
56
+ # :url => { :action => "list_emails" })
57
+ #
58
+ # You can override the generated HTML options by specifying a hash in
59
+ # <tt>options[:html]</tt>.
60
+ #
61
+ # link_to_remote "Delete this post", :update => "posts",
62
+ # :url => post_url(@post), :method => :delete,
63
+ # :html => { :class => "destructive" }
64
+ #
65
+ # You can also specify a hash for <tt>options[:update]</tt> to allow for
66
+ # easy redirection of output to an other DOM element if a server-side
67
+ # error occurs:
68
+ #
69
+ # Example:
70
+ # # Generates: <a href="#" onclick="new Ajax.Updater({success:'posts',failure:'error'}, '/blog/destroy/5',
71
+ # # {asynchronous:true, evalScripts:true}); return false;">Delete this post</a>
72
+ # link_to_remote "Delete this post",
73
+ # :url => { :action => "destroy", :id => post.id },
74
+ # :update => { :success => "posts", :failure => "error" }
75
+ #
76
+ # Optionally, you can use the <tt>options[:position]</tt> parameter to
77
+ # influence how the target DOM element is updated. It must be one of
78
+ # <tt>:before</tt>, <tt>:top</tt>, <tt>:bottom</tt>, or <tt>:after</tt>.
79
+ #
80
+ # The method used is by default POST. You can also specify GET or you
81
+ # can simulate PUT or DELETE over POST. All specified with <tt>options[:method]</tt>
82
+ #
83
+ # Example:
84
+ # # Generates: <a href="#" onclick="new Ajax.Request('/person/4', {asynchronous:true, evalScripts:true, method:'delete'});
85
+ # # return false;">Destroy</a>
86
+ # link_to_remote "Destroy", :url => person_url(:id => person), :method => :delete
87
+ #
88
+ # By default, these remote requests are processed asynchronous during
89
+ # which various JavaScript callbacks can be triggered (for progress
90
+ # indicators and the likes). All callbacks get access to the
91
+ # <tt>request</tt> object, which holds the underlying XMLHttpRequest.
92
+ #
93
+ # To access the server response, use <tt>request.responseText</tt>, to
94
+ # find out the HTTP status, use <tt>request.status</tt>.
95
+ #
96
+ # Example:
97
+ # # Generates: <a href="#" onclick="new Ajax.Request('/words/undo?n=33', {asynchronous:true, evalScripts:true,
98
+ # # onComplete:function(request){undoRequestCompleted(request)}}); return false;">hello</a>
99
+ # word = 'hello'
100
+ # link_to_remote word,
101
+ # :url => { :action => "undo", :n => word_counter },
102
+ # :complete => "undoRequestCompleted(request)"
103
+ #
104
+ # The callbacks that may be specified are (in order):
105
+ #
106
+ # <tt>:loading</tt>:: Called when the remote document is being
107
+ # loaded with data by the browser.
108
+ # <tt>:loaded</tt>:: Called when the browser has finished loading
109
+ # the remote document.
110
+ # <tt>:interactive</tt>:: Called when the user can interact with the
111
+ # remote document, even though it has not
112
+ # finished loading.
113
+ # <tt>:success</tt>:: Called when the XMLHttpRequest is completed,
114
+ # and the HTTP status code is in the 2XX range.
115
+ # <tt>:failure</tt>:: Called when the XMLHttpRequest is completed,
116
+ # and the HTTP status code is not in the 2XX
117
+ # range.
118
+ # <tt>:complete</tt>:: Called when the XMLHttpRequest is complete
119
+ # (fires after success/failure if they are
120
+ # present).
121
+ #
122
+ # You can further refine <tt>:success</tt> and <tt>:failure</tt> by
123
+ # adding additional callbacks for specific status codes.
124
+ #
125
+ # Example:
126
+ # # Generates: <a href="#" onclick="new Ajax.Request('/testing/action', {asynchronous:true, evalScripts:true,
127
+ # # on404:function(request){alert('Not found...? Wrong URL...?')},
128
+ # # onFailure:function(request){alert('HTTP Error ' + request.status + '!')}}); return false;">hello</a>
129
+ # link_to_remote word,
130
+ # :url => { :action => "action" },
131
+ # 404 => "alert('Not found...? Wrong URL...?')",
132
+ # :failure => "alert('HTTP Error ' + request.status + '!')"
133
+ #
134
+ # A status code callback overrides the success/failure handlers if
135
+ # present.
136
+ #
137
+ # If you for some reason or another need synchronous processing (that'll
138
+ # block the browser while the request is happening), you can specify
139
+ # <tt>options[:type] = :synchronous</tt>.
140
+ #
141
+ # You can customize further browser side call logic by passing in
142
+ # JavaScript code snippets via some optional parameters. In their order
143
+ # of use these are:
144
+ #
145
+ # <tt>:confirm</tt>:: Adds confirmation dialog.
146
+ # <tt>:condition</tt>:: Perform remote request conditionally
147
+ # by this expression. Use this to
148
+ # describe browser-side conditions when
149
+ # request should not be initiated.
150
+ # <tt>:before</tt>:: Called before request is initiated.
151
+ # <tt>:after</tt>:: Called immediately after request was
152
+ # initiated and before <tt>:loading</tt>.
153
+ # <tt>:submit</tt>:: Specifies the DOM element ID that's used
154
+ # as the parent of the form elements. By
155
+ # default this is the current form, but
156
+ # it could just as well be the ID of a
157
+ # table row or any other DOM element.
158
+ # <tt>:with</tt>:: A JavaScript expression specifying
159
+ # the parameters for the XMLHttpRequest.
160
+ # Any expressions should return a valid
161
+ # URL query string.
162
+ #
163
+ # Example:
164
+ #
165
+ # :with => "'name=' + $('name').value"
166
+ #
167
+ # You can generate a link that uses AJAX in the general case, while
168
+ # degrading gracefully to plain link behavior in the absence of
169
+ # JavaScript by setting <tt>html_options[:href]</tt> to an alternate URL.
170
+ # Note the extra curly braces around the <tt>options</tt> hash separate
171
+ # it as the second parameter from <tt>html_options</tt>, the third.
172
+ #
173
+ # Example:
174
+ # link_to_remote "Delete this post",
175
+ # { :update => "posts", :url => { :action => "destroy", :id => post.id } },
176
+ # :href => url_for(:action => "destroy", :id => post.id)
177
+ def link_to_remote(name, options = {}, html_options = nil)
178
+ link_to_function(name, remote_function(options), html_options || options.delete(:html))
179
+ end
180
+
181
+ # Returns a form tag that will submit using XMLHttpRequest in the
182
+ # background instead of the regular reloading POST arrangement. Even
183
+ # though it's using JavaScript to serialize the form elements, the form
184
+ # submission will work just like a regular submission as viewed by the
185
+ # receiving side (all elements available in <tt>params</tt>). The options for
186
+ # specifying the target with <tt>:url</tt> and defining callbacks is the same as
187
+ # +link_to_remote+.
188
+ #
189
+ # A "fall-through" target for browsers that doesn't do JavaScript can be
190
+ # specified with the <tt>:action</tt>/<tt>:method</tt> options on <tt>:html</tt>.
191
+ #
192
+ # Example:
193
+ # # Generates:
194
+ # # <form action="/some/place" method="post" onsubmit="new Ajax.Request('',
195
+ # # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">
196
+ # form_remote_tag :html => { :action =>
197
+ # url_for(:controller => "some", :action => "place") }
198
+ #
199
+ # The Hash passed to the <tt>:html</tt> key is equivalent to the options (2nd)
200
+ # argument in the FormTagHelper.form_tag method.
201
+ #
202
+ # By default the fall-through action is the same as the one specified in
203
+ # the <tt>:url</tt> (and the default method is <tt>:post</tt>).
204
+ #
205
+ # form_remote_tag also takes a block, like form_tag:
206
+ # # Generates:
207
+ # # <form action="/" method="post" onsubmit="new Ajax.Request('/',
208
+ # # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)});
209
+ # # return false;"> <div><input name="commit" type="submit" value="Save" /></div>
210
+ # # </form>
211
+ # <%= form_remote_tag :url => '/posts' do -%>
212
+ # <div><%= submit_tag 'Save' %></div>
213
+ # <% end -%>
214
+ def form_remote_tag(options = {}, &block)
215
+ options[:form] = true
216
+
217
+ options[:html] ||= {}
218
+ options[:html][:onsubmit] =
219
+ (options[:html][:onsubmit] ? options[:html][:onsubmit] + "; " : "") +
220
+ "#{remote_function(options)}; return false;"
221
+
222
+ form_tag(options[:html].delete(:action) || url_for(options[:url]), options[:html], &block)
223
+ end
224
+
225
+ # Creates a form that will submit using XMLHttpRequest in the background
226
+ # instead of the regular reloading POST arrangement and a scope around a
227
+ # specific resource that is used as a base for questioning about
228
+ # values for the fields.
229
+ #
230
+ # === Resource
231
+ #
232
+ # Example:
233
+ # <% remote_form_for(@post) do |f| %>
234
+ # ...
235
+ # <% end %>
236
+ #
237
+ # This will expand to be the same as:
238
+ #
239
+ # <% remote_form_for :post, @post, :url => post_path(@post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %>
240
+ # ...
241
+ # <% end %>
242
+ #
243
+ # === Nested Resource
244
+ #
245
+ # Example:
246
+ # <% remote_form_for([@post, @comment]) do |f| %>
247
+ # ...
248
+ # <% end %>
249
+ #
250
+ # This will expand to be the same as:
251
+ #
252
+ # <% remote_form_for :comment, @comment, :url => post_comment_path(@post, @comment), :html => { :method => :put, :class => "edit_comment", :id => "edit_comment_45" } do |f| %>
253
+ # ...
254
+ # <% end %>
255
+ #
256
+ # If you don't need to attach a form to a resource, then check out form_remote_tag.
257
+ #
258
+ # See FormHelper#form_for for additional semantics.
259
+ def remote_form_for(record_or_name_or_array, *args, &proc)
260
+ options = args.extract_options!
261
+
262
+ case record_or_name_or_array
263
+ when String, Symbol
264
+ object_name = record_or_name_or_array
265
+ when Array
266
+ object = record_or_name_or_array.last
267
+ object_name = ActiveModel::Naming.singular(object)
268
+ apply_form_for_options!(record_or_name_or_array, options)
269
+ args.unshift object
270
+ else
271
+ object = record_or_name_or_array
272
+ object_name = ActiveModel::Naming.singular(record_or_name_or_array)
273
+ apply_form_for_options!(object, options)
274
+ args.unshift object
275
+ end
276
+
277
+ form_remote_tag options do
278
+ fields_for object_name, *(args << options), &proc
279
+ end
280
+ end
281
+ alias_method :form_remote_for, :remote_form_for
282
+
283
+ # Returns '<tt>eval(request.responseText)</tt>' which is the JavaScript function
284
+ # that +form_remote_tag+ can call in <tt>:complete</tt> to evaluate a multiple
285
+ # update return document using +update_element_function+ calls.
286
+ def evaluate_remote_response
287
+ "eval(request.responseText)"
288
+ end
289
+
290
+ # Observes the field with the DOM ID specified by +field_id+ and calls a
291
+ # callback when its contents have changed. The default callback is an
292
+ # Ajax call. By default the value of the observed field is sent as a
293
+ # parameter with the Ajax call.
294
+ #
295
+ # Example:
296
+ # # Generates: new Form.Element.Observer('suggest', 0.25, function(element, value) {new Ajax.Updater('suggest',
297
+ # # '/testing/find_suggestion', {asynchronous:true, evalScripts:true, parameters:'q=' + value})})
298
+ # <%= observe_field :suggest, :url => { :action => :find_suggestion },
299
+ # :frequency => 0.25,
300
+ # :update => :suggest,
301
+ # :with => 'q'
302
+ # %>
303
+ #
304
+ # Required +options+ are either of:
305
+ # <tt>:url</tt>:: +url_for+-style options for the action to call
306
+ # when the field has changed.
307
+ # <tt>:function</tt>:: Instead of making a remote call to a URL, you
308
+ # can specify javascript code to be called instead.
309
+ # Note that the value of this option is used as the
310
+ # *body* of the javascript function, a function definition
311
+ # with parameters named element and value will be generated for you
312
+ # for example:
313
+ # observe_field("glass", :frequency => 1, :function => "alert('Element changed')")
314
+ # will generate:
315
+ # new Form.Element.Observer('glass', 1, function(element, value) {alert('Element changed')})
316
+ # The element parameter is the DOM element being observed, and the value is its value at the
317
+ # time the observer is triggered.
318
+ #
319
+ # Additional options are:
320
+ # <tt>:frequency</tt>:: The frequency (in seconds) at which changes to
321
+ # this field will be detected. Not setting this
322
+ # option at all or to a value equal to or less than
323
+ # zero will use event based observation instead of
324
+ # time based observation.
325
+ # <tt>:update</tt>:: Specifies the DOM ID of the element whose
326
+ # innerHTML should be updated with the
327
+ # XMLHttpRequest response text.
328
+ # <tt>:with</tt>:: A JavaScript expression specifying the parameters
329
+ # for the XMLHttpRequest. The default is to send the
330
+ # key and value of the observed field. Any custom
331
+ # expressions should return a valid URL query string.
332
+ # The value of the field is stored in the JavaScript
333
+ # variable +value+.
334
+ #
335
+ # Examples
336
+ #
337
+ # :with => "'my_custom_key=' + value"
338
+ # :with => "'person[name]=' + prompt('New name')"
339
+ # :with => "Form.Element.serialize('other-field')"
340
+ #
341
+ # Finally
342
+ # :with => 'name'
343
+ # is shorthand for
344
+ # :with => "'name=' + value"
345
+ # This essentially just changes the key of the parameter.
346
+ #
347
+ # Additionally, you may specify any of the options documented in the
348
+ # <em>Common options</em> section at the top of this document.
349
+ #
350
+ # Example:
351
+ #
352
+ # # Sends params: {:title => 'Title of the book'} when the book_title input
353
+ # # field is changed.
354
+ # observe_field 'book_title',
355
+ # :url => 'http://example.com/books/edit/1',
356
+ # :with => 'title'
357
+ #
358
+ #
359
+ def observe_field(field_id, options = {})
360
+ if options[:frequency] && options[:frequency] > 0
361
+ build_observer('Form.Element.Observer', field_id, options)
362
+ else
363
+ build_observer('Form.Element.EventObserver', field_id, options)
364
+ end
365
+ end
366
+
367
+ # Observes the form with the DOM ID specified by +form_id+ and calls a
368
+ # callback when its contents have changed. The default callback is an
369
+ # Ajax call. By default all fields of the observed field are sent as
370
+ # parameters with the Ajax call.
371
+ #
372
+ # The +options+ for +observe_form+ are the same as the options for
373
+ # +observe_field+. The JavaScript variable +value+ available to the
374
+ # <tt>:with</tt> option is set to the serialized form by default.
375
+ def observe_form(form_id, options = {})
376
+ if options[:frequency]
377
+ build_observer('Form.Observer', form_id, options)
378
+ else
379
+ build_observer('Form.EventObserver', form_id, options)
380
+ end
381
+ end
382
+
383
+ # Periodically calls the specified url (<tt>options[:url]</tt>) every
384
+ # <tt>options[:frequency]</tt> seconds (default is 10). Usually used to
385
+ # update a specified div (<tt>options[:update]</tt>) with the results
386
+ # of the remote call. The options for specifying the target with <tt>:url</tt>
387
+ # and defining callbacks is the same as link_to_remote.
388
+ # Examples:
389
+ # # Call get_averages and put its results in 'avg' every 10 seconds
390
+ # # Generates:
391
+ # # new PeriodicalExecuter(function() {new Ajax.Updater('avg', '/grades/get_averages',
392
+ # # {asynchronous:true, evalScripts:true})}, 10)
393
+ # periodically_call_remote(:url => { :action => 'get_averages' }, :update => 'avg')
394
+ #
395
+ # # Call invoice every 10 seconds with the id of the customer
396
+ # # If it succeeds, update the invoice DIV; if it fails, update the error DIV
397
+ # # Generates:
398
+ # # new PeriodicalExecuter(function() {new Ajax.Updater({success:'invoice',failure:'error'},
399
+ # # '/testing/invoice/16', {asynchronous:true, evalScripts:true})}, 10)
400
+ # periodically_call_remote(:url => { :action => 'invoice', :id => customer.id },
401
+ # :update => { :success => "invoice", :failure => "error" }
402
+ #
403
+ # # Call update every 20 seconds and update the new_block DIV
404
+ # # Generates:
405
+ # # new PeriodicalExecuter(function() {new Ajax.Updater('news_block', 'update', {asynchronous:true, evalScripts:true})}, 20)
406
+ # periodically_call_remote(:url => 'update', :frequency => '20', :update => 'news_block')
407
+ #
408
+ def periodically_call_remote(options = {})
409
+ frequency = options[:frequency] || 10 # every ten seconds by default
410
+ code = "new PeriodicalExecuter(function() {#{remote_function(options)}}, #{frequency})"
411
+ javascript_tag(code)
412
+ end
413
+
414
+ protected
415
+ def build_observer(klass, name, options = {})
416
+ if options[:with] && (options[:with] !~ /[\{=(.]/)
417
+ options[:with] = "'#{options[:with]}=' + encodeURIComponent(value)"
418
+ else
419
+ options[:with] ||= 'value' unless options[:function]
420
+ end
421
+
422
+ callback = options[:function] || remote_function(options)
423
+ javascript = "new #{klass}('#{name}', "
424
+ javascript << "#{options[:frequency]}, " if options[:frequency]
425
+ javascript << "function(element, value) {"
426
+ javascript << "#{callback}}"
427
+ javascript << ")"
428
+ javascript_tag(javascript)
429
+ end
430
+ end