rails_admin 0.8.1 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rails_admin might be problematic. Click here for more details.

Files changed (313) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +17 -34
  3. data/LICENSE.md +1 -1
  4. data/README.md +34 -26
  5. data/app/assets/images/rails_admin/aristo/images/bg_fallback.png +0 -0
  6. data/app/assets/images/rails_admin/aristo/images/slider_handles.png +0 -0
  7. data/app/assets/images/rails_admin/aristo/images/ui-icons_222222_256x240.png +0 -0
  8. data/app/assets/images/rails_admin/aristo/images/ui-icons_454545_256x240.png +0 -0
  9. data/app/assets/images/rails_admin/bullet_black.png +0 -0
  10. data/app/assets/images/rails_admin/bullet_white.png +0 -0
  11. data/app/assets/images/rails_admin/calendar.png +0 -0
  12. data/app/assets/images/rails_admin/clock.png +0 -0
  13. data/app/assets/images/rails_admin/magnifier.png +0 -0
  14. data/app/assets/images/rails_admin/multiselect/ui-icon-circle-triangle-n-dark.png +0 -0
  15. data/app/assets/images/rails_admin/multiselect/ui-icon-circle-triangle-s-dark.png +0 -0
  16. data/app/assets/images/rails_admin/multiselect/ui-icon-circle-triangle-s-light.png +0 -0
  17. data/app/assets/javascripts/rails_admin/custom/ui.js +1 -0
  18. data/app/assets/javascripts/rails_admin/jquery-ui.js.erb +8 -0
  19. data/app/assets/javascripts/rails_admin/jquery.migrate.js +3 -0
  20. data/app/assets/javascripts/rails_admin/ra.filter-box.js +148 -60
  21. data/app/assets/javascripts/rails_admin/ra.filtering-multiselect.js +31 -26
  22. data/app/assets/javascripts/rails_admin/ra.filtering-select.js +211 -110
  23. data/app/assets/javascripts/rails_admin/ra.i18n.js +28 -0
  24. data/app/assets/javascripts/rails_admin/ra.nested-form-hooks.js +59 -0
  25. data/app/assets/javascripts/rails_admin/ra.sidescroll.js +31 -0
  26. data/app/assets/javascripts/rails_admin/ra.widgets.js +379 -0
  27. data/app/assets/javascripts/rails_admin/rails_admin.js +5 -5
  28. data/app/assets/javascripts/rails_admin/ui.js +135 -0
  29. data/app/assets/stylesheets/rails_admin/aristo/images/bg_fallback.png +0 -0
  30. data/app/assets/stylesheets/rails_admin/aristo/images/slider_handles.png +0 -0
  31. data/app/assets/stylesheets/rails_admin/aristo/images/ui-icons_222222_256x240.png +0 -0
  32. data/app/assets/stylesheets/rails_admin/aristo/images/ui-icons_454545_256x240.png +0 -0
  33. data/app/assets/stylesheets/rails_admin/aristo/jquery-ui-1.8.7.custom.scss +5 -5
  34. data/app/assets/stylesheets/rails_admin/ra.sidescroll.scss +29 -0
  35. data/app/assets/stylesheets/rails_admin/ra.widgets.scss +9 -1
  36. data/app/assets/stylesheets/rails_admin/rails_admin.scss.erb +2 -1
  37. data/app/controllers/rails_admin/application_controller.rb +14 -8
  38. data/app/controllers/rails_admin/main_controller.rb +9 -9
  39. data/app/helpers/rails_admin/application_helper.rb +26 -11
  40. data/app/helpers/rails_admin/form_builder.rb +20 -12
  41. data/app/helpers/rails_admin/main_helper.rb +8 -7
  42. data/app/views/kaminari/{twitter-bootstrap → ra-twitter-bootstrap}/_gap.html.haml +0 -0
  43. data/app/views/kaminari/{twitter-bootstrap → ra-twitter-bootstrap}/_next_page.html.haml +0 -0
  44. data/app/views/kaminari/{twitter-bootstrap → ra-twitter-bootstrap}/_page.html.haml +0 -0
  45. data/app/views/kaminari/{twitter-bootstrap → ra-twitter-bootstrap}/_paginator.html.haml +0 -0
  46. data/app/views/kaminari/{twitter-bootstrap → ra-twitter-bootstrap}/_prev_page.html.haml +0 -0
  47. data/app/views/kaminari/ra-twitter-bootstrap/without_count/_next_page.html.haml +4 -0
  48. data/app/views/kaminari/ra-twitter-bootstrap/without_count/_paginator.html.haml +4 -0
  49. data/app/views/kaminari/ra-twitter-bootstrap/without_count/_prev_page.html.haml +4 -0
  50. data/app/views/layouts/rails_admin/_head.html.haml +7 -0
  51. data/app/views/layouts/rails_admin/_secondary_navigation.html.haml +2 -2
  52. data/app/views/layouts/rails_admin/_sidebar_navigation.html.haml +2 -1
  53. data/app/views/layouts/rails_admin/application.html.haml +4 -10
  54. data/app/views/layouts/rails_admin/pjax.html.haml +1 -5
  55. data/app/views/rails_admin/main/_delete_notice.html.haml +14 -9
  56. data/app/views/rails_admin/main/_form_action_text.html.haml +7 -0
  57. data/app/views/rails_admin/main/_form_colorpicker.html.haml +1 -1
  58. data/app/views/rails_admin/main/_form_enumeration.html.haml +4 -3
  59. data/app/views/rails_admin/main/_form_file_upload.html.haml +5 -5
  60. data/app/views/rails_admin/main/_form_filtering_multiselect.html.haml +7 -6
  61. data/app/views/rails_admin/main/_form_filtering_select.html.haml +1 -1
  62. data/app/views/rails_admin/main/_form_multiple_file_upload.html.haml +16 -0
  63. data/app/views/rails_admin/main/_form_polymorphic_association.html.haml +18 -3
  64. data/app/views/rails_admin/main/_form_simple_mde.haml +8 -0
  65. data/app/views/rails_admin/main/dashboard.html.haml +5 -6
  66. data/app/views/rails_admin/main/export.html.haml +45 -36
  67. data/app/views/rails_admin/main/history.html.haml +3 -3
  68. data/app/views/rails_admin/main/index.html.haml +37 -26
  69. data/app/views/rails_admin/main/show.html.haml +6 -7
  70. data/config/initializers/active_record_extensions.rb +3 -3
  71. data/config/initializers/haml.rb +4 -1
  72. data/config/locales/rails_admin.en.yml +5 -2
  73. data/lib/generators/rails_admin/templates/initializer.erb +6 -2
  74. data/lib/rails_admin/abstract_model.rb +9 -10
  75. data/lib/rails_admin/adapters/active_record/abstract_object.rb +9 -3
  76. data/lib/rails_admin/adapters/active_record/property.rb +1 -5
  77. data/lib/rails_admin/adapters/active_record.rb +83 -28
  78. data/lib/rails_admin/adapters/mongoid/abstract_object.rb +3 -3
  79. data/lib/rails_admin/adapters/mongoid/association.rb +18 -6
  80. data/lib/rails_admin/adapters/mongoid/bson.rb +29 -0
  81. data/lib/rails_admin/adapters/mongoid/extension.rb +4 -2
  82. data/lib/rails_admin/adapters/mongoid/property.rb +3 -3
  83. data/lib/rails_admin/adapters/mongoid.rb +40 -26
  84. data/lib/rails_admin/bootstrap-sass/compass_functions.rb +1 -1
  85. data/lib/rails_admin/bootstrap-sass/sass_functions.rb +1 -3
  86. data/lib/rails_admin/bootstrap-sass.rb +8 -6
  87. data/lib/rails_admin/config/actions/base.rb +20 -5
  88. data/lib/rails_admin/config/actions/bulk_delete.rb +2 -4
  89. data/lib/rails_admin/config/actions/dashboard.rb +9 -5
  90. data/lib/rails_admin/config/actions/edit.rb +1 -3
  91. data/lib/rails_admin/config/actions/export.rb +1 -1
  92. data/lib/rails_admin/config/actions/index.rb +5 -3
  93. data/lib/rails_admin/config/actions/new.rb +4 -5
  94. data/lib/rails_admin/config/actions.rb +1 -1
  95. data/lib/rails_admin/config/configurable.rb +25 -18
  96. data/lib/rails_admin/config/fields/association.rb +11 -3
  97. data/lib/rails_admin/config/fields/base.rb +20 -27
  98. data/lib/rails_admin/config/fields/factories/action_text.rb +12 -0
  99. data/lib/rails_admin/config/fields/factories/active_storage.rb +30 -0
  100. data/lib/rails_admin/config/fields/factories/carrierwave.rb +4 -2
  101. data/lib/rails_admin/config/fields/factories/dragonfly.rb +1 -1
  102. data/lib/rails_admin/config/fields/factories/shrine.rb +27 -0
  103. data/lib/rails_admin/config/fields/types/action_text.rb +30 -0
  104. data/lib/rails_admin/config/fields/types/active_record_enum.rb +19 -2
  105. data/lib/rails_admin/config/fields/types/active_storage.rb +49 -0
  106. data/lib/rails_admin/config/fields/types/all.rb +7 -1
  107. data/lib/rails_admin/config/fields/types/belongs_to_association.rb +8 -0
  108. data/lib/rails_admin/config/fields/types/bson_object_id.rb +1 -15
  109. data/lib/rails_admin/config/fields/types/ck_editor.rb +7 -7
  110. data/lib/rails_admin/config/fields/types/code_mirror.rb +10 -12
  111. data/lib/rails_admin/config/fields/types/color.rb +2 -2
  112. data/lib/rails_admin/config/fields/types/datetime.rb +6 -3
  113. data/lib/rails_admin/config/fields/types/file_upload.rb +12 -4
  114. data/lib/rails_admin/config/fields/types/froala.rb +9 -11
  115. data/lib/rails_admin/config/fields/types/has_many_association.rb +1 -1
  116. data/lib/rails_admin/config/fields/types/hidden.rb +2 -2
  117. data/lib/rails_admin/config/fields/types/json.rb +9 -1
  118. data/lib/rails_admin/config/fields/types/multiple_active_storage.rb +53 -0
  119. data/lib/rails_admin/config/fields/types/multiple_carrierwave.rb +56 -0
  120. data/lib/rails_admin/config/fields/types/multiple_file_upload.rb +125 -0
  121. data/lib/rails_admin/config/fields/types/password.rb +5 -1
  122. data/lib/rails_admin/config/fields/types/polymorphic_association.rb +12 -1
  123. data/lib/rails_admin/config/fields/types/serialized.rb +2 -2
  124. data/lib/rails_admin/config/fields/types/shrine.rb +54 -0
  125. data/lib/rails_admin/config/fields/types/simple_mde.rb +36 -0
  126. data/lib/rails_admin/config/fields/types/string.rb +8 -7
  127. data/lib/rails_admin/config/fields/types/string_like.rb +19 -0
  128. data/lib/rails_admin/config/fields/types/text.rb +2 -20
  129. data/lib/rails_admin/config/fields/types/wysihtml5.rb +14 -10
  130. data/lib/rails_admin/config/fields/types.rb +1 -1
  131. data/lib/rails_admin/config/fields.rb +3 -1
  132. data/lib/rails_admin/config/has_fields.rb +1 -1
  133. data/lib/rails_admin/config/has_groups.rb +1 -1
  134. data/lib/rails_admin/config/hideable.rb +1 -1
  135. data/lib/rails_admin/config/inspectable.rb +39 -0
  136. data/lib/rails_admin/config/lazy_model.rb +48 -8
  137. data/lib/rails_admin/config/model.rb +10 -22
  138. data/lib/rails_admin/config/proxyable/proxy.rb +7 -9
  139. data/lib/rails_admin/config/proxyable.rb +13 -1
  140. data/lib/rails_admin/config/sections/base.rb +4 -17
  141. data/lib/rails_admin/config/sections/list.rb +37 -0
  142. data/lib/rails_admin/config.rb +46 -25
  143. data/lib/rails_admin/engine.rb +37 -4
  144. data/lib/rails_admin/extension.rb +16 -4
  145. data/lib/rails_admin/extensions/cancancan/authorization_adapter.rb +23 -7
  146. data/lib/rails_admin/extensions/cancancan.rb +1 -1
  147. data/lib/rails_admin/extensions/controller_extension.rb +6 -0
  148. data/lib/rails_admin/extensions/history/auditing_adapter.rb +2 -2
  149. data/lib/rails_admin/extensions/history/history.rb +2 -2
  150. data/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb +59 -17
  151. data/lib/rails_admin/extensions/pundit/authorization_adapter.rb +11 -3
  152. data/lib/rails_admin/support/csv_converter.rb +20 -14
  153. data/lib/rails_admin/support/datetime.rb +7 -6
  154. data/lib/rails_admin/support/i18n.rb +7 -5
  155. data/lib/rails_admin/version.rb +2 -2
  156. data/lib/rails_admin.rb +23 -1
  157. data/lib/tasks/rails_admin.rake +16 -7
  158. data/vendor/assets/fonts/rails_admin/FontAwesome.otf +0 -0
  159. data/vendor/assets/fonts/rails_admin/fontawesome-webfont.eot +0 -0
  160. data/vendor/assets/fonts/rails_admin/fontawesome-webfont.svg +2671 -0
  161. data/vendor/assets/fonts/rails_admin/fontawesome-webfont.ttf +0 -0
  162. data/vendor/assets/fonts/rails_admin/fontawesome-webfont.woff +0 -0
  163. data/vendor/assets/fonts/rails_admin/fontawesome-webfont.woff2 +0 -0
  164. data/vendor/assets/images/rails_admin/bootstrap/glyphicons-halflings-white.png +0 -0
  165. data/vendor/assets/images/rails_admin/bootstrap/glyphicons-halflings.png +0 -0
  166. data/vendor/assets/images/rails_admin/colorpicker/colorpicker_background.png +0 -0
  167. data/vendor/assets/images/rails_admin/colorpicker/colorpicker_hex.png +0 -0
  168. data/vendor/assets/images/rails_admin/colorpicker/colorpicker_hsb_b.png +0 -0
  169. data/vendor/assets/images/rails_admin/colorpicker/colorpicker_hsb_h.png +0 -0
  170. data/vendor/assets/images/rails_admin/colorpicker/colorpicker_hsb_s.png +0 -0
  171. data/vendor/assets/images/rails_admin/colorpicker/colorpicker_indic.gif +0 -0
  172. data/vendor/assets/images/rails_admin/colorpicker/colorpicker_overlay.png +0 -0
  173. data/vendor/assets/images/rails_admin/colorpicker/colorpicker_rgb_b.png +0 -0
  174. data/vendor/assets/images/rails_admin/colorpicker/colorpicker_rgb_g.png +0 -0
  175. data/{app → vendor}/assets/images/rails_admin/colorpicker/colorpicker_rgb_r.png +0 -0
  176. data/{app → vendor}/assets/images/rails_admin/colorpicker/colorpicker_select.gif +0 -0
  177. data/vendor/assets/images/rails_admin/colorpicker/colorpicker_submit.png +0 -0
  178. data/vendor/assets/images/rails_admin/colorpicker/custom_background.png +0 -0
  179. data/vendor/assets/images/rails_admin/colorpicker/custom_hex.png +0 -0
  180. data/vendor/assets/images/rails_admin/colorpicker/custom_hsb_b.png +0 -0
  181. data/vendor/assets/images/rails_admin/colorpicker/custom_hsb_h.png +0 -0
  182. data/vendor/assets/images/rails_admin/colorpicker/custom_hsb_s.png +0 -0
  183. data/vendor/assets/images/rails_admin/colorpicker/custom_indic.gif +0 -0
  184. data/{app → vendor}/assets/images/rails_admin/colorpicker/custom_rgb_b.png +0 -0
  185. data/{app → vendor}/assets/images/rails_admin/colorpicker/custom_rgb_g.png +0 -0
  186. data/{app → vendor}/assets/images/rails_admin/colorpicker/custom_rgb_r.png +0 -0
  187. data/vendor/assets/images/rails_admin/colorpicker/custom_submit.png +0 -0
  188. data/vendor/assets/images/rails_admin/colorpicker/select.png +0 -0
  189. data/{app → vendor}/assets/images/rails_admin/colorpicker/select2.png +0 -0
  190. data/vendor/assets/images/rails_admin/colorpicker/slider.png +0 -0
  191. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-affix.js +50 -28
  192. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-alert.js +10 -7
  193. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-button.js +35 -20
  194. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-carousel.js +48 -25
  195. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-collapse.js +70 -28
  196. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-dropdown.js +56 -42
  197. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-modal.js +118 -40
  198. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-popover.js +26 -16
  199. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-scrollspy.js +29 -27
  200. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-tab.js +46 -19
  201. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-tooltip.js +280 -60
  202. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-transition.js +5 -5
  203. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap-typeahead.js +0 -0
  204. data/{app → vendor}/assets/javascripts/rails_admin/bootstrap/bootstrap.js +0 -0
  205. data/vendor/assets/javascripts/rails_admin/bootstrap-datetimepicker.js +317 -150
  206. data/{app → vendor}/assets/javascripts/rails_admin/jquery.colorpicker.js +0 -0
  207. data/{app → vendor}/assets/javascripts/rails_admin/jquery.pjax.js +316 -161
  208. data/vendor/assets/javascripts/rails_admin/moment-with-locales.js +16528 -8420
  209. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_alerts.scss +0 -0
  210. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_badges.scss +0 -0
  211. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_breadcrumbs.scss +0 -0
  212. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_button-groups.scss +0 -0
  213. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_buttons.scss +0 -0
  214. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_carousel.scss +0 -0
  215. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_close.scss +0 -0
  216. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_code.scss +0 -0
  217. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_component-animations.scss +0 -0
  218. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_dropdowns.scss +0 -0
  219. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_forms.scss +0 -0
  220. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_glyphicons.scss +0 -0
  221. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_grid.scss +0 -0
  222. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_input-groups.scss +0 -0
  223. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_jumbotron.scss +0 -0
  224. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_labels.scss +0 -0
  225. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_list-group.scss +0 -0
  226. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_media.scss +0 -0
  227. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_mixins.scss +0 -0
  228. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_modals.scss +0 -0
  229. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_navbar.scss +0 -0
  230. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_navs.scss +0 -0
  231. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_normalize.scss +0 -0
  232. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_pager.scss +0 -0
  233. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_pagination.scss +0 -0
  234. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_panels.scss +0 -0
  235. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_popovers.scss +0 -0
  236. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_print.scss +0 -0
  237. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_progress-bars.scss +0 -0
  238. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_responsive-embed.scss +0 -0
  239. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_responsive-utilities.scss +0 -0
  240. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_scaffolding.scss +0 -0
  241. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_tables.scss +0 -0
  242. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_theme.scss +0 -0
  243. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_thumbnails.scss +0 -0
  244. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_tooltip.scss +0 -0
  245. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_type.scss +0 -0
  246. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_utilities.scss +0 -0
  247. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_variables.scss +0 -0
  248. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/_wells.scss +0 -0
  249. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/bootstrap.scss +0 -0
  250. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_alerts.scss +0 -0
  251. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_background-variant.scss +0 -0
  252. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_border-radius.scss +0 -0
  253. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_buttons.scss +0 -0
  254. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_center-block.scss +0 -0
  255. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_clearfix.scss +0 -0
  256. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_forms.scss +0 -0
  257. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_gradients.scss +0 -0
  258. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_grid-framework.scss +0 -0
  259. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_grid.scss +0 -0
  260. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_hide-text.scss +0 -0
  261. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_image.scss +0 -0
  262. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_labels.scss +0 -0
  263. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_list-group.scss +0 -0
  264. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_nav-divider.scss +0 -0
  265. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_nav-vertical-align.scss +0 -0
  266. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_opacity.scss +0 -0
  267. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_pagination.scss +0 -0
  268. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_panels.scss +0 -0
  269. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_progress-bar.scss +0 -0
  270. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_reset-filter.scss +0 -0
  271. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_resize.scss +0 -0
  272. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_responsive-visibility.scss +0 -0
  273. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_size.scss +0 -0
  274. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_tab-focus.scss +0 -0
  275. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_table-row.scss +0 -0
  276. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_text-emphasis.scss +0 -0
  277. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_text-overflow.scss +0 -0
  278. data/{app → vendor}/assets/stylesheets/rails_admin/bootstrap/mixins/_vendor-prefixes.scss +0 -0
  279. data/vendor/assets/stylesheets/rails_admin/font-awesome.scss +2342 -0
  280. data/{app → vendor}/assets/stylesheets/rails_admin/jquery.colorpicker.scss +0 -0
  281. metadata +214 -199
  282. data/app/assets/images/rails_admin/bootstrap/glyphicons-halflings-white.png +0 -0
  283. data/app/assets/images/rails_admin/bootstrap/glyphicons-halflings.png +0 -0
  284. data/app/assets/images/rails_admin/colorpicker/colorpicker_background.png +0 -0
  285. data/app/assets/images/rails_admin/colorpicker/colorpicker_hex.png +0 -0
  286. data/app/assets/images/rails_admin/colorpicker/colorpicker_hsb_b.png +0 -0
  287. data/app/assets/images/rails_admin/colorpicker/colorpicker_hsb_h.png +0 -0
  288. data/app/assets/images/rails_admin/colorpicker/colorpicker_hsb_s.png +0 -0
  289. data/app/assets/images/rails_admin/colorpicker/colorpicker_indic.gif +0 -0
  290. data/app/assets/images/rails_admin/colorpicker/colorpicker_overlay.png +0 -0
  291. data/app/assets/images/rails_admin/colorpicker/colorpicker_rgb_b.png +0 -0
  292. data/app/assets/images/rails_admin/colorpicker/colorpicker_rgb_g.png +0 -0
  293. data/app/assets/images/rails_admin/colorpicker/colorpicker_submit.png +0 -0
  294. data/app/assets/images/rails_admin/colorpicker/custom_background.png +0 -0
  295. data/app/assets/images/rails_admin/colorpicker/custom_hex.png +0 -0
  296. data/app/assets/images/rails_admin/colorpicker/custom_hsb_b.png +0 -0
  297. data/app/assets/images/rails_admin/colorpicker/custom_hsb_h.png +0 -0
  298. data/app/assets/images/rails_admin/colorpicker/custom_hsb_s.png +0 -0
  299. data/app/assets/images/rails_admin/colorpicker/custom_indic.gif +0 -0
  300. data/app/assets/images/rails_admin/colorpicker/custom_submit.png +0 -0
  301. data/app/assets/images/rails_admin/colorpicker/select.png +0 -0
  302. data/app/assets/images/rails_admin/colorpicker/slider.png +0 -0
  303. data/app/assets/javascripts/rails_admin/custom/ui.coffee +0 -1
  304. data/app/assets/javascripts/rails_admin/jquery.remotipart.fixed.js +0 -72
  305. data/app/assets/javascripts/rails_admin/ra.i18n.coffee +0 -8
  306. data/app/assets/javascripts/rails_admin/ra.nested-form-hooks.coffee +0 -52
  307. data/app/assets/javascripts/rails_admin/ra.widgets.coffee +0 -308
  308. data/app/assets/javascripts/rails_admin/ui.coffee +0 -102
  309. data/config/initializers/devise_patch.rb +0 -9
  310. data/lib/rails_admin/config/fields/factories/refile.rb +0 -25
  311. data/lib/rails_admin/config/fields/types/refile.rb +0 -27
  312. data/lib/rails_admin/extensions/cancan/authorization_adapter.rb +0 -57
  313. data/lib/rails_admin/extensions/cancan.rb +0 -3
@@ -1,6 +1,8 @@
1
- // jquery.pjax.js
2
- // copyright chris wanstrath
3
- // https://github.com/defunkt/jquery-pjax
1
+ /*!
2
+ * Copyright 2012, Chris Wanstrath
3
+ * Released under the MIT License
4
+ * https://github.com/defunkt/jquery-pjax
5
+ */
4
6
 
5
7
  (function($){
6
8
 
@@ -17,9 +19,7 @@
17
19
  // pjax specific options:
18
20
  //
19
21
  //
20
- // container - Where to stick the response body. Usually a String selector.
21
- // $(container).html(xhr.responseBody)
22
- // (default: current jquery context)
22
+ // container - String selector for the element where to place the response body.
23
23
  // push - Whether to pushState the URL. Defaults to true (of course).
24
24
  // replace - Want to use replaceState instead? That's cool.
25
25
  //
@@ -28,11 +28,13 @@
28
28
  //
29
29
  // Returns the jQuery object
30
30
  function fnPjax(selector, container, options) {
31
- var context = this
31
+ options = optionsFor(container, options)
32
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
33
+ var opts = options
34
+ if (!opts.container) {
35
+ opts = $.extend({}, options)
36
+ opts.container = $(this).attr('data-pjax')
37
+ }
36
38
  handleClick(event, opts)
37
39
  })
38
40
  }
@@ -50,16 +52,12 @@ function fnPjax(selector, container, options) {
50
52
  // // is the same as
51
53
  // $(document).pjax('a')
52
54
  //
53
- // $(document).on('click', 'a', function(event) {
54
- // var container = $(this).closest('[data-pjax-container]')
55
- // $.pjax.click(event, container)
56
- // })
57
- //
58
55
  // Returns nothing.
59
56
  function handleClick(event, container, options) {
60
57
  options = optionsFor(container, options)
61
58
 
62
59
  var link = event.currentTarget
60
+ var $link = $(link)
63
61
 
64
62
  if (link.tagName.toUpperCase() !== 'A')
65
63
  throw "$.fn.pjax or $.pjax.click requires an anchor element"
@@ -70,28 +68,32 @@ function handleClick(event, container, options) {
70
68
  return
71
69
 
72
70
  // Ignore cross origin links
73
- if ( location.protocol !== link.protocol || location.host !== link.host )
71
+ if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
74
72
  return
75
73
 
76
- // Ignore anchors on the same page
77
- if (link.hash && link.href.replace(link.hash, '') ===
78
- location.href.replace(location.hash, ''))
74
+ // Ignore case when a hash is being tacked on the current URL
75
+ if ( link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location) )
79
76
  return
80
77
 
81
- // Ignore empty anchor "foo.html#"
82
- if (link.href === location.href + '#')
78
+ // Ignore event with default prevented
79
+ if (event.isDefaultPrevented())
83
80
  return
84
81
 
85
82
  var defaults = {
86
83
  url: link.href,
87
- container: $(link).attr('data-pjax'),
88
- target: link,
89
- fragment: null
84
+ container: $link.attr('data-pjax'),
85
+ target: link
90
86
  }
91
87
 
92
- pjax($.extend({}, defaults, options))
88
+ var opts = $.extend({}, defaults, options)
89
+ var clickEvent = $.Event('pjax:click')
90
+ $link.trigger(clickEvent, [opts])
93
91
 
94
- event.preventDefault()
92
+ if (!clickEvent.isDefaultPrevented()) {
93
+ pjax(opts)
94
+ event.preventDefault()
95
+ $link.trigger('pjax:clicked', [opts])
96
+ }
95
97
  }
96
98
 
97
99
  // Public: pjax on form submit handler
@@ -104,8 +106,7 @@ function handleClick(event, container, options) {
104
106
  // Examples
105
107
  //
106
108
  // $(document).on('submit', 'form', function(event) {
107
- // var container = $(this).closest('[data-pjax-container]')
108
- // $.pjax.submit(event, container)
109
+ // $.pjax.submit(event, '[data-pjax-container]')
109
110
  // })
110
111
  //
111
112
  // Returns nothing.
@@ -113,17 +114,30 @@ function handleSubmit(event, container, options) {
113
114
  options = optionsFor(container, options)
114
115
 
115
116
  var form = event.currentTarget
117
+ var $form = $(form)
116
118
 
117
119
  if (form.tagName.toUpperCase() !== 'FORM')
118
120
  throw "$.pjax.submit requires a form element"
119
121
 
120
122
  var defaults = {
121
- type: form.method,
122
- url: form.action,
123
- data: $(form).serializeArray(),
124
- container: $(form).attr('data-pjax'),
125
- target: form,
126
- fragment: null
123
+ type: ($form.attr('method') || 'GET').toUpperCase(),
124
+ url: $form.attr('action'),
125
+ container: $form.attr('data-pjax'),
126
+ target: form
127
+ }
128
+
129
+ if (defaults.type !== 'GET' && window.FormData !== undefined) {
130
+ defaults.data = new FormData(form)
131
+ defaults.processData = false
132
+ defaults.contentType = false
133
+ } else {
134
+ // Can't handle file uploads, exit
135
+ if ($form.find(':file').length) {
136
+ return
137
+ }
138
+
139
+ // Fallback to manually serializing the fields
140
+ defaults.data = $form.serializeArray()
127
141
  }
128
142
 
129
143
  pjax($.extend({}, defaults, options))
@@ -139,8 +153,7 @@ function handleSubmit(event, container, options) {
139
153
  //
140
154
  // Accepts these extra keys:
141
155
  //
142
- // container - Where to stick the response body.
143
- // $(container).html(xhr.responseBody)
156
+ // container - String selector for where to stick the response body.
144
157
  // push - Whether to pushState the URL. Defaults to true (of course).
145
158
  // replace - Want to use replaceState instead? That's cool.
146
159
  //
@@ -157,21 +170,32 @@ function pjax(options) {
157
170
  options.url = options.url()
158
171
  }
159
172
 
160
- var target = options.target
161
-
162
173
  var hash = parseURL(options.url).hash
163
174
 
164
- var context = options.context = findContainerFor(options.container)
175
+ var containerType = $.type(options.container)
176
+ if (containerType !== 'string') {
177
+ throw "expected string value for 'container' option; got " + containerType
178
+ }
179
+ var context = options.context = $(options.container)
180
+ if (!context.length) {
181
+ throw "the container selector '" + options.container + "' did not match anything"
182
+ }
165
183
 
166
184
  // We want the browser to maintain two separate internal caches: one
167
185
  // for pjax'd partial page loads and one for normal page loads.
168
186
  // Without adding this secret parameter, some browsers will often
169
187
  // confuse the two.
170
188
  if (!options.data) options.data = {}
171
- options.data._pjax = context.selector
189
+ if ($.isArray(options.data)) {
190
+ options.data.push({name: '_pjax', value: options.container})
191
+ } else {
192
+ options.data._pjax = options.container
193
+ }
172
194
 
173
- function fire(type, args) {
174
- var event = $.Event(type, { relatedTarget: target })
195
+ function fire(type, args, props) {
196
+ if (!props) props = {}
197
+ props.relatedTarget = options.target
198
+ var event = $.Event(type, props)
175
199
  context.trigger(event, args)
176
200
  return !event.isDefaultPrevented()
177
201
  }
@@ -186,9 +210,7 @@ function pjax(options) {
186
210
  }
187
211
 
188
212
  xhr.setRequestHeader('X-PJAX', 'true')
189
- xhr.setRequestHeader('X-PJAX-Container', context.selector)
190
-
191
- var result
213
+ xhr.setRequestHeader('X-PJAX-Container', options.container)
192
214
 
193
215
  if (!fire('pjax:beforeSend', [xhr, settings]))
194
216
  return false
@@ -203,7 +225,9 @@ function pjax(options) {
203
225
  settings.timeout = 0
204
226
  }
205
227
 
206
- options.requestUrl = parseURL(settings.url).href
228
+ var url = parseURL(settings.url)
229
+ if (hash) url.hash = hash
230
+ options.requestUrl = stripInternalParams(url)
207
231
  }
208
232
 
209
233
  options.complete = function(xhr, textStatus) {
@@ -225,8 +249,31 @@ function pjax(options) {
225
249
  }
226
250
 
227
251
  options.success = function(data, status, xhr) {
252
+ var previousState = pjax.state
253
+
254
+ // If $.pjax.defaults.version is a function, invoke it first.
255
+ // Otherwise it can be a static string.
256
+ var currentVersion = (typeof $.pjax.defaults.version === 'function') ?
257
+ $.pjax.defaults.version() :
258
+ $.pjax.defaults.version
259
+
260
+ var latestVersion = xhr.getResponseHeader('X-PJAX-Version')
261
+
228
262
  var container = extractContainer(data, xhr, options)
229
263
 
264
+ var url = parseURL(container.url)
265
+ if (hash) {
266
+ url.hash = hash
267
+ container.url = url.href
268
+ }
269
+
270
+ // If there is a layout version mismatch, hard load the new url
271
+ if (currentVersion && latestVersion && currentVersion !== latestVersion) {
272
+ locationReplace(container.url)
273
+ return
274
+ }
275
+
276
+ // If the new response is missing a body, hard load the page
230
277
  if (!container.contents) {
231
278
  locationReplace(container.url)
232
279
  return
@@ -236,7 +283,7 @@ function pjax(options) {
236
283
  id: options.id || uniqueId(),
237
284
  url: container.url,
238
285
  title: container.title,
239
- container: context.selector,
286
+ container: options.container,
240
287
  fragment: options.fragment,
241
288
  timeout: options.timeout
242
289
  }
@@ -245,35 +292,47 @@ function pjax(options) {
245
292
  window.history.replaceState(pjax.state, container.title, container.url)
246
293
  }
247
294
 
295
+ // Only blur the focus if the focused element is within the container.
296
+ var blurFocus = $.contains(options.container, document.activeElement)
297
+
298
+ // Clear out any focused controls before inserting new page contents.
299
+ if (blurFocus) {
300
+ try {
301
+ document.activeElement.blur()
302
+ } catch (e) { }
303
+ }
304
+
248
305
  if (container.title) document.title = container.title
306
+
307
+ fire('pjax:beforeReplace', [container.contents, options], {
308
+ state: pjax.state,
309
+ previousState: previousState
310
+ })
249
311
  context.html(container.contents)
250
312
 
251
- // Scroll to top by default
252
- if (typeof options.scrollTo === 'number')
253
- $(window).scrollTop(options.scrollTo)
254
-
255
- // Google Analytics support
256
- if ( (options.replace || options.push) && window._gaq )
257
- _gaq.push(['_trackPageview'])
258
-
259
- // If the URL has a hash in it, make sure the browser
260
- // knows to navigate to the hash.
261
- if ( hash !== '' ) {
262
- // Avoid using simple hash set here. Will add another history
263
- // entry. Replace the url with replaceState and scroll to target
264
- // by hand.
265
- //
266
- // window.location.hash = hash
267
- var url = parseURL(container.url)
268
- url.hash = hash
313
+ // FF bug: Won't autofocus fields that are inserted via JS.
314
+ // This behavior is incorrect. So if theres no current focus, autofocus
315
+ // the last field.
316
+ //
317
+ // http://www.w3.org/html/wg/drafts/html/master/forms.html
318
+ var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
319
+ if (autofocusEl && document.activeElement !== autofocusEl) {
320
+ autofocusEl.focus()
321
+ }
322
+
323
+ executeScriptTags(container.scripts)
269
324
 
270
- pjax.state.url = url.href
271
- window.history.replaceState(pjax.state, container.title, url.href)
325
+ var scrollTo = options.scrollTo
272
326
 
273
- var target = $(url.hash)
274
- if (target.length) $(window).scrollTop(target.offset().top)
327
+ // Ensure browser scrolls to the element referenced by the URL anchor
328
+ if (hash) {
329
+ var name = decodeURIComponent(hash.slice(1))
330
+ var target = document.getElementById(name) || document.getElementsByName(name)[0]
331
+ if (target) scrollTo = $(target).offset().top
275
332
  }
276
333
 
334
+ if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)
335
+
277
336
  fire('pjax:success', [data, status, xhr, options])
278
337
  }
279
338
 
@@ -287,7 +346,7 @@ function pjax(options) {
287
346
  id: uniqueId(),
288
347
  url: window.location.href,
289
348
  title: document.title,
290
- container: context.selector,
349
+ container: options.container,
291
350
  fragment: options.fragment,
292
351
  timeout: options.timeout
293
352
  }
@@ -295,11 +354,7 @@ function pjax(options) {
295
354
  }
296
355
 
297
356
  // Cancel the current request if we're already pjaxing
298
- var xhr = pjax.xhr
299
- if ( xhr && xhr.readyState < 4) {
300
- xhr.onreadystatechange = $.noop
301
- xhr.abort()
302
- }
357
+ abortXHR(pjax.xhr)
303
358
 
304
359
  pjax.options = options
305
360
  var xhr = pjax.xhr = $.ajax(options)
@@ -307,9 +362,9 @@ function pjax(options) {
307
362
  if (xhr.readyState > 0) {
308
363
  if (options.push && !options.replace) {
309
364
  // Cache current container element before replacing it
310
- cachePush(pjax.state.id, context.clone().contents())
365
+ cachePush(pjax.state.id, [options.container, cloneContents(context)])
311
366
 
312
- window.history.pushState(null, "", stripPjaxParam(options.requestUrl))
367
+ window.history.pushState(null, "", options.requestUrl)
313
368
  }
314
369
 
315
370
  fire('pjax:start', [xhr, options])
@@ -340,35 +395,66 @@ function pjaxReload(container, options) {
340
395
  //
341
396
  // Returns nothing.
342
397
  function locationReplace(url) {
343
- window.history.replaceState(null, "", "#")
398
+ window.history.replaceState(null, "", pjax.state.url)
344
399
  window.location.replace(url)
345
400
  }
346
401
 
402
+
403
+ var initialPop = true
404
+ var initialURL = window.location.href
405
+ var initialState = window.history.state
406
+
407
+ // Initialize $.pjax.state if possible
408
+ // Happens when reloading a page and coming forward from a different
409
+ // session history.
410
+ if (initialState && initialState.container) {
411
+ pjax.state = initialState
412
+ }
413
+
414
+ // Non-webkit browsers don't fire an initial popstate event
415
+ if ('state' in window.history) {
416
+ initialPop = false
417
+ }
418
+
347
419
  // popstate handler takes care of the back and forward buttons
348
420
  //
349
421
  // You probably shouldn't use pjax on pages with other pushState
350
422
  // stuff yet.
351
423
  function onPjaxPopstate(event) {
424
+
425
+ // Hitting back or forward should override any pending PJAX request.
426
+ if (!initialPop) {
427
+ abortXHR(pjax.xhr)
428
+ }
429
+
430
+ var previousState = pjax.state
352
431
  var state = event.state
432
+ var direction
353
433
 
354
434
  if (state && state.container) {
355
- var container = $(state.container)
356
- if (container.length) {
357
- var contents = cacheMapping[state.id]
435
+ // When coming forward from a separate history session, will get an
436
+ // initial pop with a state we are already at. Skip reloading the current
437
+ // page.
438
+ if (initialPop && initialURL == state.url) return
439
+
440
+ if (previousState) {
441
+ // If popping back to the same state, just skip.
442
+ // Could be clicking back from hashchange rather than a pushState.
443
+ if (previousState.id === state.id) return
444
+
445
+ // Since state IDs always increase, we can deduce the navigation direction
446
+ direction = previousState.id < state.id ? 'forward' : 'back'
447
+ }
358
448
 
359
- if (pjax.state) {
360
- // Since state ids always increase, we can deduce the history
361
- // direction from the previous state.
362
- var direction = pjax.state.id < state.id ? 'forward' : 'back'
449
+ var cache = cacheMapping[state.id] || []
450
+ var containerSelector = cache[0] || state.container
451
+ var container = $(containerSelector), contents = cache[1]
363
452
 
453
+ if (container.length) {
454
+ if (previousState) {
364
455
  // Cache current container before replacement and inform the
365
456
  // cache which direction the history shifted.
366
- cachePop(direction, pjax.state.id, container.clone().contents())
367
- } else {
368
- // Page was reloaded but we have an existing history entry.
369
- // Set it to our initial state.
370
- pjax.state = state;
371
- return;
457
+ cachePop(direction, previousState.id, [containerSelector, cloneContents(container)])
372
458
  }
373
459
 
374
460
  var popstateEvent = $.Event('pjax:popstate', {
@@ -380,7 +466,7 @@ function onPjaxPopstate(event) {
380
466
  var options = {
381
467
  id: state.id,
382
468
  url: state.url,
383
- container: container,
469
+ container: containerSelector,
384
470
  push: false,
385
471
  fragment: state.fragment,
386
472
  timeout: state.timeout,
@@ -390,9 +476,14 @@ function onPjaxPopstate(event) {
390
476
  if (contents) {
391
477
  container.trigger('pjax:start', [null, options])
392
478
 
479
+ pjax.state = state
393
480
  if (state.title) document.title = state.title
481
+ var beforeReplaceEvent = $.Event('pjax:beforeReplace', {
482
+ state: state,
483
+ previousState: previousState
484
+ })
485
+ container.trigger(beforeReplaceEvent, [contents, options])
394
486
  container.html(contents)
395
- pjax.state = state
396
487
 
397
488
  container.trigger('pjax:end', [null, options])
398
489
  } else {
@@ -406,6 +497,7 @@ function onPjaxPopstate(event) {
406
497
  locationReplace(location.href)
407
498
  }
408
499
  }
500
+ initialPop = false
409
501
  }
410
502
 
411
503
  // Fallback version of main pjax function for browsers that don't
@@ -436,7 +528,12 @@ function fallbackPjax(options) {
436
528
  var pair = value.split('=')
437
529
  form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
438
530
  })
531
+ } else if ($.isArray(data)) {
532
+ $.each(data, function(index, value) {
533
+ form.append($('<input>', {type: 'hidden', name: value.name, value: value.value}))
534
+ })
439
535
  } else if (typeof data === 'object') {
536
+ var key
440
537
  for (key in data)
441
538
  form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
442
539
  }
@@ -445,6 +542,15 @@ function fallbackPjax(options) {
445
542
  form.submit()
446
543
  }
447
544
 
545
+ // Internal: Abort an XmlHttpRequest if it hasn't been completed,
546
+ // also removing its event handlers.
547
+ function abortXHR(xhr) {
548
+ if ( xhr && xhr.readyState < 4) {
549
+ xhr.onreadystatechange = $.noop
550
+ xhr.abort()
551
+ }
552
+ }
553
+
448
554
  // Internal: Generate unique id for state object.
449
555
  //
450
556
  // Use a timestamp instead of a counter since ids should still be
@@ -455,16 +561,22 @@ function uniqueId() {
455
561
  return (new Date).getTime()
456
562
  }
457
563
 
458
- // Internal: Strips _pjax param from url
459
- //
460
- // url - String
564
+ function cloneContents(container) {
565
+ var cloned = container.clone()
566
+ // Unmark script tags as already being eval'd so they can get executed again
567
+ // when restored from cache. HAXX: Uses jQuery internal method.
568
+ cloned.find('script').each(function(){
569
+ if (!this.src) jQuery._data(this, 'globalEval', false)
570
+ })
571
+ return cloned.contents()
572
+ }
573
+
574
+ // Internal: Strip internal query params from parsed URL.
461
575
  //
462
- // Returns String.
463
- function stripPjaxParam(url) {
464
- return url
465
- .replace(/\?_pjax=[^&]+&?/, '?')
466
- .replace(/_pjax=[^&]+&?/, '')
467
- .replace(/[\?&]$/, '')
576
+ // Returns sanitized url.href String.
577
+ function stripInternalParams(url) {
578
+ url.search = url.search.replace(/([?&])(_pjax|_)=[^&]*/g, '')
579
+ return url.href.replace(/\?($|#)/, '$1')
468
580
  }
469
581
 
470
582
  // Internal: Parse URL components and returns a Locationish object.
@@ -478,6 +590,16 @@ function parseURL(url) {
478
590
  return a
479
591
  }
480
592
 
593
+ // Internal: Return the `href` component of given URL object with the hash
594
+ // portion removed.
595
+ //
596
+ // location - Location or HTMLAnchorElement
597
+ //
598
+ // Returns String
599
+ function stripHash(location) {
600
+ return location.href.replace(/#.*/, '')
601
+ }
602
+
481
603
  // Internal: Build options Object for arguments.
482
604
  //
483
605
  // For convenience the first parameter can be either the container or
@@ -496,44 +618,14 @@ function parseURL(url) {
496
618
  //
497
619
  // Returns options Object.
498
620
  function optionsFor(container, options) {
499
- // Both container and options
500
- if ( container && options )
621
+ if (container && options) {
622
+ options = $.extend({}, options)
501
623
  options.container = container
502
-
503
- // First argument is options Object
504
- else if ( $.isPlainObject(container) )
505
- options = container
506
-
507
- // Only container
508
- else
509
- options = {container: container}
510
-
511
- // Find and validate container
512
- if (options.container)
513
- options.container = findContainerFor(options.container)
514
-
515
- return options
516
- }
517
-
518
- // Internal: Find container element for a variety of inputs.
519
- //
520
- // Because we can't persist elements using the history API, we must be
521
- // able to find a String selector that will consistently find the Element.
522
- //
523
- // container - A selector String, jQuery object, or DOM Element.
524
- //
525
- // Returns a jQuery object whose context is `document` and has a selector.
526
- function findContainerFor(container) {
527
- container = $(container)
528
-
529
- if ( !container.length ) {
530
- throw "no pjax container for " + container.selector
531
- } else if ( container.selector !== '' && container.context === document ) {
624
+ return options
625
+ } else if ($.isPlainObject(container)) {
532
626
  return container
533
- } else if ( container.attr('id') ) {
534
- return $('#' + container.attr('id'))
535
627
  } else {
536
- throw "cant get selector for pjax container!"
628
+ return {container: container}
537
629
  }
538
630
  }
539
631
 
@@ -547,7 +639,11 @@ function findContainerFor(container) {
547
639
  //
548
640
  // Returns a jQuery object.
549
641
  function findAll(elems, selector) {
550
- return elems.filter(selector).add(elems.find(selector));
642
+ return elems.filter(selector).add(elems.find(selector))
643
+ }
644
+
645
+ function parseHTML(html) {
646
+ return $.parseHTML(html, document, true)
551
647
  }
552
648
 
553
649
  // Internal: Extracts container and metadata from response.
@@ -562,18 +658,19 @@ function findAll(elems, selector) {
562
658
  //
563
659
  // Returns an Object with url, title, and contents keys.
564
660
  function extractContainer(data, xhr, options) {
565
- var obj = {}
661
+ var obj = {}, fullDocument = /<html/i.test(data)
566
662
 
567
663
  // Prefer X-PJAX-URL header if it was set, otherwise fallback to
568
664
  // using the original requested url.
569
- obj.url = stripPjaxParam(xhr.getResponseHeader('X-PJAX-URL') || options.requestUrl)
665
+ var serverUrl = xhr.getResponseHeader('X-PJAX-URL')
666
+ obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl
570
667
 
571
668
  // Attempt to parse response html into elements
572
- if (/<html/i.test(data)) {
573
- var $head = $(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0])
574
- var $body = $(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0])
669
+ if (fullDocument) {
670
+ var $head = $(parseHTML(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]))
671
+ var $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
575
672
  } else {
576
- var $head = $body = $(data)
673
+ var $head = $body = $(parseHTML(data))
577
674
  }
578
675
 
579
676
  // If response data is empty, return fast
@@ -594,7 +691,7 @@ function extractContainer(data, xhr, options) {
594
691
  }
595
692
 
596
693
  if ($fragment.length) {
597
- obj.contents = $fragment.contents()
694
+ obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents()
598
695
 
599
696
  // If there's no title, look for data-title and title attributes
600
697
  // on the fragment
@@ -602,17 +699,21 @@ function extractContainer(data, xhr, options) {
602
699
  obj.title = $fragment.attr('title') || $fragment.data('title')
603
700
  }
604
701
 
605
- } else if (!/<html/i.test(data)) {
702
+ } else if (!fullDocument) {
606
703
  obj.contents = $body
607
704
  }
608
705
 
609
706
  // Clean up any <title> tags
610
707
  if (obj.contents) {
611
708
  // Remove any parent title elements
612
- obj.contents = obj.contents.not('title')
709
+ obj.contents = obj.contents.not(function() { return $(this).is('title') })
613
710
 
614
- // Then scrub any titles from their descendents
711
+ // Then scrub any titles from their descendants
615
712
  obj.contents.find('title').remove()
713
+
714
+ // Gather all script[src] elements
715
+ obj.scripts = findAll(obj.contents, 'script[src]').remove()
716
+ obj.contents = obj.contents.not(obj.scripts)
616
717
  }
617
718
 
618
719
  // Trim any whitespace off the title
@@ -621,6 +722,34 @@ function extractContainer(data, xhr, options) {
621
722
  return obj
622
723
  }
623
724
 
725
+ // Load an execute scripts using standard script request.
726
+ //
727
+ // Avoids jQuery's traditional $.getScript which does a XHR request and
728
+ // globalEval.
729
+ //
730
+ // scripts - jQuery object of script Elements
731
+ //
732
+ // Returns nothing.
733
+ function executeScriptTags(scripts) {
734
+ if (!scripts) return
735
+
736
+ var existingScripts = $('script[src]')
737
+
738
+ scripts.each(function() {
739
+ var src = this.src
740
+ var matchedScripts = existingScripts.filter(function() {
741
+ return this.src === src
742
+ })
743
+ if (matchedScripts.length) return
744
+
745
+ var script = document.createElement('script')
746
+ var type = $(this).attr('type')
747
+ if (type) script.type = type
748
+ script.src = $(this).attr('src')
749
+ document.head.appendChild(script)
750
+ })
751
+ }
752
+
624
753
  // Internal: History DOM caching class.
625
754
  var cacheMapping = {}
626
755
  var cacheForwardStack = []
@@ -638,14 +767,11 @@ function cachePush(id, value) {
638
767
  cacheMapping[id] = value
639
768
  cacheBackStack.push(id)
640
769
 
641
- // Remove all entires in forward history stack after pushing
642
- // a new page.
643
- while (cacheForwardStack.length)
644
- delete cacheMapping[cacheForwardStack.shift()]
770
+ // Remove all entries in forward history stack after pushing a new page.
771
+ trimCacheStack(cacheForwardStack, 0)
645
772
 
646
773
  // Trim back history stack to max cache length.
647
- while (cacheBackStack.length > pjax.defaults.maxCacheLength)
648
- delete cacheMapping[cacheBackStack.shift()]
774
+ trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength)
649
775
  }
650
776
 
651
777
  // Shifts cache from directional history cache. Should be
@@ -672,6 +798,31 @@ function cachePop(direction, id, value) {
672
798
  pushStack.push(id)
673
799
  if (id = popStack.pop())
674
800
  delete cacheMapping[id]
801
+
802
+ // Trim whichever stack we just pushed to to max cache length.
803
+ trimCacheStack(pushStack, pjax.defaults.maxCacheLength)
804
+ }
805
+
806
+ // Trim a cache stack (either cacheBackStack or cacheForwardStack) to be no
807
+ // longer than the specified length, deleting cached DOM elements as necessary.
808
+ //
809
+ // stack - Array of state IDs
810
+ // length - Maximum length to trim to
811
+ //
812
+ // Returns nothing.
813
+ function trimCacheStack(stack, length) {
814
+ while (stack.length > length)
815
+ delete cacheMapping[stack.shift()]
816
+ }
817
+
818
+ // Public: Find version identifier for the initial page load.
819
+ //
820
+ // Returns String version or undefined.
821
+ function findVersion() {
822
+ return $('meta').filter(function() {
823
+ var name = $(this).attr('http-equiv')
824
+ return name && name.toUpperCase() === 'X-PJAX-VERSION'
825
+ }).attr('content')
675
826
  }
676
827
 
677
828
  // Install pjax functions on $.pjax to enable pushState behavior.
@@ -698,9 +849,10 @@ function enable() {
698
849
  type: 'GET',
699
850
  dataType: 'html',
700
851
  scrollTo: 0,
701
- maxCacheLength: 20
852
+ maxCacheLength: 20,
853
+ version: findVersion
702
854
  }
703
- $(window).bind('popstate.pjax', onPjaxPopstate)
855
+ $(window).on('popstate.pjax', onPjaxPopstate)
704
856
  }
705
857
 
706
858
  // Disable pushState behavior.
@@ -723,21 +875,24 @@ function disable() {
723
875
  $.pjax.submit = $.noop
724
876
  $.pjax.reload = function() { window.location.reload() }
725
877
 
726
- $(window).unbind('popstate.pjax', onPjaxPopstate)
878
+ $(window).off('popstate.pjax', onPjaxPopstate)
727
879
  }
728
880
 
729
881
 
730
882
  // Add the state property to jQuery's event object so we can use it in
731
883
  // $(window).bind('popstate')
732
- if ( $.inArray('state', $.event.props) < 0 )
884
+ if ($.event.props && $.inArray('state', $.event.props) < 0) {
733
885
  $.event.props.push('state')
886
+ } else if (!('state' in $.Event.prototype)) {
887
+ $.event.addProp('state')
888
+ }
734
889
 
735
- // Is pjax supported by this browser?
890
+ // Is pjax supported by this browser?
736
891
  $.support.pjax =
737
892
  window.history && window.history.pushState && window.history.replaceState &&
738
893
  // pushState isn't reliable on iOS until 5.
739
- !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/)
894
+ !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)
740
895
 
741
896
  $.support.pjax ? enable() : disable()
742
897
 
743
- })(jQuery);
898
+ })(jQuery)