cardboard_cms 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (360) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +42 -0
  5. data/Gemfile.lock +324 -0
  6. data/Guardfile +23 -0
  7. data/LICENSE.txt +677 -0
  8. data/README.md +370 -0
  9. data/Rakefile +23 -0
  10. data/app/assets/images/cardboard/.gitkeep +0 -0
  11. data/app/assets/images/cardboard/bg.png +0 -0
  12. data/app/assets/images/cardboard/calendar.png +0 -0
  13. data/app/assets/images/cardboard/lorem-ipsum-coffe-mug.jpg +0 -0
  14. data/app/assets/javascripts/cardboard.js +1 -0
  15. data/app/assets/javascripts/cardboard/admin.js +62 -0
  16. data/app/assets/javascripts/cardboard/content_sidebar.js +27 -0
  17. data/app/assets/javascripts/cardboard/datepicker.js +19 -0
  18. data/app/assets/javascripts/cardboard/main_sidebar.js +32 -0
  19. data/app/assets/javascripts/cardboard/rich_text.js +81 -0
  20. data/app/assets/javascripts/cardboard/search_filter.js +28 -0
  21. data/app/assets/stylesheets/cardboard.css.scss +2 -0
  22. data/app/assets/stylesheets/cardboard/_bootstrap-select.css.scss +183 -0
  23. data/app/assets/stylesheets/cardboard/_content.css.scss +35 -0
  24. data/app/assets/stylesheets/cardboard/_content_sidebar.css.scss +96 -0
  25. data/app/assets/stylesheets/cardboard/_framework.css.scss +129 -0
  26. data/app/assets/stylesheets/cardboard/_main_sidebar.css.scss +38 -0
  27. data/app/assets/stylesheets/cardboard/_main_topbar.css.scss +62 -0
  28. data/app/assets/stylesheets/cardboard/_resources.css.scss +28 -0
  29. data/app/assets/stylesheets/cardboard/_rich_text.css.scss +6 -0
  30. data/app/assets/stylesheets/cardboard/_variables.scss +326 -0
  31. data/app/assets/stylesheets/cardboard/admin.css.scss +63 -0
  32. data/app/controllers/cardboard/application_controller.rb +45 -0
  33. data/app/controllers/cardboard/dashboard_controller.rb +9 -0
  34. data/app/controllers/cardboard/my_account_controller.rb +27 -0
  35. data/app/controllers/cardboard/pages_controller.rb +34 -0
  36. data/app/controllers/cardboard/resource_controller.rb +61 -0
  37. data/app/controllers/cardboard/settings_controller.rb +28 -0
  38. data/app/controllers/cardboard/super_user_controller.rb +8 -0
  39. data/app/controllers/pages_controller.rb +29 -0
  40. data/app/decorators/controllers/application_controller_decorator.rb +9 -0
  41. data/app/decorators/lib/cardboard/user_class_decorator.rb +32 -0
  42. data/app/helpers/cardboard/application_helper.rb +4 -0
  43. data/app/helpers/cardboard/public_helper.rb +53 -0
  44. data/app/helpers/cardboard/resource_helper.rb +80 -0
  45. data/app/inputs/date_picker_input.rb +10 -0
  46. data/app/inputs/date_time_input.rb +7 -0
  47. data/app/inputs/image_input.rb +3 -0
  48. data/app/inputs/rich_text_input.rb +6 -0
  49. data/app/models/cardboard/field.rb +67 -0
  50. data/app/models/cardboard/field/boolean.rb +29 -0
  51. data/app/models/cardboard/field/date.rb +24 -0
  52. data/app/models/cardboard/field/decimal.rb +25 -0
  53. data/app/models/cardboard/field/external_link.rb +4 -0
  54. data/app/models/cardboard/field/file.rb +19 -0
  55. data/app/models/cardboard/field/image.rb +33 -0
  56. data/app/models/cardboard/field/integer.rb +26 -0
  57. data/app/models/cardboard/field/resource_link.rb +4 -0
  58. data/app/models/cardboard/field/rich_text.rb +21 -0
  59. data/app/models/cardboard/field/string.rb +16 -0
  60. data/app/models/cardboard/field/text.rb +15 -0
  61. data/app/models/cardboard/page.rb +253 -0
  62. data/app/models/cardboard/page_part.rb +79 -0
  63. data/app/models/cardboard/setting.rb +46 -0
  64. data/app/views/cardboard/dashboard/index.html.slim +1 -0
  65. data/app/views/cardboard/fields/_base_input.html.slim +1 -0
  66. data/app/views/cardboard/fields/_boolean.html.slim +4 -0
  67. data/app/views/cardboard/fields/_date.html.slim +1 -0
  68. data/app/views/cardboard/fields/_external_link.html.slim +2 -0
  69. data/app/views/cardboard/fields/_file.html.slim +12 -0
  70. data/app/views/cardboard/fields/_image.html.slim +11 -0
  71. data/app/views/cardboard/fields/_resource_link.html.slim +2 -0
  72. data/app/views/cardboard/fields/_rich_text.html.slim +3 -0
  73. data/app/views/cardboard/fields/_string.html.slim +1 -0
  74. data/app/views/cardboard/my_account/edit.html.slim +29 -0
  75. data/app/views/cardboard/pages/_error.html.slim +7 -0
  76. data/app/views/cardboard/pages/_seo.html.slim +6 -0
  77. data/app/views/cardboard/pages/_sidebar.html.slim +17 -0
  78. data/app/views/cardboard/pages/_subpart_fields.html.slim +20 -0
  79. data/app/views/cardboard/pages/_url_field.html.slim +20 -0
  80. data/app/views/cardboard/pages/edit.html.slim +43 -0
  81. data/app/views/cardboard/pages/index.html.slim +2 -0
  82. data/app/views/cardboard/pages/show.html.slim +9 -0
  83. data/app/views/cardboard/resources/_advanced_search.html.slim +40 -0
  84. data/app/views/cardboard/resources/_search_button.html.slim +2 -0
  85. data/app/views/cardboard/resources/_search_helper.html.slim +17 -0
  86. data/app/views/cardboard/resources/_simple_search.html.slim +6 -0
  87. data/app/views/cardboard/rich_editor/_links_modal.html.slim +39 -0
  88. data/app/views/cardboard/settings/index.html.slim +8 -0
  89. data/app/views/cardboard/super_user/index.html.slim +10 -0
  90. data/app/views/layouts/cardboard/_flash_message.html.slim +6 -0
  91. data/app/views/layouts/cardboard/_head.html.slim +16 -0
  92. data/app/views/layouts/cardboard/_main_sidebar.html.slim +12 -0
  93. data/app/views/layouts/cardboard/_main_topbar.html.slim +32 -0
  94. data/app/views/layouts/cardboard/application.html.slim +28 -0
  95. data/cardboard.gemspec +57 -0
  96. data/config/initializers/dragonfly.rb +27 -0
  97. data/config/initializers/ranker_mapper_finder_bugfix.rb +43 -0
  98. data/config/initializers/simple_form.rb +142 -0
  99. data/config/initializers/simple_form_bootstrap.rb +45 -0
  100. data/config/locales/simple_form.en.yml +26 -0
  101. data/config/routes.rb +53 -0
  102. data/doc/apple-touch-icon.png +0 -0
  103. data/doc/classes/Cardboard.html +190 -0
  104. data/doc/classes/Cardboard/AdminController.html +134 -0
  105. data/doc/classes/Cardboard/AdminHelper.html +307 -0
  106. data/doc/classes/Cardboard/ApplicationController.html +76 -0
  107. data/doc/classes/Cardboard/ApplicationHelper.html +70 -0
  108. data/doc/classes/Cardboard/DashboardController.html +131 -0
  109. data/doc/classes/Cardboard/Field.html +283 -0
  110. data/doc/classes/Cardboard/Field/Boolean.html +218 -0
  111. data/doc/classes/Cardboard/Field/Date.html +218 -0
  112. data/doc/classes/Cardboard/Field/Decimal.html +218 -0
  113. data/doc/classes/Cardboard/Field/ExternalLink.html +76 -0
  114. data/doc/classes/Cardboard/Field/File.html +131 -0
  115. data/doc/classes/Cardboard/Field/Image.html +181 -0
  116. data/doc/classes/Cardboard/Field/Integer.html +218 -0
  117. data/doc/classes/Cardboard/Field/ResourceLink.html +76 -0
  118. data/doc/classes/Cardboard/Field/RichText.html +131 -0
  119. data/doc/classes/Cardboard/Field/String.html +131 -0
  120. data/doc/classes/Cardboard/Page.html +1184 -0
  121. data/doc/classes/Cardboard/PagePart.html +304 -0
  122. data/doc/classes/Cardboard/PagesController.html +186 -0
  123. data/doc/classes/Cardboard/PublicHelper.html +252 -0
  124. data/doc/classes/Cardboard/Setting.html +240 -0
  125. data/doc/classes/Cardboard/SettingsController.html +184 -0
  126. data/doc/classes/Cardboard/SuperUserController.html +130 -0
  127. data/doc/classes/Cardboard/UsersController.html +191 -0
  128. data/doc/classes/DatePickerInput.html +132 -0
  129. data/doc/classes/ImageInput.html +76 -0
  130. data/doc/classes/Object.html +211 -0
  131. data/doc/classes/PagesController.html +145 -0
  132. data/doc/classes/RichTextInput.html +132 -0
  133. data/doc/created.rid +31 -0
  134. data/doc/css/github.css +129 -0
  135. data/doc/css/main.css +333 -0
  136. data/doc/css/panel.css +384 -0
  137. data/doc/css/reset.css +48 -0
  138. data/doc/favicon.ico +0 -0
  139. data/doc/files/app/controllers/cardboard/admin_controller_rb.html +79 -0
  140. data/doc/files/app/controllers/cardboard/application_controller_rb.html +84 -0
  141. data/doc/files/app/controllers/cardboard/dashboard_controller_rb.html +84 -0
  142. data/doc/files/app/controllers/cardboard/pages_controller_rb.html +84 -0
  143. data/doc/files/app/controllers/cardboard/settings_controller_rb.html +84 -0
  144. data/doc/files/app/controllers/cardboard/super_user_controller_rb.html +84 -0
  145. data/doc/files/app/controllers/cardboard/users_controller_rb.html +84 -0
  146. data/doc/files/app/controllers/pages_controller_rb.html +79 -0
  147. data/doc/files/app/decorators/controllers/application_controller_decorator_rb.html +68 -0
  148. data/doc/files/app/decorators/lib/cardboard/user_class_decorator_rb.html +68 -0
  149. data/doc/files/app/helpers/cardboard/admin_helper_rb.html +84 -0
  150. data/doc/files/app/helpers/cardboard/application_helper_rb.html +84 -0
  151. data/doc/files/app/helpers/cardboard/public_helper_rb.html +84 -0
  152. data/doc/files/app/inputs/date_picker_input_rb.html +79 -0
  153. data/doc/files/app/inputs/image_input_rb.html +79 -0
  154. data/doc/files/app/inputs/rich_text_input_rb.html +79 -0
  155. data/doc/files/app/models/cardboard/field/boolean_rb.html +84 -0
  156. data/doc/files/app/models/cardboard/field/date_rb.html +84 -0
  157. data/doc/files/app/models/cardboard/field/decimal_rb.html +84 -0
  158. data/doc/files/app/models/cardboard/field/external_link_rb.html +84 -0
  159. data/doc/files/app/models/cardboard/field/file_rb.html +84 -0
  160. data/doc/files/app/models/cardboard/field/image_rb.html +84 -0
  161. data/doc/files/app/models/cardboard/field/integer_rb.html +84 -0
  162. data/doc/files/app/models/cardboard/field/resource_link_rb.html +84 -0
  163. data/doc/files/app/models/cardboard/field/rich_text_rb.html +84 -0
  164. data/doc/files/app/models/cardboard/field/string_rb.html +84 -0
  165. data/doc/files/app/models/cardboard/field_rb.html +84 -0
  166. data/doc/files/app/models/cardboard/page_part_rb.html +84 -0
  167. data/doc/files/app/models/cardboard/page_rb.html +84 -0
  168. data/doc/files/app/models/cardboard/setting_rb.html +84 -0
  169. data/doc/i/arrows.png +0 -0
  170. data/doc/i/results_bg.png +0 -0
  171. data/doc/i/tree_bg.png +0 -0
  172. data/doc/index.html +13 -0
  173. data/doc/js/highlight.pack.js +1 -0
  174. data/doc/js/jquery-1.3.2.min.js +19 -0
  175. data/doc/js/jquery-effect.js +593 -0
  176. data/doc/js/main.js +24 -0
  177. data/doc/js/navigation.js +142 -0
  178. data/doc/js/search_index.js +1 -0
  179. data/doc/js/searchdoc.js +449 -0
  180. data/doc/js/searcher.js +228 -0
  181. data/doc/panel/index.html +73 -0
  182. data/doc/panel/links.html +66 -0
  183. data/doc/panel/tree.js +1 -0
  184. data/lib/cardboard/application.rb +67 -0
  185. data/lib/cardboard/engine.rb +83 -0
  186. data/lib/cardboard/helpers/seed.rb +80 -0
  187. data/lib/cardboard/helpers/settings.rb +58 -0
  188. data/lib/cardboard/version.rb +3 -0
  189. data/lib/cardboard_cms.rb +34 -0
  190. data/lib/generators/cardboard/assets/assets_generator.rb +18 -0
  191. data/lib/generators/cardboard/install/install_generator.rb +96 -0
  192. data/lib/generators/cardboard/install/templates/cardboard.rb.erb +53 -0
  193. data/lib/generators/cardboard/install/templates/cardboard.yml +29 -0
  194. data/lib/generators/cardboard/install/templates/index.html.erb +0 -0
  195. data/lib/generators/cardboard/install/templates/migrations/1_create_cardboard_fields.rb +21 -0
  196. data/lib/generators/cardboard/install/templates/migrations/2_create_cardboard_page_parts.rb +17 -0
  197. data/lib/generators/cardboard/install/templates/migrations/3_create_cardboard_pages.rb +18 -0
  198. data/lib/generators/cardboard/install/templates/migrations/4_create_cardboard_settings.rb +14 -0
  199. data/lib/generators/cardboard/resource/resource_generator.rb +52 -0
  200. data/lib/generators/cardboard/resource/templates/admin_controller.rb +9 -0
  201. data/lib/generators/cardboard/resource/templates/slim/_fields.html.slim +5 -0
  202. data/lib/generators/cardboard/resource/templates/slim/edit.html.slim +4 -0
  203. data/lib/generators/cardboard/resource/templates/slim/index.html.slim +18 -0
  204. data/lib/generators/cardboard/resource/templates/slim/new.html.slim +4 -0
  205. data/lib/tasks/cardboard_tasks.rake +22 -0
  206. data/lib/templates/erb/scaffold/_form.html.erb +13 -0
  207. data/script/rails +8 -0
  208. data/test/dummy/README.rdoc +261 -0
  209. data/test/dummy/Rakefile +7 -0
  210. data/test/dummy/app/assets/images/defaults/CrashTest.jpg +0 -0
  211. data/test/dummy/app/assets/javascripts/admins.js +2 -0
  212. data/test/dummy/app/assets/javascripts/application.js +5 -0
  213. data/test/dummy/app/assets/javascripts/beans.js +2 -0
  214. data/test/dummy/app/assets/javascripts/cardboard.js +1 -0
  215. data/test/dummy/app/assets/javascripts/icescreams.js +2 -0
  216. data/test/dummy/app/assets/javascripts/main.js +2 -0
  217. data/test/dummy/app/assets/javascripts/news_posts.js +2 -0
  218. data/test/dummy/app/assets/javascripts/pianos.js +2 -0
  219. data/test/dummy/app/assets/stylesheets/admins.css.scss +3 -0
  220. data/test/dummy/app/assets/stylesheets/application.css.scss +9 -0
  221. data/test/dummy/app/assets/stylesheets/beans.css.scss +3 -0
  222. data/test/dummy/app/assets/stylesheets/cardboard.css.scss +5 -0
  223. data/test/dummy/app/assets/stylesheets/icescreams.css.scss +3 -0
  224. data/test/dummy/app/assets/stylesheets/main.css +4 -0
  225. data/test/dummy/app/assets/stylesheets/news_posts.css.scss +3 -0
  226. data/test/dummy/app/assets/stylesheets/pianos.css.scss +3 -0
  227. data/test/dummy/app/assets/stylesheets/scaffolds.css.scss +69 -0
  228. data/test/dummy/app/controllers/application_controller.rb +3 -0
  229. data/test/dummy/app/controllers/cardboard/pianos_controller.rb +6 -0
  230. data/test/dummy/app/controllers/pianos_controller.rb +83 -0
  231. data/test/dummy/app/helpers/application_helper.rb +9 -0
  232. data/test/dummy/app/helpers/cardboard/pianos_helper.rb +7 -0
  233. data/test/dummy/app/mailers/.gitkeep +0 -0
  234. data/test/dummy/app/models/.gitkeep +0 -0
  235. data/test/dummy/app/models/admin_user.rb +28 -0
  236. data/test/dummy/app/models/piano.rb +3 -0
  237. data/test/dummy/app/views/cardboard/pianos/_fields.html.slim +5 -0
  238. data/test/dummy/app/views/cardboard/pianos/edit.html.slim +6 -0
  239. data/test/dummy/app/views/cardboard/pianos/index.html.slim +18 -0
  240. data/test/dummy/app/views/cardboard/pianos/new.html.slim +6 -0
  241. data/test/dummy/app/views/cardboard/pianos/show.html.slim +11 -0
  242. data/test/dummy/app/views/layouts/application.html.slim +24 -0
  243. data/test/dummy/app/views/main/index.html.slim +1 -0
  244. data/test/dummy/app/views/pages/about-us.html.slim +1 -0
  245. data/test/dummy/app/views/pages/home.html.slim +3 -0
  246. data/test/dummy/app/views/pianos/_form.html.erb +25 -0
  247. data/test/dummy/app/views/pianos/edit.html.erb +6 -0
  248. data/test/dummy/app/views/pianos/index.html.erb +25 -0
  249. data/test/dummy/app/views/pianos/new.html.erb +5 -0
  250. data/test/dummy/app/views/pianos/show.html.erb +15 -0
  251. data/test/dummy/config.ru +4 -0
  252. data/test/dummy/config/application.rb +50 -0
  253. data/test/dummy/config/boot.rb +10 -0
  254. data/test/dummy/config/cardboard.yml +126 -0
  255. data/test/dummy/config/database.yml +17 -0
  256. data/test/dummy/config/environment.rb +5 -0
  257. data/test/dummy/config/environments/development.rb +24 -0
  258. data/test/dummy/config/environments/production.rb +70 -0
  259. data/test/dummy/config/environments/test.rb +33 -0
  260. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  261. data/test/dummy/config/initializers/cardboard.rb +53 -0
  262. data/test/dummy/config/initializers/devise.rb +240 -0
  263. data/test/dummy/config/initializers/inflections.rb +15 -0
  264. data/test/dummy/config/initializers/mime_types.rb +5 -0
  265. data/test/dummy/config/initializers/secret_token.rb +8 -0
  266. data/test/dummy/config/initializers/session_store.rb +8 -0
  267. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  268. data/test/dummy/config/locales/devise.en.yml +59 -0
  269. data/test/dummy/config/locales/en.yml +5 -0
  270. data/test/dummy/config/routes.rb +16 -0
  271. data/test/dummy/db/migrate/20130403142235_create_pianos.rb +10 -0
  272. data/test/dummy/db/migrate/20130417134832_add_devise_to_admin_users.rb +53 -0
  273. data/test/dummy/db/migrate/20130426021522_create_news_posts.rb +10 -0
  274. data/test/dummy/db/migrate/20130501195423_create_icescreams.rb +10 -0
  275. data/test/dummy/db/migrate/20130502165540_create_beans.rb +12 -0
  276. data/test/dummy/db/migrate/20130522151358_create_cardboard_fields.rb +21 -0
  277. data/test/dummy/db/migrate/20130522151359_create_cardboard_page_parts.rb +17 -0
  278. data/test/dummy/db/migrate/20130522151400_create_cardboard_pages.rb +18 -0
  279. data/test/dummy/db/migrate/20130522151401_create_cardboard_settings.rb +14 -0
  280. data/test/dummy/db/migrate/20130607132558_create_admins.rb +9 -0
  281. data/test/dummy/db/schema.rb +129 -0
  282. data/test/dummy/db/seeds.rb +2 -0
  283. data/test/dummy/lib/assets/.gitkeep +0 -0
  284. data/test/dummy/log/.gitkeep +0 -0
  285. data/test/dummy/public/404.html +26 -0
  286. data/test/dummy/public/422.html +26 -0
  287. data/test/dummy/public/500.html +25 -0
  288. data/test/dummy/public/favicon.ico +0 -0
  289. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_10_816_404_no_file.png +0 -0
  290. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_10_816_404_no_file.png.meta +2 -0
  291. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_17_87_404_no_file.png +0 -0
  292. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_17_87_404_no_file.png.meta +2 -0
  293. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_34_680_404_no_file.png +0 -0
  294. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_39_34_680_404_no_file.png.meta +2 -0
  295. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_44_00_698_404_no_file.png +0 -0
  296. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_44_00_698_404_no_file.png.meta +2 -0
  297. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_46_49_55_6152message_in_a_bottle.jpeg +0 -0
  298. data/test/dummy/public/system/dragonfly/development/2013/04/16/10_46_49_55_6152message_in_a_bottle.jpeg.meta +2 -0
  299. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_10_30_773_404_no_file.png +0 -0
  300. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_10_30_773_404_no_file.png.meta +2 -0
  301. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_10_38_856_airport_shuttles_20130207_1647.csv +8 -0
  302. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_10_38_856_airport_shuttles_20130207_1647.csv.meta +2 -0
  303. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_12_12_144_1361696555_GMail_Android_R.png +0 -0
  304. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_12_12_144_1361696555_GMail_Android_R.png.meta +2 -0
  305. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_16_40_989_404_no_file.png +0 -0
  306. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_16_40_989_404_no_file.png.meta +2 -0
  307. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_19_19_40_6152message_in_a_bottle.jpeg +0 -0
  308. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_19_19_40_6152message_in_a_bottle.jpeg.meta +2 -0
  309. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_21_21_825_6152message_in_a_bottle.jpeg +0 -0
  310. data/test/dummy/public/system/dragonfly/development/2013/04/16/14_21_21_825_6152message_in_a_bottle.jpeg.meta +2 -0
  311. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_46_33_341_bio.jpg +0 -0
  312. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_46_33_341_bio.jpg.meta +2 -0
  313. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_52_55_892_404_no_file.png +0 -0
  314. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_52_55_892_404_no_file.png.meta +2 -0
  315. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_52_56_30_404_no_file.png +0 -0
  316. data/test/dummy/public/system/dragonfly/development/2013/04/16/15_52_56_30_404_no_file.png.meta +2 -0
  317. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_24_04_585_Sky_3920445.jpg +0 -0
  318. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_24_04_585_Sky_3920445.jpg.meta +2 -0
  319. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_25_41_111_Sky_3920445.jpg +0 -0
  320. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_25_41_111_Sky_3920445.jpg.meta +2 -0
  321. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_27_16_937_Sky_3920445.jpg +0 -0
  322. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_27_16_937_Sky_3920445.jpg.meta +2 -0
  323. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_27_57_585_Sky_3920445.jpg +0 -0
  324. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_27_57_585_Sky_3920445.jpg.meta +2 -0
  325. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_28_24_991_Sky_3920445.jpg +0 -0
  326. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_28_24_991_Sky_3920445.jpg.meta +2 -0
  327. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_33_30_610_Sky_3920445.jpg +0 -0
  328. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_33_30_610_Sky_3920445.jpg.meta +2 -0
  329. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_35_18_437_Sky_3920445.jpg +0 -0
  330. data/test/dummy/public/system/dragonfly/development/2013/04/17/15_35_18_437_Sky_3920445.jpg.meta +2 -0
  331. data/test/dummy/public/system/dragonfly/development/2013/04/17/16_45_07_162_Vehicle_Types.jpg +0 -0
  332. data/test/dummy/public/system/dragonfly/development/2013/04/17/16_45_07_162_Vehicle_Types.jpg.meta +2 -0
  333. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_27_35_733_hall.jpg +0 -0
  334. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_27_35_733_hall.jpg.meta +2 -0
  335. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_29_15_808_fluidicon.png +0 -0
  336. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_29_15_808_fluidicon.png.meta +2 -0
  337. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_29_15_989_fluidicon.png +0 -0
  338. data/test/dummy/public/system/dragonfly/development/2013/04/18/22_29_15_989_fluidicon.png.meta +2 -0
  339. data/test/dummy/public/system/dragonfly/development/2013/04/19/09_54_44_881_hall3.jpg +0 -0
  340. data/test/dummy/public/system/dragonfly/development/2013/04/19/09_54_44_881_hall3.jpg.meta +2 -0
  341. data/test/dummy/public/system/dragonfly/development/2013/04/19/09_54_45_450_hall3.jpg +0 -0
  342. data/test/dummy/public/system/dragonfly/development/2013/04/19/09_54_45_450_hall3.jpg.meta +2 -0
  343. data/test/dummy/script/rails +6 -0
  344. data/test/dummy/test/fixtures/admins.yml +7 -0
  345. data/test/dummy/test/functional/admins_controller_test.rb +49 -0
  346. data/test/dummy/test/unit/admin_test.rb +7 -0
  347. data/test/dummy/test/unit/helpers/admins_helper_test.rb +4 -0
  348. data/test/factories.rb +47 -0
  349. data/test/integration/page_editing_test.rb +77 -0
  350. data/test/integration/seeding_test.rb +96 -0
  351. data/test/models/field_test.rb +102 -0
  352. data/test/models/page_test.rb +105 -0
  353. data/test/test_helper.rb +40 -0
  354. data/vendor/assets/javascripts/cardboard/bootstrap-select.js +590 -0
  355. data/vendor/assets/javascripts/cardboard/jquery.livesearch.js +48 -0
  356. data/vendor/assets/javascripts/cardboard/jquery.pjax.js +822 -0
  357. data/vendor/assets/javascripts/cardboard/jquery.wysihtml5_size_matters.js.coffee +44 -0
  358. data/vendor/assets/javascripts/cardboard/jquery.wysihtml5imgresizer.js +320 -0
  359. data/vendor/assets/javascripts/cardboard/wysihtml5-0.4.0pre.js +9579 -0
  360. metadata +1011 -0
@@ -0,0 +1,96 @@
1
+ require "test_helper"
2
+
3
+ describe "Seeding" do
4
+ before do
5
+ DatabaseCleaner.clean
6
+ @file_hash = {
7
+ pages: {
8
+ home:{
9
+ title: "Welcome",
10
+ position: 0,
11
+ parts:{
12
+ intro:{
13
+ position: 1,
14
+ fields:{
15
+ text:{
16
+ type: "string",
17
+ default: "default text",
18
+ label: "ok",
19
+ required: "true",
20
+ hint: "this is a hint",
21
+ placeholder: "Text"
22
+ }
23
+ }
24
+ },
25
+ slideshow:{
26
+ repeatable: true,
27
+ position: 0,
28
+ fields:{
29
+ image:{
30
+ type: "image",
31
+ default: "CrashTest.jpg"
32
+ },
33
+ desc:{
34
+ type: "string"
35
+ }
36
+ }
37
+ }
38
+ }
39
+ },
40
+ about_us:{
41
+ parts:{
42
+ about:{
43
+ fields:{
44
+ description:{
45
+ type: "rich_text"
46
+ }
47
+ }
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }.with_indifferent_access
53
+ end
54
+ describe 'Pages' do
55
+ before do
56
+ Cardboard::Seed.populate_pages(@file_hash)
57
+ @page = Cardboard::Page.root
58
+ @part = @page.parts.first
59
+ @last_part = @page.parts.last
60
+ end
61
+ it 'Should add pages' do
62
+ assert_equal "home", @page.identifier
63
+ assert_equal 2, Cardboard::Page.count
64
+ end
65
+ it 'Should add parts' do
66
+ assert_equal "slideshow", @part.identifier
67
+ assert_equal "intro", @last_part.identifier
68
+ end
69
+ it 'Should add fields' do
70
+ refute_nil @page.get("intro").fields.where(identifier: "text")
71
+ end
72
+ describe 'Modified yml file' do
73
+ before do
74
+ @file_hash[:pages].delete(:about_us)
75
+ @file_hash[:pages][:home][:parts].delete(:slideshow)
76
+ @file_hash[:pages][:home][:parts][:intro][:fields].delete(:text)
77
+ Cardboard::Seed.populate_pages(@file_hash)
78
+ @page = Cardboard::Page.root
79
+ @part = @page.parts.first
80
+ end
81
+ it 'Should remove old pages' do
82
+ assert_nil Cardboard::Page.where(:identifier => "about_us").first
83
+ assert_equal 1, Cardboard::Page.count
84
+ end
85
+ it 'Should remove old parts' do
86
+ assert_nil @page.get("slideshow")
87
+ refute_nil @page.get("intro")
88
+ end
89
+ it 'Should remove old fields' do
90
+ assert_nil @page.get("intro").attr("text")
91
+ end
92
+ end
93
+ end
94
+ describe 'Settings' do
95
+ end
96
+ end
@@ -0,0 +1,102 @@
1
+ require 'test_helper'
2
+
3
+ #TODO: get, seo, parent_url_options
4
+
5
+ describe Cardboard::Field do
6
+ before do
7
+ @part = build :page_part
8
+ end
9
+
10
+ it "should accept valid boolean values" do
11
+ @field = build :boolean_field
12
+ assert_equal true, @field.save
13
+ assert_equal true, @field.update_attributes(:value => "")
14
+ ["t", "1", "true", true].each do |val|
15
+ assert_equal true, @field.update_attributes(:value => val)
16
+ assert_equal true, @field.value
17
+ end
18
+ [nil,"f", "0", "false", false].each do |val|
19
+ assert_equal true, @field.update_attributes(:value => val)
20
+ assert_equal false, @field.value
21
+ end
22
+ assert_equal false, @field.update_attributes(:value => "somehting_bad")
23
+ end
24
+
25
+ it "should accept valid date values" do
26
+ @field = build :date_field
27
+ assert_equal true, @field.save
28
+ assert_equal true, @field.update_attributes(value: "1900-01-01")
29
+ assert_equal Time.new('1900', '01', '01', '12', '00'), @field.value #chronic dates are at noon by default
30
+ end
31
+ it "should not accept invalid date values" do
32
+ @field = build :date_field
33
+ @field.required = true
34
+ assert_equal true, @field.save
35
+ assert_equal false, @field.update_attributes(:value => "")
36
+ assert_equal false, @field.update_attributes(:value => "something")
37
+ end
38
+
39
+ it "should accept valid decimal numbers" do
40
+ @field = build :decimal_field
41
+ assert_equal true, @field.save
42
+ assert_equal true, @field.update_attributes(:value => 1.23)
43
+ assert_equal 1.23, @field.value
44
+ assert_equal true, @field.update_attributes(:value => "1.23")
45
+ assert_equal 1.23, @field.value
46
+ end
47
+ it "should not accept invalid decimal numbers" do
48
+ @field = build :decimal_field
49
+ @field.required = true
50
+ assert_equal true, @field.save
51
+ assert_equal false, @field.update_attributes(:value => "")
52
+ assert_equal false, @field.update_attributes(:value => "something")
53
+ end
54
+
55
+ it "should not accept invalid files" do
56
+ @field = build :file_field
57
+ @field.required = true
58
+ assert_equal true, @field.save
59
+
60
+ assert_equal false, @field.update_attributes(:value => "")
61
+ assert_equal nil, @field.value_uid
62
+ #TODO: test file validations
63
+ end
64
+
65
+ it "should not accept invalid images" do
66
+ @field = build :image_field
67
+ @field.required = true
68
+ assert_equal true, @field.save
69
+
70
+ assert_equal false, @field.update_attributes(:value => "")
71
+ assert_equal nil, @field.value_uid
72
+ #TODO: test image validations
73
+ end
74
+
75
+ it "should accept valid integer numbers" do
76
+ @field = build :integer_field
77
+ assert_equal true, @field.save
78
+ @field.required = true
79
+ assert_equal false, @field.update_attributes(:value => "")
80
+ assert_equal false, @field.update_attributes(:value => 1.23)
81
+ assert_equal true, @field.update_attributes(:value => "123")
82
+ assert_equal 123, @field.value
83
+ end
84
+
85
+ it "should accept valid rich text" do
86
+ @field = build :rich_text_field
87
+ assert_equal true, @field.save
88
+ @field.required = true
89
+ assert_equal true, @field.update_attributes(:value => "something<script>alert('bad')</script>")
90
+ assert_equal "something", @field.value
91
+ end
92
+
93
+ it "should accept valid string" do
94
+ @field = build :string_field
95
+ assert_equal true, @field.save
96
+ @field.required = true
97
+ assert_equal true, @field.update_attributes(:value => "something")
98
+ assert_equal "something", @field.value
99
+ assert_equal false, @field.update_attributes(:value => "")
100
+ end
101
+
102
+ end
@@ -0,0 +1,105 @@
1
+ require 'test_helper'
2
+
3
+ #TODO: get, parent_url_options
4
+
5
+ describe Cardboard::Page do
6
+ before do
7
+ @page = build(:page)
8
+ end
9
+
10
+ it 'Must be valid' do
11
+ @page.valid?.must_equal true
12
+ end
13
+
14
+ describe 'Persisted record' do
15
+ before do
16
+ @page.save
17
+ end
18
+
19
+ it 'Must find Page with url' do
20
+ Cardboard::Page.find_by_url(@page.url).must_equal @page
21
+ end
22
+
23
+ it 'Must be found with old url after changing slug' do
24
+ old_url = @page.url
25
+ @page.update_attribute :slug, 'test'
26
+ Cardboard::Page.find_by_url(old_url).must_equal @page
27
+ Cardboard::Page.find_by_url(old_url).using_slug_backup?.must_equal true
28
+ Cardboard::Page.find_by_url(@page.url).must_equal @page
29
+ Cardboard::Page.find_by_url(@page.url).using_slug_backup?.must_equal false
30
+ end
31
+
32
+ describe 'SEO' do
33
+ before do
34
+ @page.update_attribute :position_position, 1
35
+ @page.update_attribute :meta_seo, {'title' => 'Test Title'}
36
+ @subpages = create_list :page, 2, path: @page.url
37
+ @root_sibling = create :page, position_position: 2
38
+ end
39
+
40
+ it 'inherits SEO information from parent' do
41
+ @subpages.first.seo['title'].must_equal @page.seo['title']
42
+ end
43
+
44
+ it 'inherits SEO information from root' do
45
+ @root_sibling.seo['title'].must_equal Cardboard::Page.root.seo['title']
46
+ end
47
+
48
+ it 'allows to override inherited properties' do
49
+ @subpages.first.update_attribute :meta_seo, {'title' => 'Non root title'}
50
+ @subpages.first.seo['title'].wont_equal @page.seo['title']
51
+ @subpages.first.seo['title'].must_equal 'Non root title'
52
+ end
53
+ end
54
+
55
+ describe 'Children' do
56
+ before do
57
+ @subpages = create_list(:page, 2, path: @page.url)
58
+ end
59
+
60
+ it 'Must included newly created child' do
61
+ @subpage = create :page, parent: @page
62
+ @page.children.must_include @subpage
63
+ end
64
+
65
+ it 'Get the parent of a page' do
66
+ @subpages.first.parent.must_equal @page
67
+ end
68
+
69
+ it 'Get the children of a page' do
70
+ @page.children.must_include @subpages.first
71
+ @page.children.must_include @subpages.second
72
+ end
73
+
74
+ it 'Get the siblings of a page' do
75
+ @subpages.first.siblings.must_include @subpages.second
76
+ @subpages.second.siblings.must_include @subpages.first
77
+ end
78
+
79
+ it 'Preorder of results' do
80
+ DatabaseCleaner.clean
81
+
82
+ page1 = create :page, position_position: 1
83
+ page2 = create :page, position_position: 2
84
+ subpage1 = create :page, parent: page1, position_position: 1
85
+ subpage2 = create :page, parent_id: page1.identifier, position_position: 2
86
+ subpage3 = create :page, parent_url: subpage2.parent_url, position_position: 3
87
+ subpage4 = create :page, parent_url: page2.url
88
+
89
+ Cardboard::Page.arrange.must_equal({
90
+ page1 => {
91
+ subpage1 => {},
92
+ subpage2 => {},
93
+ subpage3 => {}
94
+ },
95
+ page2 => {subpage4 => {}}
96
+ })
97
+
98
+ Cardboard::Page.root.must_equal page1
99
+ Cardboard::Page.root.depth.must_equal 0
100
+ subpage1.depth.must_equal 1
101
+ end
102
+ end
103
+ end
104
+ end
105
+
@@ -0,0 +1,40 @@
1
+ require 'simplecov'
2
+ SimpleCov.start 'rails'
3
+
4
+ ENV["RAILS_ENV"] = "test"
5
+ require File.expand_path('../dummy/config/environment', __FILE__)
6
+ require "rails/test_help"
7
+
8
+ require 'faker'
9
+ require 'database_cleaner'
10
+ require "minitest/autorun"
11
+ require "minitest/rails"
12
+ require "minitest/rails/capybara"
13
+ require 'minitest/unit'
14
+ require 'minitest/mock'
15
+ require Cardboard::Engine.root.join('lib/cardboard/helpers/seed.rb')
16
+
17
+ require File.expand_path('../factories.rb', __FILE__)
18
+
19
+ begin; require 'turn/autorun'; rescue LoadError; end
20
+
21
+ DatabaseCleaner.strategy = :truncation
22
+
23
+ # Uncomment if you want awesome colorful output
24
+ # require "minitest/pride"
25
+
26
+ class ActiveSupport::TestCase
27
+ include FactoryGirl::Syntax::Methods
28
+ end
29
+
30
+ class ActionDispatch::IntegrationTest
31
+ include Rails.application.routes.url_helpers
32
+ include Capybara::DSL
33
+
34
+ include Warden::Test::Helpers
35
+ Warden.test_mode!
36
+
37
+ def cardboard
38
+ Cardboard::Engine.routes.url_helpers
39
+ end
40
+ end
@@ -0,0 +1,590 @@
1
+ !function($) {
2
+
3
+ "use strict";
4
+
5
+ var Selectpicker = function(element, options, e) {
6
+ if (e) {
7
+ e.stopPropagation();
8
+ e.preventDefault();
9
+ }
10
+ this.$element = $(element);
11
+ this.$newElement = null;
12
+ this.button = null;
13
+
14
+ //Merge defaults, options and data-attributes to make our options
15
+ this.options = $.extend({}, $.fn.selectpicker.defaults, this.$element.data(), typeof options == 'object' && options);
16
+
17
+ //If we have no title yet, check the attribute 'title' (this is missed by jq as its not a data-attribute
18
+ if(this.options.title==null)
19
+ this.options.title = this.$element.attr('title');
20
+
21
+ //Expose public methods
22
+ this.val = Selectpicker.prototype.val;
23
+ this.render = Selectpicker.prototype.render;
24
+ this.refresh = Selectpicker.prototype.refresh;
25
+ this.selectAll = Selectpicker.prototype.selectAll;
26
+ this.deselectAll = Selectpicker.prototype.deselectAll;
27
+ this.init();
28
+ };
29
+
30
+ Selectpicker.prototype = {
31
+
32
+ constructor: Selectpicker,
33
+
34
+ init: function (e) {
35
+ if (!this.options.container) {
36
+ this.$element.hide();
37
+ } else {
38
+ this.$element.css('visibility','hidden');
39
+ };
40
+ this.multiple = this.$element.prop('multiple');
41
+ var id = this.$element.attr('id');
42
+ this.$newElement = this.createView()
43
+ this.$element.after(this.$newElement);
44
+
45
+ if (this.options.container) {
46
+ this.selectPosition();
47
+ }
48
+ this.button = this.$newElement.find('> button');
49
+ if (id !== undefined) {
50
+ var _this = this;
51
+ this.button.attr('data-id', id);
52
+ $('label[for="' + id + '"]').click(function(){
53
+ _this.button.focus();
54
+ })
55
+ }
56
+ if (this.$element.attr('class')) {
57
+ this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker/gi, ''));
58
+ }
59
+
60
+ //If we are multiple, then add the show-tick class by default
61
+ if(this.multiple) {
62
+ this.$newElement.addClass('show-tick');
63
+ }
64
+ this.button.addClass(this.options.style);
65
+ this.checkDisabled();
66
+ this.checkTabIndex();
67
+ this.clickListener();
68
+
69
+ this.render();
70
+ this.setSize();
71
+ },
72
+
73
+ createDropdown: function() {
74
+ var drop =
75
+ "<div class='btn-group bootstrap-select'>" +
76
+ "<button type='button' class='btn dropdown-toggle' data-toggle='dropdown'>" +
77
+ "<div class='filter-option pull-left'></div>&nbsp;" +
78
+ "<div class='caret'></div>" +
79
+ "</button>" +
80
+ "<ul class='dropdown-menu' role='menu'>" +
81
+ "</ul>" +
82
+ "</div>";
83
+
84
+ return $(drop);
85
+ },
86
+
87
+
88
+ createView: function() {
89
+ var $drop = this.createDropdown();
90
+ var $li = this.createLi();
91
+ $drop.find('ul').append($li);
92
+ return $drop;
93
+ },
94
+
95
+ reloadLi: function() {
96
+ //Remove all children.
97
+ this.destroyLi();
98
+ //Re build
99
+ var $li = this.createLi();
100
+ this.$newElement.find('ul').append( $li );
101
+ },
102
+
103
+ destroyLi:function() {
104
+ this.$newElement.find('li').remove();
105
+ },
106
+
107
+ createLi: function() {
108
+
109
+ var _this = this;
110
+ var _liA = [];
111
+ var _liHtml = '';
112
+
113
+
114
+ this.$element.find('option').each(function(index) {
115
+ var $this = $(this);
116
+
117
+ //Get the class and text for the option
118
+ var optionClass = $this.attr("class") || '';
119
+ var text = $this.text();
120
+ var subtext = $this.data('subtext') !== undefined ? '<small class="muted">' + $this.data('subtext') + '</small>' : '';
121
+ var icon = $this.data('icon') !== undefined ? '<i class="'+$this.data('icon')+'"></i> ' : '';
122
+ if (icon !== '' && ($this.is(':disabled') || $this.parent().is(':disabled'))) {
123
+ icon = '<span>'+icon+'</span>';
124
+ }
125
+
126
+ //Prepend any icon and append any subtext to the main text.
127
+ text = icon + '<span class="text">' + text + subtext + '</span>';
128
+
129
+ if (_this.options.hideDisabled && ($this.is(':disabled') || $this.parent().is(':disabled'))) {
130
+ _liA.push('<a style="min-height: 0; padding: 0"></a>');
131
+ } else if ($this.parent().is('optgroup') && $this.data('divider') != true) {
132
+ if ($this.index() == 0) {
133
+ //Get the opt group label
134
+ var label = $this.parent().attr('label');
135
+ var labelSubtext = $this.parent().data('subtext') !== undefined ? '<small class="muted">'+$this.parent().data('subtext')+'</small>' : '';
136
+ var labelIcon = $this.parent().data('icon') ? '<i class="'+$this.parent().data('icon')+'"></i> ' : '';
137
+ label = labelIcon + '<span class="text">' + label + labelSubtext + '</span>';
138
+
139
+ if ($this[0].index != 0) {
140
+ _liA.push(
141
+ '<div class="div-contain"><div class="divider"></div></div>'+
142
+ '<dt>'+label+'</dt>'+
143
+ _this.createA(text, "opt " + optionClass )
144
+ );
145
+ } else {
146
+ _liA.push(
147
+ '<dt>'+label+'</dt>'+
148
+ _this.createA(text, "opt " + optionClass ));
149
+ }
150
+ } else {
151
+ _liA.push( _this.createA(text, "opt " + optionClass ) );
152
+ }
153
+ } else if ($this.data('divider') == true) {
154
+ _liA.push('<div class="div-contain"><div class="divider"></div></div>');
155
+ } else if ($(this).data('hidden') == true) {
156
+ _liA.push('');
157
+ } else {
158
+ _liA.push( _this.createA(text, optionClass ) );
159
+ }
160
+ });
161
+
162
+ $.each(_liA, function(i, item){
163
+ _liHtml += "<li rel=" + i + ">" + item + "</li>";
164
+ });
165
+
166
+ //If we are not multiple, and we dont have a selected item, and we dont have a title, select the first element so something is set in the button
167
+ if(!this.multiple && this.$element.find('option:selected').length==0 && !_this.options.title) {
168
+ this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');
169
+ }
170
+
171
+ return $(_liHtml);
172
+ },
173
+
174
+ createA:function(text, classes) {
175
+ return '<a tabindex="0" class="'+classes+'">' +
176
+ text +
177
+ '<i class="icon-ok check-mark"></i>' +
178
+ '</a>';
179
+ },
180
+
181
+ render:function() {
182
+ var _this = this;
183
+
184
+ //Update the LI to match the SELECT
185
+ this.$element.find('option').each(function(index) {
186
+ _this.setDisabled(index, $(this).is(':disabled') || $(this).parent().is(':disabled') );
187
+ _this.setSelected(index, $(this).is(':selected') );
188
+ });
189
+
190
+ var selectedItems = this.$element.find('option:selected').map(function(index,value) {
191
+ var subtext;
192
+ if (_this.options.showSubtext && $(this).attr('data-subtext') && !_this.multiple) {
193
+ subtext = ' <small class="muted">'+$(this).data('subtext') +'</small>';
194
+ } else {
195
+ subtext = '';
196
+ }
197
+ if($(this).attr('title')!=undefined) {
198
+ return $(this).attr('title');
199
+ } else {
200
+ return $(this).text() + subtext;
201
+ }
202
+ }).toArray();
203
+
204
+ //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled
205
+ //Convert all the values into a comma delimited string
206
+ var title = !this.multiple ? selectedItems[0] : selectedItems.join(", "),
207
+ separator = _this.options.separatorText || _this.options.defaultSeparatorText,
208
+ selected = _this.options.selectedText || _this.options.defaultSelectedText;
209
+
210
+ //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..
211
+ if(_this.multiple && _this.options.selectedTextFormat.indexOf('count') > -1) {
212
+ var max = _this.options.selectedTextFormat.split(">");
213
+ var notDisabled = this.options.hideDisabled ? ':not([disabled])' : '';
214
+ if( (max.length>1 && selectedItems.length > max[1]) || (max.length==1 && selectedItems.length>=2)) {
215
+ title = _this.options.countSelectedText.replace('{0}', selectedItems.length).replace('{1}', this.$element.find('option:not([data-divider="true"]):not([data-hidden="true"])'+notDisabled).length);
216
+ }
217
+ }
218
+
219
+ //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text
220
+ if(!title) {
221
+ title = _this.options.title != undefined ? _this.options.title : _this.options.noneSelectedText;
222
+ }
223
+
224
+ var subtext;
225
+ if (this.options.showSubtext && this.$element.find('option:selected').attr('data-subtext')) {
226
+ subtext = ' <small class="muted">'+this.$element.find('option:selected').data('subtext') +'</small>';
227
+ } else {
228
+ subtext = '';
229
+ }
230
+
231
+ var icon = this.$element.find('option:selected').data('icon') || '';
232
+ if(icon.length) {
233
+ icon = '<i class="' + icon + '"></i> ';
234
+ }
235
+
236
+ _this.$newElement.find('.filter-option').html(icon + title + subtext);
237
+ },
238
+
239
+ setSize:function() {
240
+ if(this.options.container) {
241
+ // Show $newElement before perfoming size calculations
242
+ this.$newElement.toggle(this.$element.parent().is(':visible'));
243
+ }
244
+ var _this = this;
245
+ var menu = this.$newElement.find('.dropdown-menu');
246
+ var menuA = menu.find('li > a');
247
+ var liHeight = this.$newElement.addClass('open').find('.dropdown-menu li > a').outerHeight();
248
+ this.$newElement.removeClass('open');
249
+ var divHeight = menu.find('li .divider').outerHeight(true);
250
+ var selectOffset_top = this.$newElement.offset().top;
251
+ var selectHeight = this.$newElement.outerHeight();
252
+ var menuPadding = parseInt(menu.css('padding-top')) + parseInt(menu.css('padding-bottom')) + parseInt(menu.css('border-top-width')) + parseInt(menu.css('border-bottom-width'));
253
+ var notDisabled = this.options.hideDisabled ? ':not(.disabled)' : '';
254
+ var menuHeight;
255
+ if (this.options.size == 'auto') {
256
+ var getSize = function() {
257
+ var selectOffset_top_scroll = selectOffset_top - $(window).scrollTop();
258
+ var windowHeight = window.innerHeight;
259
+ var menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2;
260
+ var selectOffset_bot = windowHeight - selectOffset_top_scroll - selectHeight - menuExtras;
261
+ var minHeight;
262
+ menuHeight = selectOffset_bot;
263
+ if (_this.$newElement.hasClass('dropup')) {
264
+ menuHeight = selectOffset_top_scroll - menuExtras;
265
+ }
266
+ if ((menu.find('li').length + menu.find('dt').length) > 3) {
267
+ minHeight = liHeight*3 + menuExtras - 2;
268
+ } else {
269
+ minHeight = 0;
270
+ }
271
+ menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'auto', 'min-height' : minHeight + 'px'});
272
+ }
273
+ getSize();
274
+ $(window).resize(getSize);
275
+ $(window).scroll(getSize);
276
+ } else if (this.options.size && this.options.size != 'auto' && menu.find('li'+notDisabled).length > this.options.size) {
277
+ var optIndex = menu.find("li"+notDisabled+" > *").filter(':not(.div-contain)').slice(0,this.options.size).last().parent().index();
278
+ var divLength = menu.find("li").slice(0,optIndex + 1).find('.div-contain').length;
279
+ menuHeight = liHeight*this.options.size + divLength*divHeight + menuPadding;
280
+ menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'auto'});
281
+ }
282
+
283
+ //Set width of select
284
+ if (this.options.width == 'auto') {
285
+ this.$newElement.find('.dropdown-menu').css('min-width','0');
286
+ var ulWidth = this.$newElement.find('.dropdown-menu').css('width');
287
+ this.$newElement.css('width',ulWidth);
288
+ if (this.options.container) {
289
+ this.$element.css('width',ulWidth);
290
+ }
291
+ } else if (this.options.width) {
292
+ if (this.options.container) {
293
+ // Note: options.width can be %
294
+ this.$element.css('width', this.options.width);
295
+ // Set pixel width of $newElement based on $element's pixel width
296
+ this.$newElement.width(this.$element.outerWidth());
297
+ } else {
298
+ this.$newElement.css('width',this.options.width);
299
+ }
300
+ } else if(this.options.container) {
301
+ // Set width of $newElement based on $element
302
+ this.$newElement.width(this.$element.outerWidth());
303
+ }
304
+ },
305
+
306
+ selectPosition:function() {
307
+ var containerOffset = $(this.options.container).offset();
308
+ var eltOffset = this.$element.offset();
309
+ if(containerOffset && eltOffset) {
310
+ var selectElementTop = eltOffset.top - containerOffset.top;
311
+ var selectElementLeft = eltOffset.left - containerOffset.left;
312
+ this.$newElement.appendTo(this.options.container);
313
+ this.$newElement.css({'position':'absolute', 'top':selectElementTop+'px', 'left':selectElementLeft+'px'});
314
+ }
315
+ },
316
+
317
+ refresh:function() {
318
+ this.reloadLi();
319
+ this.render();
320
+ this.setSize();
321
+ this.checkDisabled();
322
+ if (this.options.container) {
323
+ this.selectPosition();
324
+ }
325
+ },
326
+
327
+ setSelected:function(index, selected) {
328
+ if(selected) {
329
+ this.$newElement.find('li').eq(index).addClass('selected');
330
+ } else {
331
+ this.$newElement.find('li').eq(index).removeClass('selected');
332
+ }
333
+ },
334
+
335
+ setDisabled:function(index, disabled) {
336
+ if(disabled) {
337
+ this.$newElement.find('li').eq(index).addClass('disabled').find('a').attr('href','#').attr('tabindex',-1);
338
+ } else {
339
+ this.$newElement.find('li').eq(index).removeClass('disabled').find('a').removeAttr('href').attr('tabindex',0);
340
+ }
341
+ },
342
+
343
+ isDisabled: function() {
344
+ return this.$element.is(':disabled') || this.$element.attr('readonly');
345
+ },
346
+
347
+ checkDisabled: function() {
348
+ if (this.isDisabled()) {
349
+ this.button.addClass('disabled');
350
+ this.button.click(function(e) {
351
+ e.preventDefault();
352
+ });
353
+ this.button.attr('tabindex','-1');
354
+ } else if (!this.isDisabled() && this.button.hasClass('disabled')) {
355
+ this.button.removeClass('disabled');
356
+ this.button.click(function() {
357
+ return true;
358
+ });
359
+ this.button.removeAttr('tabindex');
360
+ }
361
+ },
362
+
363
+ checkTabIndex: function() {
364
+ if (this.$element.is('[tabindex]')) {
365
+ var tabindex = this.$element.attr("tabindex");
366
+ this.button.attr('tabindex', tabindex);
367
+ }
368
+ },
369
+
370
+ clickListener: function() {
371
+ var _this = this;
372
+
373
+ $('body').on('touchstart.dropdown', '.dropdown-menu', function (e) { e.stopPropagation(); });
374
+
375
+ this.$newElement.on('click', 'li a', function(e){
376
+ var clickedIndex = $(this).parent().index(),
377
+ $this = $(this).parent(),
378
+ $select = $this.parents('.bootstrap-select'),
379
+ prevValue = _this.$element.val();
380
+
381
+ //Dont close on multi choice menu
382
+ if(_this.multiple) {
383
+ e.stopPropagation();
384
+ }
385
+
386
+ e.preventDefault();
387
+
388
+ //Dont run if we have been disabled
389
+ if (_this.$element.not(':disabled') && !$(this).parent().hasClass('disabled')){
390
+ //Deselect all others if not multi select box
391
+ if (!_this.multiple) {
392
+ _this.$element.find('option').prop('selected', false);
393
+ _this.$element.find('option').eq(clickedIndex).prop('selected', true);
394
+ }
395
+ //Else toggle the one we have chosen if we are multi select.
396
+ else {
397
+ var selected = _this.$element.find('option').eq(clickedIndex).prop('selected');
398
+
399
+ if(selected) {
400
+ _this.$element.find('option').eq(clickedIndex).prop('selected', false);
401
+ } else {
402
+ _this.$element.find('option').eq(clickedIndex).prop('selected', true);
403
+ }
404
+ }
405
+
406
+ $select.find('button').focus();
407
+
408
+ // Trigger select 'change'
409
+ if (prevValue != _this.$element.val()) {
410
+ _this.$element.trigger('change');
411
+ }
412
+
413
+ _this.render();
414
+ }
415
+
416
+ });
417
+
418
+ this.$newElement.on('click', 'li.disabled a, li dt, li .div-contain', function(e) {
419
+ e.preventDefault();
420
+ e.stopPropagation();
421
+ var $select = $(this).parent().parents('.bootstrap-select');
422
+ $select.find('button').focus();
423
+ });
424
+
425
+ this.$element.on('change', function(e) {
426
+ _this.render();
427
+ });
428
+ },
429
+
430
+ val:function(value) {
431
+
432
+ if(value!=undefined) {
433
+ this.$element.val( value );
434
+
435
+ this.$element.trigger('change');
436
+ return this.$element;
437
+ } else {
438
+ return this.$element.val();
439
+ }
440
+ },
441
+
442
+ selectAll:function() {
443
+ this.$element.find('option').prop('selected', true).attr('selected', 'selected');
444
+ this.render();
445
+ },
446
+
447
+ deselectAll:function() {
448
+ this.$element.find('option').prop('selected', false).removeAttr('selected');
449
+ this.render();
450
+ },
451
+
452
+ keydown: function (e) {
453
+ var $this,
454
+ $items,
455
+ $parent,
456
+ index,
457
+ next,
458
+ first,
459
+ last,
460
+ prev,
461
+ nextPrev
462
+
463
+ $this = $(this);
464
+
465
+ $parent = $this.parent();
466
+
467
+ $items = $('[role=menu] li:not(.divider):visible a', $parent);
468
+
469
+ if (!$items.length) return;
470
+
471
+ if (/(38|40)/.test(e.keyCode)) {
472
+
473
+ index = $items.index($items.filter(':focus'));
474
+
475
+ first = $items.parent(':not(.disabled)').first().index();
476
+ last = $items.parent(':not(.disabled)').last().index();
477
+ next = $items.eq(index).parent().nextAll(':not(.disabled)').eq(0).index();
478
+ prev = $items.eq(index).parent().prevAll(':not(.disabled)').eq(0).index();
479
+ nextPrev = $items.eq(next).parent().prevAll(':not(.disabled)').eq(0).index();
480
+
481
+ if (e.keyCode == 38) {
482
+ if (index != nextPrev && index > prev) index = prev;
483
+ if (index < first) index = first;
484
+ }
485
+
486
+ if (e.keyCode == 40) {
487
+ if (index != nextPrev && index < next) index = next;
488
+ if (index > last) index = last;
489
+ }
490
+
491
+ $items.eq(index).focus()
492
+ } else {
493
+ var keyCodeMap = {
494
+ 48:"0", 49:"1", 50:"2", 51:"3", 52:"4", 53:"5", 54:"6", 55:"7", 56:"8", 57:"9", 59:";",
495
+ 65:"a", 66:"b", 67:"c", 68:"d", 69:"e", 70:"f", 71:"g", 72:"h", 73:"i", 74:"j", 75:"k", 76:"l",
496
+ 77:"m", 78:"n", 79:"o", 80:"p", 81:"q", 82:"r", 83:"s", 84:"t", 85:"u", 86:"v", 87:"w", 88:"x", 89:"y", 90:"z",
497
+ 96:"0", 97:"1", 98:"2", 99:"3", 100:"4", 101:"5", 102:"6", 103:"7", 104:"8", 105:"9"
498
+ }
499
+
500
+ var keyIndex = [];
501
+
502
+ $items.each(function() {
503
+ if ($(this).parent().is(':not(.disabled)')) {
504
+ if ($.trim($(this).text().toLowerCase()).substring(0,1) == keyCodeMap[e.keyCode]) {
505
+ keyIndex.push($(this).parent().index());
506
+ }
507
+ }
508
+ });
509
+
510
+ var count = $(document).data('keycount');
511
+ count++;
512
+ $(document).data('keycount',count);
513
+
514
+ var prevKey = $.trim($(':focus').text().toLowerCase()).substring(0,1);
515
+
516
+ if (prevKey != keyCodeMap[e.keyCode]) {
517
+ count = 1;
518
+ $(document).data('keycount',count);
519
+ } else if (count >= keyIndex.length) {
520
+ $(document).data('keycount',0);
521
+ }
522
+
523
+ $items.eq(keyIndex[count - 1]).focus();
524
+ }
525
+
526
+ if (/(13)/.test(e.keyCode)) {
527
+ $(':focus').click();
528
+ $parent.addClass('open');
529
+ $(document).data('keycount',0);
530
+ }
531
+ }
532
+ };
533
+
534
+ $.fn.selectpicker = function(option, event) {
535
+ //get the args of the outer function..
536
+ var args = arguments;
537
+ var value;
538
+ var chain = this.each(function () {
539
+ if ($(this).is('select')) {
540
+ var $this = $(this),
541
+ data = $this.data('selectpicker'),
542
+ options = typeof option == 'object' && option;
543
+
544
+ if (!data) {
545
+ $this.data('selectpicker', (data = new Selectpicker(this, options, event)));
546
+ } else if(options){
547
+ for(var i in options) {
548
+ data.options[i]=options[i];
549
+ }
550
+ }
551
+
552
+ if (typeof option == 'string') {
553
+ //Copy the value of option, as once we shift the arguments
554
+ //it also shifts the value of option.
555
+ var property = option;
556
+ if(data[property] instanceof Function) {
557
+ [].shift.apply(args);
558
+ value = data[property].apply(data, args);
559
+ } else {
560
+ value = data.options[property];
561
+ }
562
+ }
563
+ }
564
+ });
565
+
566
+ if(value!=undefined) {
567
+ return value;
568
+ } else {
569
+ return chain;
570
+ }
571
+ };
572
+
573
+ $.fn.selectpicker.defaults = {
574
+ style: null,
575
+ size: 'auto',
576
+ title: null,
577
+ selectedTextFormat : 'values',
578
+ noneSelectedText : 'Nothing selected',
579
+ countSelectedText: '{0} of {1} selected',
580
+ width: null,
581
+ container: false,
582
+ hideDisabled: false,
583
+ showSubtext: false
584
+ }
585
+
586
+ $(document)
587
+ .data('keycount', 0)
588
+ .on('keydown', '[data-toggle=dropdown], [role=menu]' , Selectpicker.prototype.keydown)
589
+
590
+ }(window.jQuery);