gluttonberg-core 2.6.4 → 3.0.0

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 (613) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +29 -3
  3. data/Rakefile +32 -15
  4. data/app/assets/images/chosen-sprite-2x.png +0 -0
  5. data/app/assets/images/chosen-sprite.png +0 -0
  6. data/app/assets/images/{library/gb_sort_by_asc.png → gb_sort_by_asc.png} +0 -0
  7. data/app/assets/images/{library/gb_sort_by_desc.png → gb_sort_by_desc.png} +0 -0
  8. data/app/assets/javascripts/chosen-jquery-min.js +2 -0
  9. data/app/assets/javascripts/gb_360player.js +676 -0
  10. data/app/assets/javascripts/gb_application.js +708 -463
  11. data/app/assets/javascripts/gb_html5.js +9 -0
  12. data/app/assets/javascripts/gb_jeditable.js +356 -356
  13. data/app/assets/javascripts/gb_jquery-nestable.js +490 -0
  14. data/app/assets/javascripts/gb_utils.js +1808 -0
  15. data/app/assets/javascripts/gluttonberg.js +26 -0
  16. data/app/assets/javascripts/jcrop/css/gb_jquery-Jcrop.css +163 -31
  17. data/app/assets/javascripts/jcrop/js/jquery-Jcrop-min.js +19 -243
  18. data/app/assets/javascripts/jquery-1-10-1.js +6 -0
  19. data/app/assets/javascripts/jquery-ui-1-10-3.custom-min.js +6 -0
  20. data/app/assets/javascripts/jquery-validate.js +652 -718
  21. data/app/assets/javascripts/rails.js +372 -106
  22. data/app/assets/javascripts/redactormin.js +7348 -0
  23. data/app/assets/stylesheets/chosen.css +430 -0
  24. data/app/assets/stylesheets/gb_360player.css +2 -10
  25. data/app/assets/stylesheets/gb_admin-override.sass +466 -22
  26. data/app/assets/stylesheets/gb_bootstrap.css +7 -1
  27. data/app/assets/stylesheets/gluttonberg.css +17 -0
  28. data/app/assets/stylesheets/redactor.css +864 -0
  29. data/app/assets/stylesheets/user-styles.sass +0 -3
  30. data/app/controllers/gluttonberg/admin/asset_library/assets_ajax_controller.rb +65 -0
  31. data/app/controllers/gluttonberg/admin/asset_library/assets_bulk_controller.rb +47 -0
  32. data/app/controllers/gluttonberg/admin/asset_library/assets_controller.rb +43 -266
  33. data/app/controllers/gluttonberg/admin/asset_library/base_controller.rb +29 -0
  34. data/app/controllers/gluttonberg/admin/asset_library/collections_controller.rb +11 -37
  35. data/app/controllers/gluttonberg/admin/base_controller.rb +117 -178
  36. data/app/controllers/gluttonberg/admin/content/auto_save_controller.rb +63 -0
  37. data/app/controllers/gluttonberg/admin/content/flag_controller.rb +6 -6
  38. data/app/controllers/gluttonberg/admin/content/galleries_controller.rb +29 -37
  39. data/app/controllers/gluttonberg/admin/content/page_localizations_controller.rb +82 -49
  40. data/app/controllers/gluttonberg/admin/content/pages_controller.rb +59 -32
  41. data/app/controllers/gluttonberg/admin/main_controller.rb +77 -7
  42. data/app/controllers/gluttonberg/admin/membership/base_controller.rb +2 -1
  43. data/app/controllers/gluttonberg/admin/membership/groups_controller.rb +27 -33
  44. data/app/controllers/gluttonberg/admin/membership/main_controller.rb +3 -2
  45. data/app/controllers/gluttonberg/admin/membership/members_controller.rb +37 -42
  46. data/app/controllers/gluttonberg/admin/password_resets_controller.rb +16 -28
  47. data/app/controllers/gluttonberg/admin/settings/configurations_controller.rb +101 -0
  48. data/app/controllers/gluttonberg/admin/settings/embeds_controller.rb +79 -0
  49. data/app/controllers/gluttonberg/admin/settings/locales_controller.rb +22 -28
  50. data/app/controllers/gluttonberg/admin/settings/stylesheets_controller.rb +31 -36
  51. data/app/controllers/gluttonberg/admin/settings/users_controller.rb +45 -40
  52. data/app/controllers/gluttonberg/base_controller.rb +95 -0
  53. data/app/controllers/gluttonberg/public/base_controller.rb +104 -157
  54. data/app/controllers/gluttonberg/public/flag_controller.rb +2 -7
  55. data/app/controllers/gluttonberg/public/gallery_controller.rb +1 -0
  56. data/app/controllers/gluttonberg/public/member_password_resets_controller.rb +5 -17
  57. data/app/controllers/gluttonberg/public/members_controller.rb +5 -15
  58. data/app/controllers/gluttonberg/public/pages_controller.rb +25 -14
  59. data/app/controllers/gluttonberg/public/public_assets_controller.rb +4 -2
  60. data/app/helpers/gluttonberg/admin.rb +86 -368
  61. data/app/helpers/gluttonberg/admin/assets.rb +84 -0
  62. data/app/helpers/gluttonberg/admin/form.rb +159 -0
  63. data/app/helpers/gluttonberg/admin/messages.rb +32 -0
  64. data/app/helpers/gluttonberg/admin/versioning.rb +196 -0
  65. data/app/helpers/gluttonberg/application_helper.rb +34 -7
  66. data/app/helpers/gluttonberg/asset_library.rb +29 -254
  67. data/app/helpers/gluttonberg/content_helpers.rb +17 -69
  68. data/app/helpers/gluttonberg/deprecated.rb +24 -0
  69. data/app/helpers/gluttonberg/public.rb +51 -244
  70. data/app/helpers/gluttonberg/public/assets.rb +31 -0
  71. data/app/helpers/gluttonberg/public/cms_stylesheets.rb +35 -0
  72. data/app/helpers/gluttonberg/public/html_truncate.rb +74 -0
  73. data/app/helpers/gluttonberg/public/meta_tags.rb +27 -0
  74. data/app/helpers/gluttonberg/public/nav_tree.rb +99 -0
  75. data/app/helpers/gluttonberg/public/page_info.rb +168 -0
  76. data/app/mailer/gluttonberg/base_notifier.rb +25 -0
  77. data/app/mailer/member_notifier.rb +8 -20
  78. data/app/mailer/notifier.rb +14 -39
  79. data/app/models/ability.rb +48 -34
  80. data/app/models/flag.rb +7 -7
  81. data/app/models/gluttonberg/asset.rb +115 -166
  82. data/app/models/gluttonberg/asset_bulk_import.rb +70 -0
  83. data/app/models/gluttonberg/asset_category.rb +75 -29
  84. data/app/models/gluttonberg/asset_collection.rb +65 -12
  85. data/app/models/gluttonberg/asset_mime_type.rb +5 -0
  86. data/app/models/gluttonberg/asset_thumbnail.rb +6 -1
  87. data/app/models/gluttonberg/asset_type.rb +49 -38
  88. data/app/models/gluttonberg/audio_asset_attribute.rb +7 -3
  89. data/app/models/gluttonberg/authorization.rb +10 -0
  90. data/app/models/gluttonberg/auto_save.rb +32 -0
  91. data/app/models/gluttonberg/collapsed_page.rb +13 -0
  92. data/app/models/gluttonberg/embed.rb +13 -0
  93. data/app/models/gluttonberg/feed.rb +14 -5
  94. data/app/models/gluttonberg/gallery.rb +35 -9
  95. data/app/models/gluttonberg/gallery_image.rb +9 -2
  96. data/app/models/gluttonberg/group.rb +18 -2
  97. data/app/models/gluttonberg/html_content.rb +5 -1
  98. data/app/models/gluttonberg/image_content.rb +5 -1
  99. data/app/models/gluttonberg/locale.rb +28 -9
  100. data/app/models/gluttonberg/member.rb +48 -197
  101. data/app/models/gluttonberg/page.rb +78 -288
  102. data/app/models/gluttonberg/page_localization.rb +63 -66
  103. data/app/models/gluttonberg/plain_text_content.rb +6 -0
  104. data/app/models/gluttonberg/repeater.rb +30 -0
  105. data/app/models/gluttonberg/search.rb +96 -72
  106. data/app/models/gluttonberg/select_content.rb +12 -0
  107. data/app/models/gluttonberg/setting.rb +79 -29
  108. data/app/models/gluttonberg/sitemap.rb +1 -0
  109. data/app/models/gluttonberg/stylesheet.rb +12 -6
  110. data/app/models/gluttonberg/textarea_content.rb +14 -0
  111. data/app/models/gluttonberg/version.rb +9 -0
  112. data/app/models/user.rb +137 -13
  113. data/app/observers/gluttonberg/locale_observer.rb +33 -22
  114. data/app/observers/gluttonberg/page_localization_observer.rb +22 -12
  115. data/app/observers/gluttonberg/page_observer.rb +50 -35
  116. data/app/views/{gluttonberg/public/exceptions → exceptions}/access_denied.html.haml +0 -0
  117. data/app/views/{gluttonberg/public/exceptions → exceptions}/not_found.html.haml +0 -0
  118. data/app/views/gluttonberg/admin/asset_library/assets/_browser_root.html.haml +17 -12
  119. data/app/views/gluttonberg/admin/asset_library/assets/_form.html.haml +5 -7
  120. data/app/views/gluttonberg/admin/asset_library/assets/browser.html.haml +5 -5
  121. data/app/views/gluttonberg/admin/asset_library/assets/show.html.haml +13 -7
  122. data/app/views/gluttonberg/admin/asset_library/assets/show.json.rabl +3 -0
  123. data/app/views/gluttonberg/admin/asset_library/{assets → assets_ajax}/browser_collection.json.haml +0 -0
  124. data/app/views/gluttonberg/admin/asset_library/{assets → assets_bulk}/add_assets_in_bulk.html.haml +6 -20
  125. data/app/views/gluttonberg/admin/asset_library/{assets → assets_bulk}/create_assets_in_bulk.html.haml +0 -0
  126. data/app/views/gluttonberg/admin/asset_library/collections/_form.html.haml +8 -5
  127. data/app/views/gluttonberg/admin/asset_library/shared/_asset_browser.html.haml +34 -0
  128. data/app/views/gluttonberg/admin/asset_library/shared/_asset_panels.html.haml +15 -11
  129. data/app/views/gluttonberg/admin/content/editors/_html_content.html.haml +2 -2
  130. data/app/views/gluttonberg/admin/content/editors/_select_content.html.haml +7 -0
  131. data/app/views/gluttonberg/admin/content/editors/_textarea_content.html.haml +6 -0
  132. data/app/views/gluttonberg/admin/content/flag/index.html.haml +48 -39
  133. data/app/views/gluttonberg/admin/content/galleries/_form.html.haml +46 -9
  134. data/app/views/gluttonberg/admin/content/galleries/_image_repeater.html.haml +30 -0
  135. data/app/views/gluttonberg/admin/content/galleries/edit.html.haml +1 -12
  136. data/app/views/gluttonberg/admin/content/galleries/index.html.haml +18 -9
  137. data/app/views/gluttonberg/admin/content/galleries/new.html.haml +1 -1
  138. data/app/views/gluttonberg/admin/content/main/_sidebar.html.haml +28 -16
  139. data/app/views/gluttonberg/admin/content/page_localizations/_form.html.haml +11 -20
  140. data/app/views/gluttonberg/admin/content/page_localizations/edit.html.haml +7 -0
  141. data/app/views/gluttonberg/admin/content/pages/_form.html.haml +11 -4
  142. data/app/views/gluttonberg/admin/content/pages/_page_settings.html.haml +4 -7
  143. data/app/views/gluttonberg/admin/content/pages/_row.html.haml +38 -30
  144. data/app/views/gluttonberg/admin/content/pages/index.html.haml +23 -15
  145. data/app/views/gluttonberg/admin/content/pages/pages_list_for_tinymce.html.haml +14 -3
  146. data/app/views/gluttonberg/admin/content/pages/show.html.haml +1 -1
  147. data/app/views/gluttonberg/admin/main/index.html.haml +13 -12
  148. data/app/views/gluttonberg/admin/main/waiting_for_approval.html.haml +33 -0
  149. data/app/views/gluttonberg/admin/membership/groups/index.html.haml +5 -5
  150. data/app/views/gluttonberg/admin/membership/members/_form.html.haml +3 -1
  151. data/app/views/gluttonberg/admin/membership/members/edit.html.haml +1 -0
  152. data/app/views/gluttonberg/admin/membership/members/index.html.haml +1 -1
  153. data/app/views/gluttonberg/admin/password_resets/edit.html.haml +36 -16
  154. data/app/views/gluttonberg/admin/password_resets/new.html.haml +19 -11
  155. data/app/views/gluttonberg/admin/settings/configurations/_form.html.haml +28 -0
  156. data/app/views/gluttonberg/admin/settings/configurations/_settings_table.html.haml +42 -0
  157. data/app/views/gluttonberg/admin/settings/{generic_settings → configurations}/_value_tag.html.haml +0 -0
  158. data/app/views/gluttonberg/admin/settings/configurations/edit.html.haml +4 -0
  159. data/app/views/gluttonberg/admin/settings/configurations/index.html.haml +31 -0
  160. data/app/views/gluttonberg/admin/settings/{generic_settings → configurations}/new.html.haml +2 -2
  161. data/app/views/gluttonberg/admin/settings/embeds/_form.html.haml +19 -0
  162. data/app/views/gluttonberg/admin/settings/embeds/edit.html.haml +12 -0
  163. data/app/views/gluttonberg/admin/settings/embeds/index.html.haml +36 -0
  164. data/app/views/gluttonberg/admin/settings/embeds/list_for_redactor.html.haml +29 -0
  165. data/app/views/gluttonberg/admin/settings/embeds/new.html.haml +12 -0
  166. data/app/views/gluttonberg/admin/settings/locales/edit.html.haml +9 -1
  167. data/app/views/gluttonberg/admin/settings/locales/index.html.haml +2 -1
  168. data/app/views/gluttonberg/admin/settings/locales/new.html.haml +10 -1
  169. data/app/views/gluttonberg/admin/settings/main/_sidebar.html.haml +9 -7
  170. data/app/views/gluttonberg/admin/settings/stylesheets/_form.html.haml +11 -9
  171. data/app/views/gluttonberg/admin/settings/stylesheets/edit.html.haml +11 -2
  172. data/app/views/gluttonberg/admin/settings/stylesheets/index.html.haml +45 -36
  173. data/app/views/gluttonberg/admin/settings/stylesheets/new.html.haml +11 -2
  174. data/app/views/gluttonberg/admin/settings/users/_form.html.haml +29 -18
  175. data/app/views/gluttonberg/admin/settings/users/index.html.haml +1 -1
  176. data/app/views/gluttonberg/admin/shared/_asset_panel.html.haml +19 -4
  177. data/app/views/gluttonberg/admin/shared/_auto_save_version.html.haml +12 -0
  178. data/app/views/gluttonberg/admin/shared/_datetime_field.html.haml +19 -0
  179. data/app/views/gluttonberg/admin/shared/_previous_version_warning.html.haml +5 -0
  180. data/app/views/gluttonberg/admin/shared/_version_alerts.html.haml +34 -0
  181. data/app/views/gluttonberg/admin/shared/_version_dashboard_notifications.html.haml +11 -0
  182. data/app/views/gluttonberg/admin/shared/_version_listing.html.haml +23 -0
  183. data/app/views/gluttonberg/admin/shared/delete.html.haml +21 -48
  184. data/app/views/gluttonberg/admin/shared/generic.html.haml +20 -19
  185. data/app/views/gluttonberg/admin/user_sessions/new.html.haml +14 -9
  186. data/app/views/gluttonberg/public/member_password_resets/edit.html.haml +2 -0
  187. data/app/views/gluttonberg/public/member_password_resets/new.html.haml +3 -0
  188. data/app/views/gluttonberg/public/members/_form.html.haml +3 -0
  189. data/app/views/gluttonberg/public/members/edit.html.haml +7 -9
  190. data/app/views/gluttonberg/public/members/show.html.haml +1 -3
  191. data/app/views/gluttonberg/public/pages/restrict_site_access.html.haml +3 -4
  192. data/app/views/gluttonberg/public/shared/_gallery_images_lis.html.haml +9 -0
  193. data/app/views/layouts/_flash_messages.html.haml +5 -3
  194. data/app/views/layouts/bare.html.haml +8 -17
  195. data/app/views/layouts/gluttonberg.html.haml +37 -44
  196. data/app/views/notifier/version_declined.html.haml +21 -0
  197. data/config/locales/en_au.yml +1 -1
  198. data/config/locales/en_gb.yml +2 -1
  199. data/config/routes.rb +70 -85
  200. data/db/migrate/20130801050257_create_repeater.rb +14 -0
  201. data/lib/audio_job.rb +11 -9
  202. data/lib/engine.rb +115 -72
  203. data/lib/generators/gluttonberg/resource/resource_generator.rb +51 -41
  204. data/lib/generators/gluttonberg/resource/templates/admin_controller.rb +16 -11
  205. data/lib/generators/gluttonberg/resource/templates/backend_view_edit.html.haml +7 -2
  206. data/lib/generators/gluttonberg/resource/templates/backend_view_form.html.haml +3 -14
  207. data/lib/generators/gluttonberg/resource/templates/backend_view_import.html.haml +10 -7
  208. data/lib/generators/gluttonberg/resource/templates/backend_view_index.html.haml +6 -5
  209. data/lib/generators/gluttonberg/resource/templates/backend_view_show.html.haml +2 -2
  210. data/lib/generators/gluttonberg/resource/templates/migration.rb +12 -1
  211. data/lib/generators/gluttonberg/resource/templates/model.rb +18 -1
  212. data/lib/generators/gluttonberg/resource/templates/public_view_index.html.haml +27 -10
  213. data/lib/generators/gluttonberg/resource/templates/public_view_show.html.haml +10 -4
  214. data/lib/gluttonberg.rb +68 -37
  215. data/lib/gluttonberg/can_flag.rb +64 -76
  216. data/lib/gluttonberg/components.rb +47 -24
  217. data/lib/gluttonberg/content.rb +15 -0
  218. data/lib/gluttonberg/content/block.rb +99 -85
  219. data/lib/gluttonberg/content/block_localization.rb +11 -8
  220. data/lib/gluttonberg/content/clean_html.rb +12 -15
  221. data/lib/gluttonberg/content/default_template_file.rb +44 -0
  222. data/lib/gluttonberg/content/despamilator/filter/naughty_words.rb +4 -2
  223. data/lib/gluttonberg/content/home_page_info.rb +39 -0
  224. data/lib/gluttonberg/content/import_export_csv.rb +243 -130
  225. data/lib/gluttonberg/content/localization.rb +137 -148
  226. data/lib/gluttonberg/content/page_children.rb +36 -0
  227. data/lib/gluttonberg/content/page_components.rb +23 -0
  228. data/lib/gluttonberg/content/page_description_info.rb +55 -0
  229. data/lib/gluttonberg/content/page_duplicate.rb +68 -0
  230. data/lib/gluttonberg/content/page_finder.rb +63 -0
  231. data/lib/gluttonberg/content/page_localization_slug.rb +89 -0
  232. data/lib/gluttonberg/content/page_repairer.rb +117 -0
  233. data/lib/gluttonberg/content/publishable.rb +77 -71
  234. data/lib/gluttonberg/content/slug_management.rb +74 -26
  235. data/lib/gluttonberg/content/validations.rb +58 -0
  236. data/lib/gluttonberg/content/versioning.rb +40 -22
  237. data/lib/gluttonberg/drag_tree.rb +0 -1
  238. data/lib/gluttonberg/drag_tree/action_controller.rb +49 -37
  239. data/lib/gluttonberg/drag_tree/action_view.rb +0 -6
  240. data/lib/gluttonberg/drag_tree/active_record.rb +49 -49
  241. data/lib/gluttonberg/extensions.rb +1 -0
  242. data/lib/gluttonberg/extensions/string.rb +20 -0
  243. data/lib/gluttonberg/gb_file.rb +30 -0
  244. data/lib/gluttonberg/helpers/form_builder.rb +91 -38
  245. data/lib/gluttonberg/library.rb +9 -90
  246. data/lib/gluttonberg/library/attachment_mixin.rb +88 -98
  247. data/lib/gluttonberg/library/config/image_sizes.rb +22 -19
  248. data/lib/gluttonberg/library/default_asset_types.rb +104 -0
  249. data/lib/gluttonberg/library/processor/audio.rb +32 -16
  250. data/lib/gluttonberg/library/processor/image.rb +78 -69
  251. data/lib/gluttonberg/library/quick_magick/image.rb +72 -319
  252. data/lib/gluttonberg/library/quick_magick/image/draw.rb +133 -0
  253. data/lib/gluttonberg/library/quick_magick/image/operators_and_settings.rb +78 -0
  254. data/lib/gluttonberg/library/quick_magick/image/serialization.rb +79 -0
  255. data/lib/gluttonberg/library/quick_magick/image_list.rb +0 -1
  256. data/lib/gluttonberg/library/storage/filesystem.rb +45 -46
  257. data/lib/gluttonberg/library/storage/s3.rb +123 -119
  258. data/lib/gluttonberg/membership.rb +9 -0
  259. data/lib/gluttonberg/membership/export.rb +82 -0
  260. data/lib/gluttonberg/membership/import.rb +179 -0
  261. data/lib/gluttonberg/middleware/honeypot.rb +1 -2
  262. data/lib/gluttonberg/middleware/locales.rb +69 -18
  263. data/lib/gluttonberg/middleware/rewriter.rb +57 -16
  264. data/lib/gluttonberg/mixin_manager.rb +19 -0
  265. data/lib/gluttonberg/page_description.rb +82 -112
  266. data/lib/gluttonberg/random_string_generator.rb +31 -0
  267. data/lib/gluttonberg/record_history.rb +5 -7
  268. data/lib/gluttonberg/tasks/asset.rake +19 -8
  269. data/lib/gluttonberg/tasks/gluttonberg.rake +167 -13
  270. data/lib/gluttonberg/templates.rb +1 -3
  271. data/lib/gluttonberg/version.rb +1 -1
  272. data/lib/photo_job.rb +16 -0
  273. data/spec/controllers/auto_save_controller_spec.rb +57 -0
  274. data/spec/controllers/record_history_spec.rb +75 -0
  275. data/spec/dummy/README.rdoc +261 -0
  276. data/spec/dummy/Rakefile +7 -0
  277. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  278. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  279. data/spec/dummy/app/controllers/admin/staff_profiles_controller.rb +56 -0
  280. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  281. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  282. data/spec/dummy/app/models/staff_profile.rb +20 -0
  283. data/spec/dummy/app/models/vendor_mixin.rb +14 -0
  284. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  285. data/spec/dummy/config.ru +4 -0
  286. data/spec/dummy/config/application.rb +18 -0
  287. data/spec/dummy/config/boot.rb +10 -0
  288. data/spec/dummy/config/database.yml +8 -0
  289. data/spec/dummy/config/environment.rb +5 -0
  290. data/spec/dummy/config/environments/development.rb +37 -0
  291. data/spec/dummy/config/environments/production.rb +67 -0
  292. data/spec/dummy/config/environments/test.rb +37 -0
  293. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  294. data/spec/dummy/config/initializers/gluttonberg_advance_settings.rb +73 -0
  295. data/spec/dummy/config/initializers/gluttonberg_basic_settings.rb +65 -0
  296. data/spec/dummy/config/initializers/gluttonberg_menu_settings.rb +1 -0
  297. data/spec/dummy/config/initializers/inflections.rb +15 -0
  298. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  299. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  300. data/spec/dummy/config/initializers/session_store.rb +8 -0
  301. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  302. data/spec/dummy/config/locales/en.yml +5 -0
  303. data/{lib/generators/gluttonberg/installer/templates → spec/dummy/config}/page_descriptions.rb +103 -65
  304. data/spec/dummy/config/routes.rb +10 -0
  305. data/spec/dummy/db/20130625060411_create_staff_profile.rb +35 -0
  306. data/spec/dummy/db/schema.rb +474 -0
  307. data/spec/dummy/public/404.html +26 -0
  308. data/spec/dummy/public/422.html +26 -0
  309. data/spec/dummy/public/500.html +25 -0
  310. data/spec/dummy/public/favicon.ico +0 -0
  311. data/spec/dummy/script/rails +6 -0
  312. data/spec/dummy/tmp/cache/041/891/setting_library_number_of_recent_assets +0 -0
  313. data/spec/dummy/tmp/cache/08E/741/setting_comment_number_of_emails_allowed +0 -0
  314. data/spec/dummy/tmp/cache/580/D10/setting_title +0 -0
  315. data/spec/dummy/tmp/cache/62E/160/setting_fb_icon +0 -0
  316. data/spec/dummy/tmp/cache/6D6/FB0/setting_keywords +0 -0
  317. data/spec/dummy/tmp/cache/6D8/B60/setting_s3_key_id +0 -0
  318. data/spec/dummy/tmp/cache/6E1/A40/setting_s3_bucket +0 -0
  319. data/spec/dummy/tmp/cache/779/DF0/setting_from_email +0 -0
  320. data/spec/dummy/tmp/cache/7C5/450/setting_title_site1 +0 -0
  321. data/spec/dummy/tmp/cache/7C6/460/setting_title_site2 +0 -0
  322. data/spec/dummy/tmp/cache/802/000/setting_description +0 -0
  323. data/spec/dummy/tmp/cache/836/DD0/setting_backend_logo +0 -0
  324. data/spec/dummy/tmp/cache/862/FA0/setting_audio_assets +1 -0
  325. data/spec/dummy/tmp/cache/867/4E0/setting_video_assets +0 -0
  326. data/spec/dummy/tmp/cache/867/710/setting_enable_WYSIWYG +0 -0
  327. data/spec/dummy/tmp/cache/873/9E0/setting_fb_icon_site1 +0 -0
  328. data/spec/dummy/tmp/cache/874/9F0/setting_fb_icon_site2 +0 -0
  329. data/spec/dummy/tmp/cache/87D/A10/setting_s3_access_key +0 -0
  330. data/spec/dummy/tmp/cache/8AC/280/setting_s3_server_url +0 -0
  331. data/spec/dummy/tmp/cache/91B/730/setting_keywords_site1 +0 -0
  332. data/spec/dummy/tmp/cache/91C/740/setting_keywords_site2 +0 -0
  333. data/spec/dummy/tmp/cache/933/980/setting_auto_save_time +0 -0
  334. data/spec/dummy/tmp/cache/9BE/290/setting_from_email_site1 +0 -0
  335. data/spec/dummy/tmp/cache/9BF/2A0/setting_from_email_site2 +0 -0
  336. data/spec/dummy/tmp/cache/A02/5E0/setting_google_analytics +0 -0
  337. data/spec/dummy/tmp/cache/A47/800/setting_description_site1 +0 -0
  338. data/spec/dummy/tmp/cache/A48/810/setting_description_site2 +0 -0
  339. data/spec/dummy/tmp/cache/A69/B60/setting_comment_blacklist +0 -0
  340. data/spec/dummy/tmp/cache/B5C/D40/setting_number_of_revisions +0 -0
  341. data/spec/dummy/tmp/cache/BB3/350/setting_restrict_site_access +0 -0
  342. data/spec/dummy/tmp/cache/BB7/620/setting_comment_notification +0 -0
  343. data/spec/dummy/tmp/cache/BFB/140/setting_comment_email_as_spam +0 -0
  344. data/spec/dummy/tmp/cache/C47/DE0/setting_google_analytics_site1 +0 -0
  345. data/spec/dummy/tmp/cache/C48/DF0/setting_google_analytics_site2 +0 -0
  346. data/spec/dummy/tmp/cache/D3E/E20/setting_number_of_per_page_items +0 -0
  347. data/spec/dummy/tmp/cache/DF8/DB0/setting_restrict_site_access_site1 +0 -0
  348. data/spec/dummy/tmp/cache/DF9/DC0/setting_restrict_site_access_site2 +0 -0
  349. data/spec/dummy/tmp/cache/DFC/200/setting_comment_notification_site1 +0 -0
  350. data/spec/dummy/tmp/cache/DFD/210/setting_comment_notification_site2 +0 -0
  351. data/spec/dummy/tmp/cache/FD9/200/setting_comment_number_of_urls_allowed +0 -0
  352. data/spec/fixtures/assets/assets_import.zip +0 -0
  353. data/spec/fixtures/assets/audio.mp3 +0 -0
  354. data/spec/fixtures/assets/c3-add-interactive.mov +0 -0
  355. data/spec/fixtures/assets/gb_banner.jpg +0 -0
  356. data/spec/fixtures/assets/gb_logo.png +0 -0
  357. data/spec/fixtures/assets/high_res_photo.jpg +0 -0
  358. data/spec/fixtures/assets/untitled +0 -0
  359. data/spec/fixtures/members.csv +5 -0
  360. data/spec/fixtures/staff_profiles.csv +4 -0
  361. data/spec/helpers/public/assets_spec.rb +73 -0
  362. data/spec/helpers/public/content_helpers_spec.rb +71 -0
  363. data/spec/helpers/public/html_truncate_spec.rb +37 -0
  364. data/spec/helpers/public/meta_tags_spec.rb +29 -0
  365. data/spec/helpers/public/page_info_spec.rb +233 -0
  366. data/spec/helpers/public_spec.rb +114 -0
  367. data/spec/lib/content/import_export_csv_spec.rb +177 -0
  368. data/spec/lib/content/localization_spec.rb +107 -0
  369. data/spec/lib/content/page_finder_spec.rb +71 -0
  370. data/spec/lib/content/page_repairer_spec.rb +151 -0
  371. data/spec/lib/content/publishable_spec.rb +54 -0
  372. data/spec/lib/content/validations_spec.rb +88 -0
  373. data/spec/lib/drag_tree/action_controller_spec.rb +137 -0
  374. data/spec/lib/drag_tree/active_record_spec.rb +86 -0
  375. data/spec/lib/library/s3_rspec.rb +78 -0
  376. data/spec/lib/membership/export_spec.rb +89 -0
  377. data/spec/lib/membership/import_spec.rb +68 -0
  378. data/spec/lib/middleware/locales_spec.rb +192 -0
  379. data/spec/lib/middleware/rewriter_spec.rb +186 -0
  380. data/spec/lib/page_description_spec.rb +68 -0
  381. data/spec/mailers/member_notifier_spec.rb +140 -0
  382. data/spec/mailers/notifier_spec.rb +86 -0
  383. data/spec/models/asset_bulk_import_spec.rb +43 -0
  384. data/spec/models/asset_category_spec.rb +77 -0
  385. data/spec/models/asset_collection_spec.rb +72 -0
  386. data/spec/models/asset_spec.rb +278 -0
  387. data/spec/models/asset_type_spec.rb +109 -0
  388. data/spec/models/member_spec.rb +128 -0
  389. data/spec/models/page_localization_spec.rb +81 -0
  390. data/spec/models/page_spec.rb +221 -0
  391. data/spec/models/setting_spec.rb +49 -0
  392. data/spec/models/user_spec.rb +385 -0
  393. data/spec/observers/locale_observer_spec.rb +79 -0
  394. data/spec/observers/page_localization_observer_spec.rb +87 -0
  395. data/spec/observers/page_observer_spec.rb +130 -0
  396. data/spec/spec_helper.rb +90 -0
  397. metadata +508 -331
  398. data/app/assets/images/gb_360-button-pause-light.gif +0 -0
  399. data/app/assets/images/gb_360-button-pause-light.png +0 -0
  400. data/app/assets/images/gb_360-button-pause.gif +0 -0
  401. data/app/assets/images/gb_360-button-pause.png +0 -0
  402. data/app/assets/images/gb_360-button-play-light.gif +0 -0
  403. data/app/assets/images/gb_360-button-play-light.png +0 -0
  404. data/app/assets/images/gb_360-button-play.gif +0 -0
  405. data/app/assets/images/gb_360-button-play.png +0 -0
  406. data/app/assets/images/gb_360-button-vis-pause-light.gif +0 -0
  407. data/app/assets/images/gb_360-button-vis-pause-light.png +0 -0
  408. data/app/assets/images/gb_360-button-vis-pause.gif +0 -0
  409. data/app/assets/images/gb_360-button-vis-pause.png +0 -0
  410. data/app/assets/images/gb_360-button-vis-play-light.gif +0 -0
  411. data/app/assets/images/gb_360-button-vis-play-light.png +0 -0
  412. data/app/assets/images/gb_360-button-vis-play.gif +0 -0
  413. data/app/assets/images/gb_360-button-vis-play.png +0 -0
  414. data/app/assets/images/gb_button_bkg_grey.gif +0 -0
  415. data/app/assets/images/gb_icon_content_2.png +0 -0
  416. data/app/assets/images/gb_icon_dash.png +0 -0
  417. data/app/assets/images/gb_icon_library_2.png +0 -0
  418. data/app/assets/images/gb_page_content_fillin.gif +0 -0
  419. data/app/assets/images/gb_spinner_for_dialouge.gif +0 -0
  420. data/app/assets/images/gb_sub_nav_back_bkg.gif +0 -0
  421. data/app/assets/images/gb_subnav_bkg.gif +0 -0
  422. data/app/assets/images/gb_table_head_bkg.gif +0 -0
  423. data/app/assets/images/gb_wrapper_bkg.png +0 -0
  424. data/app/assets/images/gb_wysiwyg.png +0 -0
  425. data/app/assets/images/help/gb_help.jpg +0 -0
  426. data/app/assets/images/icons/gb_collapsed.png +0 -0
  427. data/app/assets/images/icons/gb_expanded.png +0 -0
  428. data/app/assets/images/library/gb_back.gif +0 -0
  429. data/app/assets/images/library/gb_dialog_overlay.png +0 -0
  430. data/app/assets/images/library/gb_inactive_tab.jpg +0 -0
  431. data/app/assets/images/library/gb_search_icon.gif +0 -0
  432. data/app/assets/images/library/gb_wysiwyg_pic.png +0 -0
  433. data/app/assets/javascripts/gb_ajaxfileupload.js +0 -205
  434. data/app/assets/javascripts/gb_berniecode-animator.js +0 -674
  435. data/app/assets/javascripts/gb_bootstrap-datepicker.js +0 -501
  436. data/app/assets/javascripts/gb_expander.js +0 -81
  437. data/app/assets/javascripts/gb_jquery-dragTree.js +0 -525
  438. data/app/assets/javascripts/gb_jquery-tagarea.js +0 -404
  439. data/app/assets/javascripts/gb_login.js +0 -33
  440. data/app/assets/javascripts/gb_tags.js +0 -177
  441. data/app/assets/javascripts/jquery-1-7-1.js +0 -9267
  442. data/app/assets/javascripts/jquery-dimensions-min.js +0 -12
  443. data/app/assets/javascripts/jquery-ui-1-8-23-custom-min.js +0 -85
  444. data/app/assets/javascripts/tiny_mce/jquery.tinymce.js +0 -1
  445. data/app/assets/javascripts/tiny_mce/langs/en.js +0 -223
  446. data/app/assets/javascripts/tiny_mce/plugins/advhr/css/advhr.css +0 -5
  447. data/app/assets/javascripts/tiny_mce/plugins/advhr/editor_plugin.js +0 -1
  448. data/app/assets/javascripts/tiny_mce/plugins/advhr/js/rule.js +0 -43
  449. data/app/assets/javascripts/tiny_mce/plugins/advhr/langs/en_dlg.js +0 -7
  450. data/app/assets/javascripts/tiny_mce/plugins/advhr/rule.htm +0 -58
  451. data/app/assets/javascripts/tiny_mce/plugins/advlink/css/advlink.css +0 -8
  452. data/app/assets/javascripts/tiny_mce/plugins/advlink/editor_plugin.js +0 -61
  453. data/app/assets/javascripts/tiny_mce/plugins/advlink/js/advlink.js +0 -564
  454. data/app/assets/javascripts/tiny_mce/plugins/advlink/langs/en_dlg.js +0 -54
  455. data/app/assets/javascripts/tiny_mce/plugins/advlink/link.htm +0 -355
  456. data/app/assets/javascripts/tiny_mce/plugins/advlist/editor_plugin.js +0 -1
  457. data/app/assets/javascripts/tiny_mce/plugins/autolink/editor_plugin.js +0 -1
  458. data/app/assets/javascripts/tiny_mce/plugins/fullscreen/editor_plugin.js +0 -1
  459. data/app/assets/javascripts/tiny_mce/plugins/fullscreen/fullscreen.htm +0 -109
  460. data/app/assets/javascripts/tiny_mce/plugins/gb_assets/editor_plugin.js +0 -47
  461. data/app/assets/javascripts/tiny_mce/plugins/gb_assets/editor_plugin_src.js +0 -43
  462. data/app/assets/javascripts/tiny_mce/plugins/gb_assets/emotions.htm +0 -41
  463. data/app/assets/javascripts/tiny_mce/plugins/gb_assets/js/emotions.js +0 -22
  464. data/app/assets/javascripts/tiny_mce/plugins/gb_assets/langs/en_dlg.js +0 -20
  465. data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/editor_plugin.js +0 -1
  466. data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/alert.gif +0 -0
  467. data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/button.gif +0 -0
  468. data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif +0 -0
  469. data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif +0 -0
  470. data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/corners.gif +0 -0
  471. data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif +0 -0
  472. data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif +0 -0
  473. data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css +0 -90
  474. data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/template.htm +0 -387
  475. data/app/assets/javascripts/tiny_mce/plugins/insertdatetime/editor_plugin.js +0 -1
  476. data/app/assets/javascripts/tiny_mce/plugins/lists/editor_plugin.js +0 -1
  477. data/app/assets/javascripts/tiny_mce/plugins/paste/editor_plugin.js +0 -1
  478. data/app/assets/javascripts/tiny_mce/plugins/paste/js/pastetext.js +0 -36
  479. data/app/assets/javascripts/tiny_mce/plugins/paste/js/pasteword.js +0 -51
  480. data/app/assets/javascripts/tiny_mce/plugins/paste/langs/en_dlg.js +0 -5
  481. data/app/assets/javascripts/tiny_mce/plugins/paste/pastetext.htm +0 -27
  482. data/app/assets/javascripts/tiny_mce/plugins/paste/pasteword.htm +0 -21
  483. data/app/assets/javascripts/tiny_mce/plugins/preview/editor_plugin.js +0 -1
  484. data/app/assets/javascripts/tiny_mce/plugins/preview/jscripts/embed.js +0 -73
  485. data/app/assets/javascripts/tiny_mce/plugins/preview/preview.html +0 -18
  486. data/app/assets/javascripts/tiny_mce/plugins/style/css/props.css +0 -13
  487. data/app/assets/javascripts/tiny_mce/plugins/style/editor_plugin.js +0 -1
  488. data/app/assets/javascripts/tiny_mce/plugins/style/js/props.js +0 -635
  489. data/app/assets/javascripts/tiny_mce/plugins/style/langs/en_dlg.js +0 -70
  490. data/app/assets/javascripts/tiny_mce/plugins/style/props.htm +0 -838
  491. data/app/assets/javascripts/tiny_mce/plugins/table/cell.htm +0 -180
  492. data/app/assets/javascripts/tiny_mce/plugins/table/css/cell.css +0 -17
  493. data/app/assets/javascripts/tiny_mce/plugins/table/css/row.css +0 -25
  494. data/app/assets/javascripts/tiny_mce/plugins/table/css/table.css +0 -13
  495. data/app/assets/javascripts/tiny_mce/plugins/table/editor_plugin.js +0 -1
  496. data/app/assets/javascripts/tiny_mce/plugins/table/js/cell.js +0 -319
  497. data/app/assets/javascripts/tiny_mce/plugins/table/js/merge_cells.js +0 -27
  498. data/app/assets/javascripts/tiny_mce/plugins/table/js/row.js +0 -237
  499. data/app/assets/javascripts/tiny_mce/plugins/table/js/table.js +0 -450
  500. data/app/assets/javascripts/tiny_mce/plugins/table/langs/en_dlg.js +0 -75
  501. data/app/assets/javascripts/tiny_mce/plugins/table/merge_cells.htm +0 -32
  502. data/app/assets/javascripts/tiny_mce/plugins/table/row.htm +0 -158
  503. data/app/assets/javascripts/tiny_mce/plugins/table/table.htm +0 -188
  504. data/app/assets/javascripts/tiny_mce/plugins/wordcount/editor_plugin.js +0 -1
  505. data/app/assets/javascripts/tiny_mce/themes/advanced/anchor.htm +0 -26
  506. data/app/assets/javascripts/tiny_mce/themes/advanced/editor_template.js +0 -1
  507. data/app/assets/javascripts/tiny_mce/themes/advanced/editor_template_src.js +0 -1358
  508. data/app/assets/javascripts/tiny_mce/themes/advanced/img/icons.gif +0 -0
  509. data/app/assets/javascripts/tiny_mce/themes/advanced/img/trans.gif +0 -0
  510. data/app/assets/javascripts/tiny_mce/themes/advanced/js/anchor.js +0 -42
  511. data/app/assets/javascripts/tiny_mce/themes/advanced/js/link.js +0 -153
  512. data/app/assets/javascripts/tiny_mce/themes/advanced/js/source_editor.js +0 -56
  513. data/app/assets/javascripts/tiny_mce/themes/advanced/langs/en.js +0 -68
  514. data/app/assets/javascripts/tiny_mce/themes/advanced/langs/en_dlg.js +0 -54
  515. data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/content.css +0 -47
  516. data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/dialog.css +0 -117
  517. data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/buttons.png +0 -0
  518. data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/items.gif +0 -0
  519. data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/menu_arrow.gif +0 -0
  520. data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/menu_check.gif +0 -0
  521. data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/progress.gif +0 -0
  522. data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/tabs.gif +0 -0
  523. data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/ui.css +0 -227
  524. data/app/assets/javascripts/tiny_mce/themes/advanced/source_editor.htm +0 -25
  525. data/app/assets/javascripts/tiny_mce/tiny_mce.js +0 -1
  526. data/app/assets/javascripts/tiny_mce/tiny_mce_popup.js +0 -5
  527. data/app/assets/javascripts/tiny_mce/utils/editable_selects.js +0 -70
  528. data/app/assets/javascripts/tiny_mce/utils/form_utils.js +0 -210
  529. data/app/assets/javascripts/tiny_mce/utils/mctabs.js +0 -162
  530. data/app/assets/javascripts/tiny_mce/utils/validate.js +0 -252
  531. data/app/controllers/gluttonberg/admin/content/articles_controller.rb +0 -139
  532. data/app/controllers/gluttonberg/admin/content/blogs_controller.rb +0 -101
  533. data/app/controllers/gluttonberg/admin/content/comments_controller.rb +0 -130
  534. data/app/controllers/gluttonberg/admin/content/main_controller.rb +0 -13
  535. data/app/controllers/gluttonberg/admin/help_controller.rb +0 -15
  536. data/app/controllers/gluttonberg/admin/settings/generic_settings_controller.rb +0 -90
  537. data/app/controllers/gluttonberg/admin/settings/main_controller.rb +0 -11
  538. data/app/controllers/gluttonberg/public/articles_controller.rb +0 -79
  539. data/app/controllers/gluttonberg/public/blogs_controller.rb +0 -44
  540. data/app/controllers/gluttonberg/public/comments_controller.rb +0 -46
  541. data/app/models/gluttonberg/article.rb +0 -73
  542. data/app/models/gluttonberg/article_localization.rb +0 -21
  543. data/app/models/gluttonberg/blog.rb +0 -19
  544. data/app/models/gluttonberg/comment.rb +0 -142
  545. data/app/models/gluttonberg/comment_subscription.rb +0 -28
  546. data/app/models/gluttonberg/help.rb +0 -48
  547. data/app/views/gluttonberg/admin/content/articles/_form.html.haml +0 -115
  548. data/app/views/gluttonberg/admin/content/articles/edit.html.haml +0 -11
  549. data/app/views/gluttonberg/admin/content/articles/index.html.haml +0 -71
  550. data/app/views/gluttonberg/admin/content/articles/new.html.haml +0 -11
  551. data/app/views/gluttonberg/admin/content/blogs/_form.html.haml +0 -56
  552. data/app/views/gluttonberg/admin/content/blogs/edit.html.haml +0 -3
  553. data/app/views/gluttonberg/admin/content/blogs/index.html.haml +0 -35
  554. data/app/views/gluttonberg/admin/content/blogs/new.html.haml +0 -10
  555. data/app/views/gluttonberg/admin/content/comments/index.html.haml +0 -66
  556. data/app/views/gluttonberg/admin/content/galleries/_images_list.html.haml +0 -21
  557. data/app/views/gluttonberg/admin/content/galleries/add_image.html.haml +0 -1
  558. data/app/views/gluttonberg/admin/content/main/index.html.haml +0 -20
  559. data/app/views/gluttonberg/admin/content/pages/edit_home.html.haml +0 -11
  560. data/app/views/gluttonberg/admin/exceptions/internal_server_error.html.haml +0 -11
  561. data/app/views/gluttonberg/admin/exceptions/not_acceptable.html.haml +0 -9
  562. data/app/views/gluttonberg/admin/membership/main/index.html.haml +0 -11
  563. data/app/views/gluttonberg/admin/settings/generic_settings/_form.html.haml +0 -26
  564. data/app/views/gluttonberg/admin/settings/generic_settings/edit.html.haml +0 -4
  565. data/app/views/gluttonberg/admin/settings/generic_settings/index.html.haml +0 -58
  566. data/app/views/gluttonberg/admin/settings/main/index.html.haml +0 -18
  567. data/app/views/gluttonberg/public/articles/index.rss.builder +0 -21
  568. data/app/views/gluttonberg/public/blogs/show.rss.builder +0 -21
  569. data/app/views/gluttonberg/public/exceptions/internal_server_error.html.haml +0 -11
  570. data/app/views/gluttonberg/public/exceptions/not_acceptable.html.haml +0 -9
  571. data/app/views/help/gluttonberg/admin/AssetLibrary/assets/add_assets_in_bulk.html.haml +0 -41
  572. data/app/views/help/gluttonberg/admin/AssetLibrary/assets/edit.html.haml +0 -61
  573. data/app/views/help/gluttonberg/admin/AssetLibrary/assets/index.html.haml +0 -16
  574. data/app/views/help/gluttonberg/admin/AssetLibrary/assets/new.html.haml +0 -57
  575. data/app/views/help/gluttonberg/admin/AssetLibrary/collections/edit.html.haml +0 -15
  576. data/app/views/help/gluttonberg/admin/AssetLibrary/collections/index.html.haml +0 -41
  577. data/app/views/help/gluttonberg/admin/AssetLibrary/collections/new.html.haml +0 -15
  578. data/app/views/help/gluttonberg/admin/AssetLibrary/main/index.html.haml +0 -34
  579. data/app/views/help/gluttonberg/admin/content/page_localizations/edit.html.haml +0 -89
  580. data/app/views/help/gluttonberg/admin/content/pages/_page_description_help.html.haml +0 -14
  581. data/app/views/help/gluttonberg/admin/content/pages/edit.html.haml +0 -62
  582. data/app/views/help/gluttonberg/admin/content/pages/index.html.haml +0 -111
  583. data/app/views/help/gluttonberg/admin/content/pages/new.html.haml +0 -61
  584. data/app/views/help/gluttonberg/admin/settings/dialects/edit.html.haml +0 -47
  585. data/app/views/help/gluttonberg/admin/settings/dialects/index.html.haml +0 -50
  586. data/app/views/help/gluttonberg/admin/settings/dialects/new.html.haml +0 -47
  587. data/app/views/help/gluttonberg/admin/settings/generic_settings/index.html.haml +0 -74
  588. data/app/views/help/gluttonberg/admin/settings/locales/edit.html.haml +0 -71
  589. data/app/views/help/gluttonberg/admin/settings/locales/index.html.haml +0 -57
  590. data/app/views/help/gluttonberg/admin/settings/locales/new.html.haml +0 -71
  591. data/app/views/help/gluttonberg/admin/settings/users/edit.html.haml +0 -63
  592. data/app/views/help/gluttonberg/admin/settings/users/index.html.haml +0 -60
  593. data/app/views/help/gluttonberg/admin/settings/users/new.html.haml +0 -69
  594. data/app/views/notifier/comment_notification.html.haml +0 -17
  595. data/app/views/notifier/comment_notification_for_admin.html.haml +0 -19
  596. data/db/migrate/20121106025800_add_artist_and_link_to_assets.rb +0 -6
  597. data/lib/acts_as_versioned.rb +0 -496
  598. data/lib/generators/gluttonberg/blog/blog_generator.rb +0 -46
  599. data/lib/generators/gluttonberg/blog/templates/articles_index.html.haml +0 -18
  600. data/lib/generators/gluttonberg/blog/templates/articles_show.html.haml +0 -63
  601. data/lib/generators/gluttonberg/blog/templates/articles_tag.html.haml +0 -24
  602. data/lib/generators/gluttonberg/blog/templates/blog_migration.rb +0 -90
  603. data/lib/generators/gluttonberg/blog/templates/blogs_index.html.haml +0 -15
  604. data/lib/generators/gluttonberg/blog/templates/blogs_show.html.haml +0 -25
  605. data/lib/generators/gluttonberg/installer/USAGE +0 -1
  606. data/lib/generators/gluttonberg/installer/installer_generator.rb +0 -106
  607. data/lib/generators/gluttonberg/installer/templates/delayed_job_script +0 -5
  608. data/lib/generators/gluttonberg/installer/templates/gluttonberg_migration.rb +0 -368
  609. data/lib/generators/gluttonberg/installer/templates/public.html.haml +0 -24
  610. data/lib/generators/gluttonberg/installer/templates/sitemap.rb +0 -70
  611. data/lib/gluttonberg/authorizable.rb +0 -51
  612. data/lib/gluttonberg/helpers.rb +0 -20
  613. data/lib/rails/railties/tasks.rake +0 -3
@@ -0,0 +1,1808 @@
1
+ // Utility Methods
2
+ function split( val ) {
3
+ return val.split( /,\s*/ );
4
+ }
5
+ function extractLast( term ) {
6
+ return split( term ).pop();
7
+ }
8
+
9
+ /* Very handy method to check if javascript field/variable is empty */
10
+ function blank(obj){
11
+ return obj === undefined || obj === null || obj === "null" || obj === "" || (obj.length !== undefined && obj.length <= 0) || obj == "/gray_scale_images/original/missing.png";
12
+ }
13
+
14
+ /* Add remove method to Array class for removing */
15
+ Array.prototype.remove= function(){
16
+ var what, a= arguments, L= a.length, ax;
17
+ while(L && this.length){
18
+ what= a[--L];
19
+ while((ax= this.indexOf(what))!= -1){
20
+ this.splice(ax, 1);
21
+ }
22
+ }
23
+ return this;
24
+ }
25
+
26
+
27
+ /* Jquery ajax file upload */
28
+ jQuery.extend({
29
+ handleError: function( s, xhr, status, e ) {
30
+ // If a local callback was specified, fire it
31
+ if ( s.error )
32
+ s.error( xhr, status, e );
33
+ // If we have some XML response text (e.g. from an AJAX call) then log it in the console
34
+ else if(xhr.responseText)
35
+ console.log(xhr.responseText);
36
+ },
37
+ createUploadIframe: function(id, uri)
38
+ {
39
+ //create frame
40
+ var frameId = 'jUploadFrame' + id;
41
+ var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"';
42
+ if(window.ActiveXObject)
43
+ {
44
+ if(typeof uri== 'boolean'){
45
+ iframeHtml += ' src="' + 'javascript:false' + '"';
46
+ }else if(typeof uri== 'string'){
47
+ iframeHtml += ' src="' + uri + '"';
48
+ }
49
+ }
50
+ iframeHtml += ' />';
51
+ jQuery(iframeHtml).appendTo(document.body);
52
+ return jQuery('#' + frameId).get(0);
53
+ },
54
+ createUploadForm: function(id, fileElementId, data)
55
+ {
56
+ //create form
57
+ var formId = 'jUploadForm' + id;
58
+ var fileId = 'jUploadFile' + id;
59
+ var form = jQuery('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
60
+ if(data)
61
+ {
62
+ for(var i in data)
63
+ {
64
+ jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
65
+ }
66
+ }
67
+ var oldElement = jQuery('#' + fileElementId);
68
+ var newElement = jQuery(oldElement).clone();
69
+ jQuery(oldElement).attr('id', fileId);
70
+ jQuery(oldElement).before(newElement);
71
+ jQuery(oldElement).appendTo(form);
72
+
73
+ //set attributes
74
+ jQuery(form).css('position', 'absolute');
75
+ jQuery(form).css('top', '-1200px');
76
+ jQuery(form).css('left', '-1200px');
77
+ jQuery(form).appendTo('body');
78
+ return form;
79
+ },
80
+
81
+ ajaxFileUpload: function(s) {
82
+ // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
83
+ s = jQuery.extend({}, jQuery.ajaxSettings, s);
84
+ var id = new Date().getTime()
85
+ var form = jQuery.createUploadForm(id, s.fileElementId, (typeof(s.data)=='undefined'?false:s.data));
86
+ var io = jQuery.createUploadIframe(id, s.secureuri);
87
+ var frameId = 'jUploadFrame' + id;
88
+ var formId = 'jUploadForm' + id;
89
+
90
+ // Watch for a new set of requests
91
+ if ( s.global && ! jQuery.active++ )
92
+ {
93
+ jQuery.event.trigger( "ajaxStart" );
94
+ }
95
+ var requestDone = false;
96
+ // Create the request object
97
+ var xml = {}
98
+ if ( s.global )
99
+ jQuery.event.trigger("ajaxSend", [xml, s]);
100
+ // Wait for a response to come back
101
+ var uploadCallback = function(isTimeout)
102
+ {
103
+ var io = document.getElementById(frameId);
104
+ try
105
+ {
106
+ if(io.contentWindow)
107
+ {
108
+ xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
109
+ xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
110
+ }else if(io.contentDocument)
111
+ {
112
+ xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
113
+ xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
114
+ }
115
+ }catch(e)
116
+ {
117
+ jQuery.handleError(s, xml, null, e);
118
+ }
119
+ if ( xml || isTimeout == "timeout")
120
+ {
121
+ requestDone = true;
122
+ var status;
123
+ try {
124
+ status = isTimeout != "timeout" ? "success" : "error";
125
+ // Make sure that the request was successful or notmodified
126
+ if ( status != "error" )
127
+ {
128
+ // process the data (runs the xml through httpData regardless of callback)
129
+ var data = jQuery.uploadHttpData( xml, s.dataType );
130
+ // If a local callback was specified, fire it and pass it the data
131
+ if ( s.success )
132
+ s.success( data, status );
133
+
134
+ // Fire the global callback
135
+ if( s.global )
136
+ jQuery.event.trigger( "ajaxSuccess", [xml, s] );
137
+ } else
138
+ jQuery.handleError(s, xml, status);
139
+ } catch(e)
140
+ {
141
+ status = "error";
142
+ jQuery.handleError(s, xml, status, e);
143
+ }
144
+
145
+ // The request was completed
146
+ if( s.global )
147
+ jQuery.event.trigger( "ajaxComplete", [xml, s] );
148
+
149
+ // Handle the global AJAX counter
150
+ if ( s.global && ! --jQuery.active )
151
+ jQuery.event.trigger( "ajaxStop" );
152
+
153
+ // Process result
154
+ if ( s.complete )
155
+ s.complete(xml, status);
156
+
157
+ jQuery(io).unbind()
158
+
159
+ setTimeout(function(){
160
+ try
161
+ {
162
+ jQuery(io).remove();
163
+ jQuery(form).remove();
164
+
165
+ } catch(e)
166
+ {
167
+ jQuery.handleError(s, xml, null, e);
168
+ }
169
+
170
+ }, 100)
171
+
172
+ xml = null
173
+
174
+ }
175
+ }
176
+ // Timeout checker
177
+ if ( s.timeout > 0 )
178
+ {
179
+ setTimeout(function(){
180
+ // Check to see if the request is still happening
181
+ if( !requestDone ) uploadCallback( "timeout" );
182
+ }, s.timeout);
183
+ }
184
+ try{
185
+ var form = jQuery('#' + formId);
186
+ jQuery(form).attr('action', s.url);
187
+ jQuery(form).attr('method', 'POST');
188
+ jQuery(form).attr('target', frameId);
189
+ if(form.encoding)
190
+ {
191
+ jQuery(form).attr('encoding', 'multipart/form-data');
192
+ }
193
+ else
194
+ {
195
+ jQuery(form).attr('enctype', 'multipart/form-data');
196
+ }
197
+ jQuery(form).submit();
198
+
199
+ } catch(e)
200
+ {
201
+ jQuery.handleError(s, xml, null, e);
202
+ }
203
+
204
+ jQuery('#' + frameId).load(uploadCallback);
205
+ return {abort: function () {}};
206
+ },
207
+
208
+ uploadHttpData: function( r, type ) {
209
+ var data = !type;
210
+ data = type == "xml" || data ? r.responseXML : r.responseText;
211
+ // If the type is "script", eval it in global context
212
+ if ( type == "script" )
213
+ jQuery.globalEval( data );
214
+ // Get the JavaScript object, if JSON is used.
215
+ if ( type == "json" ){
216
+ data = data.replace('<pre style="word-wrap: break-word; white-space: pre-wrap;">' , "");
217
+ data = data.replace("</pre>" , "");
218
+ data = jQuery.parseJSON(data);
219
+ }
220
+ // evaluate scripts within html
221
+ if ( type == "html" )
222
+ jQuery("<div>").html(data).evalScripts();
223
+
224
+ return data;
225
+ }
226
+ });
227
+
228
+ /* gb_tags */
229
+
230
+ $(document).ready(function() {
231
+ initStaticSingleTag("input.tag");
232
+ initStaticTagging("input.tags");
233
+ initRemoteSingleTag("input.remotetag");
234
+ initRemoteTagging("input.remotetags");
235
+ });
236
+
237
+ function initStaticTagging(tag_selector){
238
+
239
+ // don't navigate away from the field on tab when selecting an item
240
+ $( tag_selector ).bind( "keydown", function( event ) {
241
+ if ( event.keyCode === $.ui.keyCode.TAB &&
242
+ $( this ).data( "autocomplete" ).menu.active ) {
243
+ event.preventDefault();
244
+ }
245
+ })
246
+
247
+
248
+ $( tag_selector ).autocomplete({
249
+ source: function( request, response ) {
250
+ var tags = $($(this).attr('element')).attr('rel').split(",");
251
+ var query = extractLast(request.term).toLowerCase();
252
+ var matchedtags = jQuery.grep(tags, function(val, i){
253
+ return val.toLowerCase().search(query) >= 0 ;
254
+ });
255
+ response(matchedtags);
256
+ },
257
+
258
+ focus: function() {
259
+ // prevent value inserted on focus
260
+ return false;
261
+ },
262
+ select: selectEvent
263
+ });
264
+ }
265
+
266
+ function initStaticSingleTag(tag_selector){
267
+
268
+ // don't navigate away from the field on tab when selecting an item
269
+ $( tag_selector ).bind( "keydown", function( event ) {
270
+ if ( event.keyCode === $.ui.keyCode.TAB &&
271
+ $( this ).data( "autocomplete" ).menu.active ) {
272
+ event.preventDefault();
273
+ }
274
+ })
275
+
276
+
277
+ $( tag_selector ).autocomplete({
278
+ source: function( request, response ) {
279
+ var tags = $($(this).attr('element')).attr('rel').split(",");
280
+ var query = request.term.toLowerCase();
281
+ var matchedtags = jQuery.grep(tags, function(val, i){
282
+ return val.toLowerCase().search(query) >= 0 ;
283
+ });
284
+ response(matchedtags);
285
+ },
286
+
287
+ focus: function() {
288
+ // prevent value inserted on focus
289
+ return false;
290
+ },
291
+ select: selectEventForSingle
292
+ });
293
+ }
294
+
295
+ var cache = {}, lastXhr;
296
+
297
+ // response of ajax should be in this format [{"id":"Management","value":"Management","label":"Management"}]
298
+ function initRemoteTagging(tag_selector){
299
+ var progress = $($( tag_selector ).attr('data-progress'));
300
+
301
+ $( tag_selector ).autocomplete({
302
+ minLength: 2,
303
+ source: function( request, response ) {
304
+ var term = extractLast(request.term).toLowerCase();
305
+ if ( term in cache ) {
306
+ response( cache[ term ] );
307
+ return;
308
+ }
309
+ var url = $($(this).attr('element')).attr('rel');
310
+ if(progress.length >= 0){
311
+ progress.show();
312
+ }
313
+ lastXhr = $.ajax({
314
+ url: url,
315
+ dataType: 'json',
316
+ data: "term="+term,
317
+ complete: function(jqXHR , msg , ex){
318
+ var data = jQuery.parseJSON(jqXHR.responseText);
319
+ cache[ term ] = data;
320
+ if ( jqXHR === lastXhr ) {
321
+ response(data);
322
+ }
323
+ if(progress.length >= 0){
324
+ progress.hide();
325
+ }
326
+ }
327
+ });
328
+ },
329
+ focus: function() {
330
+ // prevent value inserted on focus
331
+ return false;
332
+ },
333
+ select: selectEvent
334
+ });
335
+ }
336
+
337
+ // response of ajax should be in this format [{"id":"Management","value":"Management","label":"Management"}]
338
+ function initRemoteSingleTag(tag_selector){
339
+ var progress = $($( tag_selector ).attr('data-progress'));
340
+
341
+ $( tag_selector ).autocomplete({
342
+ minLength: 2,
343
+ source: function( request, response ) {
344
+ var term = request.term.toLowerCase();
345
+ if ( term in cache ) {
346
+ response( cache[ term ] );
347
+ return;
348
+ }
349
+ var url = $($(this).attr('element')).attr('rel');
350
+ if(progress.length >= 0){
351
+ progress.show();
352
+ }
353
+ lastXhr = $.ajax({
354
+ url: url,
355
+ dataType: 'json',
356
+ data: "term="+term,
357
+ complete: function(jqXHR , msg , ex){
358
+ var data = jQuery.parseJSON(jqXHR.responseText);
359
+ cache[ term ] = data;
360
+ if ( jqXHR === lastXhr ) {
361
+ response(data);
362
+ }
363
+ if(progress.length >= 0){
364
+ progress.hide();
365
+ }
366
+ }
367
+ });
368
+ },
369
+ focus: function() {
370
+ // prevent value inserted on focus
371
+ return false;
372
+ } ,
373
+ select: selectEventForSingle
374
+ });
375
+ }
376
+
377
+
378
+ function selectEvent(event, ui){
379
+ var terms = split( this.value );
380
+ // remove the current input
381
+ terms.pop();
382
+ // add the selected item
383
+ terms.push( ui.item.value );
384
+ // add placeholder to get the comma-and-space at the end
385
+ terms.push( "" );
386
+ this.value = terms.join( ", " );
387
+ return false;
388
+ }
389
+
390
+ function selectEventForSingle(event, ui){
391
+ var target = $($( this ).attr('data-value-target'));
392
+ if(target.length > 0){
393
+ target.val(ui.item.id);
394
+ }
395
+ this.value = ui.item.value ;
396
+ return false;
397
+ }
398
+
399
+
400
+ /* gb_expander */
401
+
402
+
403
+ // Automatically create expanders
404
+ $(document).ready(function(){
405
+ $(".expandable").each(function(){
406
+ var expandable = new Expander( $(this) );
407
+ });
408
+ });
409
+
410
+ var Expander = function( expandable ){
411
+
412
+ var DEBUG_MODE = false;
413
+ var SLIDE_TIME = 300;
414
+
415
+ var thisExpandable = this;
416
+
417
+ var expandButton = $(expandable);
418
+ if( expandButton.length <= 0 ){
419
+ if( DEBUG_MODE ){
420
+ console.log("Expander: No expand button found.");
421
+ }
422
+ return false;
423
+ }
424
+ if( expandButton.length > 1 ){
425
+ if( DEBUG_MODE ){
426
+ console.log("Expander: More than one expand button found.");
427
+ }
428
+ return false;
429
+ }
430
+
431
+ var toggledElements = $("" + expandButton.attr("rel"));
432
+ if( toggledElements <= 0 ){
433
+ if( DEBUG_MODE ){
434
+ console.log("Expander: No expandable elements linked to the expand button.");
435
+ }
436
+ return false;
437
+ }
438
+
439
+ this.collapse = function( time ){
440
+
441
+ if( time < 0 ){
442
+ time = SLIDE_TIME;
443
+ }
444
+ expandButton.removeClass("expanded");
445
+ expandButton.addClass("collapsed");
446
+ toggledElements.hide();//slideUp( time );
447
+ }
448
+
449
+ this.expand = function( time ){
450
+
451
+ if( time < 0 ){
452
+ time = SLIDE_TIME;
453
+ }
454
+ expandButton.addClass("expanded");
455
+ expandButton.removeClass("collapsed");
456
+ toggledElements.show();//slideDown( time );
457
+ }
458
+
459
+ if( expandButton.hasClass("expanded") ){
460
+ expandButton.removeClass("collapsed");
461
+ this.expand(0);
462
+ }
463
+
464
+ if( expandButton.hasClass("collapsed") ){
465
+ this.collapse(0);
466
+ }
467
+
468
+ if( !expandButton.hasClass("expanded") &&
469
+ !expandButton.hasClass("collapsed") ){
470
+ this.collapse(0);
471
+ }
472
+
473
+ expandButton.click( function(){
474
+ if( expandButton.hasClass("expanded") ){
475
+ thisExpandable.collapse();
476
+ }else{
477
+ thisExpandable.expand();
478
+ }
479
+ });
480
+ }
481
+
482
+
483
+ /* gb_bootstrap-datepicker */
484
+ /* ===========================================================
485
+ * bootstrap-datepicker.js v1.3.0
486
+ * http://twitter.github.com/bootstrap/javascript.html#datepicker
487
+ * ===========================================================
488
+ * Copyright 2011 Twitter, Inc.
489
+ *
490
+ * Licensed under the Apache License, Version 2.0 (the "License");
491
+ * you may not use this file except in compliance with the License.
492
+ * You may obtain a copy of the License at
493
+ *
494
+ * http://www.apache.org/licenses/LICENSE-2.0
495
+ *
496
+ * Unless required by applicable law or agreed to in writing, software
497
+ * distributed under the License is distributed on an "AS IS" BASIS,
498
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
499
+ * See the License for the specific language governing permissions and
500
+ * limitations under the License.
501
+ *
502
+ * Contributed by Scott Torborg - github.com/storborg
503
+ * Loosely based on jquery.date_input.js by Jon Leighton, heavily updated and
504
+ * rewritten to match bootstrap javascript approach and add UI features.
505
+ * =========================================================== */
506
+
507
+
508
+ !function ( $ ) {
509
+
510
+ var selector = '[data-datepicker]',
511
+ all = [];
512
+
513
+ function clearDatePickers(except) {
514
+ var ii;
515
+ for(ii = 0; ii < all.length; ii++) {
516
+ if(all[ii] != except) {
517
+ all[ii].hide();
518
+ }
519
+ }
520
+ }
521
+
522
+ function DatePicker( element, options ) {
523
+ this.$el = $(element);
524
+ this.proxy('show').proxy('ahead').proxy('hide').proxy('keyHandler').proxy('selectDate');
525
+
526
+ var options = $.extend({}, $.fn.bsdatepicker.defaults, options );
527
+
528
+ if((!!options.parse) || (!!options.format) || !this.detectNative()) {
529
+ $.extend(this, options);
530
+ this.$el.data('bsdatepicker', this);
531
+ all.push(this);
532
+ this.init();
533
+ }
534
+ }
535
+
536
+ DatePicker.prototype = {
537
+
538
+ detectNative: function(el) {
539
+ // Attempt to activate the native datepicker, if there is a known good
540
+ // one. If successful, return true. Note that input type="date"
541
+ // requires that the string be RFC3339, so if the format/parse methods
542
+ // have been overridden, this won't be used.
543
+ if(navigator.userAgent.match(/(iPad|iPhone); CPU(\ iPhone)? OS 5_\d/i)) {
544
+ // jQuery will only change the input type of a detached element.
545
+ var $marker = $('<span>').insertBefore(this.$el);
546
+ this.$el.detach().attr('type', 'date').insertAfter($marker);
547
+ $marker.remove();
548
+ return true;
549
+ }
550
+ return false;
551
+ }
552
+
553
+ , init: function() {
554
+ var $months = this.nav('months', 1);
555
+ var $years = this.nav('years', 12);
556
+
557
+ var $nav = $('<div>').addClass('nav').append($months, $years);
558
+
559
+ this.$month = $('.name', $months);
560
+ this.$year = $('.name', $years);
561
+
562
+ $calendar = $("<div>").addClass('calendar');
563
+
564
+ // Populate day of week headers, realigned by startOfWeek.
565
+ for (var i = 0; i < this.shortDayNames.length; i++) {
566
+ $calendar.append('<div class="dow">' + this.shortDayNames[(i + this.startOfWeek) % 7] + '</div>');
567
+ };
568
+
569
+ this.$days = $('<div>').addClass('days');
570
+ $calendar.append(this.$days);
571
+
572
+ this.$picker = $('<div>')
573
+ .click(function(e) { e.stopPropagation() })
574
+ // Use this to prevent accidental text selection.
575
+ .mousedown(function(e) { e.preventDefault() })
576
+ .addClass('datepicker')
577
+ .append($nav, $calendar)
578
+ .insertAfter(this.$el);
579
+
580
+ this.$el
581
+ .focus(this.show)
582
+ .click(this.show)
583
+ .change($.proxy(function() { this.selectDate(); }, this));
584
+
585
+ this.selectDate();
586
+ this.hide();
587
+ }
588
+
589
+ , nav: function( c, months ) {
590
+ var $subnav = $('<div>' +
591
+ '<span class="prev button">&larr;</span>' +
592
+ '<span class="name"></span>' +
593
+ '<span class="next button">&rarr;</span>' +
594
+ '</div>').addClass(c)
595
+ $('.prev', $subnav).click($.proxy(function() { this.ahead(-months, 0) }, this));
596
+ $('.next', $subnav).click($.proxy(function() { this.ahead(months, 0) }, this));
597
+ return $subnav;
598
+
599
+ }
600
+
601
+ , updateName: function($area, s) {
602
+ // Update either the month or year field, with a background flash
603
+ // animation.
604
+ var cur = $area.find('.fg').text(),
605
+ $fg = $('<div>').addClass('fg').append(s);
606
+ $area.empty();
607
+ if(cur != s) {
608
+ var $bg = $('<div>').addClass('bg');
609
+ $area.append($bg, $fg);
610
+ $bg.fadeOut('slow', function() {
611
+ $(this).remove();
612
+ });
613
+ } else {
614
+ $area.append($fg);
615
+ }
616
+ }
617
+
618
+ , selectMonth: function(date) {
619
+ var newMonth = new Date(date.getFullYear(), date.getMonth(), 1);
620
+
621
+ if (!this.curMonth || !(this.curMonth.getFullYear() == newMonth.getFullYear() &&
622
+ this.curMonth.getMonth() == newMonth.getMonth())) {
623
+
624
+ this.curMonth = newMonth;
625
+
626
+ var rangeStart = this.rangeStart(date), rangeEnd = this.rangeEnd(date);
627
+ var num_days = this.daysBetween(rangeStart, rangeEnd);
628
+ this.$days.empty();
629
+
630
+ for (var ii = 0; ii <= num_days; ii++) {
631
+ var thisDay = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate() + ii, 12, 00);
632
+ var $day = $('<div>').attr('date', this.format(thisDay));
633
+ $day.text(thisDay.getDate());
634
+
635
+ if (thisDay.getMonth() != date.getMonth()) {
636
+ $day.addClass('overlap');
637
+ };
638
+
639
+ this.$days.append($day);
640
+ };
641
+
642
+ this.updateName(this.$month, this.monthNames[date.getMonth()]);
643
+ this.updateName(this.$year, this.curMonth.getFullYear());
644
+
645
+ $('div', this.$days).click($.proxy(function(e) {
646
+ var $targ = $(e.target);
647
+
648
+ // The date= attribute is used here to provide relatively fast
649
+ // selectors for setting certain date cells.
650
+ this.update($targ.attr("date"));
651
+
652
+ // Don't consider this selection final if we're just going to an
653
+ // adjacent month.
654
+ if(!$targ.hasClass('overlap')) {
655
+ this.hide();
656
+ }
657
+
658
+ }, this));
659
+
660
+ $("[date='" + this.format(new Date()) + "']", this.$days).addClass('today');
661
+
662
+ };
663
+
664
+ $('.selected', this.$days).removeClass('selected');
665
+ $('[date="' + this.selectedDateStr + '"]', this.$days).addClass('selected');
666
+ }
667
+
668
+ , selectDate: function(date) {
669
+ if (typeof(date) == "undefined") {
670
+ date = this.parse(this.$el.val());
671
+ };
672
+ if (!date) date = new Date();
673
+
674
+ this.selectedDate = date;
675
+ this.selectedDateStr = this.format(this.selectedDate);
676
+ this.selectMonth(this.selectedDate);
677
+ }
678
+
679
+ , update: function(s) {
680
+ this.$el.val(s).change();
681
+ }
682
+
683
+ , show: function(e) {
684
+ e && e.stopPropagation();
685
+
686
+ // Hide all other datepickers.
687
+ clearDatePickers(this);
688
+
689
+ this.$picker.show();
690
+
691
+ $('html').on('keydown', this.keyHandler);
692
+ }
693
+
694
+ , hide: function() {
695
+ this.$picker.hide();
696
+ $('html').off('keydown', this.keyHandler);
697
+ }
698
+
699
+ , keyHandler: function(e) {
700
+ // Keyboard navigation shortcuts.
701
+ switch (e.keyCode)
702
+ {
703
+ case 9:
704
+ case 27:
705
+ // Tab or escape hides the datepicker. In this case, just return
706
+ // instead of breaking, so that the e doesn't get stopped.
707
+ this.hide(); return;
708
+ case 13:
709
+ // Enter selects the currently highlighted date.
710
+ this.update(this.selectedDateStr); this.hide(); break;
711
+ case 38:
712
+ // Arrow up goes to prev week.
713
+ this.ahead(0, -7); break;
714
+ case 40:
715
+ // Arrow down goes to next week.
716
+ this.ahead(0, 7); break;
717
+ case 37:
718
+ // Arrow left goes to prev day.
719
+ this.ahead(0, -1); break;
720
+ case 39:
721
+ // Arrow right goes to next day.
722
+ this.ahead(0, 1); break;
723
+ default:
724
+ return;
725
+ }
726
+ e.preventDefault();
727
+ }
728
+
729
+ , parse: function(s) {
730
+ // Parse a partial RFC 3339 string into a Date.
731
+ var m;
732
+ if ((m = s.match(/^(\d{4,4})-(\d{2,2})-(\d{2,2})$/))) {
733
+ return new Date(m[1], m[2] - 1, m[3]);
734
+ } else {
735
+ return null;
736
+ }
737
+ }
738
+
739
+ , format: function(date) {
740
+ // Format a Date into a string as specified by RFC 3339.
741
+ var month = (date.getMonth() + 1).toString(),
742
+ dom = date.getDate().toString();
743
+ if (month.length === 1) {
744
+ month = '0' + month;
745
+ }
746
+ if (dom.length === 1) {
747
+ dom = '0' + dom;
748
+ }
749
+ return date.getFullYear() + '-' + month + "-" + dom;
750
+ }
751
+
752
+ , ahead: function(months, days) {
753
+ // Move ahead ``months`` months and ``days`` days, both integers, can be
754
+ // negative.
755
+ this.selectDate(new Date(this.selectedDate.getFullYear(),
756
+ this.selectedDate.getMonth() + months,
757
+ this.selectedDate.getDate() + days));
758
+ }
759
+
760
+ , proxy: function(meth) {
761
+ // Bind a method so that it always gets the datepicker instance for
762
+ // ``this``. Return ``this`` so chaining calls works.
763
+ this[meth] = $.proxy(this[meth], this);
764
+ return this;
765
+ }
766
+
767
+ , daysBetween: function(start, end) {
768
+ // Return number of days between ``start`` Date object and ``end``.
769
+ var start = Date.UTC(start.getFullYear(), start.getMonth(), start.getDate());
770
+ var end = Date.UTC(end.getFullYear(), end.getMonth(), end.getDate());
771
+ return (end - start) / 86400000;
772
+ }
773
+
774
+ , findClosest: function(dow, date, direction) {
775
+ // From a starting date, find the first day ahead of behind it that is
776
+ // a given day of the week.
777
+ var difference = direction * (Math.abs(date.getDay() - dow - (direction * 7)) % 7);
778
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate() + difference);
779
+ }
780
+
781
+ , rangeStart: function(date) {
782
+ // Get the first day to show in the current calendar view.
783
+ return this.findClosest(this.startOfWeek,
784
+ new Date(date.getFullYear(), date.getMonth()),
785
+ -1);
786
+ }
787
+
788
+ , rangeEnd: function(date) {
789
+ // Get the last day to show in the current calendar view.
790
+ return this.findClosest((this.startOfWeek - 1) % 7,
791
+ new Date(date.getFullYear(), date.getMonth() + 1, 0),
792
+ 1);
793
+ }
794
+ };
795
+
796
+ /* DATEPICKER PLUGIN DEFINITION
797
+ * ============================ */
798
+
799
+ $.fn.bsdatepicker = function( options ) {
800
+ return this.each(function() { new DatePicker(this, options); });
801
+ };
802
+
803
+ $(function() {
804
+ $(selector).bsdatepicker();
805
+ $('html').click(clearDatePickers);
806
+ });
807
+
808
+ $.fn.bsdatepicker.DatePicker = DatePicker;
809
+
810
+ $.fn.bsdatepicker.defaults = {
811
+ monthNames: ["January", "February", "March", "April", "May", "June",
812
+ "July", "August", "September", "October", "November", "December"]
813
+ , shortDayNames: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
814
+ , startOfWeek: 1
815
+ };
816
+ }( window.jQuery || window.ender );
817
+
818
+ /* Update datepicker plugin so that DD/MM/YYYY format is used. */
819
+ $.extend($.fn.bsdatepicker.defaults, {
820
+ parse: function (string) {
821
+ return parseStringIntoDate(string);
822
+ },
823
+ format: function (date) {
824
+ var
825
+ month = (date.getMonth() + 1).toString(),
826
+ dom = date.getDate().toString();
827
+ if (month.length === 1) {
828
+ month = "0" + month;
829
+ }
830
+ if (dom.length === 1) {
831
+ dom = "0" + dom;
832
+ }
833
+ return dom + "/" + month + "/" + date.getFullYear();
834
+ }
835
+ });
836
+
837
+ function parseStringIntoDate(string){
838
+ var matches;
839
+ if ((matches = string.match(/^(\d{2,2})\/(\d{2,2})\/(\d{4,4})$/))) {
840
+ return new Date(matches[3], matches[2]- 1, matches[1] );
841
+ } else {
842
+ return null;
843
+ }
844
+ }
845
+
846
+ function dbDateFormat(date){
847
+ var
848
+ month = (date.getMonth() + 1).toString(),
849
+ dom = date.getDate().toString();
850
+ if (month.length === 1) {
851
+ month = "0" + month;
852
+ }
853
+ if (dom.length === 1) {
854
+ dom = "0" + dom;
855
+ }
856
+ return date.getFullYear() + "-"+ month + "-" + dom ;
857
+ }
858
+
859
+ function combine_datetime(target_field_class){
860
+ var src_date_field = $("#"+target_field_class + "_date");
861
+ var src_time_field = $("#"+target_field_class + "_time");
862
+ var date = parseStringIntoDate(src_date_field.val());
863
+ var time = src_time_field.val();
864
+
865
+ if(time == "" || time.split(":").length !=2 ){
866
+ time = "00:00"
867
+ }else{
868
+ var hours = parseInt(time.split(":")[0] , 10);
869
+ var secondpart = time.split(":")[1];
870
+ var minutes = 0;
871
+ var am_pm = "AM";
872
+
873
+ if(secondpart.search(" ") > 0){
874
+ minutes = parseInt(secondpart.split(" ")[0],10);
875
+ am_pm = secondpart.split(" ")[1];
876
+ }else{
877
+ minutes = parseInt(secondpart.substring(0,2),10);
878
+ am_pm = secondpart.substring(2);
879
+ }
880
+
881
+ if((am_pm.toLowerCase() == "am" || am_pm.toLowerCase() == "") && hours == 12){
882
+ hours = 0
883
+ }
884
+
885
+ if(am_pm.toLowerCase() == "pm" && hours != 12){
886
+ hours += 12;
887
+ }else{
888
+
889
+ }
890
+
891
+ if(hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59){
892
+ time = hours + ":"+ minutes;
893
+ }else{
894
+ time = "00:00";
895
+ }
896
+ }
897
+
898
+
899
+
900
+ var new_val = "";
901
+ if(date != null){
902
+ new_val = dbDateFormat(date) + " " + time;
903
+
904
+ }
905
+ $("."+target_field_class).val(new_val);
906
+ }
907
+
908
+ function checkDateFormat(datefield,error_label){
909
+ date = $(datefield).val();
910
+ error_label = $(error_label)
911
+ // regular expression to match required date format
912
+ re = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
913
+
914
+ if(date != '') {
915
+ if(regs = date.match(re)) {
916
+ // day value between 1 and 31
917
+ if(regs[1] < 1 || regs[1] > 31) {
918
+ show_validation_error(error_label ,"Invalid value for day: " + regs[1]);
919
+ datefield.focus();
920
+ return false;
921
+ }
922
+ // month value between 1 and 12
923
+ if(regs[2] < 1 || regs[2] > 12) {
924
+ show_validation_error(error_label ,"Invalid value for month: " + regs[2]);
925
+ datefield.focus();
926
+ return false;
927
+ }
928
+ // year value between 1902 and 2012
929
+ if(regs[3] < 1902 || regs[3] > (new Date()).getFullYear()+2) {
930
+ show_validation_error(error_label ,"Invalid value for year: " + regs[3] + " - must be between 1902 and " + (new Date()).getFullYear()+2);
931
+ datefield.focus();
932
+ return false;
933
+ }
934
+ } else {
935
+ show_validation_error(error_label ,"Invalid date format: " + date);
936
+ datefield.focus();
937
+ return false;
938
+ }
939
+ }
940
+ error_label.html('');
941
+ }
942
+
943
+ function checkTimeFormat(timeField,error_label)
944
+ {
945
+ time = $(timeField).val();
946
+ error_label = $(error_label)
947
+ // regular expression to match required time format
948
+ re = /^(\d{1,2}):(\d{2})(\s){0,1}([a|p]m)?$/i;
949
+
950
+ if(!blank(time)) {
951
+ if(regs = time.match(re)) {
952
+ if(regs[3]) {
953
+ // 12-hour value between 1 and 12
954
+ if(regs[1] < 1 || regs[1] > 12) {
955
+ show_validation_error(error_label ,"Invalid value for hours: " + regs[1]);
956
+ timeField.focus();
957
+ return false;
958
+ }
959
+ } else {
960
+ // 12-hour value between 1 and 12
961
+ if(regs[1] < 1 || regs[1] > 12) {
962
+ show_validation_error(error_label ,"Invalid value for hours: " + regs[1]);
963
+ timeField.focus();
964
+ return false;
965
+ }
966
+ }
967
+ // minute value between 0 and 59
968
+ if(regs[2] > 59) {
969
+ show_validation_error(error_label ,"Invalid value for minutes: " + regs[2]);
970
+ timeField.focus();
971
+ return false;
972
+ }
973
+ } else {
974
+ show_validation_error(error_label ,"Invalid time format: " + timeField.value);
975
+ timeField.focus();
976
+ return false;
977
+ }
978
+ }
979
+
980
+ error_label.html('');
981
+ return true;
982
+ }
983
+
984
+ function show_validation_error(error_label , message){
985
+ error_label.html(message);
986
+ }
987
+
988
+
989
+
990
+ /* gb_jquery-dragTree */
991
+ /*
992
+ *
993
+ * jQuery dragTree Plugin 2.0. Built for Gluttonberg CMS system
994
+ *
995
+ *
996
+ * Orginal treetable code based onjQuery treeTable Plugin 2.1 -
997
+ * http://ludo.cubicphuse.nl/jquery-plugins/treeTable/
998
+ * The orginal code has been significantly modified.
999
+ *
1000
+ *
1001
+ * Call dragTreeManager.init() in your Javaascript once to initialise all
1002
+ * Drag Trees
1003
+ *
1004
+ * To make a table into a DragTree you need to do the following:
1005
+ * - set the CSS class of the table to "drag-tree"
1006
+ * - set the CSS of the element in the cell that is to be used for
1007
+ * dragging to drag-node
1008
+ *
1009
+ * - during drag operations the following CSS classes are applied
1010
+ * to the tr of the target row:
1011
+ * "insert_child": when mouse if over the row and the source will be made a child of the target
1012
+ * "insert_before": when mouse is at the "top" part of the target row and source will be insert before this row
1013
+ * "insert_after": when mouse id at the "bottom" part of the target row and source will be inserted after (or as child) of this row
1014
+ *
1015
+ * - Set each tr in the table to have a CSS ID of
1016
+ * "node-<x>" where <x> is a unique integer value
1017
+ *
1018
+ * - To make a tree set a row's css to the following class
1019
+ * "child-of-<x>" where <x> is the number assigned to the
1020
+ * nodes parent in the CSS ID "node-<x>"
1021
+ *
1022
+ */
1023
+
1024
+ (function($) {
1025
+ // Helps to make options available to all functions
1026
+ // TODO: This gives problems when there are both expandable and non-expandable
1027
+ // trees on a page. The options shouldn't be global to all these instances!
1028
+ var options;
1029
+
1030
+ $.fn.treeTable = function(opts) {
1031
+ options = $.extend({}, $.fn.treeTable.defaults, opts);
1032
+
1033
+ return this.each(function() {
1034
+ $(this).addClass("treeTable").find("tbody tr").each(function() {
1035
+ // Initialize root nodes only whenever possible
1036
+ if(!options.expandable || $(this)[0].className.search("child-of-") == -1) {
1037
+ initialize($(this));
1038
+ }
1039
+ });
1040
+ });
1041
+ };
1042
+
1043
+ $.fn.treeTable.defaults = {
1044
+ childPrefix: "child-of-",
1045
+ expandable: true,
1046
+ indent: 19,
1047
+ initialState: "collapsed",
1048
+ treeColumn: 0
1049
+ };
1050
+
1051
+ // Recursively hide all node's children in a tree
1052
+ $.fn.collapse_recursive = function() {
1053
+ $(this).addClass("collapsed");
1054
+
1055
+ childrenOf($(this)).each(function() {
1056
+ if(!$(this).hasClass("collapsed")) {
1057
+ $(this).collapse_recursive();
1058
+ }
1059
+
1060
+ $(this).hide();
1061
+ });
1062
+
1063
+ return this;
1064
+ };
1065
+
1066
+ // Recursively show all node's children in a tree
1067
+ $.fn.expand = function() {
1068
+ $(this).removeClass("collapsed").addClass("expanded");
1069
+
1070
+ childrenOf($(this)).each(function() {
1071
+ initialize($(this));
1072
+
1073
+ if($(this).is(".expanded.parent")) {
1074
+ $(this).expand();
1075
+ }
1076
+
1077
+ $(this).show();
1078
+ });
1079
+
1080
+ return this;
1081
+ };
1082
+
1083
+ // Add an entire branch to +destination+
1084
+ $.fn.appendBranchTo = function(destination, success_callback) {
1085
+ var node = $(this);
1086
+ var parent = parentOf(node);
1087
+
1088
+ var ancestorNames = $.map(ancestorsOf($(destination)), function(a) { return a.id; });
1089
+
1090
+ // Conditions:
1091
+ // 1: +node+ should not be inserted in a location in a branch if this would
1092
+ // result in +node+ being an ancestor of itself.
1093
+ // 2: +node+ should not have a parent OR the destination should not be the
1094
+ // same as +node+'s current parent (this last condition prevents +node+
1095
+ // from being moved to the same location where it already is).
1096
+ // 3: +node+ should not be inserted as a child of +node+ itself.
1097
+ if($.inArray(node[0].id, ancestorNames) == -1 && (!parent || (destination.id != parent[0].id)) && destination.id != node[0].id) {
1098
+ indent(node, ancestorsOf(node).length * options.indent * -1); // Remove indentation
1099
+
1100
+ if(parent) { node.removeClass(options.childPrefix + parent[0].id); }
1101
+
1102
+ node.addClass(options.childPrefix + destination.id);
1103
+ move(node, destination); // Recursively move nodes to new location
1104
+ indent(node, ancestorsOf(node).length * options.indent);
1105
+
1106
+ if (success_callback) {
1107
+ success_callback.call();
1108
+ }
1109
+ }
1110
+
1111
+ return this;
1112
+ };
1113
+
1114
+ $.fn.insertBranchAfter = function(destination, success_callback) {
1115
+ insertBranchBeforeOrAfter(this, destination, false, success_callback);
1116
+ }
1117
+
1118
+ $.fn.insertBranchBefore = function(destination, success_callback) {
1119
+ insertBranchBeforeOrAfter(this, destination, true, success_callback);
1120
+ }
1121
+
1122
+ // Add reverse() function from JS Arrays
1123
+ $.fn.reverse = function() {
1124
+ return this.pushStack(this.get().reverse(), arguments);
1125
+ };
1126
+
1127
+ // Toggle an entire branch
1128
+ $.fn.toggleBranch = function() {
1129
+ if($(this).hasClass("collapsed")) {
1130
+ $(this).expand();
1131
+ } else {
1132
+ $(this).removeClass("expanded").collapse_recursive();
1133
+ }
1134
+
1135
+ return this;
1136
+ };
1137
+
1138
+ // === Private functions
1139
+
1140
+ insertBranchBeforeOrAfter = function(source, destination, before, success_callback) {
1141
+ var sourceNode = $(source);
1142
+ var targetNode = $(destination);
1143
+ var targetParent = undefined;
1144
+
1145
+ // if we are inserting after a node and that node has children, we are actually
1146
+ // reparenting to that node.
1147
+ if (!before && hasChildren(targetNode)){
1148
+ targetParent = targetNode;
1149
+ } else {
1150
+ targetParent = parentOf(targetNode);
1151
+ }
1152
+
1153
+ var sourceParent = parentOf(sourceNode);
1154
+ var needsIndenting = false;
1155
+
1156
+ if(nodeNotInDestinationAncestry(sourceNode, targetNode) && nodesDifferent(targetNode, sourceNode)) {
1157
+ if (nodesDifferent(sourceParent, targetParent)){
1158
+ // The nodes have different parents so reparent the node
1159
+ indent(sourceNode, ancestorsOf(sourceNode).length * options.indent * -1); // Remove indentation
1160
+ needsIndenting = true;
1161
+ if (sourceParent) {sourceNode.removeClass(options.childPrefix + sourceParent[0].id); }
1162
+ if (targetParent) {sourceNode.addClass(options.childPrefix + targetParent[0].id);}
1163
+ }
1164
+
1165
+ // move node
1166
+ if (before) {
1167
+ moveBefore(sourceNode, destination); // Recursively move nodes to new location
1168
+ } else {
1169
+ move(sourceNode, destination); // Recursively move nodes to new location
1170
+ }
1171
+
1172
+ if (needsIndenting){
1173
+ // the parent was changed so re-apply indentation
1174
+ indent(sourceNode, ancestorsOf(sourceNode).length * options.indent);
1175
+ }
1176
+
1177
+ if (success_callback) {
1178
+ success_callback.call();
1179
+ }
1180
+ }
1181
+ return this;
1182
+ }
1183
+
1184
+ function nodeNotInDestinationAncestry(node, destination){
1185
+ var ancestorNames = $.map(ancestorsOf(destination), function(a) { return a.id; });
1186
+ return $.inArray(node[0].id, ancestorNames) == -1;
1187
+ }
1188
+
1189
+ function nodesSame(nodeA, nodeB){
1190
+ if (nodeA && nodeB){
1191
+ return (nodeA[0].id == nodeB[0].id);
1192
+ } else {
1193
+ return (nodeA == nodeB)
1194
+ }
1195
+ }
1196
+
1197
+ function nodesDifferent(nodeA, nodeB){
1198
+ return !(nodesSame(nodeA, nodeB));
1199
+ }
1200
+
1201
+ function ancestorsOf(node) {
1202
+ var ancestors = [];
1203
+ while(node = parentOf(node)) {
1204
+ ancestors[ancestors.length] = node[0];
1205
+ }
1206
+ return ancestors;
1207
+ };
1208
+
1209
+ function childrenOf(node) {
1210
+ return $("table.treeTable tbody tr." + options.childPrefix + node[0].id);
1211
+ };
1212
+
1213
+ function indent(node, value) {
1214
+ var cell = $(node.children("td")[options.treeColumn]);
1215
+ var padding = parseInt(cell.css("padding-left"), 10) + value;
1216
+
1217
+ cell.css("padding-left", + padding + "px");
1218
+
1219
+ childrenOf(node).each(function() {
1220
+ indent($(this), value);
1221
+ });
1222
+ };
1223
+
1224
+ function hasChildren(node){
1225
+ var childNodes = childrenOf(node);
1226
+ return childNodes.length > 0;
1227
+ }
1228
+
1229
+ function initialize(node) {
1230
+ if(!node.hasClass("initialized")) {
1231
+ node.addClass("initialized");
1232
+
1233
+ var childNodes = childrenOf(node);
1234
+
1235
+ if(!node.hasClass("parent") && childNodes.length > 0) {
1236
+ node.addClass("parent");
1237
+ }
1238
+
1239
+ if(node.hasClass("parent")) {
1240
+ var cell = $(node.children("td")[options.treeColumn]);
1241
+ var padding = parseInt(cell.css("padding-left"), 10) + options.indent;
1242
+
1243
+ childNodes.each(function() {
1244
+ $($(this).children("td")[options.treeColumn]).css("padding-left", padding + "px");
1245
+ });
1246
+
1247
+ if(options.expandable) {
1248
+ cell.prepend('<span style="margin-left: -' + options.indent + 'px; padding-left: ' + options.indent + 'px" class="expander"></span>');
1249
+ $(cell[0].firstChild).click(function() { node.toggleBranch(); });
1250
+
1251
+ // Check for a class set explicitly by the user, otherwise set the default class
1252
+ if(!(node.hasClass("expanded") || node.hasClass("collapsed"))) {
1253
+ node.addClass(options.initialState);
1254
+ }
1255
+
1256
+ if(node.hasClass("collapsed")) {
1257
+ node.collapse_recursive();
1258
+ } else if (node.hasClass("expanded")) {
1259
+ node.expand();
1260
+ }
1261
+ }
1262
+ }
1263
+ }
1264
+ };
1265
+
1266
+ function move(node, destination) {
1267
+ node.insertAfter(destination);
1268
+ childrenOf(node).reverse().each(function() { move($(this), node[0]); });
1269
+ };
1270
+
1271
+ function moveBefore(node, destination) {
1272
+ node.insertBefore(destination);
1273
+ childrenOf(node).reverse().each(function() { move($(this), node[0]); });
1274
+ };
1275
+
1276
+ function parentOf(node) {
1277
+ var classNames = node[0].className.split(' ');
1278
+ for(key = 0 ; key < classNames.length ; key++) {
1279
+ if(classNames[key].match("child-of-")) {
1280
+ return $("#" + classNames[key].substring(9));
1281
+ }
1282
+ }
1283
+ };
1284
+ })(jQuery);
1285
+
1286
+ DM_NONE = null;
1287
+ DM_INSERT_BEFORE = {};
1288
+ DM_INSERT_AFTER = {};
1289
+ DM_INSERT_CHILD = {};
1290
+
1291
+ var dragTreeManager = {
1292
+ init: function(){
1293
+
1294
+ var dragManager = {
1295
+ dropSite: null,
1296
+ dragMode: DM_NONE
1297
+ };
1298
+
1299
+ // Look for all tables with a class of 'drag_tree' and make them
1300
+ // into dragtrees
1301
+ $(".drag-tree").each(function(index){
1302
+
1303
+ var dragTree = $(this);
1304
+
1305
+ var dragFlat = $(this).hasClass('drag-flat');
1306
+
1307
+ try{
1308
+ dragTree.treeTable({expandable: false});
1309
+ }catch(e){
1310
+ console.log(e);
1311
+ }
1312
+
1313
+
1314
+ var remote_move_node = function(source, destination, mode){
1315
+
1316
+ var ids = get_sorted_element_ids(dragTree).toString();
1317
+ $.ajax({
1318
+ type: "POST",
1319
+ url: dragTree.attr("rel"),
1320
+ data: "element_ids=" + ids,
1321
+ beforeSend: function(jqXHR, settings){
1322
+ showOverlay();
1323
+ },
1324
+ success: function(html){
1325
+ window.setTimeout(function(){
1326
+ hideOverlay();
1327
+ },500)
1328
+ },
1329
+ error: function(html){
1330
+
1331
+ $("#assetsDialogOverlay").html(html.responseText);
1332
+ window.setTimeout(function(){
1333
+ hideOverlay();
1334
+ },10000)
1335
+
1336
+
1337
+ }
1338
+ });
1339
+
1340
+
1341
+ }
1342
+
1343
+ // Configure draggable rows
1344
+ try{
1345
+ dragTree.find(".drag-node").draggable({
1346
+ helper: "clone",
1347
+ opacity: .75,
1348
+ revert: "invalid",
1349
+ revertDuration: 300,
1350
+ scroll: true,
1351
+ drag: function(e, ui){
1352
+ if (dragManager.dropSite) {
1353
+ var top = dragManager.dropSite.offset().top ;
1354
+ var height = dragManager.dropSite.height();
1355
+
1356
+ var mouseTop = e.pageY;
1357
+ var topOffset = 10;
1358
+ var bottomOffset = 10;
1359
+
1360
+ if (dragFlat) {
1361
+ topOffset = height / 2;
1362
+ bottomOffset = height / 2;
1363
+ }
1364
+
1365
+ dragTree.find("#"+$(this).attr('rel')).addClass("ui-draggable-dragging")
1366
+
1367
+ if( dragManager.dropSite.attr('id') != $(this).attr('rel')){
1368
+ if (mouseTop < (top + topOffset)){
1369
+ dragManager.dropSite.addClass("insert_before").removeClass("insert_child insert_after");
1370
+ dragManager.dragMode = DM_INSERT_BEFORE;
1371
+ } else if (mouseTop > (top + height - bottomOffset)) {
1372
+ dragManager.dropSite.addClass("insert_after").removeClass("insert_before insert_child");
1373
+ dragManager.dragMode = DM_INSERT_AFTER;
1374
+ } else {
1375
+ if (!dragFlat){
1376
+ dragManager.dropSite.addClass("insert_child").removeClass("insert_after insert_before");
1377
+ dragManager.dragMode = DM_INSERT_CHILD;
1378
+ }
1379
+ }
1380
+ }else{//self node check
1381
+ dragManager.dropSite.removeClass("insert_child insert_after insert_before");
1382
+ }
1383
+ }
1384
+ }
1385
+ });
1386
+
1387
+ }catch(e){
1388
+ console.log(e);
1389
+ }
1390
+
1391
+
1392
+ try{
1393
+ // Configure droppable rows
1394
+ dragTree.find(".drag-node").each(function() {
1395
+ $(this).parents("tr").droppable({
1396
+ accept: ".drag-node:not(selected)",
1397
+ drop: function(e, ui) {
1398
+
1399
+ var sourceNode = $(ui.draggable).parents("tr")
1400
+ var targetNode = this;
1401
+
1402
+ sourceNode.removeClass("ui-draggable-dragging")
1403
+
1404
+ if ((dragManager.dragMode == DM_INSERT_CHILD) && (!dragFlat)) {
1405
+ $(sourceNode).appendBranchTo(targetNode,
1406
+ function(){
1407
+ remote_move_node(sourceNode, targetNode, 'INSERT');
1408
+ }
1409
+ );
1410
+ }
1411
+ if (dragManager.dragMode == DM_INSERT_BEFORE) {
1412
+ $(sourceNode).insertBranchBefore(targetNode,
1413
+ function(){
1414
+ remote_move_node(sourceNode, targetNode, 'BEFORE');
1415
+ }
1416
+ );
1417
+ }
1418
+ if (dragManager.dragMode == DM_INSERT_AFTER) {
1419
+ $(sourceNode).insertBranchAfter(targetNode,
1420
+ function(){
1421
+ remote_move_node(sourceNode, targetNode, 'AFTER');
1422
+ }
1423
+ );
1424
+ }
1425
+
1426
+ $(sourceNode).effect("highlight", {}, 2000);
1427
+ dragTree.find("tr").removeClass("insert_child insert_before insert_after");
1428
+ dragManager.dropSite = null;
1429
+ dragManager.dragMode = DM_NONE;
1430
+ },
1431
+ hoverClass: "accept",
1432
+ over: function(e, ui) {
1433
+
1434
+ element = $(this); //ui.draggable.parent();
1435
+
1436
+ if (element.parents("tr") != dragManager.dropSite) {
1437
+ dragManager.dropSite = element;
1438
+ }
1439
+ // Make the droppable branch expand when a draggable node is moved over it.
1440
+ if(this.id != ui.draggable.parents("tr")[0].id && !$(this).is(".expanded")) {
1441
+ $(this).expand();
1442
+ }
1443
+ },
1444
+ out: function(e, ui){
1445
+ element = $(this);
1446
+ element.removeClass("insert_child insert_before insert_after");
1447
+ if (dragManager.dropSite == element) {
1448
+ dragManager.dropSite = null;
1449
+ dragManager.dragMode = DM_NONE;
1450
+ }
1451
+ }
1452
+ });
1453
+ });
1454
+
1455
+ }catch(e){
1456
+ console.log(e);
1457
+ }
1458
+
1459
+ // Make visible that a row is clicked
1460
+ dragTree.find("tbody tr").mousedown(function() {
1461
+ $("tr.selected").removeClass("selected"); // Deselect currently selected rows
1462
+ $(this).addClass("selected");
1463
+ });
1464
+
1465
+ // Make sure row is selected when span is clicked
1466
+ dragTree.find("tbody tr span").mousedown(function() {
1467
+ $($(this).parents("tr")[0]).trigger("mousedown");
1468
+ });
1469
+ });
1470
+
1471
+ }
1472
+ }
1473
+
1474
+ // it take ids of all ".orderable-list-item" inside container (wrapper_id)
1475
+ // and returns array of all ids
1476
+ function get_sorted_element_ids(wrapper)
1477
+ {
1478
+ try{
1479
+ var items = wrapper.find("tbody tr.ui-droppable");
1480
+ items = $.map(items, function(value){
1481
+ return value.id.replace("node-","");
1482
+ });
1483
+ return items;
1484
+ }catch(e){}
1485
+ }
1486
+
1487
+
1488
+ function showOverlay() {
1489
+ if ($("#assetsDialogOverlay").length == 0) {
1490
+ var height = $('#wrapper').height() + 50;
1491
+ AssetBrowser.overlay = $('<div id="assetsDialogOverlay" class="modal-backdrop"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>');
1492
+ $("body").append(AssetBrowser.overlay);
1493
+ }
1494
+ else {
1495
+ $("#assetsDialogOverlay").css({
1496
+ display: "block"
1497
+ });
1498
+ }
1499
+ set_height = wrapper_height = $("body").height();
1500
+ window_height = $(window).height() + $(window).scrollTop()
1501
+ if(set_height < window_height)
1502
+ set_height = window_height;
1503
+ $("#assetsDialogOverlay").height( set_height )
1504
+ }
1505
+
1506
+ function hideOverlay(){
1507
+ $("#assetsDialogOverlay").remove();
1508
+ }
1509
+
1510
+
1511
+ /* Redactor gluttonberg plugins */
1512
+ if (typeof RedactorPlugins === 'undefined') var RedactorPlugins = {};
1513
+
1514
+ RedactorPlugins.asset_library_image = {
1515
+
1516
+ init: function()
1517
+ {
1518
+ this.buttonAddBefore('video', 'asset_library_image', 'Insert image', function()
1519
+ {
1520
+ this.selectionSave();
1521
+ var self = this;
1522
+ var url = "/admin/browser?filter=image&size_selector=true";
1523
+ var link = $("<a href='"+url+"'/>");
1524
+ var p = $("<p> </p>");
1525
+ AssetBrowser.showOverlay()
1526
+ $.get(url, null,
1527
+ function(markup) {
1528
+ AssetBrowser.load(p, link, markup, self );
1529
+ }
1530
+ );
1531
+ });
1532
+ }
1533
+ }
1534
+
1535
+ RedactorPlugins.gluttonberg_embeds = {
1536
+
1537
+ init: function()
1538
+ {
1539
+ this.buttonAddAfter('table', 'gluttonberg_embeds', 'Embed', function()
1540
+ {
1541
+ this.selectionSave();
1542
+ console.log($(".redactor_btn_gluttonberg_embeds").attr('title'))
1543
+ var self = this;
1544
+ var url = "/admin/embeds/list-for-redactor";
1545
+ AssetBrowser.showOverlay()
1546
+ $.get(url, null,
1547
+ function(markup) {
1548
+ $("body").append(markup);
1549
+ $("#embedDialog .cancel").click(function(e){
1550
+ AssetBrowser.overlay.hide();
1551
+ $("#embedDialog").remove();
1552
+ e.preventDefault();
1553
+ });
1554
+
1555
+ $("#embedDialog .embed-btn").click(function(){
1556
+ self.selectionRestore();
1557
+ self.insertHtml($(this).attr('data-shortcode'));
1558
+ $("#embedDialog .cancel").click();
1559
+ e.preventDefault();
1560
+ })
1561
+ }
1562
+ );
1563
+ });
1564
+ }
1565
+ }
1566
+
1567
+ RedactorPlugins.gluttonberg_pages = {
1568
+
1569
+ init: function()
1570
+ {
1571
+ var self = this;
1572
+ var dropdown = {};
1573
+
1574
+ if(linkCount > 0){
1575
+ dropdown["gluttonberg_pages"] = {
1576
+ title: 'Insert internal link',
1577
+ callback: function(){
1578
+ self.showModal(self);
1579
+ }
1580
+ };
1581
+ }
1582
+
1583
+ dropdown["link"] = {
1584
+ title: 'Insert link',
1585
+ func: 'linkShow'
1586
+ };
1587
+
1588
+ dropdown["unlink"] = {
1589
+ title: 'Unlink',
1590
+ exec: 'unlink'
1591
+ };
1592
+
1593
+ dropdown["gluttonberg_files"] = {
1594
+ title: 'Attach file',
1595
+ callback: function(){
1596
+ this.selectionSave();
1597
+ self.showAssetSelector(self);
1598
+ }
1599
+ };
1600
+
1601
+ this.buttonAddAfter('table', 'gb_link', 'Link', false, dropdown);
1602
+ },
1603
+ showAssetSelector : function(self){
1604
+ var url = "/admin/browser?size_selector=true";
1605
+ var link = $("<a href='"+url+"' class='attach'/>");
1606
+ var p = $("<p> </p>");
1607
+ $.get(url, null,
1608
+ function(markup) {
1609
+ AssetBrowser.load(p, link, markup, self );
1610
+ }
1611
+ );
1612
+ },
1613
+ showModal: function(self){
1614
+ self.selectionSave();
1615
+ $.get("/admin/pages_list_for_tinymce", null,
1616
+ function(response) {
1617
+ var options = "<option> </option> " + response;
1618
+ var modal_gluttonberg_link = String()
1619
+ + '<section>'
1620
+ + '<form id="redactorInsertLinkForm" method="post" action="">'
1621
+ + '<div class="redactor_tab" id="redactor_tab1">'
1622
+ + '<label>URL</label>'
1623
+ + '<select id="redactor_gluttonberg_link_url" class="redactor_input chzn-select" data-placeholder="Please select a link" >'
1624
+ + options
1625
+ + '</select>'
1626
+ + '<label>Text</label>'
1627
+ + '<input type="text" class="redactor_input redactor_link_text" id="redactor_gluttonberg_link_url_text" />'
1628
+ + '<label><input type="checkbox" id="redactor_gluttonberg_link_blank"> Open link in new tab</label>'
1629
+ + '</div>'
1630
+ + '</form>'
1631
+ + '</section>'
1632
+ + '<footer>'
1633
+ + '<a href="#" class="redactor_modal_btn redactor_btn_modal_close">Cancel</a>'
1634
+ + '<input type="button" class="redactor_modal_btn" id="redactor_insert_gluttonberg_link_btn" value="Insert" />'
1635
+ + '</footer>';
1636
+ self.modalInit('Insert internal link', modal_gluttonberg_link, 460, function(){self.gluttonbergLinkModalClickcallback(self); });
1637
+ }
1638
+ );
1639
+ },
1640
+ gluttonbergLinkModalClickcallback : function(self)
1641
+ {
1642
+ self.insert_link_node = false;
1643
+
1644
+ var sel = self.getSelection();
1645
+ var url = '', text = '', target = '';
1646
+
1647
+ var elem = self.getParent();
1648
+ var par = $(elem).parent().get(0);
1649
+ if (par && par.tagName === 'A')
1650
+ {
1651
+ elem = par;
1652
+ }
1653
+
1654
+ if (elem && elem.tagName === 'A')
1655
+ {
1656
+ url = elem.href;
1657
+ text = $(elem).text();
1658
+ target = elem.target;
1659
+
1660
+ self.insert_link_node = elem;
1661
+ }
1662
+ else{
1663
+ text = sel.toString();
1664
+ }
1665
+ $('#redactor_gluttonberg_link_url_text').val(text);
1666
+ $('#redactor_gluttonberg_link_url').val($('<a>').prop('href',url).prop('pathname'));
1667
+ if (target === '_blank'){
1668
+ $('#redactor_gluttonberg_link_blank').prop('checked', true);
1669
+ }
1670
+ $('#redactor_insert_gluttonberg_link_btn').click($.proxy(self.gbLinkProcess, self));
1671
+ setTimeout(function()
1672
+ {
1673
+ $('#redactor_gluttonberg_link_url').focus();
1674
+ }, 200);
1675
+
1676
+ $(".chzn-select").chosen();
1677
+
1678
+ },
1679
+ gbLinkProcess : function()
1680
+ {
1681
+ var self = this;
1682
+ var link = '', text = '', target = '', targetBlank = '';
1683
+
1684
+ // url
1685
+ link = $('#redactor_gluttonberg_link_url').val();
1686
+ text = $('#redactor_gluttonberg_link_url_text').val();
1687
+
1688
+ if ($('#redactor_gluttonberg_link_blank').prop('checked'))
1689
+ {
1690
+ target = ' target="_blank"';
1691
+ targetBlank = '_blank';
1692
+ }
1693
+
1694
+ // test url (add protocol)
1695
+ var pattern = '((xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}';
1696
+ var re = new RegExp('^(http|ftp|https)://' + pattern, 'i');
1697
+ var re2 = new RegExp('^' + pattern, 'i');
1698
+
1699
+ if (link.search(re) == -1 && link.search(re2) == 0 && self.opts.linkProtocol)
1700
+ {
1701
+ link = self.opts.linkProtocol + link;
1702
+ }
1703
+
1704
+ self.gbLinkInsert('<a href="' + link + '"' + target + '>' + text + '</a>', $.trim(text), link, targetBlank);
1705
+
1706
+ },
1707
+ gbLinkInsert : function (a, text, link, target)
1708
+ {
1709
+ var self = this;
1710
+ self.selectionRestore();
1711
+
1712
+ if (text !== '')
1713
+ {
1714
+ if (self.insert_link_node)
1715
+ {
1716
+ self.bufferSet();
1717
+ $(self.insert_link_node).text(text).attr('href', link);
1718
+
1719
+ if (target !== '') $(self.insert_link_node).attr('target', target);
1720
+ else $(self.insert_link_node).removeAttr('target');
1721
+
1722
+ self.sync();
1723
+ }
1724
+ else
1725
+ {
1726
+ self.exec('inserthtml', a);
1727
+ }
1728
+ }
1729
+ self.modalClose();
1730
+ }
1731
+ }
1732
+
1733
+ function getParameterByName(url, name ){
1734
+ name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
1735
+ var regexS = "[\\?&]"+name+"=([^&#]*)",
1736
+ regex = new RegExp( regexS ),
1737
+ results = regex.exec( url );
1738
+ if( results == null ){
1739
+ return "";
1740
+ } else{
1741
+ return decodeURIComponent(results[1].replace(/\+/g, " "));
1742
+ }
1743
+ }
1744
+
1745
+
1746
+ /* Helper methods for form repeater. Add/remove functionality of repeatable component.
1747
+ */
1748
+ var HtmlFormRepeater = {
1749
+ add: function(containerselector, rowSelector, link, callback){
1750
+ var duplicatedForm = $(containerselector).find(rowSelector).last().clone();
1751
+ HtmlFormRepeater.htmlCleanup(link, duplicatedForm);
1752
+ $(containerselector).append(duplicatedForm);
1753
+ var newElement = $(containerselector).find(rowSelector).last();
1754
+ if(callback != undefined){
1755
+ callback(newElement);
1756
+ }
1757
+ $(newElement).find("._destroy_button").click(function(e){
1758
+ HtmlFormRepeater.remove($(this).parents(rowSelector));
1759
+ e.preventDefault();
1760
+ });
1761
+ },
1762
+ htmlCleanup: function(link, duplicatedForm){
1763
+ var count = parseInt($(link).attr("data-count"));
1764
+ count++;
1765
+
1766
+ duplicatedForm.show();
1767
+ var html = duplicatedForm.html();
1768
+ if(html) {
1769
+ html = HtmlFormRepeater.idAndNameCleanup(count, html);
1770
+ duplicatedForm.html(html);
1771
+ HtmlFormRepeater.textInputCleanup(duplicatedForm);
1772
+ duplicatedForm.find("input._destroy").val("");
1773
+ }
1774
+ duplicatedForm.addClass("new-item");
1775
+ duplicatedForm.find("input._position").val(count);
1776
+ $(link).attr("data-count", count);
1777
+ },
1778
+ idAndNameCleanup: function(count, html){
1779
+ html = html.replace(/\[[0-9]+\]/g, "["+count+"]"); // name update
1780
+ html = html.replace(/_attributes_[0-9]+_/g, "_attributes_"+count+"_"); //id update
1781
+ return html;
1782
+ },
1783
+ textInputCleanup: function(duplicatedForm){
1784
+ duplicatedForm.find("input[type='text']").val("");
1785
+ },
1786
+ remove: function(rowSelector){
1787
+ $(rowSelector).hide();
1788
+ $(rowSelector).find("._destroy").val("true");
1789
+ },
1790
+ initRemoveButton: function(containerselector, rowSelector){
1791
+ $(containerselector).find("._destroy_button").click(function(e){
1792
+ HtmlFormRepeater.remove($(this).parents(rowSelector));
1793
+ e.preventDefault();
1794
+ });
1795
+ },
1796
+ initSorter: function(containerselector, rowSelector){
1797
+ $(containerselector).sortable({
1798
+ revert: true,
1799
+ handle: ".repeater-drag-node",
1800
+ update: function( event, ui ){
1801
+ $(containerselector).find(rowSelector).each(function(index){
1802
+ $(this).find("._position").val(index);
1803
+ });
1804
+ }
1805
+ });
1806
+ }
1807
+ }
1808
+