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,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);