wafflemix 0.0.1

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 (276) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +96 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/javascripts/mercury/page_editor.js.coffee +254 -0
  5. data/app/assets/javascripts/wafflemix/admin/admin.js.coffee +73 -0
  6. data/app/assets/javascripts/wafflemix/admin/admin_js.js +16 -0
  7. data/app/assets/javascripts/wafflemix/admin/bootstrap-datepicker.js +454 -0
  8. data/app/assets/javascripts/wafflemix/admin/jquery.nested_sortable.js +608 -0
  9. data/app/assets/javascripts/wafflemix/application.js +43 -0
  10. data/app/assets/javascripts/wafflemix/assets.js +2 -0
  11. data/app/assets/javascripts/wafflemix/contact_forms.js +2 -0
  12. data/app/assets/javascripts/wafflemix/mercury.js +469 -0
  13. data/app/assets/javascripts/wafflemix/pages.js +2 -0
  14. data/app/assets/javascripts/wafflemix/portfolios.js +2 -0
  15. data/app/assets/javascripts/wafflemix/posts.js +2 -0
  16. data/app/assets/javascripts/wafflemix/roles.js +2 -0
  17. data/app/assets/javascripts/wafflemix/users.js +2 -0
  18. data/app/assets/stylesheets/wafflemix/admin/admin.css.sass +76 -0
  19. data/app/assets/stylesheets/wafflemix/admin/bootstrap-datepicker.css +7 -0
  20. data/app/assets/stylesheets/wafflemix/application.css +15 -0
  21. data/app/assets/stylesheets/wafflemix/assets.css +4 -0
  22. data/app/assets/stylesheets/wafflemix/clearfix.css +20 -0
  23. data/app/assets/stylesheets/wafflemix/contact_forms.css +4 -0
  24. data/app/assets/stylesheets/wafflemix/main.css.sass +11 -0
  25. data/app/assets/stylesheets/wafflemix/mercury.css +23 -0
  26. data/app/assets/stylesheets/wafflemix/pages.css +4 -0
  27. data/app/assets/stylesheets/wafflemix/partials/_base.css.sass +131 -0
  28. data/app/assets/stylesheets/wafflemix/portfolios.css +4 -0
  29. data/app/assets/stylesheets/wafflemix/posts.css +4 -0
  30. data/app/assets/stylesheets/wafflemix/roles.css +4 -0
  31. data/app/assets/stylesheets/wafflemix/users.css +4 -0
  32. data/app/controllers/wafflemix/admin/assets_controller.rb +95 -0
  33. data/app/controllers/wafflemix/admin/categories_controller.rb +77 -0
  34. data/app/controllers/wafflemix/admin/contact_forms_controller.rb +77 -0
  35. data/app/controllers/wafflemix/admin/content_sections_controller.rb +85 -0
  36. data/app/controllers/wafflemix/admin/pages_controller.rb +93 -0
  37. data/app/controllers/wafflemix/admin/portfolios_controller.rb +93 -0
  38. data/app/controllers/wafflemix/admin/posts_controller.rb +82 -0
  39. data/app/controllers/wafflemix/admin/roles_controller.rb +77 -0
  40. data/app/controllers/wafflemix/admin/slides_controller.rb +88 -0
  41. data/app/controllers/wafflemix/admin/users_controller.rb +78 -0
  42. data/app/controllers/wafflemix/application_controller.rb +11 -0
  43. data/app/controllers/wafflemix/assets_controller.rb +71 -0
  44. data/app/controllers/wafflemix/categories_controller.rb +34 -0
  45. data/app/controllers/wafflemix/contact_forms_controller.rb +47 -0
  46. data/app/controllers/wafflemix/pages_controller.rb +56 -0
  47. data/app/controllers/wafflemix/portfolios_controller.rb +35 -0
  48. data/app/controllers/wafflemix/posts_controller.rb +52 -0
  49. data/app/helpers/wafflemix/admin/slides_helper.rb +11 -0
  50. data/app/helpers/wafflemix/application_helper.rb +88 -0
  51. data/app/helpers/wafflemix/assets_helper.rb +4 -0
  52. data/app/helpers/wafflemix/categories_helper.rb +4 -0
  53. data/app/helpers/wafflemix/contact_forms_helper.rb +4 -0
  54. data/app/helpers/wafflemix/content_sections_helper.rb +4 -0
  55. data/app/helpers/wafflemix/pages_helper.rb +23 -0
  56. data/app/helpers/wafflemix/portfolios_helper.rb +11 -0
  57. data/app/helpers/wafflemix/posts_helper.rb +5 -0
  58. data/app/helpers/wafflemix/roles_helper.rb +4 -0
  59. data/app/helpers/wafflemix/users_helper.rb +4 -0
  60. data/app/models/user.rb +10 -0
  61. data/app/models/wafflemix/Categorical.rb +8 -0
  62. data/app/models/wafflemix/asset.rb +22 -0
  63. data/app/models/wafflemix/category.rb +8 -0
  64. data/app/models/wafflemix/contact_form.rb +19 -0
  65. data/app/models/wafflemix/content_section.rb +21 -0
  66. data/app/models/wafflemix/image.rb +8 -0
  67. data/app/models/wafflemix/meta_content.rb +5 -0
  68. data/app/models/wafflemix/page.rb +39 -0
  69. data/app/models/wafflemix/portfolio.rb +16 -0
  70. data/app/models/wafflemix/post.rb +33 -0
  71. data/app/models/wafflemix/role.rb +10 -0
  72. data/app/models/wafflemix/slide.rb +14 -0
  73. data/app/models/wafflemix/user.rb +11 -0
  74. data/app/models/wafflemix/user_role.rb +8 -0
  75. data/app/views/devise/_links.erb +25 -0
  76. data/app/views/devise/confirmations/new.html.erb +12 -0
  77. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  78. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  79. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  80. data/app/views/devise/passwords/edit.html.erb +16 -0
  81. data/app/views/devise/passwords/new.html.erb +12 -0
  82. data/app/views/devise/registrations/edit.html.erb +25 -0
  83. data/app/views/devise/registrations/new.html.erb +18 -0
  84. data/app/views/devise/sessions/new.html.erb +17 -0
  85. data/app/views/devise/unlocks/new.html.erb +12 -0
  86. data/app/views/layouts/mercury.html.erb +24 -0
  87. data/app/views/layouts/wafflemix/admin.html.erb +19 -0
  88. data/app/views/layouts/wafflemix/example_layout.html.erb +35 -0
  89. data/app/views/wafflemix/admin/assets/_form.html.erb +22 -0
  90. data/app/views/wafflemix/admin/assets/add_image.js.erb +1 -0
  91. data/app/views/wafflemix/admin/assets/edit.html.erb +6 -0
  92. data/app/views/wafflemix/admin/assets/index.html.erb +41 -0
  93. data/app/views/wafflemix/admin/assets/new.html.erb +5 -0
  94. data/app/views/wafflemix/admin/assets/show.html.erb +20 -0
  95. data/app/views/wafflemix/admin/categories/_form.html.erb +29 -0
  96. data/app/views/wafflemix/admin/categories/edit.html.erb +6 -0
  97. data/app/views/wafflemix/admin/categories/index.html.erb +36 -0
  98. data/app/views/wafflemix/admin/categories/new.html.erb +5 -0
  99. data/app/views/wafflemix/admin/categories/show.html.erb +25 -0
  100. data/app/views/wafflemix/admin/contact_forms/_form.html.erb +15 -0
  101. data/app/views/wafflemix/admin/contact_forms/edit.html.erb +6 -0
  102. data/app/views/wafflemix/admin/contact_forms/index.html.erb +38 -0
  103. data/app/views/wafflemix/admin/contact_forms/new.html.erb +5 -0
  104. data/app/views/wafflemix/admin/contact_forms/show.html.erb +25 -0
  105. data/app/views/wafflemix/admin/content_sections/_form.html.erb +33 -0
  106. data/app/views/wafflemix/admin/content_sections/create.js.erb +3 -0
  107. data/app/views/wafflemix/admin/content_sections/destroy.js.erb +4 -0
  108. data/app/views/wafflemix/admin/content_sections/edit.html.erb +6 -0
  109. data/app/views/wafflemix/admin/content_sections/index.html.erb +29 -0
  110. data/app/views/wafflemix/admin/content_sections/new.html.erb +5 -0
  111. data/app/views/wafflemix/admin/content_sections/show.html.erb +25 -0
  112. data/app/views/wafflemix/admin/pages/_form.html.erb +47 -0
  113. data/app/views/wafflemix/admin/pages/_page.html.erb +15 -0
  114. data/app/views/wafflemix/admin/pages/edit.html.erb +3 -0
  115. data/app/views/wafflemix/admin/pages/index.html.erb +21 -0
  116. data/app/views/wafflemix/admin/pages/new.html.erb +3 -0
  117. data/app/views/wafflemix/admin/pages/show.html.erb +40 -0
  118. data/app/views/wafflemix/admin/portfolios/_form.html.erb +174 -0
  119. data/app/views/wafflemix/admin/portfolios/_portfolio.html.erb +11 -0
  120. data/app/views/wafflemix/admin/portfolios/edit.html.erb +5 -0
  121. data/app/views/wafflemix/admin/portfolios/index.html.erb +21 -0
  122. data/app/views/wafflemix/admin/portfolios/new.html.erb +5 -0
  123. data/app/views/wafflemix/admin/portfolios/show.html.erb +20 -0
  124. data/app/views/wafflemix/admin/posts/_form.html.erb +191 -0
  125. data/app/views/wafflemix/admin/posts/edit.html.erb +5 -0
  126. data/app/views/wafflemix/admin/posts/index.html.erb +38 -0
  127. data/app/views/wafflemix/admin/posts/new.html.erb +3 -0
  128. data/app/views/wafflemix/admin/posts/show.html.erb +20 -0
  129. data/app/views/wafflemix/admin/roles/_form.html.erb +21 -0
  130. data/app/views/wafflemix/admin/roles/edit.html.erb +6 -0
  131. data/app/views/wafflemix/admin/roles/index.html.erb +34 -0
  132. data/app/views/wafflemix/admin/roles/new.html.erb +5 -0
  133. data/app/views/wafflemix/admin/roles/show.html.erb +10 -0
  134. data/app/views/wafflemix/admin/slides/_form.html.erb +170 -0
  135. data/app/views/wafflemix/admin/slides/_slide.html.erb +11 -0
  136. data/app/views/wafflemix/admin/slides/edit.html.erb +5 -0
  137. data/app/views/wafflemix/admin/slides/index.html.erb +21 -0
  138. data/app/views/wafflemix/admin/slides/new.html.erb +5 -0
  139. data/app/views/wafflemix/admin/slides/show.html.erb +10 -0
  140. data/app/views/wafflemix/admin/users/_form.html.erb +29 -0
  141. data/app/views/wafflemix/admin/users/edit.html.erb +6 -0
  142. data/app/views/wafflemix/admin/users/index.html.erb +36 -0
  143. data/app/views/wafflemix/admin/users/new.html.erb +5 -0
  144. data/app/views/wafflemix/admin/users/show.html.erb +14 -0
  145. data/app/views/wafflemix/categories/index.erb +16 -0
  146. data/app/views/wafflemix/categories/show.html.erb +16 -0
  147. data/app/views/wafflemix/contact_forms/_form.html.erb +33 -0
  148. data/app/views/wafflemix/contact_forms/new.html.erb +19 -0
  149. data/app/views/wafflemix/contact_forms/show.html.erb +25 -0
  150. data/app/views/wafflemix/pages/home.html.erb +7 -0
  151. data/app/views/wafflemix/pages/index.html.erb +31 -0
  152. data/app/views/wafflemix/pages/show.html.erb +14 -0
  153. data/app/views/wafflemix/portfolios/index.html.erb +21 -0
  154. data/app/views/wafflemix/portfolios/show.html.erb +36 -0
  155. data/app/views/wafflemix/posts/_sidebar.html.erb +12 -0
  156. data/app/views/wafflemix/posts/index.html.erb +16 -0
  157. data/app/views/wafflemix/posts/show.html.erb +40 -0
  158. data/app/views/wafflemix/posts/tagged.html.erb +16 -0
  159. data/config/initializers/devise.rb +227 -0
  160. data/config/initializers/dragonfly.rb +16 -0
  161. data/config/initializers/formtastic.rb +78 -0
  162. data/config/initializers/spam_filter.rb +4 -0
  163. data/config/locales/devise.en.yml +57 -0
  164. data/config/routes.rb +55 -0
  165. data/db/migrate/20120814113226_create_wafflemix_pages.rb +19 -0
  166. data/db/migrate/20120901141321_create_wafflemix_users.rb +29 -0
  167. data/db/migrate/20120901150334_create_wafflemix_assets.rb +11 -0
  168. data/db/migrate/20120901151421_create_wafflemix_roles.rb +9 -0
  169. data/db/migrate/20120901151704_create_wafflemix_user_roles.rb +13 -0
  170. data/db/migrate/20120915124116_add_ancestry_to_pages.rb +7 -0
  171. data/db/migrate/20120918100336_create_wafflemix_categories.rb +15 -0
  172. data/db/migrate/20120923131130_create_wafflemix_slides.rb +11 -0
  173. data/db/migrate/20120923131307_create_wafflemix_content_sections.rb +12 -0
  174. data/db/migrate/20120923135949_add_position_to_slides.rb +5 -0
  175. data/db/migrate/20121005124419_update_asset_table.rb +10 -0
  176. data/db/migrate/20121113131239_create_wafflemix_posts.rb +15 -0
  177. data/db/migrate/20121113132413_add_translation_table_for_posts.rb +9 -0
  178. data/db/migrate/20121114135432_update_draft_to_boolean_on_posts.rb +11 -0
  179. data/db/migrate/20121120125114_add_page_translations.rb +9 -0
  180. data/db/migrate/20121205221122_acts_as_taggable_on_migration.rb +30 -0
  181. data/db/migrate/20121206132733_re_do_categories.rb +19 -0
  182. data/db/migrate/20121206132923_add_new_categories_table.rb +11 -0
  183. data/db/migrate/20121206133026_add_category_joins_table.rb +14 -0
  184. data/db/migrate/20121211095114_finalize_asset_table.rb +11 -0
  185. data/db/migrate/20121211095847_store_asset_url.rb +5 -0
  186. data/db/migrate/20130202161212_create_wafflemix_images.rb +11 -0
  187. data/db/migrate/20130202182435_add_extra_fields_to_slides.rb +6 -0
  188. data/db/migrate/20130204225256_create_wafflemix_portfolios.rb +11 -0
  189. data/db/migrate/20130204230818_add_ancestry_to_portfolio.rb +6 -0
  190. data/db/migrate/20130216190558_create_wafflemix_meta_contents.rb +13 -0
  191. data/db/migrate/20130219121412_create_wafflemix_contact_forms.rb +12 -0
  192. data/db/migrate/20130219130609_add_spam_to_contact_forms.rb +5 -0
  193. data/lib/tasks/wafflemix_tasks.rake +15 -0
  194. data/lib/templates/erb/scaffold/_form.html.erb +11 -0
  195. data/lib/wafflemix/engine.rb +9 -0
  196. data/lib/wafflemix/version.rb +3 -0
  197. data/lib/wafflemix.rb +17 -0
  198. data/test/dummy/README.rdoc +261 -0
  199. data/test/dummy/Rakefile +7 -0
  200. data/test/dummy/app/assets/javascripts/application.js +15 -0
  201. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  202. data/test/dummy/app/controllers/application_controller.rb +3 -0
  203. data/test/dummy/app/helpers/application_helper.rb +2 -0
  204. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  205. data/test/dummy/config/application.rb +64 -0
  206. data/test/dummy/config/boot.rb +10 -0
  207. data/test/dummy/config/environment.rb +5 -0
  208. data/test/dummy/config/environments/development.rb +39 -0
  209. data/test/dummy/config/environments/production.rb +69 -0
  210. data/test/dummy/config/environments/test.rb +37 -0
  211. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  212. data/test/dummy/config/initializers/inflections.rb +15 -0
  213. data/test/dummy/config/initializers/local_s3.rb +3 -0
  214. data/test/dummy/config/initializers/mime_types.rb +5 -0
  215. data/test/dummy/config/initializers/secret_token.rb +7 -0
  216. data/test/dummy/config/initializers/session_store.rb +8 -0
  217. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  218. data/test/dummy/config/locales/en.yml +5 -0
  219. data/test/dummy/config/routes.rb +5 -0
  220. data/test/dummy/config.ru +4 -0
  221. data/test/dummy/db/schema.rb +87 -0
  222. data/test/dummy/public/404.html +26 -0
  223. data/test/dummy/public/422.html +26 -0
  224. data/test/dummy/public/500.html +25 -0
  225. data/test/dummy/public/favicon.ico +0 -0
  226. data/test/dummy/script/rails +6 -0
  227. data/test/fixtures/wafflemix/assets.yml +11 -0
  228. data/test/fixtures/wafflemix/categories.yml +13 -0
  229. data/test/fixtures/wafflemix/contact_forms.yml +13 -0
  230. data/test/fixtures/wafflemix/content_sections.yml +13 -0
  231. data/test/fixtures/wafflemix/images.yml +11 -0
  232. data/test/fixtures/wafflemix/meta_contents.yml +15 -0
  233. data/test/fixtures/wafflemix/pages.yml +19 -0
  234. data/test/fixtures/wafflemix/portfolios.yml +11 -0
  235. data/test/fixtures/wafflemix/posts.yml +11 -0
  236. data/test/fixtures/wafflemix/roles.yml +7 -0
  237. data/test/fixtures/wafflemix/slides.yml +7 -0
  238. data/test/fixtures/wafflemix/user_roles.yml +9 -0
  239. data/test/fixtures/wafflemix/users.yml +11 -0
  240. data/test/functional/wafflemix/assets_controller_test.rb +51 -0
  241. data/test/functional/wafflemix/categories_controller_test.rb +51 -0
  242. data/test/functional/wafflemix/contact_forms_controller_test.rb +51 -0
  243. data/test/functional/wafflemix/content_sections_controller_test.rb +51 -0
  244. data/test/functional/wafflemix/pages_controller_test.rb +51 -0
  245. data/test/functional/wafflemix/portfolios_controller_test.rb +51 -0
  246. data/test/functional/wafflemix/posts_controller_test.rb +51 -0
  247. data/test/functional/wafflemix/roles_controller_test.rb +51 -0
  248. data/test/functional/wafflemix/slides_controller_test.rb +51 -0
  249. data/test/functional/wafflemix/users_controller_test.rb +51 -0
  250. data/test/integration/navigation_test.rb +10 -0
  251. data/test/test_helper.rb +15 -0
  252. data/test/unit/helpers/wafflemix/assets_helper_test.rb +6 -0
  253. data/test/unit/helpers/wafflemix/categories_helper_test.rb +6 -0
  254. data/test/unit/helpers/wafflemix/contact_forms_helper_test.rb +6 -0
  255. data/test/unit/helpers/wafflemix/content_sections_helper_test.rb +6 -0
  256. data/test/unit/helpers/wafflemix/pages_helper_test.rb +6 -0
  257. data/test/unit/helpers/wafflemix/portfolios_helper_test.rb +6 -0
  258. data/test/unit/helpers/wafflemix/posts_helper_test.rb +6 -0
  259. data/test/unit/helpers/wafflemix/roles_helper_test.rb +6 -0
  260. data/test/unit/helpers/wafflemix/slides_helper_test.rb +6 -0
  261. data/test/unit/helpers/wafflemix/users_helper_test.rb +6 -0
  262. data/test/unit/wafflemix/asset_test.rb +9 -0
  263. data/test/unit/wafflemix/category_test.rb +9 -0
  264. data/test/unit/wafflemix/contact_form_test.rb +9 -0
  265. data/test/unit/wafflemix/content_section_test.rb +9 -0
  266. data/test/unit/wafflemix/image_test.rb +9 -0
  267. data/test/unit/wafflemix/meta_content_test.rb +9 -0
  268. data/test/unit/wafflemix/page_test.rb +9 -0
  269. data/test/unit/wafflemix/portfolio_test.rb +9 -0
  270. data/test/unit/wafflemix/post_test.rb +9 -0
  271. data/test/unit/wafflemix/role_test.rb +9 -0
  272. data/test/unit/wafflemix/slide_test.rb +9 -0
  273. data/test/unit/wafflemix/user_role_test.rb +9 -0
  274. data/test/unit/wafflemix/user_test.rb +9 -0
  275. data/test/wafflemix_test.rb +7 -0
  276. metadata +654 -0
@@ -0,0 +1,608 @@
1
+ /*
2
+ * jQuery UI Nested Sortable
3
+ * v 2.0 / 29 oct 2012
4
+ * http://mjsarfatti.com/sandbox/nestedSortable
5
+ *
6
+ * Depends on:
7
+ * jquery.ui.sortable.js 1.10+
8
+ *
9
+ * Copyright (c) 2010-2013 Manuele J Sarfatti
10
+ * Licensed under the MIT License
11
+ * http://www.opensource.org/licenses/mit-license.php
12
+ */
13
+
14
+ (function($) {
15
+
16
+ function isOverAxis( x, reference, size ) {
17
+ return ( x > reference ) && ( x < ( reference + size ) );
18
+ }
19
+
20
+ $.widget("mjs.nestedSortable", $.extend({}, $.ui.sortable.prototype, {
21
+
22
+ options: {
23
+ doNotClear: false,
24
+ expandOnHover: 700,
25
+ isAllowed: function(placeholder, placeholderParent, originalItem) { return true; },
26
+ isTree: false,
27
+ listType: 'ol',
28
+ maxLevels: 0,
29
+ protectRoot: false,
30
+ rootID: null,
31
+ rtl: false,
32
+ startCollapsed: false,
33
+ tabSize: 20,
34
+
35
+ branchClass: 'mjs-nestedSortable-branch',
36
+ collapsedClass: 'mjs-nestedSortable-collapsed',
37
+ disableNestingClass: 'mjs-nestedSortable-no-nesting',
38
+ errorClass: 'mjs-nestedSortable-error',
39
+ expandedClass: 'mjs-nestedSortable-expanded',
40
+ hoveringClass: 'mjs-nestedSortable-hovering',
41
+ leafClass: 'mjs-nestedSortable-leaf'
42
+ },
43
+
44
+ _create: function() {
45
+ this.element.data('ui-sortable', this.element.data('mjs-nestedSortable'));
46
+
47
+ // mjs - prevent browser from freezing if the HTML is not correct
48
+ if (!this.element.is(this.options.listType))
49
+ throw new Error('nestedSortable: Please check that the listType option is set to your actual list type');
50
+
51
+ // mjs - force 'intersect' tolerance method if we have a tree with expanding/collapsing functionality
52
+ if (this.options.isTree) this.options.tolerance = 'intersect';
53
+
54
+ $.ui.sortable.prototype._create.apply(this, arguments);
55
+
56
+ // mjs - prepare the tree by applying the right classes (the CSS is responsible for actual hide/show functionality)
57
+ if (this.options.isTree) {
58
+ var self = this;
59
+ $(this.items).each(function() {
60
+ var $li = this.item;
61
+ if ($li.children(self.options.listType).length) {
62
+ $li.addClass(self.options.branchClass);
63
+ // expand/collapse class only if they have children
64
+ if (self.options.startCollapsed) $li.addClass(self.options.collapsedClass);
65
+ else $li.addClass(self.options.expandedClass);
66
+ } else {
67
+ $li.addClass(self.options.leafClass);
68
+ }
69
+ })
70
+ }
71
+ },
72
+
73
+ _destroy: function() {
74
+ this.element
75
+ .removeData("mjs-nestedSortable")
76
+ .removeData("ui-sortable");
77
+ return $.ui.sortable.prototype._destroy.apply(this, arguments);
78
+ },
79
+
80
+ _mouseDrag: function(event) {
81
+ var i, item, itemElement, intersection,
82
+ o = this.options,
83
+ scrolled = false;
84
+
85
+ //Compute the helpers position
86
+ this.position = this._generatePosition(event);
87
+ this.positionAbs = this._convertPositionTo("absolute");
88
+
89
+ if (!this.lastPositionAbs) {
90
+ this.lastPositionAbs = this.positionAbs;
91
+ }
92
+
93
+ //Do scrolling
94
+ if(this.options.scroll) {
95
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
96
+
97
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
98
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
99
+ } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
100
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
101
+ }
102
+
103
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
104
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
105
+ } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
106
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
107
+ }
108
+
109
+ } else {
110
+
111
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
112
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
113
+ } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
114
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
115
+ }
116
+
117
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
118
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
119
+ } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
120
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
121
+ }
122
+
123
+ }
124
+
125
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
126
+ $.ui.ddmanager.prepareOffsets(this, event);
127
+ }
128
+
129
+ //Regenerate the absolute position used for position checks
130
+ this.positionAbs = this._convertPositionTo("absolute");
131
+
132
+ // mjs - find the top offset before rearrangement,
133
+ var previousTopOffset = this.placeholder.offset().top;
134
+
135
+ //Set the helper position
136
+ if(!this.options.axis || this.options.axis !== "y") {
137
+ this.helper[0].style.left = this.position.left+"px";
138
+ }
139
+ if(!this.options.axis || this.options.axis !== "x") {
140
+ this.helper[0].style.top = this.position.top+"px";
141
+ }
142
+
143
+ // mjs - check and reset hovering state at each cycle
144
+ this.hovering = this.hovering ? this.hovering : null;
145
+ this.mouseentered = this.mouseentered ? this.mouseentered : false;
146
+
147
+ // mjs - let's start caching some variables
148
+ var parentItem = (this.placeholder[0].parentNode.parentNode &&
149
+ $(this.placeholder[0].parentNode.parentNode).closest('.ui-sortable').length)
150
+ ? $(this.placeholder[0].parentNode.parentNode)
151
+ : null,
152
+ level = this._getLevel(this.placeholder),
153
+ childLevels = this._getChildLevels(this.helper);
154
+
155
+ var newList = document.createElement(o.listType);
156
+
157
+ //Rearrange
158
+ for (i = this.items.length - 1; i >= 0; i--) {
159
+
160
+ //Cache variables and intersection, continue if no intersection
161
+ item = this.items[i];
162
+ itemElement = item.item[0];
163
+ intersection = this._intersectsWithPointer(item);
164
+ if (!intersection) {
165
+ continue;
166
+ }
167
+
168
+ // Only put the placeholder inside the current Container, skip all
169
+ // items form other containers. This works because when moving
170
+ // an item from one container to another the
171
+ // currentContainer is switched before the placeholder is moved.
172
+ //
173
+ // Without this moving items in "sub-sortables" can cause the placeholder to jitter
174
+ // beetween the outer and inner container.
175
+ if (item.instance !== this.currentContainer) {
176
+ continue;
177
+ }
178
+
179
+ // cannot intersect with itself
180
+ // no useless actions that have been done before
181
+ // no action if the item moved is the parent of the item checked
182
+ if (itemElement !== this.currentItem[0] &&
183
+ this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
184
+ !$.contains(this.placeholder[0], itemElement) &&
185
+ (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
186
+ ) {
187
+
188
+ // mjs - we are intersecting an element: trigger the mouseenter event and store this state
189
+ if (!this.mouseentered) {
190
+ $(itemElement).mouseenter();
191
+ this.mouseentered = true;
192
+ }
193
+
194
+ // mjs - if the element has children and they are hidden, show them after a delay (CSS responsible)
195
+ if (o.isTree && $(itemElement).hasClass(o.collapsedClass) && o.expandOnHover) {
196
+ if (!this.hovering) {
197
+ $(itemElement).addClass(o.hoveringClass);
198
+ var self = this;
199
+ this.hovering = window.setTimeout(function() {
200
+ $(itemElement).removeClass(o.collapsedClass).addClass(o.expandedClass);
201
+ self.refreshPositions();
202
+ self._trigger("expand", event, self._uiHash());
203
+ }, o.expandOnHover);
204
+ }
205
+ }
206
+
207
+ this.direction = intersection == 1 ? "down" : "up";
208
+
209
+ // mjs - rearrange the elements and reset timeouts and hovering state
210
+ if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
211
+ $(itemElement).mouseleave();
212
+ this.mouseentered = false;
213
+ $(itemElement).removeClass(o.hoveringClass);
214
+ this.hovering && window.clearTimeout(this.hovering);
215
+ this.hovering = null;
216
+
217
+ // mjs - do not switch container if it's a root item and 'protectRoot' is true
218
+ // or if it's not a root item but we are trying to make it root
219
+ if (o.protectRoot
220
+ && ! (this.currentItem[0].parentNode == this.element[0] // it's a root item
221
+ && itemElement.parentNode != this.element[0]) // it's intersecting a non-root item
222
+ ) {
223
+ if (this.currentItem[0].parentNode != this.element[0]
224
+ && itemElement.parentNode == this.element[0]
225
+ ) {
226
+
227
+ if ( ! $(itemElement).children(o.listType).length) {
228
+ itemElement.appendChild(newList);
229
+ o.isTree && $(itemElement).removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.expandedClass);
230
+ }
231
+
232
+ var a = this.direction === "down" ? $(itemElement).prev().children(o.listType) : $(itemElement).children(o.listType);
233
+ if (a[0] !== undefined) {
234
+ this._rearrange(event, null, a);
235
+ }
236
+
237
+ } else {
238
+ this._rearrange(event, item);
239
+ }
240
+ } else if ( ! o.protectRoot) {
241
+ this._rearrange(event, item);
242
+ }
243
+ } else {
244
+ break;
245
+ }
246
+
247
+ // Clear emtpy ul's/ol's
248
+ this._clearEmpty(itemElement);
249
+
250
+ this._trigger("change", event, this._uiHash());
251
+ break;
252
+ }
253
+ }
254
+
255
+ // mjs - to find the previous sibling in the list, keep backtracking until we hit a valid list item.
256
+ var previousItem = this.placeholder[0].previousSibling ? $(this.placeholder[0].previousSibling) : null;
257
+ if (previousItem != null) {
258
+ while (previousItem[0].nodeName.toLowerCase() != 'li' || previousItem[0] == this.currentItem[0] || previousItem[0] == this.helper[0]) {
259
+ if (previousItem[0].previousSibling) {
260
+ previousItem = $(previousItem[0].previousSibling);
261
+ } else {
262
+ previousItem = null;
263
+ break;
264
+ }
265
+ }
266
+ }
267
+
268
+ // mjs - to find the next sibling in the list, keep stepping forward until we hit a valid list item.
269
+ var nextItem = this.placeholder[0].nextSibling ? $(this.placeholder[0].nextSibling) : null;
270
+ if (nextItem != null) {
271
+ while (nextItem[0].nodeName.toLowerCase() != 'li' || nextItem[0] == this.currentItem[0] || nextItem[0] == this.helper[0]) {
272
+ if (nextItem[0].nextSibling) {
273
+ nextItem = $(nextItem[0].nextSibling);
274
+ } else {
275
+ nextItem = null;
276
+ break;
277
+ }
278
+ }
279
+ }
280
+
281
+ this.beyondMaxLevels = 0;
282
+
283
+ // mjs - if the item is moved to the left, send it one level up but only if it's at the bottom of the list
284
+ if (parentItem != null
285
+ && nextItem == null
286
+ && ! (o.protectRoot && parentItem[0].parentNode == this.element[0])
287
+ &&
288
+ (o.rtl && (this.positionAbs.left + this.helper.outerWidth() > parentItem.offset().left + parentItem.outerWidth())
289
+ || ! o.rtl && (this.positionAbs.left < parentItem.offset().left))
290
+ ) {
291
+
292
+ parentItem.after(this.placeholder[0]);
293
+ if (o.isTree && parentItem.children(o.listItem).children('li:visible:not(.ui-sortable-helper)').length < 1) {
294
+ parentItem.removeClass(this.options.branchClass + ' ' + this.options.expandedClass)
295
+ .addClass(this.options.leafClass);
296
+ }
297
+ this._clearEmpty(parentItem[0]);
298
+ this._trigger("change", event, this._uiHash());
299
+ }
300
+ // mjs - if the item is below a sibling and is moved to the right, make it a child of that sibling
301
+ else if (previousItem != null
302
+ && ! previousItem.hasClass(o.disableNestingClass)
303
+ &&
304
+ (previousItem.children(o.listType).length && previousItem.children(o.listType).is(':visible')
305
+ || ! previousItem.children(o.listType).length)
306
+ && ! (o.protectRoot && this.currentItem[0].parentNode == this.element[0])
307
+ &&
308
+ (o.rtl && (this.positionAbs.left + this.helper.outerWidth() < previousItem.offset().left + previousItem.outerWidth() - o.tabSize)
309
+ || ! o.rtl && (this.positionAbs.left > previousItem.offset().left + o.tabSize))
310
+ ) {
311
+
312
+ this._isAllowed(previousItem, level, level+childLevels+1);
313
+
314
+ if (!previousItem.children(o.listType).length) {
315
+ previousItem[0].appendChild(newList);
316
+ o.isTree && previousItem.removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.expandedClass);
317
+ }
318
+
319
+ // mjs - if this item is being moved from the top, add it to the top of the list.
320
+ if (previousTopOffset && (previousTopOffset <= previousItem.offset().top)) {
321
+ previousItem.children(o.listType).prepend(this.placeholder);
322
+ }
323
+ // mjs - otherwise, add it to the bottom of the list.
324
+ else {
325
+ previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
326
+ }
327
+
328
+ this._trigger("change", event, this._uiHash());
329
+ }
330
+ else {
331
+ this._isAllowed(parentItem, level, level+childLevels);
332
+ }
333
+
334
+ //Post events to containers
335
+ this._contactContainers(event);
336
+
337
+ //Interconnect with droppables
338
+ if($.ui.ddmanager) {
339
+ $.ui.ddmanager.drag(this, event);
340
+ }
341
+
342
+ //Call callbacks
343
+ this._trigger('sort', event, this._uiHash());
344
+
345
+ this.lastPositionAbs = this.positionAbs;
346
+ return false;
347
+
348
+ },
349
+
350
+ _mouseStop: function(event, noPropagation) {
351
+
352
+ // mjs - if the item is in a position not allowed, send it back
353
+ if (this.beyondMaxLevels) {
354
+
355
+ this.placeholder.removeClass(this.options.errorClass);
356
+
357
+ if (this.domPosition.prev) {
358
+ $(this.domPosition.prev).after(this.placeholder);
359
+ } else {
360
+ $(this.domPosition.parent).prepend(this.placeholder);
361
+ }
362
+
363
+ this._trigger("revert", event, this._uiHash());
364
+
365
+ }
366
+
367
+
368
+ // mjs - clear the hovering timeout, just to be sure
369
+ $('.'+this.options.hoveringClass).mouseleave().removeClass(this.options.hoveringClass);
370
+ this.mouseentered = false;
371
+ this.hovering && window.clearTimeout(this.hovering);
372
+ this.hovering = null;
373
+
374
+ $.ui.sortable.prototype._mouseStop.apply(this, arguments);
375
+
376
+ },
377
+
378
+ // mjs - this function is slightly modified to make it easier to hover over a collapsed element and have it expand
379
+ _intersectsWithSides: function(item) {
380
+
381
+ var half = this.options.isTree ? .8 : .5;
382
+
383
+ var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height*half), item.height),
384
+ isOverTopHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top - (item.height*half), item.height),
385
+ isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
386
+ verticalDirection = this._getDragVerticalDirection(),
387
+ horizontalDirection = this._getDragHorizontalDirection();
388
+
389
+ if (this.floating && horizontalDirection) {
390
+ return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
391
+ } else {
392
+ return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && isOverTopHalf));
393
+ }
394
+
395
+ },
396
+
397
+ _contactContainers: function(event) {
398
+
399
+ if (this.options.protectRoot && this.currentItem[0].parentNode == this.element[0] ) {
400
+ return;
401
+ }
402
+
403
+ $.ui.sortable.prototype._contactContainers.apply(this, arguments);
404
+
405
+ },
406
+
407
+ _clear: function(event, noPropagation) {
408
+
409
+ $.ui.sortable.prototype._clear.apply(this, arguments);
410
+
411
+ // mjs - clean last empty ul/ol
412
+ for (var i = this.items.length - 1; i >= 0; i--) {
413
+ var item = this.items[i].item[0];
414
+ this._clearEmpty(item);
415
+ }
416
+
417
+ },
418
+
419
+ serialize: function(options) {
420
+
421
+ var o = $.extend({}, this.options, options),
422
+ items = this._getItemsAsjQuery(o && o.connected),
423
+ str = [];
424
+
425
+ $(items).each(function() {
426
+ var res = ($(o.item || this).attr(o.attribute || 'id') || '')
427
+ .match(o.expression || (/(.+)[-=_](.+)/)),
428
+ pid = ($(o.item || this).parent(o.listType)
429
+ .parent(o.items)
430
+ .attr(o.attribute || 'id') || '')
431
+ .match(o.expression || (/(.+)[-=_](.+)/));
432
+
433
+ if (res) {
434
+ str.push(((o.key || res[1]) + '[' + (o.key && o.expression ? res[1] : res[2]) + ']')
435
+ + '='
436
+ + (pid ? (o.key && o.expression ? pid[1] : pid[2]) : o.rootID));
437
+ }
438
+ });
439
+
440
+ if(!str.length && o.key) {
441
+ str.push(o.key + '=');
442
+ }
443
+
444
+ return str.join('&');
445
+
446
+ },
447
+
448
+ toHierarchy: function(options) {
449
+
450
+ var o = $.extend({}, this.options, options),
451
+ sDepth = o.startDepthCount || 0,
452
+ ret = [];
453
+
454
+ $(this.element).children(o.items).each(function () {
455
+ var level = _recursiveItems(this);
456
+ ret.push(level);
457
+ });
458
+
459
+ return ret;
460
+
461
+ function _recursiveItems(item) {
462
+ var id = ($(item).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
463
+ if (id) {
464
+ var currentItem = {"id" : id[2]};
465
+ if ($(item).children(o.listType).children(o.items).length > 0) {
466
+ currentItem.children = [];
467
+ $(item).children(o.listType).children(o.items).each(function() {
468
+ var level = _recursiveItems(this);
469
+ currentItem.children.push(level);
470
+ });
471
+ }
472
+ return currentItem;
473
+ }
474
+ }
475
+ },
476
+
477
+ toArray: function(options) {
478
+
479
+ var o = $.extend({}, this.options, options),
480
+ sDepth = o.startDepthCount || 0,
481
+ ret = [],
482
+ left = 2;
483
+
484
+ ret.push({
485
+ "item_id": o.rootID,
486
+ "parent_id": 'none',
487
+ "depth": sDepth,
488
+ "left": '1',
489
+ "right": ($(o.items, this.element).length + 1) * 2
490
+ });
491
+
492
+ $(this.element).children(o.items).each(function () {
493
+ left = _recursiveArray(this, sDepth + 1, left);
494
+ });
495
+
496
+ ret = ret.sort(function(a,b){ return (a.left - b.left); });
497
+
498
+ return ret;
499
+
500
+ function _recursiveArray(item, depth, left) {
501
+
502
+ var right = left + 1,
503
+ id,
504
+ pid;
505
+
506
+ if ($(item).children(o.listType).children(o.items).length > 0) {
507
+ depth ++;
508
+ $(item).children(o.listType).children(o.items).each(function () {
509
+ right = _recursiveArray($(this), depth, right);
510
+ });
511
+ depth --;
512
+ }
513
+
514
+ id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/));
515
+
516
+ if (depth === sDepth + 1) {
517
+ pid = o.rootID;
518
+ } else {
519
+ var parentItem = ($(item).parent(o.listType)
520
+ .parent(o.items)
521
+ .attr(o.attribute || 'id'))
522
+ .match(o.expression || (/(.+)[-=_](.+)/));
523
+ pid = parentItem[2];
524
+ }
525
+
526
+ if (id) {
527
+ ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right});
528
+ }
529
+
530
+ left = right + 1;
531
+ return left;
532
+ }
533
+
534
+ },
535
+
536
+ _clearEmpty: function(item) {
537
+ var o = this.options;
538
+
539
+ var emptyList = $(item).children(o.listType);
540
+
541
+ if (emptyList.length && !emptyList.children().length && !o.doNotClear) {
542
+ o.isTree && $(item).removeClass(o.branchClass + ' ' + o.expandedClass).addClass(o.leafClass);
543
+ emptyList.remove();
544
+ } else if (o.isTree && emptyList.length && emptyList.children().length && emptyList.is(':visible')) {
545
+ $(item).removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.expandedClass);
546
+ } else if (o.isTree && emptyList.length && emptyList.children().length && !emptyList.is(':visible')) {
547
+ $(item).removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.collapsedClass);
548
+ }
549
+
550
+ },
551
+
552
+ _getLevel: function(item) {
553
+
554
+ var level = 1;
555
+
556
+ if (this.options.listType) {
557
+ var list = item.closest(this.options.listType);
558
+ while (list && list.length > 0 &&
559
+ !list.is('.ui-sortable')) {
560
+ level++;
561
+ list = list.parent().closest(this.options.listType);
562
+ }
563
+ }
564
+
565
+ return level;
566
+ },
567
+
568
+ _getChildLevels: function(parent, depth) {
569
+ var self = this,
570
+ o = this.options,
571
+ result = 0;
572
+ depth = depth || 0;
573
+
574
+ $(parent).children(o.listType).children(o.items).each(function (index, child) {
575
+ result = Math.max(self._getChildLevels(child, depth + 1), result);
576
+ });
577
+
578
+ return depth ? result + 1 : result;
579
+ },
580
+
581
+ _isAllowed: function(parentItem, level, levels) {
582
+ var o = this.options,
583
+ maxLevels = this.placeholder.closest('.ui-sortable').nestedSortable('option', 'maxLevels'); // this takes into account the maxLevels set to the recipient list
584
+
585
+ // mjs - is the root protected?
586
+ // mjs - are we nesting too deep?
587
+ if ( ! o.isAllowed(this.placeholder, parentItem, this.currentItem)) {
588
+ this.placeholder.addClass(o.errorClass);
589
+ if (maxLevels < levels && maxLevels != 0) {
590
+ this.beyondMaxLevels = levels - maxLevels;
591
+ } else {
592
+ this.beyondMaxLevels = 1;
593
+ }
594
+ } else {
595
+ if (maxLevels < levels && maxLevels != 0) {
596
+ this.placeholder.addClass(o.errorClass);
597
+ this.beyondMaxLevels = levels - maxLevels;
598
+ } else {
599
+ this.placeholder.removeClass(o.errorClass);
600
+ this.beyondMaxLevels = 0;
601
+ }
602
+ }
603
+ }
604
+
605
+ }));
606
+
607
+ $.mjs.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.mjs.nestedSortable.prototype.options);
608
+ })(jQuery);
@@ -0,0 +1,43 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ //= require jquery
8
+ //= require jquery_ujs
9
+ //= require bootstrap-dropdown
10
+ //= require bootstrap-modal
11
+
12
+ $(document).ready(function(){
13
+
14
+ $('.dropdown-toggle').dropdown();
15
+
16
+ // fix sub nav on scroll
17
+ var $win = $(window)
18
+ , $nav = $('.subnav')
19
+ , navTop = $('.subnav').length && $('.subnav').offset().top - 40
20
+ , isFixed = 0;
21
+
22
+ processScroll();
23
+
24
+ // hack sad times - holdover until rewrite for 2.1
25
+ $nav.on('click', function () {
26
+ if (!isFixed) setTimeout(function () { $win.scrollTop($win.scrollTop() - 47) }, 10)
27
+ });
28
+
29
+ $win.on('scroll', processScroll)
30
+
31
+ function processScroll() {
32
+ var i, scrollTop = $win.scrollTop();
33
+ if (scrollTop >= navTop && !isFixed) {
34
+ isFixed = 1;
35
+ $nav.addClass('subnav-fixed')
36
+ } else if (scrollTop <= navTop && isFixed) {
37
+ isFixed = 0;
38
+ $nav.removeClass('subnav-fixed')
39
+ }
40
+ }
41
+
42
+ });
43
+
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.