rails_admin 3.0.0.beta2 → 3.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (250) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -2
  3. data/Rakefile +11 -0
  4. data/app/assets/javascripts/rails_admin.js +4 -4
  5. data/app/assets/stylesheets/rails_admin.scss +31 -0
  6. data/app/controllers/rails_admin/application_controller.rb +1 -1
  7. data/app/controllers/rails_admin/main_controller.rb +10 -18
  8. data/app/helpers/rails_admin/application_helper.rb +12 -13
  9. data/app/helpers/rails_admin/form_builder.rb +3 -3
  10. data/app/helpers/rails_admin/main_helper.rb +1 -1
  11. data/app/views/kaminari/ra-twitter-bootstrap/_gap.html.erb +2 -2
  12. data/app/views/kaminari/ra-twitter-bootstrap/_next_page.html.erb +4 -4
  13. data/app/views/kaminari/ra-twitter-bootstrap/_page.html.erb +4 -4
  14. data/app/views/kaminari/ra-twitter-bootstrap/_paginator.html.erb +12 -10
  15. data/app/views/kaminari/ra-twitter-bootstrap/_prev_page.html.erb +4 -4
  16. data/app/views/kaminari/ra-twitter-bootstrap/without_count/_next_page.html.erb +4 -4
  17. data/app/views/kaminari/ra-twitter-bootstrap/without_count/_paginator.html.erb +6 -4
  18. data/app/views/kaminari/ra-twitter-bootstrap/without_count/_prev_page.html.erb +4 -4
  19. data/app/views/layouts/rails_admin/_navigation.html.erb +12 -16
  20. data/app/views/layouts/rails_admin/_secondary_navigation.html.erb +8 -8
  21. data/app/views/layouts/rails_admin/_sidebar_navigation.html.erb +1 -5
  22. data/app/views/layouts/rails_admin/application.html.erb +4 -7
  23. data/app/views/layouts/rails_admin/{pjax.html.erb → content.html.erb} +7 -5
  24. data/app/views/layouts/rails_admin/modal.js.erb +1 -1
  25. data/app/views/rails_admin/main/_dashboard_history.html.erb +1 -1
  26. data/app/views/rails_admin/main/_delete_notice.html.erb +2 -2
  27. data/app/views/rails_admin/main/_form_boolean.html.erb +6 -8
  28. data/app/views/rails_admin/main/_form_colorpicker.html.erb +5 -1
  29. data/app/views/rails_admin/main/_form_datetime.html.erb +8 -7
  30. data/app/views/rails_admin/main/_form_enumeration.html.erb +5 -1
  31. data/app/views/rails_admin/main/_form_file_upload.html.erb +1 -1
  32. data/app/views/rails_admin/main/_form_filtering_multiselect.html.erb +14 -14
  33. data/app/views/rails_admin/main/_form_filtering_select.html.erb +16 -21
  34. data/app/views/rails_admin/main/_form_multiple_file_upload.html.erb +1 -1
  35. data/app/views/rails_admin/main/_form_nested_many.html.erb +4 -4
  36. data/app/views/rails_admin/main/_form_nested_one.html.erb +4 -4
  37. data/app/views/rails_admin/main/_form_polymorphic_association.html.erb +11 -6
  38. data/app/views/rails_admin/main/_submit_buttons.html.erb +8 -8
  39. data/app/views/rails_admin/main/bulk_delete.html.erb +1 -1
  40. data/app/views/rails_admin/main/dashboard.html.erb +4 -4
  41. data/app/views/rails_admin/main/delete.html.erb +1 -1
  42. data/app/views/rails_admin/main/edit.html.erb +1 -1
  43. data/app/views/rails_admin/main/export.html.erb +35 -32
  44. data/app/views/rails_admin/main/history.html.erb +16 -14
  45. data/app/views/rails_admin/main/index.html.erb +38 -35
  46. data/app/views/rails_admin/main/new.html.erb +1 -1
  47. data/config/locales/rails_admin.en.yml +0 -1
  48. data/lib/generators/rails_admin/install_generator.rb +0 -1
  49. data/lib/generators/rails_admin/templates/webpack.config.js +0 -3
  50. data/lib/rails_admin/adapters/active_record/object_extension.rb +1 -1
  51. data/lib/rails_admin/adapters/active_record/property.rb +1 -1
  52. data/lib/rails_admin/adapters/active_record.rb +7 -3
  53. data/lib/rails_admin/adapters/mongoid/property.rb +3 -3
  54. data/lib/rails_admin/adapters/mongoid.rb +2 -2
  55. data/lib/rails_admin/config/actions/base.rb +1 -6
  56. data/lib/rails_admin/config/actions/dashboard.rb +13 -9
  57. data/lib/rails_admin/config/actions/delete.rb +4 -0
  58. data/lib/rails_admin/config/actions/edit.rb +4 -0
  59. data/lib/rails_admin/config/actions/new.rb +5 -0
  60. data/lib/rails_admin/config/actions/show_in_app.rb +0 -4
  61. data/lib/rails_admin/config/fields/association.rb +6 -1
  62. data/lib/rails_admin/config/fields/base.rb +1 -1
  63. data/lib/rails_admin/config/fields/types/action_text.rb +1 -1
  64. data/lib/rails_admin/config/fields/types/date.rb +7 -0
  65. data/lib/rails_admin/config/fields/types/datetime.rb +9 -4
  66. data/lib/rails_admin/config/fields/types/has_many_association.rb +4 -0
  67. data/lib/rails_admin/config/fields/types/has_one_association.rb +4 -0
  68. data/lib/rails_admin/config/fields/types/time.rb +9 -0
  69. data/lib/rails_admin/config/has_fields.rb +4 -0
  70. data/lib/rails_admin/config/model.rb +8 -0
  71. data/lib/rails_admin/config/sections/list.rb +4 -4
  72. data/lib/rails_admin/config.rb +4 -1
  73. data/lib/rails_admin/engine.rb +2 -5
  74. data/lib/rails_admin/support/datetime.rb +50 -53
  75. data/lib/rails_admin/support/esmodule_preprocessor.rb +2 -1
  76. data/lib/rails_admin/version.rb +1 -1
  77. data/package.json +7 -5
  78. data/src/rails_admin/base.js +3 -6
  79. data/src/rails_admin/filter-box.js +36 -37
  80. data/src/rails_admin/filtering-select.js +3 -6
  81. data/src/rails_admin/i18n.js +0 -3
  82. data/src/rails_admin/nested-form-hooks.js +16 -8
  83. data/src/rails_admin/remote-form.js +18 -15
  84. data/src/rails_admin/styles/base/theming.scss +80 -155
  85. data/src/rails_admin/styles/base/variables.scss +2 -0
  86. data/src/rails_admin/styles/base.scss +8 -45
  87. data/src/rails_admin/styles/filtering-multiselect.scss +2 -2
  88. data/src/rails_admin/styles/filtering-select.scss +1 -1
  89. data/src/rails_admin/styles/widgets.scss +1 -10
  90. data/src/rails_admin/ui.js +4 -54
  91. data/src/rails_admin/widgets.js +38 -48
  92. data/vendor/assets/javascripts/rails_admin/bootstrap.js +5046 -0
  93. data/vendor/assets/javascripts/rails_admin/flatpickr-with-locales.js +10683 -0
  94. data/vendor/assets/javascripts/rails_admin/popper.js +1974 -0
  95. data/vendor/assets/stylesheets/rails_admin/bootstrap/_accordion.scss +118 -0
  96. data/vendor/assets/stylesheets/rails_admin/bootstrap/_alert.scss +57 -0
  97. data/vendor/assets/stylesheets/rails_admin/bootstrap/_badge.scss +29 -0
  98. data/vendor/assets/stylesheets/rails_admin/bootstrap/_breadcrumb.scss +28 -0
  99. data/vendor/assets/stylesheets/rails_admin/bootstrap/_button-group.scss +139 -0
  100. data/vendor/assets/stylesheets/rails_admin/bootstrap/_buttons.scss +64 -110
  101. data/vendor/assets/stylesheets/rails_admin/bootstrap/_card.scss +216 -0
  102. data/vendor/assets/stylesheets/rails_admin/bootstrap/_carousel.scss +162 -176
  103. data/vendor/assets/stylesheets/rails_admin/bootstrap/_close.scss +31 -26
  104. data/vendor/assets/stylesheets/rails_admin/bootstrap/_containers.scss +41 -0
  105. data/vendor/assets/stylesheets/rails_admin/bootstrap/_dropdown.scss +240 -0
  106. data/vendor/assets/stylesheets/rails_admin/bootstrap/_forms.scss +9 -538
  107. data/vendor/assets/stylesheets/rails_admin/bootstrap/_functions.scss +302 -0
  108. data/vendor/assets/stylesheets/rails_admin/bootstrap/_grid.scss +18 -69
  109. data/vendor/assets/stylesheets/rails_admin/bootstrap/_helpers.scss +9 -0
  110. data/vendor/assets/stylesheets/rails_admin/bootstrap/_images.scss +42 -0
  111. data/vendor/assets/stylesheets/rails_admin/bootstrap/_list-group.scss +127 -84
  112. data/vendor/assets/stylesheets/rails_admin/bootstrap/_mixins.scss +26 -22
  113. data/vendor/assets/stylesheets/rails_admin/bootstrap/_modal.scss +209 -0
  114. data/vendor/assets/stylesheets/rails_admin/bootstrap/_nav.scss +139 -0
  115. data/vendor/assets/stylesheets/rails_admin/bootstrap/_navbar.scss +218 -542
  116. data/vendor/assets/stylesheets/rails_admin/bootstrap/_offcanvas.scss +83 -0
  117. data/vendor/assets/stylesheets/rails_admin/bootstrap/_pagination.scss +46 -70
  118. data/vendor/assets/stylesheets/rails_admin/bootstrap/_placeholders.scss +51 -0
  119. data/vendor/assets/stylesheets/rails_admin/bootstrap/_popover.scss +158 -0
  120. data/vendor/assets/stylesheets/rails_admin/bootstrap/_progress.scss +48 -0
  121. data/vendor/assets/stylesheets/rails_admin/bootstrap/_reboot.scss +625 -0
  122. data/vendor/assets/stylesheets/rails_admin/bootstrap/_root.scss +54 -0
  123. data/vendor/assets/stylesheets/rails_admin/bootstrap/_spinners.scss +69 -0
  124. data/vendor/assets/stylesheets/rails_admin/bootstrap/_tables.scss +100 -178
  125. data/vendor/assets/stylesheets/rails_admin/bootstrap/_toasts.scss +51 -0
  126. data/vendor/assets/stylesheets/rails_admin/bootstrap/_tooltip.scss +97 -77
  127. data/vendor/assets/stylesheets/rails_admin/bootstrap/_transitions.scss +27 -0
  128. data/vendor/assets/stylesheets/rails_admin/bootstrap/_type.scss +54 -254
  129. data/vendor/assets/stylesheets/rails_admin/bootstrap/_utilities.scss +628 -55
  130. data/vendor/assets/stylesheets/rails_admin/bootstrap/_variables.scss +1572 -781
  131. data/vendor/assets/stylesheets/rails_admin/bootstrap/bootstrap.scss +38 -35
  132. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_floating-labels.scss +63 -0
  133. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-check.scss +152 -0
  134. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-control.scss +219 -0
  135. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-range.scss +91 -0
  136. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-select.scss +72 -0
  137. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-text.scss +11 -0
  138. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_input-group.scss +121 -0
  139. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_labels.scss +36 -0
  140. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_validation.scss +12 -0
  141. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_clearfix.scss +3 -0
  142. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_colored-links.scss +12 -0
  143. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_position.scss +30 -0
  144. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_ratio.scss +26 -0
  145. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_stacks.scss +15 -0
  146. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_stretched-link.scss +15 -0
  147. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_text-truncation.scss +7 -0
  148. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_visually-hidden.scss +8 -0
  149. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_vr.scss +8 -0
  150. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_alert.scss +11 -0
  151. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_backdrop.scss +14 -0
  152. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_border-radius.scss +72 -12
  153. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_box-shadow.scss +18 -0
  154. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_breakpoints.scss +127 -0
  155. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_buttons.scss +113 -30
  156. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_caret.scss +64 -0
  157. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_clearfix.scss +5 -18
  158. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_color-scheme.scss +7 -0
  159. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_container.scss +9 -0
  160. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_deprecate.scss +10 -0
  161. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_forms.scss +130 -70
  162. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_gradients.scss +27 -38
  163. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_grid.scss +127 -98
  164. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_image.scss +6 -24
  165. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_list-group.scss +13 -20
  166. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_lists.scss +7 -0
  167. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_pagination.scss +24 -16
  168. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_reset-text.scss +17 -0
  169. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_resize.scss +1 -1
  170. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_table-variants.scss +21 -0
  171. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/{_text-overflow.scss → _text-truncate.scss} +2 -2
  172. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_transition.scss +26 -0
  173. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_utilities.scss +89 -0
  174. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_visually-hidden.scss +29 -0
  175. data/vendor/assets/stylesheets/rails_admin/bootstrap/utilities/_api.scss +47 -0
  176. data/vendor/assets/stylesheets/rails_admin/bootstrap/vendor/_rfs.scss +354 -0
  177. data/vendor/assets/stylesheets/rails_admin/flatpickr.css +791 -0
  178. metadata +80 -91
  179. data/app/assets/stylesheets/rails_admin.scss.erb +0 -76
  180. data/lib/generators/rails_admin/templates/environment.js +0 -6
  181. data/src/rails_admin/styles/themes/cerulean/mixins.scss +0 -0
  182. data/src/rails_admin/styles/themes/cerulean/theming.scss +0 -135
  183. data/src/rails_admin/styles/themes/cerulean/variables.scss +0 -830
  184. data/src/rails_admin/styles/themes/default/mixins.scss +0 -8
  185. data/src/rails_admin/styles/themes/default/theming.scss +0 -11
  186. data/src/rails_admin/styles/themes/default/variables.scss +0 -12
  187. data/src/rails_admin/vendor/jquery.pjax.js +0 -899
  188. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-affix.js +0 -164
  189. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-alert.js +0 -95
  190. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-button.js +0 -125
  191. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-carousel.js +0 -246
  192. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-collapse.js +0 -212
  193. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-dropdown.js +0 -165
  194. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-modal.js +0 -358
  195. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-popover.js +0 -123
  196. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-scrollspy.js +0 -172
  197. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-tab.js +0 -155
  198. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-tooltip.js +0 -677
  199. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-transition.js +0 -59
  200. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-typeahead.js +0 -1782
  201. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap.js +0 -13
  202. data/vendor/assets/javascripts/rails_admin/bootstrap-datetimepicker.js +0 -2611
  203. data/vendor/assets/javascripts/rails_admin/jquery.pjax.js +0 -898
  204. data/vendor/assets/javascripts/rails_admin/moment-with-locales.js +0 -18085
  205. data/vendor/assets/stylesheets/rails_admin/_bootstrap-datetimepicker.scss +0 -343
  206. data/vendor/assets/stylesheets/rails_admin/bootstrap/_alerts.scss +0 -68
  207. data/vendor/assets/stylesheets/rails_admin/bootstrap/_badges.scss +0 -57
  208. data/vendor/assets/stylesheets/rails_admin/bootstrap/_breadcrumbs.scss +0 -26
  209. data/vendor/assets/stylesheets/rails_admin/bootstrap/_button-groups.scss +0 -240
  210. data/vendor/assets/stylesheets/rails_admin/bootstrap/_code.scss +0 -68
  211. data/vendor/assets/stylesheets/rails_admin/bootstrap/_component-animations.scss +0 -35
  212. data/vendor/assets/stylesheets/rails_admin/bootstrap/_dropdowns.scss +0 -215
  213. data/vendor/assets/stylesheets/rails_admin/bootstrap/_glyphicons.scss +0 -237
  214. data/vendor/assets/stylesheets/rails_admin/bootstrap/_input-groups.scss +0 -166
  215. data/vendor/assets/stylesheets/rails_admin/bootstrap/_jumbotron.scss +0 -48
  216. data/vendor/assets/stylesheets/rails_admin/bootstrap/_labels.scss +0 -66
  217. data/vendor/assets/stylesheets/rails_admin/bootstrap/_media.scss +0 -56
  218. data/vendor/assets/stylesheets/rails_admin/bootstrap/_modals.scss +0 -150
  219. data/vendor/assets/stylesheets/rails_admin/bootstrap/_navs.scss +0 -242
  220. data/vendor/assets/stylesheets/rails_admin/bootstrap/_normalize.scss +0 -425
  221. data/vendor/assets/stylesheets/rails_admin/bootstrap/_pager.scss +0 -55
  222. data/vendor/assets/stylesheets/rails_admin/bootstrap/_panels.scss +0 -243
  223. data/vendor/assets/stylesheets/rails_admin/bootstrap/_popovers.scss +0 -133
  224. data/vendor/assets/stylesheets/rails_admin/bootstrap/_print.scss +0 -101
  225. data/vendor/assets/stylesheets/rails_admin/bootstrap/_progress-bars.scss +0 -105
  226. data/vendor/assets/stylesheets/rails_admin/bootstrap/_responsive-embed.scss +0 -34
  227. data/vendor/assets/stylesheets/rails_admin/bootstrap/_responsive-utilities.scss +0 -174
  228. data/vendor/assets/stylesheets/rails_admin/bootstrap/_scaffolding.scss +0 -150
  229. data/vendor/assets/stylesheets/rails_admin/bootstrap/_theme.scss +0 -258
  230. data/vendor/assets/stylesheets/rails_admin/bootstrap/_thumbnails.scss +0 -38
  231. data/vendor/assets/stylesheets/rails_admin/bootstrap/_wells.scss +0 -29
  232. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_alerts.scss +0 -14
  233. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_background-variant.scss +0 -11
  234. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_center-block.scss +0 -7
  235. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_grid-framework.scss +0 -81
  236. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_hide-text.scss +0 -21
  237. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_labels.scss +0 -12
  238. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_nav-divider.scss +0 -10
  239. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_nav-vertical-align.scss +0 -9
  240. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_opacity.scss +0 -8
  241. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_panels.scss +0 -24
  242. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_progress-bar.scss +0 -10
  243. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_reset-filter.scss +0 -8
  244. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_responsive-visibility.scss +0 -21
  245. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_size.scss +0 -10
  246. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_tab-focus.scss +0 -9
  247. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_table-row.scss +0 -28
  248. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_text-emphasis.scss +0 -11
  249. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_vendor-prefixes.scss +0 -219
  250. data/vendor/assets/stylesheets/rails_admin/bootstrap-datetimepicker-build.scss +0 -16
@@ -1,898 +0,0 @@
1
- /*!
2
- * Copyright 2012, Chris Wanstrath
3
- * Released under the MIT License
4
- * https://github.com/defunkt/jquery-pjax
5
- */
6
-
7
- (function($){
8
-
9
- // When called on a container with a selector, fetches the href with
10
- // ajax into the container or with the data-pjax attribute on the link
11
- // itself.
12
- //
13
- // Tries to make sure the back button and ctrl+click work the way
14
- // you'd expect.
15
- //
16
- // Exported as $.fn.pjax
17
- //
18
- // Accepts a jQuery ajax options object that may include these
19
- // pjax specific options:
20
- //
21
- //
22
- // container - String selector for the element where to place the response body.
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
- options = optionsFor(container, options)
32
- return this.on('click.pjax', selector, function(event) {
33
- var opts = options
34
- if (!opts.container) {
35
- opts = $.extend({}, options)
36
- opts.container = $(this).attr('data-pjax')
37
- }
38
- handleClick(event, opts)
39
- })
40
- }
41
-
42
- // Public: pjax on click handler
43
- //
44
- // Exported as $.pjax.click.
45
- //
46
- // event - "click" jQuery.Event
47
- // options - pjax options
48
- //
49
- // Examples
50
- //
51
- // $(document).on('click', 'a', $.pjax.click)
52
- // // is the same as
53
- // $(document).pjax('a')
54
- //
55
- // Returns nothing.
56
- function handleClick(event, container, options) {
57
- options = optionsFor(container, options)
58
-
59
- var link = event.currentTarget
60
- var $link = $(link)
61
-
62
- if (link.tagName.toUpperCase() !== 'A')
63
- throw "$.fn.pjax or $.pjax.click requires an anchor element"
64
-
65
- // Middle click, cmd click, and ctrl click should open
66
- // links in a new tab as normal.
67
- if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
68
- return
69
-
70
- // Ignore cross origin links
71
- if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
72
- return
73
-
74
- // Ignore case when a hash is being tacked on the current URL
75
- if ( link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location) )
76
- return
77
-
78
- // Ignore event with default prevented
79
- if (event.isDefaultPrevented())
80
- return
81
-
82
- var defaults = {
83
- url: link.href,
84
- container: $link.attr('data-pjax'),
85
- target: link
86
- }
87
-
88
- var opts = $.extend({}, defaults, options)
89
- var clickEvent = $.Event('pjax:click')
90
- $link.trigger(clickEvent, [opts])
91
-
92
- if (!clickEvent.isDefaultPrevented()) {
93
- pjax(opts)
94
- event.preventDefault()
95
- $link.trigger('pjax:clicked', [opts])
96
- }
97
- }
98
-
99
- // Public: pjax on form submit handler
100
- //
101
- // Exported as $.pjax.submit
102
- //
103
- // event - "click" jQuery.Event
104
- // options - pjax options
105
- //
106
- // Examples
107
- //
108
- // $(document).on('submit', 'form', function(event) {
109
- // $.pjax.submit(event, '[data-pjax-container]')
110
- // })
111
- //
112
- // Returns nothing.
113
- function handleSubmit(event, container, options) {
114
- options = optionsFor(container, options)
115
-
116
- var form = event.currentTarget
117
- var $form = $(form)
118
-
119
- if (form.tagName.toUpperCase() !== 'FORM')
120
- throw "$.pjax.submit requires a form element"
121
-
122
- var defaults = {
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()
141
- }
142
-
143
- pjax($.extend({}, defaults, options))
144
-
145
- event.preventDefault()
146
- }
147
-
148
- // Loads a URL with ajax, puts the response body inside a container,
149
- // then pushState()'s the loaded URL.
150
- //
151
- // Works just like $.ajax in that it accepts a jQuery ajax
152
- // settings object (with keys like url, type, data, etc).
153
- //
154
- // Accepts these extra keys:
155
- //
156
- // container - String selector for where to stick the response body.
157
- // push - Whether to pushState the URL. Defaults to true (of course).
158
- // replace - Want to use replaceState instead? That's cool.
159
- //
160
- // Use it just like $.ajax:
161
- //
162
- // var xhr = $.pjax({ url: this.href, container: '#main' })
163
- // console.log( xhr.readyState )
164
- //
165
- // Returns whatever $.ajax returns.
166
- function pjax(options) {
167
- options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)
168
-
169
- if ($.isFunction(options.url)) {
170
- options.url = options.url()
171
- }
172
-
173
- var hash = parseURL(options.url).hash
174
-
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
- }
183
-
184
- // We want the browser to maintain two separate internal caches: one
185
- // for pjax'd partial page loads and one for normal page loads.
186
- // Without adding this secret parameter, some browsers will often
187
- // confuse the two.
188
- if (!options.data) options.data = {}
189
- if ($.isArray(options.data)) {
190
- options.data.push({name: '_pjax', value: options.container})
191
- } else {
192
- options.data._pjax = options.container
193
- }
194
-
195
- function fire(type, args, props) {
196
- if (!props) props = {}
197
- props.relatedTarget = options.target
198
- var event = $.Event(type, props)
199
- context.trigger(event, args)
200
- return !event.isDefaultPrevented()
201
- }
202
-
203
- var timeoutTimer
204
-
205
- options.beforeSend = function(xhr, settings) {
206
- // No timeout for non-GET requests
207
- // Its not safe to request the resource again with a fallback method.
208
- if (settings.type !== 'GET') {
209
- settings.timeout = 0
210
- }
211
-
212
- xhr.setRequestHeader('X-PJAX', 'true')
213
- xhr.setRequestHeader('X-PJAX-Container', options.container)
214
-
215
- if (!fire('pjax:beforeSend', [xhr, settings]))
216
- return false
217
-
218
- if (settings.timeout > 0) {
219
- timeoutTimer = setTimeout(function() {
220
- if (fire('pjax:timeout', [xhr, options]))
221
- xhr.abort('timeout')
222
- }, settings.timeout)
223
-
224
- // Clear timeout setting so jquerys internal timeout isn't invoked
225
- settings.timeout = 0
226
- }
227
-
228
- var url = parseURL(settings.url)
229
- if (hash) url.hash = hash
230
- options.requestUrl = stripInternalParams(url)
231
- }
232
-
233
- options.complete = function(xhr, textStatus) {
234
- if (timeoutTimer)
235
- clearTimeout(timeoutTimer)
236
-
237
- fire('pjax:complete', [xhr, textStatus, options])
238
-
239
- fire('pjax:end', [xhr, options])
240
- }
241
-
242
- options.error = function(xhr, textStatus, errorThrown) {
243
- var container = extractContainer("", xhr, options)
244
-
245
- var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
246
- if (options.type == 'GET' && textStatus !== 'abort' && allowed) {
247
- locationReplace(container.url)
248
- }
249
- }
250
-
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
-
262
- var container = extractContainer(data, xhr, options)
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
277
- if (!container.contents) {
278
- locationReplace(container.url)
279
- return
280
- }
281
-
282
- pjax.state = {
283
- id: options.id || uniqueId(),
284
- url: container.url,
285
- title: container.title,
286
- container: options.container,
287
- fragment: options.fragment,
288
- timeout: options.timeout
289
- }
290
-
291
- if (options.push || options.replace) {
292
- window.history.replaceState(pjax.state, container.title, container.url)
293
- }
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
-
305
- if (container.title) document.title = container.title
306
-
307
- fire('pjax:beforeReplace', [container.contents, options], {
308
- state: pjax.state,
309
- previousState: previousState
310
- })
311
- context.html(container.contents)
312
-
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)
324
-
325
- var scrollTo = options.scrollTo
326
-
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
332
- }
333
-
334
- if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)
335
-
336
- fire('pjax:success', [data, status, xhr, options])
337
- }
338
-
339
-
340
- // Initialize pjax.state for the initial page load. Assume we're
341
- // using the container and options of the link we're loading for the
342
- // back button to the initial page. This ensures good back button
343
- // behavior.
344
- if (!pjax.state) {
345
- pjax.state = {
346
- id: uniqueId(),
347
- url: window.location.href,
348
- title: document.title,
349
- container: options.container,
350
- fragment: options.fragment,
351
- timeout: options.timeout
352
- }
353
- window.history.replaceState(pjax.state, document.title)
354
- }
355
-
356
- // Cancel the current request if we're already pjaxing
357
- abortXHR(pjax.xhr)
358
-
359
- pjax.options = options
360
- var xhr = pjax.xhr = $.ajax(options)
361
-
362
- if (xhr.readyState > 0) {
363
- if (options.push && !options.replace) {
364
- // Cache current container element before replacing it
365
- cachePush(pjax.state.id, [options.container, cloneContents(context)])
366
-
367
- window.history.pushState(null, "", options.requestUrl)
368
- }
369
-
370
- fire('pjax:start', [xhr, options])
371
- fire('pjax:send', [xhr, options])
372
- }
373
-
374
- return pjax.xhr
375
- }
376
-
377
- // Public: Reload current page with pjax.
378
- //
379
- // Returns whatever $.pjax returns.
380
- function pjaxReload(container, options) {
381
- var defaults = {
382
- url: window.location.href,
383
- push: false,
384
- replace: true,
385
- scrollTo: false
386
- }
387
-
388
- return pjax($.extend(defaults, optionsFor(container, options)))
389
- }
390
-
391
- // Internal: Hard replace current state with url.
392
- //
393
- // Work for around WebKit
394
- // https://bugs.webkit.org/show_bug.cgi?id=93506
395
- //
396
- // Returns nothing.
397
- function locationReplace(url) {
398
- window.history.replaceState(null, "", pjax.state.url)
399
- window.location.replace(url)
400
- }
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
-
419
- // popstate handler takes care of the back and forward buttons
420
- //
421
- // You probably shouldn't use pjax on pages with other pushState
422
- // stuff yet.
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
431
- var state = event.state
432
- var direction
433
-
434
- if (state && state.container) {
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
- }
448
-
449
- var cache = cacheMapping[state.id] || []
450
- var containerSelector = cache[0] || state.container
451
- var container = $(containerSelector), contents = cache[1]
452
-
453
- if (container.length) {
454
- if (previousState) {
455
- // Cache current container before replacement and inform the
456
- // cache which direction the history shifted.
457
- cachePop(direction, previousState.id, [containerSelector, cloneContents(container)])
458
- }
459
-
460
- var popstateEvent = $.Event('pjax:popstate', {
461
- state: state,
462
- direction: direction
463
- })
464
- container.trigger(popstateEvent)
465
-
466
- var options = {
467
- id: state.id,
468
- url: state.url,
469
- container: containerSelector,
470
- push: false,
471
- fragment: state.fragment,
472
- timeout: state.timeout,
473
- scrollTo: false
474
- }
475
-
476
- if (contents) {
477
- container.trigger('pjax:start', [null, options])
478
-
479
- pjax.state = state
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])
486
- container.html(contents)
487
-
488
- container.trigger('pjax:end', [null, options])
489
- } else {
490
- pjax(options)
491
- }
492
-
493
- // Force reflow/relayout before the browser tries to restore the
494
- // scroll position.
495
- container[0].offsetHeight
496
- } else {
497
- locationReplace(location.href)
498
- }
499
- }
500
- initialPop = false
501
- }
502
-
503
- // Fallback version of main pjax function for browsers that don't
504
- // support pushState.
505
- //
506
- // Returns nothing since it retriggers a hard form submission.
507
- function fallbackPjax(options) {
508
- var url = $.isFunction(options.url) ? options.url() : options.url,
509
- method = options.type ? options.type.toUpperCase() : 'GET'
510
-
511
- var form = $('<form>', {
512
- method: method === 'GET' ? 'GET' : 'POST',
513
- action: url,
514
- style: 'display:none'
515
- })
516
-
517
- if (method !== 'GET' && method !== 'POST') {
518
- form.append($('<input>', {
519
- type: 'hidden',
520
- name: '_method',
521
- value: method.toLowerCase()
522
- }))
523
- }
524
-
525
- var data = options.data
526
- if (typeof data === 'string') {
527
- $.each(data.split('&'), function(index, value) {
528
- var pair = value.split('=')
529
- form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
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
- })
535
- } else if (typeof data === 'object') {
536
- var key
537
- for (key in data)
538
- form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
539
- }
540
-
541
- $(document.body).append(form)
542
- form.submit()
543
- }
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
-
554
- // Internal: Generate unique id for state object.
555
- //
556
- // Use a timestamp instead of a counter since ids should still be
557
- // unique across page loads.
558
- //
559
- // Returns Number.
560
- function uniqueId() {
561
- return (new Date).getTime()
562
- }
563
-
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.
575
- //
576
- // Returns sanitized url.href String.
577
- function stripInternalParams(url) {
578
- url.search = url.search.replace(/([?&])(_pjax|_)=[^&]*/g, '')
579
- return url.href.replace(/\?($|#)/, '$1')
580
- }
581
-
582
- // Internal: Parse URL components and returns a Locationish object.
583
- //
584
- // url - String URL
585
- //
586
- // Returns HTMLAnchorElement that acts like Location.
587
- function parseURL(url) {
588
- var a = document.createElement('a')
589
- a.href = url
590
- return a
591
- }
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
-
603
- // Internal: Build options Object for arguments.
604
- //
605
- // For convenience the first parameter can be either the container or
606
- // the options object.
607
- //
608
- // Examples
609
- //
610
- // optionsFor('#container')
611
- // // => {container: '#container'}
612
- //
613
- // optionsFor('#container', {push: true})
614
- // // => {container: '#container', push: true}
615
- //
616
- // optionsFor({container: '#container', push: true})
617
- // // => {container: '#container', push: true}
618
- //
619
- // Returns options Object.
620
- function optionsFor(container, options) {
621
- if (container && options) {
622
- options = $.extend({}, options)
623
- options.container = container
624
- return options
625
- } else if ($.isPlainObject(container)) {
626
- return container
627
- } else {
628
- return {container: container}
629
- }
630
- }
631
-
632
- // Internal: Filter and find all elements matching the selector.
633
- //
634
- // Where $.fn.find only matches descendants, findAll will test all the
635
- // top level elements in the jQuery object as well.
636
- //
637
- // elems - jQuery object of Elements
638
- // selector - String selector to match
639
- //
640
- // Returns a jQuery object.
641
- function findAll(elems, selector) {
642
- return elems.filter(selector).add(elems.find(selector))
643
- }
644
-
645
- function parseHTML(html) {
646
- return $.parseHTML(html, document, true)
647
- }
648
-
649
- // Internal: Extracts container and metadata from response.
650
- //
651
- // 1. Extracts X-PJAX-URL header if set
652
- // 2. Extracts inline <title> tags
653
- // 3. Builds response Element and extracts fragment if set
654
- //
655
- // data - String response data
656
- // xhr - XHR response
657
- // options - pjax options Object
658
- //
659
- // Returns an Object with url, title, and contents keys.
660
- function extractContainer(data, xhr, options) {
661
- var obj = {}, fullDocument = /<html/i.test(data)
662
-
663
- // Prefer X-PJAX-URL header if it was set, otherwise fallback to
664
- // using the original requested url.
665
- var serverUrl = xhr.getResponseHeader('X-PJAX-URL')
666
- obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl
667
-
668
- // Attempt to parse response html into elements
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]))
672
- } else {
673
- var $head = $body = $(parseHTML(data))
674
- }
675
-
676
- // If response data is empty, return fast
677
- if ($body.length === 0)
678
- return obj
679
-
680
- // If there's a <title> tag in the header, use it as
681
- // the page's title.
682
- obj.title = findAll($head, 'title').last().text()
683
-
684
- if (options.fragment) {
685
- // If they specified a fragment, look for it in the response
686
- // and pull it out.
687
- if (options.fragment === 'body') {
688
- var $fragment = $body
689
- } else {
690
- var $fragment = findAll($body, options.fragment).first()
691
- }
692
-
693
- if ($fragment.length) {
694
- obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents()
695
-
696
- // If there's no title, look for data-title and title attributes
697
- // on the fragment
698
- if (!obj.title)
699
- obj.title = $fragment.attr('title') || $fragment.data('title')
700
- }
701
-
702
- } else if (!fullDocument) {
703
- obj.contents = $body
704
- }
705
-
706
- // Clean up any <title> tags
707
- if (obj.contents) {
708
- // Remove any parent title elements
709
- obj.contents = obj.contents.not(function() { return $(this).is('title') })
710
-
711
- // Then scrub any titles from their descendants
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)
717
- }
718
-
719
- // Trim any whitespace off the title
720
- if (obj.title) obj.title = $.trim(obj.title)
721
-
722
- return obj
723
- }
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
-
753
- // Internal: History DOM caching class.
754
- var cacheMapping = {}
755
- var cacheForwardStack = []
756
- var cacheBackStack = []
757
-
758
- // Push previous state id and container contents into the history
759
- // cache. Should be called in conjunction with `pushState` to save the
760
- // previous container contents.
761
- //
762
- // id - State ID Number
763
- // value - DOM Element to cache
764
- //
765
- // Returns nothing.
766
- function cachePush(id, value) {
767
- cacheMapping[id] = value
768
- cacheBackStack.push(id)
769
-
770
- // Remove all entries in forward history stack after pushing a new page.
771
- trimCacheStack(cacheForwardStack, 0)
772
-
773
- // Trim back history stack to max cache length.
774
- trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength)
775
- }
776
-
777
- // Shifts cache from directional history cache. Should be
778
- // called on `popstate` with the previous state id and container
779
- // contents.
780
- //
781
- // direction - "forward" or "back" String
782
- // id - State ID Number
783
- // value - DOM Element to cache
784
- //
785
- // Returns nothing.
786
- function cachePop(direction, id, value) {
787
- var pushStack, popStack
788
- cacheMapping[id] = value
789
-
790
- if (direction === 'forward') {
791
- pushStack = cacheBackStack
792
- popStack = cacheForwardStack
793
- } else {
794
- pushStack = cacheForwardStack
795
- popStack = cacheBackStack
796
- }
797
-
798
- pushStack.push(id)
799
- if (id = popStack.pop())
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')
826
- }
827
-
828
- // Install pjax functions on $.pjax to enable pushState behavior.
829
- //
830
- // Does nothing if already enabled.
831
- //
832
- // Examples
833
- //
834
- // $.pjax.enable()
835
- //
836
- // Returns nothing.
837
- function enable() {
838
- $.fn.pjax = fnPjax
839
- $.pjax = pjax
840
- $.pjax.enable = $.noop
841
- $.pjax.disable = disable
842
- $.pjax.click = handleClick
843
- $.pjax.submit = handleSubmit
844
- $.pjax.reload = pjaxReload
845
- $.pjax.defaults = {
846
- timeout: 650,
847
- push: true,
848
- replace: false,
849
- type: 'GET',
850
- dataType: 'html',
851
- scrollTo: 0,
852
- maxCacheLength: 20,
853
- version: findVersion
854
- }
855
- $(window).on('popstate.pjax', onPjaxPopstate)
856
- }
857
-
858
- // Disable pushState behavior.
859
- //
860
- // This is the case when a browser doesn't support pushState. It is
861
- // sometimes useful to disable pushState for debugging on a modern
862
- // browser.
863
- //
864
- // Examples
865
- //
866
- // $.pjax.disable()
867
- //
868
- // Returns nothing.
869
- function disable() {
870
- $.fn.pjax = function() { return this }
871
- $.pjax = fallbackPjax
872
- $.pjax.enable = enable
873
- $.pjax.disable = $.noop
874
- $.pjax.click = $.noop
875
- $.pjax.submit = $.noop
876
- $.pjax.reload = function() { window.location.reload() }
877
-
878
- $(window).off('popstate.pjax', onPjaxPopstate)
879
- }
880
-
881
-
882
- // Add the state property to jQuery's event object so we can use it in
883
- // $(window).bind('popstate')
884
- if ($.event.props && $.inArray('state', $.event.props) < 0) {
885
- $.event.props.push('state')
886
- } else if (!('state' in $.Event.prototype)) {
887
- $.event.addProp('state')
888
- }
889
-
890
- // Is pjax supported by this browser?
891
- $.support.pjax =
892
- window.history && window.history.pushState && window.history.replaceState &&
893
- // pushState isn't reliable on iOS until 5.
894
- !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)
895
-
896
- $.support.pjax ? enable() : disable()
897
-
898
- })(jQuery)