browsercms 3.1.5 → 3.3.0.beta

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 (425) hide show
  1. data/app/controllers/cms/base_controller.rb +3 -3
  2. data/app/controllers/cms/content_block_controller.rb +2 -2
  3. data/app/controllers/cms/content_controller.rb +5 -4
  4. data/app/controllers/cms/error_handling.rb +1 -1
  5. data/app/controllers/cms/routes_controller.rb +4 -5
  6. data/app/controllers/cms/section_nodes_controller.rb +1 -6
  7. data/app/controllers/cms/sections_controller.rb +2 -3
  8. data/app/controllers/cms/tasks_controller.rb +3 -0
  9. data/app/controllers/cms/users_controller.rb +1 -1
  10. data/app/helpers/cms/application_helper.rb +137 -34
  11. data/app/helpers/cms/form_builder.rb +33 -21
  12. data/app/helpers/cms/page_helper.rb +43 -10
  13. data/app/helpers/cms/path_helper.rb +1 -1
  14. data/app/helpers/cms/rendering_helper.rb +3 -4
  15. data/app/helpers/cms/section_nodes_helper.rb +5 -43
  16. data/app/models/abstract_file_block.rb +1 -16
  17. data/app/models/attachment.rb +57 -22
  18. data/app/models/category.rb +4 -4
  19. data/app/models/category_type.rb +2 -2
  20. data/app/models/cms/view_context.rb +46 -0
  21. data/app/models/connector.rb +7 -6
  22. data/app/models/content_type.rb +3 -3
  23. data/app/models/dynamic_view.rb +1 -1
  24. data/app/models/email_message.rb +2 -2
  25. data/app/models/file_block.rb +12 -0
  26. data/app/models/group.rb +4 -4
  27. data/app/models/group_type.rb +4 -4
  28. data/app/models/html_block.rb +1 -1
  29. data/app/models/image_block.rb +12 -0
  30. data/app/models/link.rb +22 -5
  31. data/app/models/page.rb +87 -46
  32. data/app/models/page_route.rb +61 -6
  33. data/app/models/permission.rb +1 -1
  34. data/app/models/portlet.rb +14 -4
  35. data/app/models/section.rb +48 -86
  36. data/app/models/section_node.rb +25 -40
  37. data/app/models/site.rb +1 -1
  38. data/app/models/tag.rb +1 -1
  39. data/app/models/task.rb +8 -7
  40. data/app/models/user.rb +2 -7
  41. data/app/portlets/forgot_password_portlet.rb +6 -2
  42. data/app/portlets/reset_password_portlet.rb +1 -1
  43. data/app/views/cms/blocks/_toolbar.html.erb +1 -1
  44. data/app/views/cms/blocks/_toolbar_for_collection.html.erb +3 -6
  45. data/app/views/cms/blocks/_toolbar_for_member.html.erb +3 -5
  46. data/app/views/cms/blocks/edit.html.erb +4 -4
  47. data/app/views/cms/blocks/index.html.erb +7 -7
  48. data/app/views/cms/blocks/new.html.erb +4 -4
  49. data/app/views/cms/blocks/show.html.erb +2 -2
  50. data/app/views/cms/blocks/usages.html.erb +2 -2
  51. data/app/views/cms/blocks/versions.html.erb +4 -4
  52. data/app/views/cms/cache/show.html.erb +2 -2
  53. data/app/views/cms/categories/_form.html.erb +2 -2
  54. data/app/views/cms/connectors/new.html.erb +6 -8
  55. data/app/views/cms/content/no_page.html.erb +1 -1
  56. data/app/views/cms/content/show.html.erb +2 -7
  57. data/app/views/cms/dashboard/_page_drafts.html.erb +1 -1
  58. data/app/views/cms/dashboard/_tasks.html.erb +1 -1
  59. data/app/views/cms/dashboard/index.html.erb +1 -1
  60. data/app/views/cms/dynamic_views/_form.html.erb +2 -2
  61. data/app/views/cms/dynamic_views/index.html.erb +7 -10
  62. data/app/views/cms/email_messages/show.html.erb +2 -2
  63. data/app/views/cms/file_blocks/_form.html.erb +4 -4
  64. data/app/views/cms/form_builder/_cms_fancy_drop_down.html.erb +2 -2
  65. data/app/views/cms/form_builder/_cms_file_field.html.erb +2 -2
  66. data/app/views/cms/form_builder/_cms_tag_list.html.erb +2 -2
  67. data/app/views/cms/form_builder/_cms_text_editor.html.erb +2 -2
  68. data/app/views/cms/groups/_form.html.erb +5 -5
  69. data/app/views/cms/groups/_permissions.html.erb +4 -4
  70. data/app/views/cms/groups/_sections.html.erb +1 -2
  71. data/app/views/cms/groups/index.html.erb +1 -1
  72. data/app/views/cms/html_blocks/render.html.erb +1 -1
  73. data/app/views/cms/image_blocks/_form.html.erb +4 -5
  74. data/app/views/cms/links/_form.html.erb +1 -1
  75. data/app/views/cms/links/edit.html.erb +2 -2
  76. data/app/views/cms/links/new.html.erb +2 -2
  77. data/app/views/cms/page_routes/_form.html.erb +2 -2
  78. data/app/views/cms/page_routes/index.html.erb +6 -9
  79. data/app/views/cms/page_routes/show.html.erb +5 -8
  80. data/app/views/cms/pages/_edit_connector.html.erb +1 -1
  81. data/app/views/cms/pages/_form.html.erb +3 -3
  82. data/app/views/cms/pages/edit.html.erb +2 -2
  83. data/app/views/cms/pages/new.html.erb +7 -7
  84. data/app/views/cms/pages/versions.html.erb +4 -4
  85. data/app/views/cms/redirects/_form.html.erb +2 -2
  86. data/app/views/cms/redirects/index.html.erb +8 -7
  87. data/app/views/cms/routes/index.html.erb +2 -2
  88. data/app/views/cms/section_nodes/_link.html.erb +3 -6
  89. data/app/views/cms/section_nodes/_node.html.erb +4 -13
  90. data/app/views/cms/section_nodes/_page.html.erb +7 -13
  91. data/app/views/cms/section_nodes/_section.html.erb +8 -24
  92. data/app/views/cms/section_nodes/_section_node.html.erb +10 -0
  93. data/app/views/cms/section_nodes/index.html.erb +18 -30
  94. data/app/views/cms/sections/_form.html.erb +4 -6
  95. data/app/views/cms/sections/edit.html.erb +2 -2
  96. data/app/views/cms/sections/index.html.erb +3 -3
  97. data/app/views/cms/sections/new.html.erb +3 -3
  98. data/app/views/cms/sessions/new.html.erb +3 -3
  99. data/app/views/cms/shared/_pagination.html.erb +1 -1
  100. data/app/views/cms/shared/error.html.erb +1 -1
  101. data/app/views/cms/tags/render.html.erb +2 -2
  102. data/app/views/cms/tasks/new.html.erb +4 -4
  103. data/app/views/cms/users/_form.html.erb +3 -3
  104. data/app/views/cms/users/_toolbar.html.erb +3 -3
  105. data/app/views/cms/users/change_password.html.erb +5 -5
  106. data/app/views/cms/users/edit.html.erb +2 -2
  107. data/app/views/cms/users/index.html.erb +4 -4
  108. data/app/views/cms/users/new.html.erb +2 -2
  109. data/app/views/cms/users/show.html.erb +16 -16
  110. data/app/views/layouts/_cms_toolbar.html.erb +5 -5
  111. data/app/views/layouts/_page_toolbar.html.erb +11 -11
  112. data/app/views/layouts/cms/_footer.erb +1 -1
  113. data/app/views/layouts/cms/_head.html.erb +2 -6
  114. data/app/views/layouts/cms/administration.html.erb +32 -32
  115. data/app/views/layouts/cms/content_library.html.erb +5 -5
  116. data/app/views/layouts/cms/toolbar.html.erb +1 -1
  117. data/app/views/portlets/email_page/render.html.erb +2 -2
  118. data/app/views/portlets/forgot_password/render.html.erb +1 -1
  119. data/app/views/portlets/login/render.html.erb +4 -2
  120. data/app/views/portlets/reset_password/render.html.erb +1 -1
  121. data/app/views/tests/pretend/open_with_layout.html.erb +1 -1
  122. data/bin/bcms +0 -0
  123. data/bin/bcms-upgrade +232 -0
  124. data/bin/browsercms +2 -2
  125. data/browsercms.gemspec +16 -14
  126. data/db/migrate/20100705083859_browsercms_3_3_0.rb +56 -0
  127. data/db/seeds.rb +58 -0
  128. data/doc/guides/html/authentication.html +448 -192
  129. data/doc/guides/html/build_it_yourself.html +454 -175
  130. data/doc/guides/html/building_modules.html +451 -220
  131. data/doc/guides/html/building_templates.html +448 -498
  132. data/doc/guides/html/content_blocks.html +450 -470
  133. data/doc/guides/html/customizing_browsercms.html +453 -169
  134. data/doc/guides/html/deployment_guide.html +443 -82
  135. data/doc/guides/html/files/bcmsorg.js +28 -0
  136. data/doc/guides/html/files/clearfix.css +8 -0
  137. data/doc/guides/html/files/cufon.js +7 -0
  138. data/doc/guides/html/files/global.css +190 -0
  139. data/doc/guides/html/files/helvetica.js +91 -0
  140. data/doc/guides/html/files/jquery.js +11 -0
  141. data/doc/guides/html/getting_started.html +454 -213
  142. data/doc/guides/html/index.html +454 -174
  143. data/doc/guides/html/installing_modules.html +454 -186
  144. data/doc/guides/html/portlets.html +451 -232
  145. data/doc/guides/html/user_guide.html +452 -270
  146. data/doc/guides/html/writing_guides.html +454 -161
  147. data/lib/acts_as_list.rb +1 -1
  148. data/lib/browsercms.rb +10 -6
  149. data/lib/cms/acts.rb +7 -0
  150. data/lib/cms/authentication.rb +4 -0
  151. data/lib/cms/authentication/controller.rb +1 -1
  152. data/lib/cms/behaviors.rb +1 -1
  153. data/lib/cms/behaviors/archiving.rb +2 -2
  154. data/lib/cms/behaviors/attaching.rb +28 -43
  155. data/lib/cms/behaviors/categorizing.rb +1 -1
  156. data/lib/cms/behaviors/connecting.rb +27 -12
  157. data/lib/cms/behaviors/dynamic_attributes.rb +8 -5
  158. data/lib/cms/behaviors/hiding.rb +2 -2
  159. data/lib/cms/behaviors/publishing.rb +32 -22
  160. data/lib/cms/behaviors/rendering.rb +41 -18
  161. data/lib/cms/behaviors/searching.rb +1 -1
  162. data/lib/cms/behaviors/soft_deleting.rb +58 -29
  163. data/lib/cms/behaviors/taggable.rb +1 -1
  164. data/lib/cms/behaviors/userstamping.rb +5 -4
  165. data/lib/cms/behaviors/versioning.rb +192 -111
  166. data/lib/cms/content_rendering_support.rb +3 -3
  167. data/lib/cms/date_picker.rb +23 -0
  168. data/lib/cms/engine.rb +46 -0
  169. data/lib/cms/extensions.rb +1 -1
  170. data/lib/cms/extensions/active_record/errors.rb +2 -2
  171. data/lib/cms/extensions/hash.rb +4 -2
  172. data/lib/cms/extensions/string.rb +7 -2
  173. data/lib/cms/init.rb +32 -21
  174. data/lib/cms/module.rb +22 -0
  175. data/lib/cms/module_installation.rb +38 -0
  176. data/lib/cms/routes.rb +127 -115
  177. data/lib/cms/version.rb +2 -2
  178. data/lib/generators/browser_cms.rb +12 -0
  179. data/lib/generators/browser_cms/cms/USAGE +2 -0
  180. data/lib/generators/browser_cms/cms/cms_generator.rb +36 -0
  181. data/{rails_generators/browser_cms → lib/generators/browser_cms/cms}/templates/README +0 -0
  182. data/{rails_generators/browser_cms_demo_site → lib/generators/browser_cms/demo_site}/USAGE +0 -0
  183. data/lib/generators/browser_cms/demo_site/demo_site_generator.rb +138 -0
  184. data/lib/generators/browser_cms/demo_site/templates/demo_site.rake +11 -0
  185. data/{rails_generators/browser_cms_demo_site/templates/migration.rb → lib/generators/browser_cms/demo_site/templates/migration.erb} +2 -8
  186. data/lib/generators/cms/content_block/USAGE +22 -0
  187. data/lib/generators/cms/content_block/content_block_generator.rb +55 -0
  188. data/{rails_generators → lib/generators/cms}/content_block/templates/_form.html.erb +0 -0
  189. data/{rails_generators → lib/generators/cms}/content_block/templates/content_block.rb +0 -0
  190. data/{rails_generators → lib/generators/cms}/content_block/templates/controller.rb +0 -0
  191. data/{rails_generators → lib/generators/cms}/content_block/templates/functional_test.erb +0 -0
  192. data/{rails_generators/content_block/templates/migration.rb → lib/generators/cms/content_block/templates/migration.erb} +1 -1
  193. data/{rails_generators → lib/generators/cms}/content_block/templates/render.html.erb +0 -0
  194. data/{rails_generators → lib/generators/cms}/content_block/templates/unit_test.erb +0 -0
  195. data/lib/generators/cms/install/USAGE +8 -0
  196. data/lib/generators/cms/install/install_generator.rb +20 -0
  197. data/{rails_generators → lib/generators/cms}/portlet/USAGE +3 -16
  198. data/lib/generators/cms/portlet/portlet_generator.rb +38 -0
  199. data/{rails_generators → lib/generators/cms}/portlet/templates/_form.html.erb +0 -0
  200. data/{rails_generators → lib/generators/cms}/portlet/templates/portlet.rb +0 -0
  201. data/{rails_generators → lib/generators/cms}/portlet/templates/portlet_helper.rb +0 -0
  202. data/{rails_generators → lib/generators/cms}/portlet/templates/render.html.erb +0 -0
  203. data/{rails_generators → lib/generators/cms}/portlet/templates/unit_test.erb +0 -0
  204. data/{rails_generators → lib/generators/cms}/template/USAGE +1 -1
  205. data/lib/generators/cms/template/template_generator.rb +18 -0
  206. data/lib/generators/cms/template/templates/template.erb +2 -0
  207. data/lib/generators/cms/upgrade_module/README.txt +3 -0
  208. data/lib/generators/cms/upgrade_module/templates/20100705083859_browsercms_3_3_0.rb +56 -0
  209. data/lib/generators/cms/upgrade_module/templates/README +1 -0
  210. data/lib/generators/cms/upgrade_module/templates/USAGE.erb +10 -0
  211. data/lib/generators/cms/upgrade_module/templates/build_gem.rake +5 -0
  212. data/lib/generators/cms/upgrade_module/templates/engine.erb +7 -0
  213. data/lib/generators/cms/upgrade_module/templates/gemspec.erb +25 -0
  214. data/lib/generators/cms/upgrade_module/templates/gitignore.erb +11 -0
  215. data/lib/generators/cms/upgrade_module/templates/install.erb +9 -0
  216. data/lib/generators/cms/upgrade_module/templates/module_file.erb +3 -0
  217. data/lib/generators/cms/upgrade_module/templates/routes.erb +7 -0
  218. data/lib/generators/cms/upgrade_module/upgrade_module_generator.rb +61 -0
  219. data/lib/tasks/build_gem.rake +1 -0
  220. data/lib/tasks/cms.rake +34 -6
  221. data/lib/tasks/cucumber.rake +53 -0
  222. data/lib/tasks/db.rake +2 -2
  223. data/public/javascripts/cms/application.js +144 -135
  224. data/public/javascripts/cms/sitemap.js +383 -357
  225. data/public/javascripts/jquery-ui.js +782 -591
  226. data/public/javascripts/jquery.cookie.js +38 -43
  227. data/public/javascripts/jquery.js +13 -8
  228. data/public/javascripts/jquery.taglist.js +7 -0
  229. data/public/stylesheets/cms/date_picker.css +49 -40
  230. data/rails/init.rb +2 -3
  231. data/templates/blank.rb +13 -7
  232. data/templates/demo.rb +15 -7
  233. data/templates/module.rb +12 -75
  234. metadata +87 -407
  235. data/app/helpers/cms/content_block_helper.rb +0 -27
  236. data/app/views/layouts/cms/thickbox.html.erb +0 -24
  237. data/db/migrate/20120117144039_browsercms315.rb +0 -94
  238. data/db/migrate/20121114172307_load_seeds.rb +0 -70
  239. data/lib/cms/addressable.rb +0 -83
  240. data/lib/cms/error_pages.rb +0 -8
  241. data/public/images/cms/thickbox/loadingAnimation.gif +0 -0
  242. data/public/images/cms/thickbox/macFFBgHack.png +0 -0
  243. data/public/javascripts/jquery.contextMenu.js +0 -211
  244. data/public/javascripts/jquery.dimensions.js +0 -119
  245. data/public/javascripts/jquery.thickbox.js +0 -10
  246. data/public/stylesheets/cms/jquery.contextMenu.css +0 -61
  247. data/public/stylesheets/cms/thickbox.css +0 -163
  248. data/rails_generators/browser_cms/USAGE +0 -2
  249. data/rails_generators/browser_cms/browser_cms_generator.rb +0 -35
  250. data/rails_generators/browser_cms_demo_site/browser_cms_demo_site_generator.rb +0 -63
  251. data/rails_generators/content_block/USAGE +0 -32
  252. data/rails_generators/content_block/content_block_generator.rb +0 -69
  253. data/rails_generators/portlet/portlet_generator.rb +0 -35
  254. data/rails_generators/template/template_generator.rb +0 -18
  255. data/rails_generators/template/templates/template.erb +0 -3
  256. data/test/custom_assertions.rb +0 -74
  257. data/test/factories.rb +0 -111
  258. data/test/factories/sitemap_factories.rb +0 -28
  259. data/test/fixtures/connectors.yml +0 -97
  260. data/test/fixtures/content_type_groups.yml +0 -13
  261. data/test/fixtures/content_types.yml +0 -50
  262. data/test/fixtures/dynamic_view_versions.yml +0 -26
  263. data/test/fixtures/dynamic_views.yml +0 -26
  264. data/test/fixtures/group_permissions.yml +0 -16
  265. data/test/fixtures/group_sections.yml +0 -31
  266. data/test/fixtures/group_type_permissions.yml +0 -11
  267. data/test/fixtures/group_types.yml +0 -25
  268. data/test/fixtures/groups.yml +0 -25
  269. data/test/fixtures/html_block_versions.yml +0 -67
  270. data/test/fixtures/html_blocks.yml +0 -63
  271. data/test/fixtures/page_versions.yml +0 -265
  272. data/test/fixtures/pages.yml +0 -85
  273. data/test/fixtures/permissions.yml +0 -28
  274. data/test/fixtures/section_nodes.yml +0 -46
  275. data/test/fixtures/sections.yml +0 -19
  276. data/test/fixtures/sites.yml +0 -9
  277. data/test/fixtures/user_group_memberships.yml +0 -11
  278. data/test/fixtures/users.yml +0 -15
  279. data/test/functional/cms/cache_controller_test.rb +0 -14
  280. data/test/functional/cms/categories_controller_test.rb +0 -25
  281. data/test/functional/cms/connectors_controller_test.rb +0 -60
  282. data/test/functional/cms/content_block_controller_test.rb +0 -120
  283. data/test/functional/cms/content_controller_test.rb +0 -439
  284. data/test/functional/cms/content_types_controller_test.rb +0 -18
  285. data/test/functional/cms/dashboard_controller_test.rb +0 -16
  286. data/test/functional/cms/dynamic_views_controller_test.rb +0 -52
  287. data/test/functional/cms/file_blocks_controller_test.rb +0 -52
  288. data/test/functional/cms/groups_controller_test.rb +0 -50
  289. data/test/functional/cms/home_controller_test.rb +0 -156
  290. data/test/functional/cms/html_blocks_controller_test.rb +0 -164
  291. data/test/functional/cms/image_blocks_controller_test.rb +0 -82
  292. data/test/functional/cms/links_controller_test.rb +0 -148
  293. data/test/functional/cms/pages_controller_test.rb +0 -227
  294. data/test/functional/cms/portlets_controller_test.rb +0 -67
  295. data/test/functional/cms/section_nodes_controller_test.rb +0 -112
  296. data/test/functional/cms/sections_controller_test.rb +0 -227
  297. data/test/functional/cms/sessions_controller_test.rb +0 -76
  298. data/test/functional/cms/toolbar_controller_test.rb +0 -64
  299. data/test/functional/cms/users_controller_test.rb +0 -231
  300. data/test/functional/tests/pretend_controller_test.rb +0 -57
  301. data/test/integration/cms/ckeditor_test.rb +0 -30
  302. data/test/integration/cms/password_management_test.rb +0 -56
  303. data/test/integration/login_test.rb +0 -14
  304. data/test/integration/sitemap_performance_test.rb +0 -26
  305. data/test/selenium-core/Blank.html +0 -7
  306. data/test/selenium-core/InjectedRemoteRunner.html +0 -8
  307. data/test/selenium-core/RemoteRunner.html +0 -110
  308. data/test/selenium-core/SeleniumLog.html +0 -109
  309. data/test/selenium-core/TestPrompt.html +0 -145
  310. data/test/selenium-core/TestRunner-splash.html +0 -55
  311. data/test/selenium-core/TestRunner.hta +0 -176
  312. data/test/selenium-core/TestRunner.html +0 -176
  313. data/test/selenium-core/domviewer/butmin.gif +0 -0
  314. data/test/selenium-core/domviewer/butplus.gif +0 -0
  315. data/test/selenium-core/domviewer/domviewer.css +0 -298
  316. data/test/selenium-core/domviewer/domviewer.html +0 -16
  317. data/test/selenium-core/domviewer/selenium-domviewer.js +0 -205
  318. data/test/selenium-core/icons/all.png +0 -0
  319. data/test/selenium-core/icons/continue.png +0 -0
  320. data/test/selenium-core/icons/continue_disabled.png +0 -0
  321. data/test/selenium-core/icons/pause.png +0 -0
  322. data/test/selenium-core/icons/pause_disabled.png +0 -0
  323. data/test/selenium-core/icons/selected.png +0 -0
  324. data/test/selenium-core/icons/step.png +0 -0
  325. data/test/selenium-core/icons/step_disabled.png +0 -0
  326. data/test/selenium-core/iedoc-core.xml +0 -1515
  327. data/test/selenium-core/iedoc.xml +0 -1469
  328. data/test/selenium-core/lib/cssQuery/cssQuery-p.js +0 -6
  329. data/test/selenium-core/lib/cssQuery/src/cssQuery-level2.js +0 -142
  330. data/test/selenium-core/lib/cssQuery/src/cssQuery-level3.js +0 -150
  331. data/test/selenium-core/lib/cssQuery/src/cssQuery-standard.js +0 -53
  332. data/test/selenium-core/lib/cssQuery/src/cssQuery.js +0 -356
  333. data/test/selenium-core/lib/prototype.js +0 -2006
  334. data/test/selenium-core/lib/scriptaculous/builder.js +0 -101
  335. data/test/selenium-core/lib/scriptaculous/controls.js +0 -815
  336. data/test/selenium-core/lib/scriptaculous/dragdrop.js +0 -915
  337. data/test/selenium-core/lib/scriptaculous/effects.js +0 -958
  338. data/test/selenium-core/lib/scriptaculous/scriptaculous.js +0 -47
  339. data/test/selenium-core/lib/scriptaculous/slider.js +0 -283
  340. data/test/selenium-core/lib/scriptaculous/unittest.js +0 -383
  341. data/test/selenium-core/scripts/find_matching_child.js +0 -69
  342. data/test/selenium-core/scripts/htmlutils.js +0 -894
  343. data/test/selenium-core/scripts/injection.html +0 -72
  344. data/test/selenium-core/scripts/js2html.js +0 -70
  345. data/test/selenium-core/scripts/narcissus-defs.js +0 -175
  346. data/test/selenium-core/scripts/narcissus-exec.js +0 -1054
  347. data/test/selenium-core/scripts/narcissus-parse.js +0 -1003
  348. data/test/selenium-core/scripts/se2html.js +0 -63
  349. data/test/selenium-core/scripts/selenium-api.js +0 -2409
  350. data/test/selenium-core/scripts/selenium-browserbot.js +0 -2203
  351. data/test/selenium-core/scripts/selenium-browserdetect.js +0 -150
  352. data/test/selenium-core/scripts/selenium-commandhandlers.js +0 -377
  353. data/test/selenium-core/scripts/selenium-executionloop.js +0 -175
  354. data/test/selenium-core/scripts/selenium-logging.js +0 -147
  355. data/test/selenium-core/scripts/selenium-remoterunner.js +0 -571
  356. data/test/selenium-core/scripts/selenium-testrunner.js +0 -1333
  357. data/test/selenium-core/scripts/selenium-version.js +0 -5
  358. data/test/selenium-core/scripts/user-extensions.js +0 -3
  359. data/test/selenium-core/scripts/user-extensions.js.sample +0 -75
  360. data/test/selenium-core/scripts/xmlextras.js +0 -153
  361. data/test/selenium-core/selenium-logo.png +0 -0
  362. data/test/selenium-core/selenium-test.css +0 -43
  363. data/test/selenium-core/selenium.css +0 -299
  364. data/test/selenium-core/xpath/dom.js +0 -428
  365. data/test/selenium-core/xpath/misc.js +0 -252
  366. data/test/selenium-core/xpath/xpath.js +0 -2223
  367. data/test/selenium/_login_as_cmsadmin.rsel +0 -4
  368. data/test/selenium/dashboard.rsel +0 -5
  369. data/test/selenium/html_blocks.rsel +0 -4
  370. data/test/selenium/login/failed_login.rsel +0 -8
  371. data/test/selenium/login/successful_login.rsel +0 -9
  372. data/test/selenium/page_templates.rsel +0 -12
  373. data/test/selenium/pages/edit_properties.rsel +0 -5
  374. data/test/selenium/site/view_home_page.rsel +0 -4
  375. data/test/selenium/sitemap/move_page.rsel +0 -9
  376. data/test/selenium/sitemap/open_section.rsel +0 -6
  377. data/test/selenium/sitemap/select_page.rsel +0 -12
  378. data/test/selenium/sitemap/select_section.rsel +0 -17
  379. data/test/test_helper.rb +0 -193
  380. data/test/test_logging.rb +0 -67
  381. data/test/unit/behaviors/attaching_test.rb +0 -357
  382. data/test/unit/behaviors/connectable_test.rb +0 -29
  383. data/test/unit/behaviors/dynamic_attributes_test.rb +0 -38
  384. data/test/unit/behaviors/publishable_test.rb +0 -84
  385. data/test/unit/behaviors/searching_test.rb +0 -102
  386. data/test/unit/behaviors/taggable_test.rb +0 -109
  387. data/test/unit/behaviors/versioning_test.rb +0 -36
  388. data/test/unit/extensions/active_record/base_test.rb +0 -10
  389. data/test/unit/extensions/hash_test.rb +0 -17
  390. data/test/unit/extensions/integer_test.rb +0 -10
  391. data/test/unit/helpers/application_helper_test.rb +0 -77
  392. data/test/unit/helpers/form_builder_test.rb +0 -36
  393. data/test/unit/helpers/menu_helper_test.rb +0 -242
  394. data/test/unit/helpers/page_helper_test.rb +0 -67
  395. data/test/unit/helpers/path_helper_test.rb +0 -57
  396. data/test/unit/lib/acts_as_content_page_test.rb +0 -72
  397. data/test/unit/lib/cms/authentication/controller_test.rb +0 -20
  398. data/test/unit/lib/cms/sitemap_test.rb +0 -206
  399. data/test/unit/lib/cms_domain_support_test.rb +0 -43
  400. data/test/unit/lib/command_line_test.rb +0 -70
  401. data/test/unit/lib/content_block_test.rb +0 -203
  402. data/test/unit/lib/content_rendering_support_test.rb +0 -40
  403. data/test/unit/lib/generators_test.rb +0 -40
  404. data/test/unit/lib/routes_test.rb +0 -57
  405. data/test/unit/models/attachment_test.rb +0 -116
  406. data/test/unit/models/category_test.rb +0 -40
  407. data/test/unit/models/category_type_test.rb +0 -8
  408. data/test/unit/models/connector_test.rb +0 -152
  409. data/test/unit/models/content_type_test.rb +0 -56
  410. data/test/unit/models/email_page_portlet_test.rb +0 -14
  411. data/test/unit/models/file_block_test.rb +0 -230
  412. data/test/unit/models/group_test.rb +0 -13
  413. data/test/unit/models/html_block_test.rb +0 -102
  414. data/test/unit/models/link_test.rb +0 -52
  415. data/test/unit/models/page_partial_test.rb +0 -29
  416. data/test/unit/models/page_route_test.rb +0 -29
  417. data/test/unit/models/page_template_test.rb +0 -40
  418. data/test/unit/models/page_test.rb +0 -792
  419. data/test/unit/models/permission_test.rb +0 -10
  420. data/test/unit/models/portlet_test.rb +0 -69
  421. data/test/unit/models/sections_test.rb +0 -264
  422. data/test/unit/models/site_test.rb +0 -50
  423. data/test/unit/models/task_test.rb +0 -141
  424. data/test/unit/models/user_test.rb +0 -352
  425. data/test/unit/schema_statements_test.rb +0 -41
@@ -1,101 +0,0 @@
1
- // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
- //
3
- // See scriptaculous.js for full license.
4
-
5
- var Builder = {
6
- NODEMAP: {
7
- AREA: 'map',
8
- CAPTION: 'table',
9
- COL: 'table',
10
- COLGROUP: 'table',
11
- LEGEND: 'fieldset',
12
- OPTGROUP: 'select',
13
- OPTION: 'select',
14
- PARAM: 'object',
15
- TBODY: 'table',
16
- TD: 'table',
17
- TFOOT: 'table',
18
- TH: 'table',
19
- THEAD: 'table',
20
- TR: 'table'
21
- },
22
- // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
23
- // due to a Firefox bug
24
- node: function(elementName) {
25
- elementName = elementName.toUpperCase();
26
-
27
- // try innerHTML approach
28
- var parentTag = this.NODEMAP[elementName] || 'div';
29
- var parentElement = document.createElement(parentTag);
30
- try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
31
- parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
32
- } catch(e) {}
33
- var element = parentElement.firstChild || null;
34
-
35
- // see if browser added wrapping tags
36
- if(element && (element.tagName != elementName))
37
- element = element.getElementsByTagName(elementName)[0];
38
-
39
- // fallback to createElement approach
40
- if(!element) element = document.createElement(elementName);
41
-
42
- // abort if nothing could be created
43
- if(!element) return;
44
-
45
- // attributes (or text)
46
- if(arguments[1])
47
- if(this._isStringOrNumber(arguments[1]) ||
48
- (arguments[1] instanceof Array)) {
49
- this._children(element, arguments[1]);
50
- } else {
51
- var attrs = this._attributes(arguments[1]);
52
- if(attrs.length) {
53
- try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
54
- parentElement.innerHTML = "<" +elementName + " " +
55
- attrs + "></" + elementName + ">";
56
- } catch(e) {}
57
- element = parentElement.firstChild || null;
58
- // workaround firefox 1.0.X bug
59
- if(!element) {
60
- element = document.createElement(elementName);
61
- for(attr in arguments[1])
62
- element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
63
- }
64
- if(element.tagName != elementName)
65
- element = parentElement.getElementsByTagName(elementName)[0];
66
- }
67
- }
68
-
69
- // text, or array of children
70
- if(arguments[2])
71
- this._children(element, arguments[2]);
72
-
73
- return element;
74
- },
75
- _text: function(text) {
76
- return document.createTextNode(text);
77
- },
78
- _attributes: function(attributes) {
79
- var attrs = [];
80
- for(attribute in attributes)
81
- attrs.push((attribute=='className' ? 'class' : attribute) +
82
- '="' + attributes[attribute].toString().escapeHTML() + '"');
83
- return attrs.join(" ");
84
- },
85
- _children: function(element, children) {
86
- if(typeof children=='object') { // array can hold nodes and text
87
- children.flatten().each( function(e) {
88
- if(typeof e=='object')
89
- element.appendChild(e)
90
- else
91
- if(Builder._isStringOrNumber(e))
92
- element.appendChild(Builder._text(e));
93
- });
94
- } else
95
- if(Builder._isStringOrNumber(children))
96
- element.appendChild(Builder._text(children));
97
- },
98
- _isStringOrNumber: function(param) {
99
- return(typeof param=='string' || typeof param=='number');
100
- }
101
- }
@@ -1,815 +0,0 @@
1
- // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
- // (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
3
- // (c) 2005 Jon Tirsen (http://www.tirsen.com)
4
- // Contributors:
5
- // Richard Livsey
6
- // Rahul Bhargava
7
- // Rob Wills
8
- //
9
- // See scriptaculous.js for full license.
10
-
11
- // Autocompleter.Base handles all the autocompletion functionality
12
- // that's independent of the data source for autocompletion. This
13
- // includes drawing the autocompletion menu, observing keyboard
14
- // and mouse events, and similar.
15
- //
16
- // Specific autocompleters need to provide, at the very least,
17
- // a getUpdatedChoices function that will be invoked every time
18
- // the text inside the monitored textbox changes. This method
19
- // should get the text for which to provide autocompletion by
20
- // invoking this.getToken(), NOT by directly accessing
21
- // this.element.value. This is to allow incremental tokenized
22
- // autocompletion. Specific auto-completion logic (AJAX, etc)
23
- // belongs in getUpdatedChoices.
24
- //
25
- // Tokenized incremental autocompletion is enabled automatically
26
- // when an autocompleter is instantiated with the 'tokens' option
27
- // in the options parameter, e.g.:
28
- // new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
29
- // will incrementally autocomplete with a comma as the token.
30
- // Additionally, ',' in the above example can be replaced with
31
- // a token array, e.g. { tokens: [',', '\n'] } which
32
- // enables autocompletion on multiple tokens. This is most
33
- // useful when one of the tokens is \n (a newline), as it
34
- // allows smart autocompletion after linebreaks.
35
-
36
- var Autocompleter = {}
37
- Autocompleter.Base = function() {};
38
- Autocompleter.Base.prototype = {
39
- baseInitialize: function(element, update, options) {
40
- this.element = $(element);
41
- this.update = $(update);
42
- this.hasFocus = false;
43
- this.changed = false;
44
- this.active = false;
45
- this.index = 0;
46
- this.entryCount = 0;
47
-
48
- if (this.setOptions)
49
- this.setOptions(options);
50
- else
51
- this.options = options || {};
52
-
53
- this.options.paramName = this.options.paramName || this.element.name;
54
- this.options.tokens = this.options.tokens || [];
55
- this.options.frequency = this.options.frequency || 0.4;
56
- this.options.minChars = this.options.minChars || 1;
57
- this.options.onShow = this.options.onShow ||
58
- function(element, update){
59
- if(!update.style.position || update.style.position=='absolute') {
60
- update.style.position = 'absolute';
61
- Position.clone(element, update, {setHeight: false, offsetTop: element.offsetHeight});
62
- }
63
- Effect.Appear(update,{duration:0.15});
64
- };
65
- this.options.onHide = this.options.onHide ||
66
- function(element, update){ new Effect.Fade(update,{duration:0.15}) };
67
-
68
- if (typeof(this.options.tokens) == 'string')
69
- this.options.tokens = new Array(this.options.tokens);
70
-
71
- this.observer = null;
72
-
73
- this.element.setAttribute('autocomplete','off');
74
-
75
- Element.hide(this.update);
76
-
77
- Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
78
- Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
79
- },
80
-
81
- show: function() {
82
- if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
83
- if(!this.iefix &&
84
- (navigator.appVersion.indexOf('MSIE')>0) &&
85
- (navigator.userAgent.indexOf('Opera')<0) &&
86
- (Element.getStyle(this.update, 'position')=='absolute')) {
87
- new Insertion.After(this.update,
88
- '<iframe id="' + this.update.id + '_iefix" '+
89
- 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
90
- 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
91
- this.iefix = $(this.update.id+'_iefix');
92
- }
93
- if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
94
- },
95
-
96
- fixIEOverlapping: function() {
97
- Position.clone(this.update, this.iefix);
98
- this.iefix.style.zIndex = 1;
99
- this.update.style.zIndex = 2;
100
- Element.show(this.iefix);
101
- },
102
-
103
- hide: function() {
104
- this.stopIndicator();
105
- if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
106
- if(this.iefix) Element.hide(this.iefix);
107
- },
108
-
109
- startIndicator: function() {
110
- if(this.options.indicator) Element.show(this.options.indicator);
111
- },
112
-
113
- stopIndicator: function() {
114
- if(this.options.indicator) Element.hide(this.options.indicator);
115
- },
116
-
117
- onKeyPress: function(event) {
118
- if(this.active)
119
- switch(event.keyCode) {
120
- case Event.KEY_TAB:
121
- case Event.KEY_RETURN:
122
- this.selectEntry();
123
- Event.stop(event);
124
- case Event.KEY_ESC:
125
- this.hide();
126
- this.active = false;
127
- Event.stop(event);
128
- return;
129
- case Event.KEY_LEFT:
130
- case Event.KEY_RIGHT:
131
- return;
132
- case Event.KEY_UP:
133
- this.markPrevious();
134
- this.render();
135
- if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
136
- return;
137
- case Event.KEY_DOWN:
138
- this.markNext();
139
- this.render();
140
- if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
141
- return;
142
- }
143
- else
144
- if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
145
- (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return;
146
-
147
- this.changed = true;
148
- this.hasFocus = true;
149
-
150
- if(this.observer) clearTimeout(this.observer);
151
- this.observer =
152
- setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
153
- },
154
-
155
- activate: function() {
156
- this.changed = false;
157
- this.hasFocus = true;
158
- this.getUpdatedChoices();
159
- },
160
-
161
- onHover: function(event) {
162
- var element = Event.findElement(event, 'LI');
163
- if(this.index != element.autocompleteIndex)
164
- {
165
- this.index = element.autocompleteIndex;
166
- this.render();
167
- }
168
- Event.stop(event);
169
- },
170
-
171
- onClick: function(event) {
172
- var element = Event.findElement(event, 'LI');
173
- this.index = element.autocompleteIndex;
174
- this.selectEntry();
175
- this.hide();
176
- },
177
-
178
- onBlur: function(event) {
179
- // needed to make click events working
180
- setTimeout(this.hide.bind(this), 250);
181
- this.hasFocus = false;
182
- this.active = false;
183
- },
184
-
185
- render: function() {
186
- if(this.entryCount > 0) {
187
- for (var i = 0; i < this.entryCount; i++)
188
- this.index==i ?
189
- Element.addClassName(this.getEntry(i),"selected") :
190
- Element.removeClassName(this.getEntry(i),"selected");
191
-
192
- if(this.hasFocus) {
193
- this.show();
194
- this.active = true;
195
- }
196
- } else {
197
- this.active = false;
198
- this.hide();
199
- }
200
- },
201
-
202
- markPrevious: function() {
203
- if(this.index > 0) this.index--
204
- else this.index = this.entryCount-1;
205
- },
206
-
207
- markNext: function() {
208
- if(this.index < this.entryCount-1) this.index++
209
- else this.index = 0;
210
- },
211
-
212
- getEntry: function(index) {
213
- return this.update.firstChild.childNodes[index];
214
- },
215
-
216
- getCurrentEntry: function() {
217
- return this.getEntry(this.index);
218
- },
219
-
220
- selectEntry: function() {
221
- this.active = false;
222
- this.updateElement(this.getCurrentEntry());
223
- },
224
-
225
- updateElement: function(selectedElement) {
226
- if (this.options.updateElement) {
227
- this.options.updateElement(selectedElement);
228
- return;
229
- }
230
- var value = '';
231
- if (this.options.select) {
232
- var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
233
- if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
234
- } else
235
- value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
236
-
237
- var lastTokenPos = this.findLastToken();
238
- if (lastTokenPos != -1) {
239
- var newValue = this.element.value.substr(0, lastTokenPos + 1);
240
- var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
241
- if (whitespace)
242
- newValue += whitespace[0];
243
- this.element.value = newValue + value;
244
- } else {
245
- this.element.value = value;
246
- }
247
- this.element.focus();
248
-
249
- if (this.options.afterUpdateElement)
250
- this.options.afterUpdateElement(this.element, selectedElement);
251
- },
252
-
253
- updateChoices: function(choices) {
254
- if(!this.changed && this.hasFocus) {
255
- this.update.innerHTML = choices;
256
- Element.cleanWhitespace(this.update);
257
- Element.cleanWhitespace(this.update.firstChild);
258
-
259
- if(this.update.firstChild && this.update.firstChild.childNodes) {
260
- this.entryCount =
261
- this.update.firstChild.childNodes.length;
262
- for (var i = 0; i < this.entryCount; i++) {
263
- var entry = this.getEntry(i);
264
- entry.autocompleteIndex = i;
265
- this.addObservers(entry);
266
- }
267
- } else {
268
- this.entryCount = 0;
269
- }
270
-
271
- this.stopIndicator();
272
-
273
- this.index = 0;
274
- this.render();
275
- }
276
- },
277
-
278
- addObservers: function(element) {
279
- Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
280
- Event.observe(element, "click", this.onClick.bindAsEventListener(this));
281
- },
282
-
283
- onObserverEvent: function() {
284
- this.changed = false;
285
- if(this.getToken().length>=this.options.minChars) {
286
- this.startIndicator();
287
- this.getUpdatedChoices();
288
- } else {
289
- this.active = false;
290
- this.hide();
291
- }
292
- },
293
-
294
- getToken: function() {
295
- var tokenPos = this.findLastToken();
296
- if (tokenPos != -1)
297
- var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,'');
298
- else
299
- var ret = this.element.value;
300
-
301
- return /\n/.test(ret) ? '' : ret;
302
- },
303
-
304
- findLastToken: function() {
305
- var lastTokenPos = -1;
306
-
307
- for (var i=0; i<this.options.tokens.length; i++) {
308
- var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
309
- if (thisTokenPos > lastTokenPos)
310
- lastTokenPos = thisTokenPos;
311
- }
312
- return lastTokenPos;
313
- }
314
- }
315
-
316
- Ajax.Autocompleter = Class.create();
317
- Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
318
- initialize: function(element, update, url, options) {
319
- this.baseInitialize(element, update, options);
320
- this.options.asynchronous = true;
321
- this.options.onComplete = this.onComplete.bind(this);
322
- this.options.defaultParams = this.options.parameters || null;
323
- this.url = url;
324
- },
325
-
326
- getUpdatedChoices: function() {
327
- entry = encodeURIComponent(this.options.paramName) + '=' +
328
- encodeURIComponent(this.getToken());
329
-
330
- this.options.parameters = this.options.callback ?
331
- this.options.callback(this.element, entry) : entry;
332
-
333
- if(this.options.defaultParams)
334
- this.options.parameters += '&' + this.options.defaultParams;
335
-
336
- new Ajax.Request(this.url, this.options);
337
- },
338
-
339
- onComplete: function(request) {
340
- this.updateChoices(request.responseText);
341
- }
342
-
343
- });
344
-
345
- // The local array autocompleter. Used when you'd prefer to
346
- // inject an array of autocompletion options into the page, rather
347
- // than sending out Ajax queries, which can be quite slow sometimes.
348
- //
349
- // The constructor takes four parameters. The first two are, as usual,
350
- // the id of the monitored textbox, and id of the autocompletion menu.
351
- // The third is the array you want to autocomplete from, and the fourth
352
- // is the options block.
353
- //
354
- // Extra local autocompletion options:
355
- // - choices - How many autocompletion choices to offer
356
- //
357
- // - partialSearch - If false, the autocompleter will match entered
358
- // text only at the beginning of strings in the
359
- // autocomplete array. Defaults to true, which will
360
- // match text at the beginning of any *word* in the
361
- // strings in the autocomplete array. If you want to
362
- // search anywhere in the string, additionally set
363
- // the option fullSearch to true (default: off).
364
- //
365
- // - fullSsearch - Search anywhere in autocomplete array strings.
366
- //
367
- // - partialChars - How many characters to enter before triggering
368
- // a partial match (unlike minChars, which defines
369
- // how many characters are required to do any match
370
- // at all). Defaults to 2.
371
- //
372
- // - ignoreCase - Whether to ignore case when autocompleting.
373
- // Defaults to true.
374
- //
375
- // It's possible to pass in a custom function as the 'selector'
376
- // option, if you prefer to write your own autocompletion logic.
377
- // In that case, the other options above will not apply unless
378
- // you support them.
379
-
380
- Autocompleter.Local = Class.create();
381
- Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
382
- initialize: function(element, update, array, options) {
383
- this.baseInitialize(element, update, options);
384
- this.options.array = array;
385
- },
386
-
387
- getUpdatedChoices: function() {
388
- this.updateChoices(this.options.selector(this));
389
- },
390
-
391
- setOptions: function(options) {
392
- this.options = Object.extend({
393
- choices: 10,
394
- partialSearch: true,
395
- partialChars: 2,
396
- ignoreCase: true,
397
- fullSearch: false,
398
- selector: function(instance) {
399
- var ret = []; // Beginning matches
400
- var partial = []; // Inside matches
401
- var entry = instance.getToken();
402
- var count = 0;
403
-
404
- for (var i = 0; i < instance.options.array.length &&
405
- ret.length < instance.options.choices ; i++) {
406
-
407
- var elem = instance.options.array[i];
408
- var foundPos = instance.options.ignoreCase ?
409
- elem.toLowerCase().indexOf(entry.toLowerCase()) :
410
- elem.indexOf(entry);
411
-
412
- while (foundPos != -1) {
413
- if (foundPos == 0 && elem.length != entry.length) {
414
- ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
415
- elem.substr(entry.length) + "</li>");
416
- break;
417
- } else if (entry.length >= instance.options.partialChars &&
418
- instance.options.partialSearch && foundPos != -1) {
419
- if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
420
- partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
421
- elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
422
- foundPos + entry.length) + "</li>");
423
- break;
424
- }
425
- }
426
-
427
- foundPos = instance.options.ignoreCase ?
428
- elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
429
- elem.indexOf(entry, foundPos + 1);
430
-
431
- }
432
- }
433
- if (partial.length)
434
- ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
435
- return "<ul>" + ret.join('') + "</ul>";
436
- }
437
- }, options || {});
438
- }
439
- });
440
-
441
- // AJAX in-place editor
442
- //
443
- // see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
444
-
445
- // Use this if you notice weird scrolling problems on some browsers,
446
- // the DOM might be a bit confused when this gets called so do this
447
- // waits 1 ms (with setTimeout) until it does the activation
448
- Field.scrollFreeActivate = function(field) {
449
- setTimeout(function() {
450
- Field.activate(field);
451
- }, 1);
452
- }
453
-
454
- Ajax.InPlaceEditor = Class.create();
455
- Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
456
- Ajax.InPlaceEditor.prototype = {
457
- initialize: function(element, url, options) {
458
- this.url = url;
459
- this.element = $(element);
460
-
461
- this.options = Object.extend({
462
- okButton: true,
463
- okText: "ok",
464
- cancelLink: true,
465
- cancelText: "cancel",
466
- savingText: "Saving...",
467
- clickToEditText: "Click to edit",
468
- okText: "ok",
469
- rows: 1,
470
- onComplete: function(transport, element) {
471
- new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
472
- },
473
- onFailure: function(transport) {
474
- alert("Error communicating with the server: " + transport.responseText.stripTags());
475
- },
476
- callback: function(form) {
477
- return Form.serialize(form);
478
- },
479
- handleLineBreaks: true,
480
- loadingText: 'Loading...',
481
- savingClassName: 'inplaceeditor-saving',
482
- loadingClassName: 'inplaceeditor-loading',
483
- formClassName: 'inplaceeditor-form',
484
- highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
485
- highlightendcolor: "#FFFFFF",
486
- externalControl: null,
487
- submitOnBlur: false,
488
- ajaxOptions: {},
489
- evalScripts: false
490
- }, options || {});
491
-
492
- if(!this.options.formId && this.element.id) {
493
- this.options.formId = this.element.id + "-inplaceeditor";
494
- if ($(this.options.formId)) {
495
- // there's already a form with that name, don't specify an id
496
- this.options.formId = null;
497
- }
498
- }
499
-
500
- if (this.options.externalControl) {
501
- this.options.externalControl = $(this.options.externalControl);
502
- }
503
-
504
- this.originalBackground = Element.getStyle(this.element, 'background-color');
505
- if (!this.originalBackground) {
506
- this.originalBackground = "transparent";
507
- }
508
-
509
- this.element.title = this.options.clickToEditText;
510
-
511
- this.onclickListener = this.enterEditMode.bindAsEventListener(this);
512
- this.mouseoverListener = this.enterHover.bindAsEventListener(this);
513
- this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
514
- Event.observe(this.element, 'click', this.onclickListener);
515
- Event.observe(this.element, 'mouseover', this.mouseoverListener);
516
- Event.observe(this.element, 'mouseout', this.mouseoutListener);
517
- if (this.options.externalControl) {
518
- Event.observe(this.options.externalControl, 'click', this.onclickListener);
519
- Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
520
- Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
521
- }
522
- },
523
- enterEditMode: function(evt) {
524
- if (this.saving) return;
525
- if (this.editing) return;
526
- this.editing = true;
527
- this.onEnterEditMode();
528
- if (this.options.externalControl) {
529
- Element.hide(this.options.externalControl);
530
- }
531
- Element.hide(this.element);
532
- this.createForm();
533
- this.element.parentNode.insertBefore(this.form, this.element);
534
- Field.scrollFreeActivate(this.editField);
535
- // stop the event to avoid a page refresh in Safari
536
- if (evt) {
537
- Event.stop(evt);
538
- }
539
- return false;
540
- },
541
- createForm: function() {
542
- this.form = document.createElement("form");
543
- this.form.id = this.options.formId;
544
- Element.addClassName(this.form, this.options.formClassName)
545
- this.form.onsubmit = this.onSubmit.bind(this);
546
-
547
- this.createEditField();
548
-
549
- if (this.options.textarea) {
550
- var br = document.createElement("br");
551
- this.form.appendChild(br);
552
- }
553
-
554
- if (this.options.okButton) {
555
- okButton = document.createElement("input");
556
- okButton.type = "submit";
557
- okButton.value = this.options.okText;
558
- okButton.className = 'editor_ok_button';
559
- this.form.appendChild(okButton);
560
- }
561
-
562
- if (this.options.cancelLink) {
563
- cancelLink = document.createElement("a");
564
- cancelLink.href = "#";
565
- cancelLink.appendChild(document.createTextNode(this.options.cancelText));
566
- cancelLink.onclick = this.onclickCancel.bind(this);
567
- cancelLink.className = 'editor_cancel';
568
- this.form.appendChild(cancelLink);
569
- }
570
- },
571
- hasHTMLLineBreaks: function(string) {
572
- if (!this.options.handleLineBreaks) return false;
573
- return string.match(/<br/i) || string.match(/<p>/i);
574
- },
575
- convertHTMLLineBreaks: function(string) {
576
- return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
577
- },
578
- createEditField: function() {
579
- var text;
580
- if(this.options.loadTextURL) {
581
- text = this.options.loadingText;
582
- } else {
583
- text = this.getText();
584
- }
585
-
586
- var obj = this;
587
-
588
- if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
589
- this.options.textarea = false;
590
- var textField = document.createElement("input");
591
- textField.obj = this;
592
- textField.type = "text";
593
- textField.name = "value";
594
- textField.value = text;
595
- textField.style.backgroundColor = this.options.highlightcolor;
596
- textField.className = 'editor_field';
597
- var size = this.options.size || this.options.cols || 0;
598
- if (size != 0) textField.size = size;
599
- if (this.options.submitOnBlur)
600
- textField.onblur = this.onSubmit.bind(this);
601
- this.editField = textField;
602
- } else {
603
- this.options.textarea = true;
604
- var textArea = document.createElement("textarea");
605
- textArea.obj = this;
606
- textArea.name = "value";
607
- textArea.value = this.convertHTMLLineBreaks(text);
608
- textArea.rows = this.options.rows;
609
- textArea.cols = this.options.cols || 40;
610
- textArea.className = 'editor_field';
611
- if (this.options.submitOnBlur)
612
- textArea.onblur = this.onSubmit.bind(this);
613
- this.editField = textArea;
614
- }
615
-
616
- if(this.options.loadTextURL) {
617
- this.loadExternalText();
618
- }
619
- this.form.appendChild(this.editField);
620
- },
621
- getText: function() {
622
- return this.element.innerHTML;
623
- },
624
- loadExternalText: function() {
625
- Element.addClassName(this.form, this.options.loadingClassName);
626
- this.editField.disabled = true;
627
- new Ajax.Request(
628
- this.options.loadTextURL,
629
- Object.extend({
630
- asynchronous: true,
631
- onComplete: this.onLoadedExternalText.bind(this)
632
- }, this.options.ajaxOptions)
633
- );
634
- },
635
- onLoadedExternalText: function(transport) {
636
- Element.removeClassName(this.form, this.options.loadingClassName);
637
- this.editField.disabled = false;
638
- this.editField.value = transport.responseText.stripTags();
639
- },
640
- onclickCancel: function() {
641
- this.onComplete();
642
- this.leaveEditMode();
643
- return false;
644
- },
645
- onFailure: function(transport) {
646
- this.options.onFailure(transport);
647
- if (this.oldInnerHTML) {
648
- this.element.innerHTML = this.oldInnerHTML;
649
- this.oldInnerHTML = null;
650
- }
651
- return false;
652
- },
653
- onSubmit: function() {
654
- // onLoading resets these so we need to save them away for the Ajax call
655
- var form = this.form;
656
- var value = this.editField.value;
657
-
658
- // do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
659
- // which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
660
- // to be displayed indefinitely
661
- this.onLoading();
662
-
663
- if (this.options.evalScripts) {
664
- new Ajax.Request(
665
- this.url, Object.extend({
666
- parameters: this.options.callback(form, value),
667
- onComplete: this.onComplete.bind(this),
668
- onFailure: this.onFailure.bind(this),
669
- asynchronous:true,
670
- evalScripts:true
671
- }, this.options.ajaxOptions));
672
- } else {
673
- new Ajax.Updater(
674
- { success: this.element,
675
- // don't update on failure (this could be an option)
676
- failure: null },
677
- this.url, Object.extend({
678
- parameters: this.options.callback(form, value),
679
- onComplete: this.onComplete.bind(this),
680
- onFailure: this.onFailure.bind(this)
681
- }, this.options.ajaxOptions));
682
- }
683
- // stop the event to avoid a page refresh in Safari
684
- if (arguments.length > 1) {
685
- Event.stop(arguments[0]);
686
- }
687
- return false;
688
- },
689
- onLoading: function() {
690
- this.saving = true;
691
- this.removeForm();
692
- this.leaveHover();
693
- this.showSaving();
694
- },
695
- showSaving: function() {
696
- this.oldInnerHTML = this.element.innerHTML;
697
- this.element.innerHTML = this.options.savingText;
698
- Element.addClassName(this.element, this.options.savingClassName);
699
- this.element.style.backgroundColor = this.originalBackground;
700
- Element.show(this.element);
701
- },
702
- removeForm: function() {
703
- if(this.form) {
704
- if (this.form.parentNode) Element.remove(this.form);
705
- this.form = null;
706
- }
707
- },
708
- enterHover: function() {
709
- if (this.saving) return;
710
- this.element.style.backgroundColor = this.options.highlightcolor;
711
- if (this.effect) {
712
- this.effect.cancel();
713
- }
714
- Element.addClassName(this.element, this.options.hoverClassName)
715
- },
716
- leaveHover: function() {
717
- if (this.options.backgroundColor) {
718
- this.element.style.backgroundColor = this.oldBackground;
719
- }
720
- Element.removeClassName(this.element, this.options.hoverClassName)
721
- if (this.saving) return;
722
- this.effect = new Effect.Highlight(this.element, {
723
- startcolor: this.options.highlightcolor,
724
- endcolor: this.options.highlightendcolor,
725
- restorecolor: this.originalBackground
726
- });
727
- },
728
- leaveEditMode: function() {
729
- Element.removeClassName(this.element, this.options.savingClassName);
730
- this.removeForm();
731
- this.leaveHover();
732
- this.element.style.backgroundColor = this.originalBackground;
733
- Element.show(this.element);
734
- if (this.options.externalControl) {
735
- Element.show(this.options.externalControl);
736
- }
737
- this.editing = false;
738
- this.saving = false;
739
- this.oldInnerHTML = null;
740
- this.onLeaveEditMode();
741
- },
742
- onComplete: function(transport) {
743
- this.leaveEditMode();
744
- this.options.onComplete.bind(this)(transport, this.element);
745
- },
746
- onEnterEditMode: function() {},
747
- onLeaveEditMode: function() {},
748
- dispose: function() {
749
- if (this.oldInnerHTML) {
750
- this.element.innerHTML = this.oldInnerHTML;
751
- }
752
- this.leaveEditMode();
753
- Event.stopObserving(this.element, 'click', this.onclickListener);
754
- Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
755
- Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
756
- if (this.options.externalControl) {
757
- Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
758
- Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
759
- Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
760
- }
761
- }
762
- };
763
-
764
- Ajax.InPlaceCollectionEditor = Class.create();
765
- Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
766
- Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
767
- createEditField: function() {
768
- if (!this.cached_selectTag) {
769
- var selectTag = document.createElement("select");
770
- var collection = this.options.collection || [];
771
- var optionTag;
772
- collection.each(function(e,i) {
773
- optionTag = document.createElement("option");
774
- optionTag.value = (e instanceof Array) ? e[0] : e;
775
- if(this.options.value==optionTag.value) optionTag.selected = true;
776
- optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
777
- selectTag.appendChild(optionTag);
778
- }.bind(this));
779
- this.cached_selectTag = selectTag;
780
- }
781
-
782
- this.editField = this.cached_selectTag;
783
- if(this.options.loadTextURL) this.loadExternalText();
784
- this.form.appendChild(this.editField);
785
- this.options.callback = function(form, value) {
786
- return "value=" + encodeURIComponent(value);
787
- }
788
- }
789
- });
790
-
791
- // Delayed observer, like Form.Element.Observer,
792
- // but waits for delay after last key input
793
- // Ideal for live-search fields
794
-
795
- Form.Element.DelayedObserver = Class.create();
796
- Form.Element.DelayedObserver.prototype = {
797
- initialize: function(element, delay, callback) {
798
- this.delay = delay || 0.5;
799
- this.element = $(element);
800
- this.callback = callback;
801
- this.timer = null;
802
- this.lastValue = $F(this.element);
803
- Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
804
- },
805
- delayedListener: function(event) {
806
- if(this.lastValue == $F(this.element)) return;
807
- if(this.timer) clearTimeout(this.timer);
808
- this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
809
- this.lastValue = $F(this.element);
810
- },
811
- onTimerEvent: function() {
812
- this.timer = null;
813
- this.callback(this.element, $F(this.element));
814
- }
815
- };