qbrick 2.5.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (297) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +423 -0
  3. data/Rakefile +82 -0
  4. data/app/assets/javascripts/ckeditor/plugins/adv_link/LICENSE.txt +674 -0
  5. data/app/assets/javascripts/ckeditor/plugins/adv_link/README.md +62 -0
  6. data/app/assets/javascripts/ckeditor/plugins/adv_link/dialogs/anchor.js.coffee +81 -0
  7. data/app/assets/javascripts/ckeditor/plugins/adv_link/dialogs/link.js.coffee +1353 -0
  8. data/app/assets/javascripts/ckeditor/plugins/adv_link/images/anchor.png +0 -0
  9. data/app/assets/javascripts/ckeditor/plugins/adv_link/images/hidpi/anchor.png +0 -0
  10. data/app/assets/javascripts/ckeditor/plugins/adv_link/lang/de.js +68 -0
  11. data/app/assets/javascripts/ckeditor/plugins/adv_link/lang/en.js +68 -0
  12. data/app/assets/javascripts/ckeditor/plugins/adv_link/plugin.js.coffee +282 -0
  13. data/app/assets/javascripts/kuhsaft/application.js.coffee +7 -0
  14. data/app/assets/javascripts/kuhsaft/cms/application.js.coffee.erb +136 -0
  15. data/app/assets/javascripts/kuhsaft/views/read_more_view.js.coffee +17 -0
  16. data/app/assets/stylesheets/kuhsaft/application.css.sass +1 -0
  17. data/app/assets/stylesheets/kuhsaft/cms/application.css.sass +204 -0
  18. data/app/assets/stylesheets/kuhsaft/modules/_text_brick.css.sass +16 -0
  19. data/app/controllers/kuhsaft/api/pages_controller.rb +14 -0
  20. data/app/controllers/kuhsaft/cms/admin_controller.rb +18 -0
  21. data/app/controllers/kuhsaft/cms/assets_controller.rb +38 -0
  22. data/app/controllers/kuhsaft/cms/bricks_controller.rb +61 -0
  23. data/app/controllers/kuhsaft/cms/ckimages_controller.rb +26 -0
  24. data/app/controllers/kuhsaft/cms/pages_controller.rb +71 -0
  25. data/app/controllers/kuhsaft/pages_controller.rb +38 -0
  26. data/app/controllers/kuhsaft/sitemaps_controller.rb +12 -0
  27. data/app/helpers/cms_helper.rb +27 -0
  28. data/app/helpers/kuhsaft/admin_helper.rb +20 -0
  29. data/app/helpers/kuhsaft/cms/admin_helper.rb +21 -0
  30. data/app/helpers/kuhsaft/cms/pages_helper.rb +17 -0
  31. data/app/helpers/pages_helper.rb +49 -0
  32. data/app/helpers/sitemaps_helper.rb +12 -0
  33. data/app/models/kuhsaft/accordion_brick.rb +15 -0
  34. data/app/models/kuhsaft/accordion_item_brick.rb +21 -0
  35. data/app/models/kuhsaft/anchor_brick.rb +17 -0
  36. data/app/models/kuhsaft/asset.rb +29 -0
  37. data/app/models/kuhsaft/asset_brick.rb +26 -0
  38. data/app/models/kuhsaft/brick.rb +137 -0
  39. data/app/models/kuhsaft/brick_type.rb +7 -0
  40. data/app/models/kuhsaft/brick_type_filter.rb +18 -0
  41. data/app/models/kuhsaft/ckimage.rb +5 -0
  42. data/app/models/kuhsaft/cms.rb +7 -0
  43. data/app/models/kuhsaft/column_brick.rb +22 -0
  44. data/app/models/kuhsaft/image_brick.rb +16 -0
  45. data/app/models/kuhsaft/image_size.rb +51 -0
  46. data/app/models/kuhsaft/link_brick.rb +21 -0
  47. data/app/models/kuhsaft/page.rb +160 -0
  48. data/app/models/kuhsaft/page_type.rb +11 -0
  49. data/app/models/kuhsaft/partition.rb +18 -0
  50. data/app/models/kuhsaft/placeholder_brick.rb +23 -0
  51. data/app/models/kuhsaft/publish_state.rb +24 -0
  52. data/app/models/kuhsaft/slider_brick.rb +18 -0
  53. data/app/models/kuhsaft/text_brick.rb +23 -0
  54. data/app/models/kuhsaft/two_column_brick.rb +46 -0
  55. data/app/models/kuhsaft/video_brick.rb +22 -0
  56. data/app/uploaders/kuhsaft/asset_brick_asset_uploader.rb +43 -0
  57. data/app/uploaders/kuhsaft/asset_uploader.rb +50 -0
  58. data/app/uploaders/kuhsaft/ckimage_uploader.rb +16 -0
  59. data/app/uploaders/kuhsaft/image_brick_image_uploader.rb +35 -0
  60. data/app/views/kuhsaft/accordion_bricks/_accordion_brick.html.haml +3 -0
  61. data/app/views/kuhsaft/accordion_bricks/accordion_brick/_edit.html.haml +0 -0
  62. data/app/views/kuhsaft/accordion_item_bricks/_accordion_item_brick.html.haml +8 -0
  63. data/app/views/kuhsaft/accordion_item_bricks/accordion_item_brick/_edit.html.haml +1 -0
  64. data/app/views/kuhsaft/anchor_bricks/_anchor_brick.html.haml +1 -0
  65. data/app/views/kuhsaft/anchor_bricks/anchor_brick/_edit.html.haml +1 -0
  66. data/app/views/kuhsaft/asset_bricks/_asset_brick.html.haml +2 -0
  67. data/app/views/kuhsaft/asset_bricks/asset_brick/_edit.html.haml +8 -0
  68. data/app/views/kuhsaft/cms/admin/_brick_type_dropdown.html.haml +14 -0
  69. data/app/views/kuhsaft/cms/admin/_content_language_switch.html.haml +7 -0
  70. data/app/views/kuhsaft/cms/admin/_empty_state.html.haml +5 -0
  71. data/app/views/kuhsaft/cms/admin/_flash.html.haml +7 -0
  72. data/app/views/kuhsaft/cms/admin/_main_navigation.html.haml +6 -0
  73. data/app/views/kuhsaft/cms/assets/_form.html.haml +15 -0
  74. data/app/views/kuhsaft/cms/assets/_list.html.haml +11 -0
  75. data/app/views/kuhsaft/cms/assets/edit.html.haml +2 -0
  76. data/app/views/kuhsaft/cms/assets/index.html.haml +3 -0
  77. data/app/views/kuhsaft/cms/assets/new.html.haml +2 -0
  78. data/app/views/kuhsaft/cms/bricks/_brick_header.html.haml +43 -0
  79. data/app/views/kuhsaft/cms/bricks/_brick_item.html.haml +25 -0
  80. data/app/views/kuhsaft/cms/bricks/_brick_list.html.haml +4 -0
  81. data/app/views/kuhsaft/cms/bricks/_new.html.haml +41 -0
  82. data/app/views/kuhsaft/cms/bricks/_sort_form.html.haml +3 -0
  83. data/app/views/kuhsaft/cms/bricks/create.js.erb +11 -0
  84. data/app/views/kuhsaft/cms/bricks/destroy.js.erb +10 -0
  85. data/app/views/kuhsaft/cms/bricks/new.js.erb +14 -0
  86. data/app/views/kuhsaft/cms/bricks/update.js.erb +8 -0
  87. data/app/views/kuhsaft/cms/ckimages/create.html.haml +11 -0
  88. data/app/views/kuhsaft/cms/ckimages/destroy.js.erb +2 -0
  89. data/app/views/kuhsaft/cms/ckimages/index.html.haml +13 -0
  90. data/app/views/kuhsaft/cms/pages/_branch.html.haml +19 -0
  91. data/app/views/kuhsaft/cms/pages/_form.html.haml +45 -0
  92. data/app/views/kuhsaft/cms/pages/edit.html.haml +16 -0
  93. data/app/views/kuhsaft/cms/pages/index.html.haml +14 -0
  94. data/app/views/kuhsaft/cms/pages/new.html.haml +1 -0
  95. data/app/views/kuhsaft/cms/pages/show.html.haml +0 -0
  96. data/app/views/kuhsaft/cms/pages/sort.js.erb +0 -0
  97. data/app/views/kuhsaft/column_bricks/_column_brick.html.haml +3 -0
  98. data/app/views/kuhsaft/column_bricks/column_brick/_edit.html.haml +0 -0
  99. data/app/views/kuhsaft/image_bricks/_image_brick.html.haml +11 -0
  100. data/app/views/kuhsaft/image_bricks/image_brick/_edit.html.haml +13 -0
  101. data/app/views/kuhsaft/link_bricks/_link_brick.html.haml +2 -0
  102. data/app/views/kuhsaft/link_bricks/link_brick/_edit.html.haml +4 -0
  103. data/app/views/kuhsaft/pages/index.html.haml +7 -0
  104. data/app/views/kuhsaft/pages/show.html.haml +11 -0
  105. data/app/views/kuhsaft/placeholder_bricks/_placeholder_brick.html.haml +2 -0
  106. data/app/views/kuhsaft/placeholder_bricks/placeholder_brick/_edit.html.haml +1 -0
  107. data/app/views/kuhsaft/search/_form.html.haml +2 -0
  108. data/app/views/kuhsaft/search/_results.html.haml +8 -0
  109. data/app/views/kuhsaft/search/_results_entry.html.haml +13 -0
  110. data/app/views/kuhsaft/sitemaps/index.xml.haml +9 -0
  111. data/app/views/kuhsaft/slider_bricks/_slider_brick.html.haml +10 -0
  112. data/app/views/kuhsaft/slider_bricks/slider_brick/_edit.html.haml +0 -0
  113. data/app/views/kuhsaft/text_bricks/_text_brick.html.haml +11 -0
  114. data/app/views/kuhsaft/text_bricks/text_brick/_edit.html.haml +2 -0
  115. data/app/views/kuhsaft/two_column_bricks/_two_column_brick.html.haml +3 -0
  116. data/app/views/kuhsaft/two_column_bricks/two_column_brick/_childs.html.haml +5 -0
  117. data/app/views/kuhsaft/two_column_bricks/two_column_brick/_edit.html.haml +1 -0
  118. data/app/views/kuhsaft/video_bricks/_video_brick.html.haml +9 -0
  119. data/app/views/kuhsaft/video_bricks/video_brick/_edit.html.haml +8 -0
  120. data/app/views/layouts/kuhsaft/cms/application.html.haml +25 -0
  121. data/app/views/layouts/kuhsaft/cms/ckimages.html.haml +18 -0
  122. data/config/initializers/simple_form.rb +142 -0
  123. data/config/initializers/simple_form_bootstrap.rb +45 -0
  124. data/config/locales/de.yml +207 -0
  125. data/config/locales/en.yml +211 -0
  126. data/config/locales/models/kuhsaft/accordion_brick/de.yml +4 -0
  127. data/config/locales/models/kuhsaft/accordion_brick/en.yml +4 -0
  128. data/config/locales/models/kuhsaft/accordion_item_brick/de.yml +7 -0
  129. data/config/locales/models/kuhsaft/accordion_item_brick/en.yml +7 -0
  130. data/config/locales/models/kuhsaft/anchor_brick/de.yml +7 -0
  131. data/config/locales/models/kuhsaft/anchor_brick/en.yml +7 -0
  132. data/config/locales/models/kuhsaft/asset_brick/de.yml +9 -0
  133. data/config/locales/models/kuhsaft/asset_brick/en.yml +9 -0
  134. data/config/locales/models/kuhsaft/brick/de.yml +5 -0
  135. data/config/locales/models/kuhsaft/brick/en.yml +5 -0
  136. data/config/locales/models/kuhsaft/column_brick/de.yml +4 -0
  137. data/config/locales/models/kuhsaft/column_brick/en.yml +4 -0
  138. data/config/locales/models/kuhsaft/image_brick/de.yml +11 -0
  139. data/config/locales/models/kuhsaft/image_brick/en.yml +11 -0
  140. data/config/locales/models/kuhsaft/image_size/de.yml +13 -0
  141. data/config/locales/models/kuhsaft/image_size/en.yml +13 -0
  142. data/config/locales/models/kuhsaft/link_brick/de.yml +10 -0
  143. data/config/locales/models/kuhsaft/link_brick/en.yml +10 -0
  144. data/config/locales/models/kuhsaft/page/de.yml +19 -0
  145. data/config/locales/models/kuhsaft/page/en.yml +19 -0
  146. data/config/locales/models/kuhsaft/placeholder_brick/de.yml +8 -0
  147. data/config/locales/models/kuhsaft/placeholder_brick/en.yml +8 -0
  148. data/config/locales/models/kuhsaft/slider_brick/de.yml +4 -0
  149. data/config/locales/models/kuhsaft/slider_brick/en.yml +4 -0
  150. data/config/locales/models/kuhsaft/text_brick/de.yml +11 -0
  151. data/config/locales/models/kuhsaft/text_brick/en.yml +11 -0
  152. data/config/locales/models/kuhsaft/two_column_brick/de.yml +7 -0
  153. data/config/locales/models/kuhsaft/two_column_brick/en.yml +7 -0
  154. data/config/locales/models/kuhsaft/video_brick/de.yml +9 -0
  155. data/config/locales/models/kuhsaft/video_brick/en.yml +9 -0
  156. data/config/locales/simple_form.en.yml +26 -0
  157. data/config/locales/views/kuhsaft/cms/admin/de.yml +13 -0
  158. data/config/locales/views/kuhsaft/cms/admin/en.yml +12 -0
  159. data/config/locales/views/kuhsaft/cms/bricks/de.yml +18 -0
  160. data/config/locales/views/kuhsaft/cms/bricks/en.yml +18 -0
  161. data/config/locales/views/kuhsaft/cms/pages/de.yml +31 -0
  162. data/config/locales/views/kuhsaft/cms/pages/en.yml +31 -0
  163. data/config/locales/views/kuhsaft/image_brick/de.yml +6 -0
  164. data/config/locales/views/kuhsaft/image_brick/en.yml +6 -0
  165. data/config/locales/views/kuhsaft/search/de.yml +12 -0
  166. data/config/locales/views/kuhsaft/search/en.yml +12 -0
  167. data/config/locales/views/kuhsaft/text_brick/de.yml +6 -0
  168. data/config/locales/views/kuhsaft/text_brick/en.yml +6 -0
  169. data/config/locales/views/kuhsaft/video_brick/de.yml +7 -0
  170. data/config/locales/views/kuhsaft/video_brick/en.yml +7 -0
  171. data/config/routes.rb +30 -0
  172. data/db/migrate/01_create_kuhsaft_pages.rb +31 -0
  173. data/db/migrate/02_create_kuhsaft_bricks.rb +23 -0
  174. data/db/migrate/03_create_kuhsaft_brick_types.rb +12 -0
  175. data/db/migrate/04_create_kuhsaft_assets.rb +10 -0
  176. data/db/migrate/05_remove_cms_admin.rb +9 -0
  177. data/db/migrate/06_add_template_name_to_kuhsaft_bricks.rb +7 -0
  178. data/db/migrate/07_add_default_value_to_brick_type_enabled.rb +6 -0
  179. data/db/migrate/08_add_display_styles_to_bricks.rb +5 -0
  180. data/db/migrate/09_add_additional_fields_to_kuhsaft_bricks.rb +6 -0
  181. data/db/migrate/10_add_redirect_url_to_kuhsaft_pages.rb +7 -0
  182. data/db/migrate/11_update_url_and_redirect_url_value.rb +45 -0
  183. data/db/migrate/12_regenerate_fulltext.rb +12 -0
  184. data/db/migrate/13_add_page_title_to_pages.rb +7 -0
  185. data/db/migrate/14_move_kuhsaft_assets.rb +22 -0
  186. data/db/migrate/15_add_alt_text_to_bricks.rb +5 -0
  187. data/db/migrate/16_update_default_value_for_page_type.rb +9 -0
  188. data/db/migrate/17_set_page_type_to_content_for_empty_fields.rb +7 -0
  189. data/db/migrate/18_add_identifier_to_kuhsaft_pages.rb +6 -0
  190. data/db/migrate/19_add_col_count_to_bricks.rb +5 -0
  191. data/db/migrate/20_create_kuhsaft_ckimages.rb +9 -0
  192. data/db/seeds.rb +20 -0
  193. data/lib/generators/kuhsaft/assets/install_generator.rb +25 -0
  194. data/lib/generators/kuhsaft/translations/add_generator.rb +41 -0
  195. data/lib/kuhsaft.rb +22 -0
  196. data/lib/kuhsaft/brick_list.rb +87 -0
  197. data/lib/kuhsaft/engine.rb +27 -0
  198. data/lib/kuhsaft/gridded.rb +20 -0
  199. data/lib/kuhsaft/image_uploader_mounting.rb +22 -0
  200. data/lib/kuhsaft/orderable.rb +71 -0
  201. data/lib/kuhsaft/page_tree.rb +14 -0
  202. data/lib/kuhsaft/partial_extractor.rb +21 -0
  203. data/lib/kuhsaft/searchable.rb +69 -0
  204. data/lib/kuhsaft/touch_placeholders.rb +31 -0
  205. data/lib/kuhsaft/translatable.rb +54 -0
  206. data/lib/kuhsaft/version.rb +3 -0
  207. data/lib/tasks/kuhsaft_tasks.rake +22 -0
  208. data/lib/templates/kuhsaft/assets/ck-config.js.coffee +48 -0
  209. data/lib/templates/kuhsaft/assets/customizations.css.sass +0 -0
  210. data/lib/templates/kuhsaft/assets/customizations.js.coffee +0 -0
  211. data/lib/templates/kuhsaft/translations/add_translation.erb +8 -0
  212. data/spec/controllers/kuhsaft/api/pages_controller_spec.rb +70 -0
  213. data/spec/controllers/kuhsaft/pages_controller_spec.rb +90 -0
  214. data/spec/controllers/kuhsaft/sitemaps_controller_spec.rb +13 -0
  215. data/spec/dummy/Rakefile +7 -0
  216. data/spec/dummy/app/assets/images/spec-image.png +0 -0
  217. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  218. data/spec/dummy/app/assets/javascripts/kuhsaft/cms/ck-config.js.coffee +48 -0
  219. data/spec/dummy/app/assets/javascripts/kuhsaft/cms/customizations.js.coffee +0 -0
  220. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  221. data/spec/dummy/app/assets/stylesheets/kuhsaft/cms/customizations.css.sass +0 -0
  222. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  223. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  224. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  225. data/spec/dummy/bin/bundle +3 -0
  226. data/spec/dummy/bin/rails +4 -0
  227. data/spec/dummy/bin/rake +4 -0
  228. data/spec/dummy/config.ru +4 -0
  229. data/spec/dummy/config/application.rb +26 -0
  230. data/spec/dummy/config/boot.rb +3 -0
  231. data/spec/dummy/config/database.yml +19 -0
  232. data/spec/dummy/config/environment.rb +5 -0
  233. data/spec/dummy/config/environments/development.rb +29 -0
  234. data/spec/dummy/config/environments/production.rb +81 -0
  235. data/spec/dummy/config/environments/test.rb +36 -0
  236. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  237. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  238. data/spec/dummy/config/initializers/inflections.rb +16 -0
  239. data/spec/dummy/config/initializers/kuhsaft.rb +5 -0
  240. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  241. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  242. data/spec/dummy/config/initializers/session_store.rb +3 -0
  243. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  244. data/spec/dummy/config/locales/en.yml +23 -0
  245. data/spec/dummy/config/routes.rb +3 -0
  246. data/spec/dummy/db/.gitkeep +0 -0
  247. data/spec/dummy/lib/assets/.gitkeep +0 -0
  248. data/spec/dummy/log/.gitkeep +0 -0
  249. data/spec/dummy/public/404.html +26 -0
  250. data/spec/dummy/public/422.html +26 -0
  251. data/spec/dummy/public/500.html +25 -0
  252. data/spec/dummy/public/favicon.ico +0 -0
  253. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  254. data/spec/dummy/script/rails +6 -0
  255. data/spec/factories.rb +26 -0
  256. data/spec/features/cms_pages_spec.rb +76 -0
  257. data/spec/features/search_spec.rb +78 -0
  258. data/spec/helpers/kuhsaft/cms/admin_helper_spec.rb +25 -0
  259. data/spec/helpers/kuhsaft/cms/pages_helper_spec.rb +46 -0
  260. data/spec/helpers/kuhsaft/pages_helper_spec.rb +21 -0
  261. data/spec/kuhsaft_spec.rb +7 -0
  262. data/spec/lib/brick_list_spec.rb +50 -0
  263. data/spec/lib/engine_spec.rb +25 -0
  264. data/spec/lib/gridded_spec.rb +24 -0
  265. data/spec/lib/image_uploader_mounting_spec.rb +14 -0
  266. data/spec/lib/page_tree_spec.rb +38 -0
  267. data/spec/lib/searchable_spec.rb +30 -0
  268. data/spec/lib/touch_placeholders_spec.rb +44 -0
  269. data/spec/lib/translatable_spec.rb +155 -0
  270. data/spec/models/accordion_brick_spec.rb +38 -0
  271. data/spec/models/accordion_item_brick_spec.rb +50 -0
  272. data/spec/models/anchor_brick_spec.rb +26 -0
  273. data/spec/models/asset_brick_spec.rb +45 -0
  274. data/spec/models/asset_spec.rb +41 -0
  275. data/spec/models/brick_spec.rb +134 -0
  276. data/spec/models/brick_type_filter_spec.rb +64 -0
  277. data/spec/models/column_brick_spec.rb +32 -0
  278. data/spec/models/image_brick_spec.rb +49 -0
  279. data/spec/models/image_size_spec.rb +36 -0
  280. data/spec/models/link_brick_spec.rb +51 -0
  281. data/spec/models/page_spec.rb +472 -0
  282. data/spec/models/placeholder_brick_spec.rb +46 -0
  283. data/spec/models/publish_state_spec.rb +33 -0
  284. data/spec/models/slider_brick_spec.rb +26 -0
  285. data/spec/models/text_brick_spec.rb +30 -0
  286. data/spec/models/two_column_brick_spec.rb +82 -0
  287. data/spec/models/video_brick_spec.rb +32 -0
  288. data/spec/spec_helper.rb +81 -0
  289. data/spec/support/kuhsaft_spec_helper.rb +8 -0
  290. data/spec/support/write_expectation.rb +57 -0
  291. data/spec/views/kuhsaft/sitemaps/index.xml.haml_spec.rb +67 -0
  292. data/vendor/assets/javascripts/bootstrap-modal-v2.js +376 -0
  293. data/vendor/assets/javascripts/bootstrap-modalmanager.js +423 -0
  294. data/vendor/assets/javascripts/jquery.nestable.js +485 -0
  295. data/vendor/assets/stylesheets/bootstrap_modal.css +214 -0
  296. data/vendor/assets/stylesheets/nestable.css +84 -0
  297. metadata +870 -0
@@ -0,0 +1,485 @@
1
+ /*!
2
+ * Nestable jQuery Plugin - Copyright (c) 2012 David Bushell - http://dbushell.com/
3
+ * Dual-licensed under the BSD or MIT licenses
4
+ */
5
+ ;(function($, window, document, undefined)
6
+ {
7
+ var hasTouch = 'ontouchstart' in window;
8
+
9
+ /**
10
+ * Detect CSS pointer-events property
11
+ * events are normally disabled on the dragging element to avoid conflicts
12
+ * https://github.com/ausi/Feature-detection-technique-for-pointer-events/blob/master/modernizr-pointerevents.js
13
+ */
14
+ var hasPointerEvents = (function()
15
+ {
16
+ var el = document.createElement('div'),
17
+ docEl = document.documentElement;
18
+ if (!('pointerEvents' in el.style)) {
19
+ return false;
20
+ }
21
+ el.style.pointerEvents = 'auto';
22
+ el.style.pointerEvents = 'x';
23
+ docEl.appendChild(el);
24
+ var supports = window.getComputedStyle && window.getComputedStyle(el, '').pointerEvents === 'auto';
25
+ docEl.removeChild(el);
26
+ return !!supports;
27
+ })();
28
+
29
+ var eStart = hasTouch ? 'touchstart' : 'mousedown',
30
+ eMove = hasTouch ? 'touchmove' : 'mousemove',
31
+ eEnd = hasTouch ? 'touchend' : 'mouseup';
32
+ eCancel = hasTouch ? 'touchcancel' : 'mouseup';
33
+
34
+ var defaults = {
35
+ listNodeName : 'ol',
36
+ itemNodeName : 'li',
37
+ rootClass : 'dd',
38
+ listClass : 'dd-list',
39
+ itemClass : 'dd-item',
40
+ dragClass : 'dd-dragel',
41
+ handleClass : 'dd-handle',
42
+ collapsedClass : 'dd-collapsed',
43
+ placeClass : 'dd-placeholder',
44
+ noDragClass : 'dd-nodrag',
45
+ emptyClass : 'dd-empty',
46
+ expandBtnHTML : '<button data-action="expand" type="button">Expand</button>',
47
+ collapseBtnHTML : '<button data-action="collapse" type="button">Collapse</button>',
48
+ group : 0,
49
+ maxDepth : 5,
50
+ threshold : 20
51
+ };
52
+
53
+ function Plugin(element, options)
54
+ {
55
+ this.w = $(window);
56
+ this.el = $(element);
57
+ this.options = $.extend({}, defaults, options);
58
+ this.init();
59
+ }
60
+
61
+ Plugin.prototype = {
62
+
63
+ init: function()
64
+ {
65
+ var list = this;
66
+
67
+ list.reset();
68
+
69
+ list.el.data('nestable-group', this.options.group);
70
+
71
+ list.placeEl = $('<div class="' + list.options.placeClass + '"/>');
72
+
73
+ $.each(this.el.find(list.options.itemNodeName), function(k, el) {
74
+ list.setParent($(el));
75
+ });
76
+
77
+ list.el.on('click', 'button', function(e) {
78
+ if (list.dragEl || (!hasTouch && e.button !== 0)) {
79
+ return;
80
+ }
81
+ var target = $(e.currentTarget),
82
+ action = target.data('action'),
83
+ item = target.parent(list.options.itemNodeName);
84
+ if (action === 'collapse') {
85
+ list.collapseItem(item);
86
+ }
87
+ if (action === 'expand') {
88
+ list.expandItem(item);
89
+ }
90
+ });
91
+
92
+ var onStartEvent = function(e)
93
+ {
94
+ var handle = $(e.target);
95
+ if (!handle.hasClass(list.options.handleClass)) {
96
+ if (handle.closest('.' + list.options.noDragClass).length) {
97
+ return;
98
+ }
99
+ handle = handle.closest('.' + list.options.handleClass);
100
+ }
101
+ if (!handle.length || list.dragEl || (!hasTouch && e.button !== 0) || (hasTouch && e.touches.length !== 1)) {
102
+ return;
103
+ }
104
+ e.preventDefault();
105
+ list.dragStart(hasTouch ? e.touches[0] : e);
106
+ };
107
+
108
+ var onMoveEvent = function(e)
109
+ {
110
+ if (list.dragEl) {
111
+ e.preventDefault();
112
+ list.dragMove(hasTouch ? e.touches[0] : e);
113
+ }
114
+ };
115
+
116
+ var onEndEvent = function(e)
117
+ {
118
+ if (list.dragEl) {
119
+ e.preventDefault();
120
+ list.dragStop(hasTouch ? e.touches[0] : e);
121
+ }
122
+ };
123
+
124
+ if (hasTouch) {
125
+ list.el[0].addEventListener(eStart, onStartEvent, false);
126
+ window.addEventListener(eMove, onMoveEvent, false);
127
+ window.addEventListener(eEnd, onEndEvent, false);
128
+ window.addEventListener(eCancel, onEndEvent, false);
129
+ } else {
130
+ list.el.on(eStart, onStartEvent);
131
+ list.w.on(eMove, onMoveEvent);
132
+ list.w.on(eEnd, onEndEvent);
133
+ }
134
+
135
+ },
136
+
137
+ serialize: function()
138
+ {
139
+ var data,
140
+ depth = 0,
141
+ list = this;
142
+ step = function(level, depth)
143
+ {
144
+ var array = [ ],
145
+ items = level.children(list.options.itemNodeName);
146
+ items.each(function()
147
+ {
148
+ var li = $(this),
149
+ item = $.extend({}, li.data()),
150
+ sub = li.children(list.options.listNodeName);
151
+ if (sub.length) {
152
+ item.children = step(sub, depth + 1);
153
+ }
154
+ array.push(item);
155
+ });
156
+ return array;
157
+ };
158
+ data = step(list.el.find(list.options.listNodeName).first(), depth);
159
+ return data;
160
+ },
161
+
162
+ serialise: function()
163
+ {
164
+ return this.serialize();
165
+ },
166
+
167
+ reset: function()
168
+ {
169
+ this.mouse = {
170
+ offsetX : 0,
171
+ offsetY : 0,
172
+ startX : 0,
173
+ startY : 0,
174
+ lastX : 0,
175
+ lastY : 0,
176
+ nowX : 0,
177
+ nowY : 0,
178
+ distX : 0,
179
+ distY : 0,
180
+ dirAx : 0,
181
+ dirX : 0,
182
+ dirY : 0,
183
+ lastDirX : 0,
184
+ lastDirY : 0,
185
+ distAxX : 0,
186
+ distAxY : 0
187
+ };
188
+ this.moving = false;
189
+ this.dragEl = null;
190
+ this.dragRootEl = null;
191
+ this.dragDepth = 0;
192
+ this.hasNewRoot = false;
193
+ this.pointEl = null;
194
+ },
195
+
196
+ expandItem: function(li)
197
+ {
198
+ li.removeClass(this.options.collapsedClass);
199
+ li.children('[data-action="expand"]').hide();
200
+ li.children('[data-action="collapse"]').show();
201
+ li.children(this.options.listNodeName).show();
202
+ },
203
+
204
+ collapseItem: function(li)
205
+ {
206
+ var lists = li.children(this.options.listNodeName);
207
+ if (lists.length) {
208
+ li.addClass(this.options.collapsedClass);
209
+ li.children('[data-action="collapse"]').hide();
210
+ li.children('[data-action="expand"]').show();
211
+ li.children(this.options.listNodeName).hide();
212
+ }
213
+ },
214
+
215
+ expandAll: function()
216
+ {
217
+ var list = this;
218
+ list.el.find(list.options.itemNodeName).each(function() {
219
+ list.expandItem($(this));
220
+ });
221
+ },
222
+
223
+ collapseAll: function()
224
+ {
225
+ var list = this;
226
+ list.el.find(list.options.itemNodeName).each(function() {
227
+ list.collapseItem($(this));
228
+ });
229
+ },
230
+
231
+ setParent: function(li)
232
+ {
233
+ if (li.children(this.options.listNodeName).length) {
234
+ li.prepend($(this.options.expandBtnHTML));
235
+ li.prepend($(this.options.collapseBtnHTML));
236
+ }
237
+ li.children('[data-action="expand"]').hide();
238
+ },
239
+
240
+ unsetParent: function(li)
241
+ {
242
+ li.removeClass(this.options.collapsedClass);
243
+ li.children('[data-action]').remove();
244
+ li.children(this.options.listNodeName).remove();
245
+ },
246
+
247
+ dragStart: function(e)
248
+ {
249
+ var mouse = this.mouse,
250
+ target = $(e.target),
251
+ dragItem = target.closest(this.options.itemNodeName);
252
+
253
+ this.placeEl.css('height', dragItem.height());
254
+
255
+ mouse.offsetX = e.offsetX !== undefined ? e.offsetX : e.pageX - target.offset().left;
256
+ mouse.offsetY = e.offsetY !== undefined ? e.offsetY : e.pageY - target.offset().top;
257
+ mouse.startX = mouse.lastX = e.pageX;
258
+ mouse.startY = mouse.lastY = e.pageY;
259
+
260
+ this.dragRootEl = this.el;
261
+
262
+ this.dragEl = $(document.createElement(this.options.listNodeName)).addClass(this.options.listClass + ' ' + this.options.dragClass);
263
+ this.dragEl.css('width', dragItem.width());
264
+
265
+ // fix for zepto.js
266
+ //dragItem.after(this.placeEl).detach().appendTo(this.dragEl);
267
+ dragItem.after(this.placeEl);
268
+ dragItem[0].parentNode.removeChild(dragItem[0]);
269
+ dragItem.appendTo(this.dragEl);
270
+
271
+ $(document.body).append(this.dragEl);
272
+ this.dragEl.css({
273
+ 'left' : e.pageX - mouse.offsetX,
274
+ 'top' : e.pageY - mouse.offsetY
275
+ });
276
+ // total depth of dragging item
277
+ var i, depth,
278
+ items = this.dragEl.find(this.options.itemNodeName);
279
+ for (i = 0; i < items.length; i++) {
280
+ depth = $(items[i]).parents(this.options.listNodeName).length;
281
+ if (depth > this.dragDepth) {
282
+ this.dragDepth = depth;
283
+ }
284
+ }
285
+ },
286
+
287
+ dragStop: function(e)
288
+ {
289
+ // fix for zepto.js
290
+ //this.placeEl.replaceWith(this.dragEl.children(this.options.itemNodeName + ':first').detach());
291
+ var el = this.dragEl.children(this.options.itemNodeName).first();
292
+ el[0].parentNode.removeChild(el[0]);
293
+ this.placeEl.replaceWith(el);
294
+
295
+ this.dragEl.remove();
296
+ this.el.trigger('change');
297
+ if (this.hasNewRoot) {
298
+ this.dragRootEl.trigger('change');
299
+ }
300
+ this.reset();
301
+ },
302
+
303
+ dragMove: function(e)
304
+ {
305
+ var list, parent, prev, next, depth,
306
+ opt = this.options,
307
+ mouse = this.mouse;
308
+
309
+ this.dragEl.css({
310
+ 'left' : e.pageX - mouse.offsetX,
311
+ 'top' : e.pageY - mouse.offsetY
312
+ });
313
+
314
+ // mouse position last events
315
+ mouse.lastX = mouse.nowX;
316
+ mouse.lastY = mouse.nowY;
317
+ // mouse position this events
318
+ mouse.nowX = e.pageX;
319
+ mouse.nowY = e.pageY;
320
+ // distance mouse moved between events
321
+ mouse.distX = mouse.nowX - mouse.lastX;
322
+ mouse.distY = mouse.nowY - mouse.lastY;
323
+ // direction mouse was moving
324
+ mouse.lastDirX = mouse.dirX;
325
+ mouse.lastDirY = mouse.dirY;
326
+ // direction mouse is now moving (on both axis)
327
+ mouse.dirX = mouse.distX === 0 ? 0 : mouse.distX > 0 ? 1 : -1;
328
+ mouse.dirY = mouse.distY === 0 ? 0 : mouse.distY > 0 ? 1 : -1;
329
+ // axis mouse is now moving on
330
+ var newAx = Math.abs(mouse.distX) > Math.abs(mouse.distY) ? 1 : 0;
331
+
332
+ // do nothing on first move
333
+ if (!mouse.moving) {
334
+ mouse.dirAx = newAx;
335
+ mouse.moving = true;
336
+ return;
337
+ }
338
+
339
+ // calc distance moved on this axis (and direction)
340
+ if (mouse.dirAx !== newAx) {
341
+ mouse.distAxX = 0;
342
+ mouse.distAxY = 0;
343
+ } else {
344
+ mouse.distAxX += Math.abs(mouse.distX);
345
+ if (mouse.dirX !== 0 && mouse.dirX !== mouse.lastDirX) {
346
+ mouse.distAxX = 0;
347
+ }
348
+ mouse.distAxY += Math.abs(mouse.distY);
349
+ if (mouse.dirY !== 0 && mouse.dirY !== mouse.lastDirY) {
350
+ mouse.distAxY = 0;
351
+ }
352
+ }
353
+ mouse.dirAx = newAx;
354
+
355
+ /**
356
+ * move horizontal
357
+ */
358
+ if (mouse.dirAx && mouse.distAxX >= opt.threshold) {
359
+ // reset move distance on x-axis for new phase
360
+ mouse.distAxX = 0;
361
+ prev = this.placeEl.prev(opt.itemNodeName);
362
+ // increase horizontal level if previous sibling exists and is not collapsed
363
+ if (mouse.distX > 0 && prev.length && !prev.hasClass(opt.collapsedClass)) {
364
+ // cannot increase level when item above is collapsed
365
+ list = prev.find(opt.listNodeName).last();
366
+ // check if depth limit has reached
367
+ depth = this.placeEl.parents(opt.listNodeName).length;
368
+ if (depth + this.dragDepth <= opt.maxDepth) {
369
+ // create new sub-level if one doesn't exist
370
+ if (!list.length) {
371
+ list = $('<' + opt.listNodeName + '/>').addClass(opt.listClass);
372
+ list.append(this.placeEl);
373
+ prev.append(list);
374
+ this.setParent(prev);
375
+ } else {
376
+ // else append to next level up
377
+ list = prev.children(opt.listNodeName).last();
378
+ list.append(this.placeEl);
379
+ }
380
+ }
381
+ }
382
+ // decrease horizontal level
383
+ if (mouse.distX < 0) {
384
+ // we can't decrease a level if an item preceeds the current one
385
+ next = this.placeEl.next(opt.itemNodeName);
386
+ if (!next.length) {
387
+ parent = this.placeEl.parent();
388
+ this.placeEl.closest(opt.itemNodeName).after(this.placeEl);
389
+ if (!parent.children().length) {
390
+ this.unsetParent(parent.parent());
391
+ }
392
+ }
393
+ }
394
+ }
395
+
396
+ var isEmpty = false;
397
+
398
+ // find list item under cursor
399
+ if (!hasPointerEvents) {
400
+ this.dragEl[0].style.visibility = 'hidden';
401
+ }
402
+ this.pointEl = $(document.elementFromPoint(e.pageX - document.body.scrollLeft, e.pageY - (window.pageYOffset || document.documentElement.scrollTop)));
403
+ if (!hasPointerEvents) {
404
+ this.dragEl[0].style.visibility = 'visible';
405
+ }
406
+ if (this.pointEl.hasClass(opt.handleClass)) {
407
+ this.pointEl = this.pointEl.parent(opt.itemNodeName);
408
+ }
409
+ if (this.pointEl.hasClass(opt.emptyClass)) {
410
+ isEmpty = true;
411
+ }
412
+ else if (!this.pointEl.length || !this.pointEl.hasClass(opt.itemClass)) {
413
+ return;
414
+ }
415
+
416
+ // find parent list of item under cursor
417
+ var pointElRoot = this.pointEl.closest('.' + opt.rootClass),
418
+ isNewRoot = this.dragRootEl.data('nestable-id') !== pointElRoot.data('nestable-id');
419
+
420
+ /**
421
+ * move vertical
422
+ */
423
+ if (!mouse.dirAx || isNewRoot || isEmpty) {
424
+ // check if groups match if dragging over new root
425
+ if (isNewRoot && opt.group !== pointElRoot.data('nestable-group')) {
426
+ return;
427
+ }
428
+ // check depth limit
429
+ depth = this.dragDepth - 1 + this.pointEl.parents(opt.listNodeName).length;
430
+ if (depth > opt.maxDepth) {
431
+ return;
432
+ }
433
+ var before = e.pageY < (this.pointEl.offset().top + this.pointEl.height() / 2);
434
+ parent = this.placeEl.parent();
435
+ // if empty create new list to replace empty placeholder
436
+ if (isEmpty) {
437
+ list = $(document.createElement(opt.listNodeName)).addClass(opt.listClass);
438
+ list.append(this.placeEl);
439
+ this.pointEl.replaceWith(list);
440
+ }
441
+ else if (before) {
442
+ this.pointEl.before(this.placeEl);
443
+ }
444
+ else {
445
+ this.pointEl.after(this.placeEl);
446
+ }
447
+ if (!parent.children().length) {
448
+ this.unsetParent(parent.parent());
449
+ }
450
+ if (!this.dragRootEl.find(opt.itemNodeName).length) {
451
+ this.dragRootEl.append('<div class="' + opt.emptyClass + '"/>');
452
+ }
453
+ // parent root list has changed
454
+ if (isNewRoot) {
455
+ this.dragRootEl = pointElRoot;
456
+ this.hasNewRoot = this.el[0] !== this.dragRootEl[0];
457
+ }
458
+ }
459
+ }
460
+
461
+ };
462
+
463
+ $.fn.nestable = function(params)
464
+ {
465
+ var lists = this,
466
+ retval = this;
467
+
468
+ lists.each(function()
469
+ {
470
+ var plugin = $(this).data("nestable");
471
+
472
+ if (!plugin) {
473
+ $(this).data("nestable", new Plugin(this, params));
474
+ $(this).data("nestable-id", new Date().getTime());
475
+ } else {
476
+ if (typeof params === 'string' && typeof plugin[params] === 'function') {
477
+ retval = plugin[params]();
478
+ }
479
+ }
480
+ });
481
+
482
+ return retval || lists;
483
+ };
484
+
485
+ })(window.jQuery || window.Zepto, window, document);