cardboard_cms 0.1.4

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 (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,48 @@
1
+ // https://github.com/nakajima/jquery-livesearch
2
+ (function($) {
3
+ $.extend($.expr[':'], {
4
+ 'containsi': function(elem, i, match, array) {
5
+ return $(elem).text().toLowerCase()
6
+ .indexOf((match[3] || "").toLowerCase()) >= 0;
7
+ }
8
+ });
9
+
10
+ var Search = function(block) {
11
+ this.callbacks = {};
12
+ block(this);
13
+ }
14
+
15
+ Search.prototype.all = function(fn) { this.callbacks.all = fn; }
16
+ Search.prototype.reset = function(fn) { this.callbacks.reset = fn; }
17
+ Search.prototype.empty = function(fn) { this.callbacks.empty = fn; }
18
+ Search.prototype.results = function(fn) { this.callbacks.results = fn; }
19
+
20
+ function query(selector) {
21
+ if (val = this.val()) {
22
+ return $(selector + ':containsi("' + val + '")');
23
+ } else {
24
+ return false;
25
+ }
26
+ }
27
+
28
+ $.fn.search = function search(selector, block) {
29
+ var search = new Search(block);
30
+ var callbacks = search.callbacks;
31
+
32
+ function perform() {
33
+ if (result = query.call($(this), selector)) {
34
+ callbacks.all && callbacks.all.call(this, result);
35
+ var method = result.size() > 0 ? 'results' : 'empty';
36
+ return callbacks[method] && callbacks[method].call(this, result);
37
+ } else {
38
+ callbacks.all && callbacks.all.call(this, $(selector));
39
+ return callbacks.reset && callbacks.reset.call(this);
40
+ };
41
+ }
42
+
43
+ $(this).on('keypress', perform);
44
+ $(this).on('keydown', perform);
45
+ $(this).on('keyup', perform);
46
+ $(this).on('blur', perform);
47
+ }
48
+ })(jQuery);
@@ -0,0 +1,822 @@
1
+ // jquery.pjax.js
2
+ // copyright chris wanstrath
3
+ // https://github.com/defunkt/jquery-pjax
4
+
5
+ (function($){
6
+
7
+ // When called on a container with a selector, fetches the href with
8
+ // ajax into the container or with the data-pjax attribute on the link
9
+ // itself.
10
+ //
11
+ // Tries to make sure the back button and ctrl+click work the way
12
+ // you'd expect.
13
+ //
14
+ // Exported as $.fn.pjax
15
+ //
16
+ // Accepts a jQuery ajax options object that may include these
17
+ // pjax specific options:
18
+ //
19
+ //
20
+ // container - Where to stick the response body. Usually a String selector.
21
+ // $(container).html(xhr.responseBody)
22
+ // (default: current jquery context)
23
+ // push - Whether to pushState the URL. Defaults to true (of course).
24
+ // replace - Want to use replaceState instead? That's cool.
25
+ //
26
+ // For convenience the second parameter can be either the container or
27
+ // the options object.
28
+ //
29
+ // Returns the jQuery object
30
+ function fnPjax(selector, container, options) {
31
+ var context = this
32
+ return this.on('click.pjax', selector, function(event) {
33
+ var opts = $.extend({}, optionsFor(container, options))
34
+ if (!opts.container)
35
+ opts.container = $(this).attr('data-pjax') || context
36
+ handleClick(event, opts)
37
+ })
38
+ }
39
+
40
+ // Public: pjax on click handler
41
+ //
42
+ // Exported as $.pjax.click.
43
+ //
44
+ // event - "click" jQuery.Event
45
+ // options - pjax options
46
+ //
47
+ // Examples
48
+ //
49
+ // $(document).on('click', 'a', $.pjax.click)
50
+ // // is the same as
51
+ // $(document).pjax('a')
52
+ //
53
+ // $(document).on('click', 'a', function(event) {
54
+ // var container = $(this).closest('[data-pjax-container]')
55
+ // $.pjax.click(event, container)
56
+ // })
57
+ //
58
+ // Returns nothing.
59
+ function handleClick(event, container, options) {
60
+ options = optionsFor(container, options)
61
+
62
+ var link = event.currentTarget
63
+
64
+ if (link.tagName.toUpperCase() !== 'A')
65
+ throw "$.fn.pjax or $.pjax.click requires an anchor element"
66
+
67
+ // Middle click, cmd click, and ctrl click should open
68
+ // links in a new tab as normal.
69
+ if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
70
+ return
71
+
72
+ // Ignore cross origin links
73
+ if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
74
+ return
75
+
76
+ // Ignore anchors on the same page
77
+ if (link.hash && link.href.replace(link.hash, '') ===
78
+ location.href.replace(location.hash, ''))
79
+ return
80
+
81
+ // Ignore empty anchor "foo.html#"
82
+ if (link.href === location.href + '#')
83
+ return
84
+
85
+ var defaults = {
86
+ url: link.href,
87
+ container: $(link).attr('data-pjax'),
88
+ target: link,
89
+ fragment: null
90
+ }
91
+
92
+ var opts = $.extend({}, defaults, options)
93
+ var clickEvent = $.Event('pjax:click')
94
+ $(link).trigger(clickEvent, [opts])
95
+
96
+ if (!clickEvent.isDefaultPrevented()) {
97
+ pjax(opts)
98
+ event.preventDefault()
99
+ }
100
+ }
101
+
102
+ // Public: pjax on form submit handler
103
+ //
104
+ // Exported as $.pjax.submit
105
+ //
106
+ // event - "click" jQuery.Event
107
+ // options - pjax options
108
+ //
109
+ // Examples
110
+ //
111
+ // $(document).on('submit', 'form', function(event) {
112
+ // var container = $(this).closest('[data-pjax-container]')
113
+ // $.pjax.submit(event, container)
114
+ // })
115
+ //
116
+ // Returns nothing.
117
+ function handleSubmit(event, container, options) {
118
+ options = optionsFor(container, options)
119
+
120
+ var form = event.currentTarget
121
+
122
+ if (form.tagName.toUpperCase() !== 'FORM')
123
+ throw "$.pjax.submit requires a form element"
124
+
125
+ var defaults = {
126
+ type: form.method.toUpperCase(),
127
+ url: form.action,
128
+ data: $(form).serializeArray(),
129
+ container: $(form).attr('data-pjax'),
130
+ target: form,
131
+ fragment: null
132
+ }
133
+
134
+ pjax($.extend({}, defaults, options))
135
+
136
+ event.preventDefault()
137
+ }
138
+
139
+ // Loads a URL with ajax, puts the response body inside a container,
140
+ // then pushState()'s the loaded URL.
141
+ //
142
+ // Works just like $.ajax in that it accepts a jQuery ajax
143
+ // settings object (with keys like url, type, data, etc).
144
+ //
145
+ // Accepts these extra keys:
146
+ //
147
+ // container - Where to stick the response body.
148
+ // $(container).html(xhr.responseBody)
149
+ // push - Whether to pushState the URL. Defaults to true (of course).
150
+ // replace - Want to use replaceState instead? That's cool.
151
+ //
152
+ // Use it just like $.ajax:
153
+ //
154
+ // var xhr = $.pjax({ url: this.href, container: '#main' })
155
+ // console.log( xhr.readyState )
156
+ //
157
+ // Returns whatever $.ajax returns.
158
+ function pjax(options) {
159
+ options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)
160
+
161
+ if ($.isFunction(options.url)) {
162
+ options.url = options.url()
163
+ }
164
+
165
+ var target = options.target
166
+
167
+ var hash = parseURL(options.url).hash
168
+
169
+ var context = options.context = findContainerFor(options.container)
170
+
171
+ // We want the browser to maintain two separate internal caches: one
172
+ // for pjax'd partial page loads and one for normal page loads.
173
+ // Without adding this secret parameter, some browsers will often
174
+ // confuse the two.
175
+ if (!options.data) options.data = {}
176
+ options.data._pjax = context.selector
177
+
178
+ function fire(type, args) {
179
+ var event = $.Event(type, { relatedTarget: target })
180
+ context.trigger(event, args)
181
+ return !event.isDefaultPrevented()
182
+ }
183
+
184
+ var timeoutTimer
185
+
186
+ options.beforeSend = function(xhr, settings) {
187
+ // No timeout for non-GET requests
188
+ // Its not safe to request the resource again with a fallback method.
189
+ if (settings.type !== 'GET') {
190
+ settings.timeout = 0
191
+ }
192
+
193
+ xhr.setRequestHeader('X-PJAX', 'true')
194
+ xhr.setRequestHeader('X-PJAX-Container', context.selector)
195
+
196
+ if (!fire('pjax:beforeSend', [xhr, settings]))
197
+ return false
198
+
199
+ if (settings.timeout > 0) {
200
+ timeoutTimer = setTimeout(function() {
201
+ if (fire('pjax:timeout', [xhr, options]))
202
+ xhr.abort('timeout')
203
+ }, settings.timeout)
204
+
205
+ // Clear timeout setting so jquerys internal timeout isn't invoked
206
+ settings.timeout = 0
207
+ }
208
+
209
+ options.requestUrl = parseURL(settings.url).href
210
+ }
211
+
212
+ options.complete = function(xhr, textStatus) {
213
+ if (timeoutTimer)
214
+ clearTimeout(timeoutTimer)
215
+
216
+ fire('pjax:complete', [xhr, textStatus, options])
217
+
218
+ fire('pjax:end', [xhr, options])
219
+ }
220
+
221
+ options.error = function(xhr, textStatus, errorThrown) {
222
+ var container = extractContainer("", xhr, options)
223
+
224
+ var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
225
+ if (options.type == 'GET' && textStatus !== 'abort' && allowed) {
226
+ locationReplace(container.url)
227
+ }
228
+ }
229
+
230
+ options.success = function(data, status, xhr) {
231
+ // If $.pjax.defaults.version is a function, invoke it first.
232
+ // Otherwise it can be a static string.
233
+ var currentVersion = (typeof $.pjax.defaults.version === 'function') ?
234
+ $.pjax.defaults.version() :
235
+ $.pjax.defaults.version
236
+
237
+ var latestVersion = xhr.getResponseHeader('X-PJAX-Version')
238
+
239
+ var container = extractContainer(data, xhr, options)
240
+
241
+ // If there is a layout version mismatch, hard load the new url
242
+ if (currentVersion && latestVersion && currentVersion !== latestVersion) {
243
+ locationReplace(container.url)
244
+ return
245
+ }
246
+
247
+ // If the new response is missing a body, hard load the page
248
+ if (!container.contents) {
249
+ locationReplace(container.url)
250
+ return
251
+ }
252
+
253
+ pjax.state = {
254
+ id: options.id || uniqueId(),
255
+ url: container.url,
256
+ title: container.title,
257
+ container: context.selector,
258
+ fragment: options.fragment,
259
+ timeout: options.timeout
260
+ }
261
+
262
+ if (options.push || options.replace) {
263
+ window.history.replaceState(pjax.state, container.title, container.url)
264
+ }
265
+
266
+ if (container.title) document.title = container.title
267
+ context.html(container.contents)
268
+ executeScriptTags(container.scripts)
269
+
270
+ // Scroll to top by default
271
+ if (typeof options.scrollTo === 'number')
272
+ $(window).scrollTop(options.scrollTo)
273
+
274
+ // If the URL has a hash in it, make sure the browser
275
+ // knows to navigate to the hash.
276
+ if ( hash !== '' ) {
277
+ // Avoid using simple hash set here. Will add another history
278
+ // entry. Replace the url with replaceState and scroll to target
279
+ // by hand.
280
+ //
281
+ // window.location.hash = hash
282
+ var url = parseURL(container.url)
283
+ url.hash = hash
284
+
285
+ pjax.state.url = url.href
286
+ window.history.replaceState(pjax.state, container.title, url.href)
287
+
288
+ var target = $(url.hash)
289
+ if (target.length) $(window).scrollTop(target.offset().top)
290
+ }
291
+
292
+ fire('pjax:success', [data, status, xhr, options])
293
+ }
294
+
295
+
296
+ // Initialize pjax.state for the initial page load. Assume we're
297
+ // using the container and options of the link we're loading for the
298
+ // back button to the initial page. This ensures good back button
299
+ // behavior.
300
+ if (!pjax.state) {
301
+ pjax.state = {
302
+ id: uniqueId(),
303
+ url: window.location.href,
304
+ title: document.title,
305
+ container: context.selector,
306
+ fragment: options.fragment,
307
+ timeout: options.timeout
308
+ }
309
+ window.history.replaceState(pjax.state, document.title)
310
+ }
311
+
312
+ // Cancel the current request if we're already pjaxing
313
+ var xhr = pjax.xhr
314
+ if ( xhr && xhr.readyState < 4) {
315
+ xhr.onreadystatechange = $.noop
316
+ xhr.abort()
317
+ }
318
+
319
+ pjax.options = options
320
+ var xhr = pjax.xhr = $.ajax(options)
321
+
322
+ if (xhr.readyState > 0) {
323
+ if (options.push && !options.replace) {
324
+ // Cache current container element before replacing it
325
+ cachePush(pjax.state.id, context.clone().contents())
326
+
327
+ window.history.pushState(null, "", stripPjaxParam(options.requestUrl))
328
+ }
329
+
330
+ fire('pjax:start', [xhr, options])
331
+ fire('pjax:send', [xhr, options])
332
+ }
333
+
334
+ return pjax.xhr
335
+ }
336
+
337
+ // Public: Reload current page with pjax.
338
+ //
339
+ // Returns whatever $.pjax returns.
340
+ function pjaxReload(container, options) {
341
+ var defaults = {
342
+ url: window.location.href,
343
+ push: false,
344
+ replace: true,
345
+ scrollTo: false
346
+ }
347
+
348
+ return pjax($.extend(defaults, optionsFor(container, options)))
349
+ }
350
+
351
+ // Internal: Hard replace current state with url.
352
+ //
353
+ // Work for around WebKit
354
+ // https://bugs.webkit.org/show_bug.cgi?id=93506
355
+ //
356
+ // Returns nothing.
357
+ function locationReplace(url) {
358
+ window.history.replaceState(null, "", "#")
359
+ window.location.replace(url)
360
+ }
361
+
362
+
363
+ var initialPop = true
364
+ var initialURL = window.location.href
365
+ var initialState = window.history.state
366
+
367
+ // Initialize $.pjax.state if possible
368
+ // Happens when reloading a page and coming forward from a different
369
+ // session history.
370
+ if (initialState && initialState.container) {
371
+ pjax.state = initialState
372
+ }
373
+
374
+ // Non-webkit browsers don't fire an initial popstate event
375
+ if ('state' in window.history) {
376
+ initialPop = false
377
+ }
378
+
379
+ // popstate handler takes care of the back and forward buttons
380
+ //
381
+ // You probably shouldn't use pjax on pages with other pushState
382
+ // stuff yet.
383
+ function onPjaxPopstate(event) {
384
+ var state = event.state
385
+
386
+ if (state && state.container) {
387
+ // When coming forward from a seperate history session, will get an
388
+ // initial pop with a state we are already at. Skip reloading the current
389
+ // page.
390
+ if (initialPop && initialURL == state.url) return
391
+
392
+ var container = $(state.container)
393
+ if (container.length) {
394
+ var direction, contents = cacheMapping[state.id]
395
+
396
+ if (pjax.state) {
397
+ // Since state ids always increase, we can deduce the history
398
+ // direction from the previous state.
399
+ direction = pjax.state.id < state.id ? 'forward' : 'back'
400
+
401
+ // Cache current container before replacement and inform the
402
+ // cache which direction the history shifted.
403
+ cachePop(direction, pjax.state.id, container.clone().contents())
404
+ }
405
+
406
+ var popstateEvent = $.Event('pjax:popstate', {
407
+ state: state,
408
+ direction: direction
409
+ })
410
+ container.trigger(popstateEvent)
411
+
412
+ var options = {
413
+ id: state.id,
414
+ url: state.url,
415
+ container: container,
416
+ push: false,
417
+ fragment: state.fragment,
418
+ timeout: state.timeout,
419
+ scrollTo: false
420
+ }
421
+
422
+ if (contents) {
423
+ container.trigger('pjax:start', [null, options])
424
+
425
+ if (state.title) document.title = state.title
426
+ container.html(contents)
427
+ pjax.state = state
428
+
429
+ container.trigger('pjax:end', [null, options])
430
+ } else {
431
+ pjax(options)
432
+ }
433
+
434
+ // Force reflow/relayout before the browser tries to restore the
435
+ // scroll position.
436
+ container[0].offsetHeight
437
+ } else {
438
+ locationReplace(location.href)
439
+ }
440
+ }
441
+ initialPop = false
442
+ }
443
+
444
+ // Fallback version of main pjax function for browsers that don't
445
+ // support pushState.
446
+ //
447
+ // Returns nothing since it retriggers a hard form submission.
448
+ function fallbackPjax(options) {
449
+ var url = $.isFunction(options.url) ? options.url() : options.url,
450
+ method = options.type ? options.type.toUpperCase() : 'GET'
451
+
452
+ var form = $('<form>', {
453
+ method: method === 'GET' ? 'GET' : 'POST',
454
+ action: url,
455
+ style: 'display:none'
456
+ })
457
+
458
+ if (method !== 'GET' && method !== 'POST') {
459
+ form.append($('<input>', {
460
+ type: 'hidden',
461
+ name: '_method',
462
+ value: method.toLowerCase()
463
+ }))
464
+ }
465
+
466
+ var data = options.data
467
+ if (typeof data === 'string') {
468
+ $.each(data.split('&'), function(index, value) {
469
+ var pair = value.split('=')
470
+ form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
471
+ })
472
+ } else if (typeof data === 'object') {
473
+ for (key in data)
474
+ form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
475
+ }
476
+
477
+ $(document.body).append(form)
478
+ form.submit()
479
+ }
480
+
481
+ // Internal: Generate unique id for state object.
482
+ //
483
+ // Use a timestamp instead of a counter since ids should still be
484
+ // unique across page loads.
485
+ //
486
+ // Returns Number.
487
+ function uniqueId() {
488
+ return (new Date).getTime()
489
+ }
490
+
491
+ // Internal: Strips _pjax param from url
492
+ //
493
+ // url - String
494
+ //
495
+ // Returns String.
496
+ function stripPjaxParam(url) {
497
+ return url
498
+ .replace(/\?_pjax=[^&]+&?/, '?')
499
+ .replace(/_pjax=[^&]+&?/, '')
500
+ .replace(/[\?&]$/, '')
501
+ }
502
+
503
+ // Internal: Parse URL components and returns a Locationish object.
504
+ //
505
+ // url - String URL
506
+ //
507
+ // Returns HTMLAnchorElement that acts like Location.
508
+ function parseURL(url) {
509
+ var a = document.createElement('a')
510
+ a.href = url
511
+ return a
512
+ }
513
+
514
+ // Internal: Build options Object for arguments.
515
+ //
516
+ // For convenience the first parameter can be either the container or
517
+ // the options object.
518
+ //
519
+ // Examples
520
+ //
521
+ // optionsFor('#container')
522
+ // // => {container: '#container'}
523
+ //
524
+ // optionsFor('#container', {push: true})
525
+ // // => {container: '#container', push: true}
526
+ //
527
+ // optionsFor({container: '#container', push: true})
528
+ // // => {container: '#container', push: true}
529
+ //
530
+ // Returns options Object.
531
+ function optionsFor(container, options) {
532
+ // Both container and options
533
+ if ( container && options )
534
+ options.container = container
535
+
536
+ // First argument is options Object
537
+ else if ( $.isPlainObject(container) )
538
+ options = container
539
+
540
+ // Only container
541
+ else
542
+ options = {container: container}
543
+
544
+ // Find and validate container
545
+ if (options.container)
546
+ options.container = findContainerFor(options.container)
547
+
548
+ return options
549
+ }
550
+
551
+ // Internal: Find container element for a variety of inputs.
552
+ //
553
+ // Because we can't persist elements using the history API, we must be
554
+ // able to find a String selector that will consistently find the Element.
555
+ //
556
+ // container - A selector String, jQuery object, or DOM Element.
557
+ //
558
+ // Returns a jQuery object whose context is `document` and has a selector.
559
+ function findContainerFor(container) {
560
+ container = $(container)
561
+
562
+ if ( !container.length ) {
563
+ throw "no pjax container for " + container.selector
564
+ } else if ( container.selector !== '' && container.context === document ) {
565
+ return container
566
+ } else if ( container.attr('id') ) {
567
+ return $('#' + container.attr('id'))
568
+ } else {
569
+ throw "cant get selector for pjax container!"
570
+ }
571
+ }
572
+
573
+ // Internal: Filter and find all elements matching the selector.
574
+ //
575
+ // Where $.fn.find only matches descendants, findAll will test all the
576
+ // top level elements in the jQuery object as well.
577
+ //
578
+ // elems - jQuery object of Elements
579
+ // selector - String selector to match
580
+ //
581
+ // Returns a jQuery object.
582
+ function findAll(elems, selector) {
583
+ return elems.filter(selector).add(elems.find(selector));
584
+ }
585
+
586
+ function parseHTML(html) {
587
+ return $.parseHTML(html, document, true)
588
+ }
589
+
590
+ // Internal: Extracts container and metadata from response.
591
+ //
592
+ // 1. Extracts X-PJAX-URL header if set
593
+ // 2. Extracts inline <title> tags
594
+ // 3. Builds response Element and extracts fragment if set
595
+ //
596
+ // data - String response data
597
+ // xhr - XHR response
598
+ // options - pjax options Object
599
+ //
600
+ // Returns an Object with url, title, and contents keys.
601
+ function extractContainer(data, xhr, options) {
602
+ var obj = {}
603
+
604
+ // Prefer X-PJAX-URL header if it was set, otherwise fallback to
605
+ // using the original requested url.
606
+ obj.url = stripPjaxParam(xhr.getResponseHeader('X-PJAX-URL') || options.requestUrl)
607
+
608
+ // Attempt to parse response html into elements
609
+ if (/<html/i.test(data)) {
610
+ var $head = $(parseHTML(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]))
611
+ var $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
612
+ } else {
613
+ var $head = $body = $(parseHTML(data))
614
+ }
615
+
616
+ // If response data is empty, return fast
617
+ if ($body.length === 0)
618
+ return obj
619
+
620
+ // If there's a <title> tag in the header, use it as
621
+ // the page's title.
622
+ obj.title = findAll($head, 'title').last().text()
623
+
624
+ if (options.fragment) {
625
+ // If they specified a fragment, look for it in the response
626
+ // and pull it out.
627
+ if (options.fragment === 'body') {
628
+ var $fragment = $body
629
+ } else {
630
+ var $fragment = findAll($body, options.fragment).first()
631
+ }
632
+
633
+ if ($fragment.length) {
634
+ obj.contents = $fragment.contents()
635
+
636
+ // If there's no title, look for data-title and title attributes
637
+ // on the fragment
638
+ if (!obj.title)
639
+ obj.title = $fragment.attr('title') || $fragment.data('title')
640
+ }
641
+
642
+ } else if (!/<html/i.test(data)) {
643
+ obj.contents = $body
644
+ }
645
+
646
+ // Clean up any <title> tags
647
+ if (obj.contents) {
648
+ // Remove any parent title elements
649
+ obj.contents = obj.contents.not(function() { return $(this).is('title') })
650
+
651
+ // Then scrub any titles from their descendents
652
+ obj.contents.find('title').remove()
653
+
654
+ // Gather all script[src] elements
655
+ obj.scripts = findAll(obj.contents, 'script[src]').remove()
656
+ obj.contents = obj.contents.not(obj.scripts)
657
+ }
658
+
659
+ // Trim any whitespace off the title
660
+ if (obj.title) obj.title = $.trim(obj.title)
661
+
662
+ return obj
663
+ }
664
+
665
+ // Load an execute scripts using standard script request.
666
+ //
667
+ // Avoids jQuery's traditional $.getScript which does a XHR request and
668
+ // globalEval.
669
+ //
670
+ // scripts - jQuery object of script Elements
671
+ //
672
+ // Returns nothing.
673
+ function executeScriptTags(scripts) {
674
+ if (!scripts) return
675
+
676
+ var existingScripts = $('script[src]')
677
+
678
+ scripts.each(function() {
679
+ var src = this.src
680
+ var matchedScripts = existingScripts.filter(function() {
681
+ return this.src === src
682
+ })
683
+ if (matchedScripts.length) return
684
+
685
+ var script = document.createElement('script')
686
+ script.type = $(this).attr('type')
687
+ script.src = $(this).attr('src')
688
+ document.head.appendChild(script)
689
+ })
690
+ }
691
+
692
+ // Internal: History DOM caching class.
693
+ var cacheMapping = {}
694
+ var cacheForwardStack = []
695
+ var cacheBackStack = []
696
+
697
+ // Push previous state id and container contents into the history
698
+ // cache. Should be called in conjunction with `pushState` to save the
699
+ // previous container contents.
700
+ //
701
+ // id - State ID Number
702
+ // value - DOM Element to cache
703
+ //
704
+ // Returns nothing.
705
+ function cachePush(id, value) {
706
+ cacheMapping[id] = value
707
+ cacheBackStack.push(id)
708
+
709
+ // Remove all entires in forward history stack after pushing
710
+ // a new page.
711
+ while (cacheForwardStack.length)
712
+ delete cacheMapping[cacheForwardStack.shift()]
713
+
714
+ // Trim back history stack to max cache length.
715
+ while (cacheBackStack.length > pjax.defaults.maxCacheLength)
716
+ delete cacheMapping[cacheBackStack.shift()]
717
+ }
718
+
719
+ // Shifts cache from directional history cache. Should be
720
+ // called on `popstate` with the previous state id and container
721
+ // contents.
722
+ //
723
+ // direction - "forward" or "back" String
724
+ // id - State ID Number
725
+ // value - DOM Element to cache
726
+ //
727
+ // Returns nothing.
728
+ function cachePop(direction, id, value) {
729
+ var pushStack, popStack
730
+ cacheMapping[id] = value
731
+
732
+ if (direction === 'forward') {
733
+ pushStack = cacheBackStack
734
+ popStack = cacheForwardStack
735
+ } else {
736
+ pushStack = cacheForwardStack
737
+ popStack = cacheBackStack
738
+ }
739
+
740
+ pushStack.push(id)
741
+ if (id = popStack.pop())
742
+ delete cacheMapping[id]
743
+ }
744
+
745
+ // Public: Find version identifier for the initial page load.
746
+ //
747
+ // Returns String version or undefined.
748
+ function findVersion() {
749
+ return $('meta').filter(function() {
750
+ var name = $(this).attr('http-equiv')
751
+ return name && name.toUpperCase() === 'X-PJAX-VERSION'
752
+ }).attr('content')
753
+ }
754
+
755
+ // Install pjax functions on $.pjax to enable pushState behavior.
756
+ //
757
+ // Does nothing if already enabled.
758
+ //
759
+ // Examples
760
+ //
761
+ // $.pjax.enable()
762
+ //
763
+ // Returns nothing.
764
+ function enable() {
765
+ $.fn.pjax = fnPjax
766
+ $.pjax = pjax
767
+ $.pjax.enable = $.noop
768
+ $.pjax.disable = disable
769
+ $.pjax.click = handleClick
770
+ $.pjax.submit = handleSubmit
771
+ $.pjax.reload = pjaxReload
772
+ $.pjax.defaults = {
773
+ timeout: 650,
774
+ push: true,
775
+ replace: false,
776
+ type: 'GET',
777
+ dataType: 'html',
778
+ scrollTo: 0,
779
+ maxCacheLength: 20,
780
+ version: findVersion
781
+ }
782
+ $(window).on('popstate.pjax', onPjaxPopstate)
783
+ }
784
+
785
+ // Disable pushState behavior.
786
+ //
787
+ // This is the case when a browser doesn't support pushState. It is
788
+ // sometimes useful to disable pushState for debugging on a modern
789
+ // browser.
790
+ //
791
+ // Examples
792
+ //
793
+ // $.pjax.disable()
794
+ //
795
+ // Returns nothing.
796
+ function disable() {
797
+ $.fn.pjax = function() { return this }
798
+ $.pjax = fallbackPjax
799
+ $.pjax.enable = enable
800
+ $.pjax.disable = $.noop
801
+ $.pjax.click = $.noop
802
+ $.pjax.submit = $.noop
803
+ $.pjax.reload = function() { window.location.reload() }
804
+
805
+ $(window).off('popstate.pjax', onPjaxPopstate)
806
+ }
807
+
808
+
809
+ // Add the state property to jQuery's event object so we can use it in
810
+ // $(window).bind('popstate')
811
+ if ( $.inArray('state', $.event.props) < 0 )
812
+ $.event.props.push('state')
813
+
814
+ // Is pjax supported by this browser?
815
+ $.support.pjax =
816
+ window.history && window.history.pushState && window.history.replaceState &&
817
+ // pushState isn't reliable on iOS until 5.
818
+ !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/)
819
+
820
+ $.support.pjax ? enable() : disable()
821
+
822
+ })(jQuery);