obitum-rails_admin 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. data/Gemfile +1 -8
  2. data/README.md +6 -2
  3. data/app/assets/javascripts/rails_admin/custom/ui.js +5 -5
  4. data/app/assets/javascripts/rails_admin/jquery-ui-1.8.16.custom.js +4727 -4727
  5. data/app/assets/javascripts/rails_admin/jquery.colorpicker.js +484 -484
  6. data/app/assets/javascripts/rails_admin/jquery.pjax.js +250 -85
  7. data/app/assets/javascripts/rails_admin/jquery.ui.timepicker.js +1371 -1219
  8. data/app/assets/javascripts/rails_admin/ra.filter-box.js +30 -30
  9. data/app/assets/javascripts/rails_admin/ra.filtering-select.js +11 -11
  10. data/app/assets/javascripts/rails_admin/ra.nested-form-hooks.coffee +40 -0
  11. data/app/assets/javascripts/rails_admin/ra.remote-form.js +41 -39
  12. data/app/assets/javascripts/rails_admin/rails_admin.js.erb +4 -3
  13. data/app/assets/javascripts/rails_admin/themes/default/ui.js +6 -6
  14. data/app/assets/javascripts/rails_admin/ui.js.coffee +44 -16
  15. data/app/assets/stylesheets/rails_admin/base/README +2 -2
  16. data/app/assets/stylesheets/rails_admin/base/theming.css.scss +226 -113
  17. data/app/assets/stylesheets/rails_admin/custom/mixins.css.scss +1 -1
  18. data/app/assets/stylesheets/rails_admin/custom/theming.css.scss +2 -2
  19. data/app/assets/stylesheets/rails_admin/custom/variables.css.scss +3 -3
  20. data/app/assets/stylesheets/rails_admin/imports.css.scss.erb +36 -1
  21. data/app/assets/stylesheets/rails_admin/jquery.ui.timepicker.css.scss +16 -0
  22. data/app/assets/stylesheets/rails_admin/ra.filtering-multiselect.css.scss +2 -2
  23. data/app/assets/stylesheets/rails_admin/themes/default/mixins.css.scss +1 -1
  24. data/app/assets/stylesheets/rails_admin/themes/default/theming.css.scss +2 -2
  25. data/app/assets/stylesheets/rails_admin/themes/default/variables.css.scss +3 -3
  26. data/app/controllers/rails_admin/application_controller.rb +13 -18
  27. data/app/controllers/rails_admin/main_controller.rb +15 -16
  28. data/app/helpers/rails_admin/application_helper.rb +67 -41
  29. data/app/helpers/rails_admin/form_builder.rb +31 -29
  30. data/app/helpers/rails_admin/main_helper.rb +4 -4
  31. data/app/views/layouts/rails_admin/_secondary_navigation.html.haml +12 -11
  32. data/app/views/layouts/rails_admin/application.html.haml +29 -29
  33. data/app/views/rails_admin/main/_dashboard_history.html.haml +1 -1
  34. data/app/views/rails_admin/main/_delete_notice.html.haml +4 -5
  35. data/app/views/rails_admin/main/_form_colorpicker.html.haml +2 -1
  36. data/app/views/rails_admin/main/_form_datetime.html.haml +1 -1
  37. data/app/views/rails_admin/main/_form_enumeration.html.haml +1 -1
  38. data/app/views/rails_admin/main/_form_field.html.haml +1 -1
  39. data/app/views/rails_admin/main/_form_file_upload.html.haml +3 -2
  40. data/app/views/rails_admin/main/_form_filtering_multiselect.html.haml +6 -4
  41. data/app/views/rails_admin/main/_form_filtering_select.html.haml +6 -5
  42. data/app/views/rails_admin/main/_form_nested_many.html.haml +41 -6
  43. data/app/views/rails_admin/main/_form_nested_one.html.haml +34 -5
  44. data/app/views/rails_admin/main/_form_text.html.haml +3 -3
  45. data/app/views/rails_admin/main/_submit_buttons.html.haml +6 -4
  46. data/app/views/rails_admin/main/bulk_delete.html.haml +7 -3
  47. data/app/views/rails_admin/main/dashboard.html.haml +4 -4
  48. data/app/views/rails_admin/main/delete.html.haml +7 -3
  49. data/app/views/rails_admin/main/edit.html.haml +1 -1
  50. data/app/views/rails_admin/main/export.html.haml +57 -53
  51. data/app/views/rails_admin/main/history.html.haml +8 -8
  52. data/app/views/rails_admin/main/index.html.haml +22 -21
  53. data/app/views/rails_admin/main/new.html.haml +1 -1
  54. data/app/views/rails_admin/main/show.html.haml +2 -2
  55. data/config/initializers/active_record_extensions.rb +2 -2
  56. data/config/initializers/haml.rb +0 -1
  57. data/config/locales/rails_admin.en.yml +5 -5
  58. data/lib/generators/rails_admin/templates/initializer.erb +7 -7
  59. data/lib/rails_admin/abstract_model.rb +36 -53
  60. data/lib/rails_admin/adapters/active_record/abstract_object.rb +32 -0
  61. data/lib/rails_admin/adapters/active_record.rb +56 -137
  62. data/lib/rails_admin/config/actions/base.rb +40 -28
  63. data/lib/rails_admin/config/actions/bulk_delete.rb +10 -11
  64. data/lib/rails_admin/config/actions/dashboard.rb +9 -5
  65. data/lib/rails_admin/config/actions/delete.rb +12 -9
  66. data/lib/rails_admin/config/actions/edit.rb +13 -9
  67. data/lib/rails_admin/config/actions/export.rb +9 -6
  68. data/lib/rails_admin/config/actions/history_index.rb +9 -5
  69. data/lib/rails_admin/config/actions/history_show.rb +9 -5
  70. data/lib/rails_admin/config/actions/index.rb +23 -13
  71. data/lib/rails_admin/config/actions/new.rb +14 -10
  72. data/lib/rails_admin/config/actions/show.rb +10 -5
  73. data/lib/rails_admin/config/actions/show_in_app.rb +9 -4
  74. data/lib/rails_admin/config/actions.rb +16 -16
  75. data/lib/rails_admin/config/configurable.rb +92 -0
  76. data/lib/rails_admin/config/fields/association.rb +6 -23
  77. data/lib/rails_admin/config/fields/base.rb +58 -40
  78. data/lib/rails_admin/config/fields/factories/belongs_to_association.rb +26 -0
  79. data/lib/rails_admin/config/fields/factories/carrierwave.rb +21 -2
  80. data/lib/rails_admin/config/fields/factories/devise.rb +9 -12
  81. data/lib/rails_admin/config/fields/factories/dragonfly.rb +13 -7
  82. data/lib/rails_admin/config/fields/factories/paperclip.rb +14 -15
  83. data/lib/rails_admin/config/fields/group.rb +16 -3
  84. data/lib/rails_admin/config/fields/types/belongs_to_association.rb +2 -2
  85. data/lib/rails_admin/config/fields/types/carrierwave.rb +0 -9
  86. data/lib/rails_admin/config/fields/types/color.rb +3 -3
  87. data/lib/rails_admin/config/fields/types/dragonfly.rb +1 -19
  88. data/lib/rails_admin/config/fields/types/file_upload.rb +7 -11
  89. data/lib/rails_admin/config/fields/types/has_many_association.rb +1 -6
  90. data/lib/rails_admin/config/fields/types/has_one_association.rb +4 -4
  91. data/lib/rails_admin/config/fields/types/paperclip.rb +0 -18
  92. data/lib/rails_admin/config/fields/types/password.rb +2 -2
  93. data/lib/rails_admin/config/fields/types/polymorphic_association.rb +2 -2
  94. data/lib/rails_admin/config/fields/types/text.rb +2 -2
  95. data/lib/rails_admin/config/fields.rb +7 -17
  96. data/lib/rails_admin/config/has_fields.rb +9 -9
  97. data/lib/rails_admin/config/has_groups.rb +2 -2
  98. data/lib/rails_admin/config/hideable.rb +2 -2
  99. data/lib/rails_admin/config/model.rb +23 -17
  100. data/lib/rails_admin/config/proxyable/proxy.rb +43 -0
  101. data/lib/rails_admin/config/proxyable.rb +12 -0
  102. data/lib/rails_admin/config/sections/base.rb +14 -4
  103. data/lib/rails_admin/config.rb +38 -9
  104. data/lib/rails_admin/extension.rb +1 -1
  105. data/lib/rails_admin/extensions/history/auditing_adapter.rb +6 -6
  106. data/lib/rails_admin/extensions/history/history.rb +2 -1
  107. data/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb +13 -13
  108. data/lib/rails_admin/support/csv_converter.rb +6 -6
  109. data/lib/rails_admin/version.rb +1 -1
  110. data/lib/rails_admin.rb +0 -5
  111. data/spec/controllers/main_controller_spec.rb +7 -7
  112. data/spec/dummy_app/Gemfile +10 -7
  113. data/spec/dummy_app/Rakefile +1 -1
  114. data/spec/dummy_app/app/assets/images/rails.png +0 -0
  115. data/spec/dummy_app/app/assets/javascripts/application.js +15 -0
  116. data/spec/dummy_app/app/assets/stylesheets/application.css +13 -0
  117. data/spec/dummy_app/app/controllers/players_controller.rb +1 -1
  118. data/spec/dummy_app/app/models/cms/basic_page.rb +1 -1
  119. data/spec/dummy_app/app/models/division.rb +5 -1
  120. data/spec/dummy_app/app/models/field_test.rb +4 -4
  121. data/spec/dummy_app/app/models/nested_field_test.rb +3 -0
  122. data/spec/dummy_app/app/models/player.rb +3 -3
  123. data/spec/dummy_app/app/views/layouts/application.html.erb +3 -2
  124. data/spec/dummy_app/app/views/players/show.html.haml +1 -1
  125. data/spec/dummy_app/config/application.rb +20 -5
  126. data/spec/dummy_app/config/database.yml +5 -2
  127. data/spec/dummy_app/config/environments/development.rb +11 -1
  128. data/spec/dummy_app/config/environments/production.rb +19 -3
  129. data/spec/dummy_app/config/environments/test.rb +5 -7
  130. data/spec/dummy_app/config/initializers/devise.rb +6 -0
  131. data/spec/dummy_app/config/initializers/inflections.rb +5 -0
  132. data/spec/dummy_app/config/initializers/secret_token.rb +1 -1
  133. data/spec/dummy_app/{foo/test/dummy/config → config}/initializers/wrap_parameters.rb +1 -1
  134. data/spec/dummy_app/config/routes.rb +1 -1
  135. data/spec/dummy_app/db/migrate/00000000000006_devise_create_users.rb +35 -5
  136. data/spec/dummy_app/db/migrate/20120118122004_add_categories.rb +1 -1
  137. data/spec/dummy_app/doc/README_FOR_APP +2 -0
  138. data/spec/dummy_app/public/404.html +26 -0
  139. data/spec/dummy_app/{foo/test/dummy/public → public}/422.html +0 -0
  140. data/spec/dummy_app/{foo/test/dummy/public → public}/500.html +0 -1
  141. data/spec/dummy_app/public/favicon.ico +0 -0
  142. data/spec/dummy_app/public/robots.txt +5 -0
  143. data/spec/helpers/application_helper_spec.rb +107 -42
  144. data/spec/{requests → integration}/authorization/cancan_spec.rb +4 -5
  145. data/spec/{requests → integration}/basic/bulk_action/rails_admin_basic_bulk_action_spec.rb +0 -0
  146. data/spec/{requests → integration}/basic/bulk_destroy/rails_admin_basic_bulk_destroy_spec.rb +3 -16
  147. data/spec/{requests → integration}/basic/create/rails_admin_basic_create_spec.rb +0 -2
  148. data/spec/{requests → integration}/basic/create/rails_admin_namespaced_model_create_spec.rb +0 -16
  149. data/spec/{requests → integration}/basic/delete/rails_admin_basic_delete_spec.rb +0 -0
  150. data/spec/{requests → integration}/basic/destroy/rails_admin_basic_destroy_spec.rb +0 -0
  151. data/spec/{requests → integration}/basic/edit/rails_admin_basic_edit_spec.rb +2 -2
  152. data/spec/{requests → integration}/basic/export/rails_admin_basic_export_spec.rb +1 -1
  153. data/spec/{requests → integration}/basic/list/rails_admin_basic_list_spec.rb +12 -38
  154. data/spec/{requests → integration}/basic/new/rails_admin_basic_new_spec.rb +0 -0
  155. data/spec/{requests → integration}/basic/new/rails_admin_namespaced_model_new_spec.rb +0 -0
  156. data/spec/{requests → integration}/basic/show/rails_admin_basic_show_spec.rb +1 -2
  157. data/spec/{requests → integration}/basic/update/rails_admin_basic_update_spec.rb +2 -2
  158. data/spec/{requests → integration}/config/edit/rails_admin_config_edit_spec.rb +65 -24
  159. data/spec/{requests → integration}/config/list/rails_admin_config_list_spec.rb +2 -2
  160. data/spec/{requests → integration}/config/show/rails_admin_config_show_spec.rb +20 -0
  161. data/spec/{requests → integration}/history/rails_admin_history_spec.rb +3 -3
  162. data/spec/{requests → integration}/rails_admin_spec.rb +8 -41
  163. data/spec/{requests → integration}/relation_spec.rb +0 -0
  164. data/spec/spec_helper.rb +13 -31
  165. data/spec/{lib → unit/adapters/active_record}/abstract_object_spec.rb +17 -5
  166. data/spec/unit/adapters/active_record_spec.rb +53 -0
  167. data/spec/{requests/actions.rb → unit/config/actions_spec.rb} +47 -31
  168. data/spec/unit/config/fields/base_spec.rb +291 -0
  169. data/spec/unit/config/model_spec.rb +75 -0
  170. data/spec/unit/config/sections_spec.rb +123 -0
  171. data/spec/{lib/rails_admin_spec.rb → unit/config_spec.rb} +65 -93
  172. metadata +127 -223
  173. data/app/assets/javascripts/rails_admin/jquery_nested_form.js +0 -58
  174. data/app/views/layouts/rails_admin/_navigation.html.haml +0 -17
  175. data/lib/rails_admin/abstract_object.rb +0 -28
  176. data/lib/rails_admin/config/base.rb +0 -111
  177. data/lib/rails_admin/config/proxy.rb +0 -40
  178. data/lib/rails_admin/generic_support.rb +0 -18
  179. data/spec/dummy_app/config/initializers/quiet_assets.rb +0 -10
  180. data/spec/dummy_app/foo/Gemfile +0 -17
  181. data/spec/dummy_app/foo/MIT-LICENSE +0 -20
  182. data/spec/dummy_app/foo/README.rdoc +0 -3
  183. data/spec/dummy_app/foo/Rakefile +0 -39
  184. data/spec/dummy_app/foo/app/assets/javascripts/foo/application.js +0 -9
  185. data/spec/dummy_app/foo/app/assets/stylesheets/foo/application.css +0 -7
  186. data/spec/dummy_app/foo/app/controllers/foo/application_controller.rb +0 -4
  187. data/spec/dummy_app/foo/app/helpers/foo/application_helper.rb +0 -4
  188. data/spec/dummy_app/foo/app/models/foo/bar.rb +0 -4
  189. data/spec/dummy_app/foo/app/views/layouts/foo/application.html.erb +0 -14
  190. data/spec/dummy_app/foo/config/routes.rb +0 -2
  191. data/spec/dummy_app/foo/foo.gemspec +0 -23
  192. data/spec/dummy_app/foo/lib/foo/engine.rb +0 -5
  193. data/spec/dummy_app/foo/lib/foo/version.rb +0 -3
  194. data/spec/dummy_app/foo/lib/foo.rb +0 -4
  195. data/spec/dummy_app/foo/lib/tasks/foo_tasks.rake +0 -4
  196. data/spec/dummy_app/foo/script/rails +0 -6
  197. data/spec/dummy_app/foo/test/dummy/Rakefile +0 -7
  198. data/spec/dummy_app/foo/test/dummy/app/assets/javascripts/application.js +0 -9
  199. data/spec/dummy_app/foo/test/dummy/app/assets/stylesheets/application.css +0 -7
  200. data/spec/dummy_app/foo/test/dummy/app/controllers/application_controller.rb +0 -3
  201. data/spec/dummy_app/foo/test/dummy/app/helpers/application_helper.rb +0 -2
  202. data/spec/dummy_app/foo/test/dummy/app/views/layouts/application.html.erb +0 -14
  203. data/spec/dummy_app/foo/test/dummy/config/application.rb +0 -45
  204. data/spec/dummy_app/foo/test/dummy/config/boot.rb +0 -10
  205. data/spec/dummy_app/foo/test/dummy/config/database.yml +0 -25
  206. data/spec/dummy_app/foo/test/dummy/config/environment.rb +0 -5
  207. data/spec/dummy_app/foo/test/dummy/config/environments/development.rb +0 -30
  208. data/spec/dummy_app/foo/test/dummy/config/environments/production.rb +0 -60
  209. data/spec/dummy_app/foo/test/dummy/config/environments/test.rb +0 -39
  210. data/spec/dummy_app/foo/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  211. data/spec/dummy_app/foo/test/dummy/config/initializers/inflections.rb +0 -10
  212. data/spec/dummy_app/foo/test/dummy/config/initializers/mime_types.rb +0 -5
  213. data/spec/dummy_app/foo/test/dummy/config/initializers/secret_token.rb +0 -7
  214. data/spec/dummy_app/foo/test/dummy/config/initializers/session_store.rb +0 -8
  215. data/spec/dummy_app/foo/test/dummy/config/locales/en.yml +0 -5
  216. data/spec/dummy_app/foo/test/dummy/config/routes.rb +0 -4
  217. data/spec/dummy_app/foo/test/dummy/config.ru +0 -4
  218. data/spec/dummy_app/foo/test/dummy/db/schema.rb +0 -21
  219. data/spec/dummy_app/foo/test/dummy/public/404.html +0 -26
  220. data/spec/dummy_app/foo/test/dummy/public/favicon.ico +0 -0
  221. data/spec/dummy_app/foo/test/dummy/script/rails +0 -6
  222. data/spec/dummy_app/foo/test/fixtures/foo/bars.yml +0 -11
  223. data/spec/dummy_app/foo/test/foo_test.rb +0 -7
  224. data/spec/dummy_app/foo/test/integration/navigation_test.rb +0 -10
  225. data/spec/dummy_app/foo/test/test_helper.rb +0 -10
  226. data/spec/dummy_app/foo/test/unit/foo/bar_test.rb +0 -9
  227. data/spec/generator_helpers.rb +0 -30
  228. data/spec/generators/install_generator_spec.rb +0 -85
  229. data/spec/generators/uninstall_generator_spec.rb +0 -35
  230. data/spec/lib/custom_field.rb +0 -7
  231. data/spec/requests/config/navigation/rails_admin_config_navigation_spec.rb +0 -107
  232. data/spec/requests/config/rails_admin_config_spec.rb +0 -227
@@ -24,35 +24,61 @@
24
24
  //
25
25
  // Returns the jQuery object
26
26
  $.fn.pjax = function( container, options ) {
27
- if ( options )
28
- options.container = container
29
- else
30
- options = $.isPlainObject(container) ? container : {container:container}
27
+ options = optionsFor(container, options)
28
+ return this.live('click', function(event){
29
+ return handleClick(event, options)
30
+ })
31
+ }
31
32
 
32
- // We can't persist $objects using the history API so we must use
33
- // a String selector. Bail if we got anything else.
34
- if ( options.container && typeof options.container !== 'string' ) {
35
- throw "pjax container must be a string selector!"
36
- return false
33
+ // Public: pjax on click handler
34
+ //
35
+ // Exported as $.pjax.click.
36
+ //
37
+ // event - "click" jQuery.Event
38
+ // options - pjax options
39
+ //
40
+ // Examples
41
+ //
42
+ // $('a').live('click', $.pjax.click)
43
+ // // is the same as
44
+ // $('a').pjax()
45
+ //
46
+ // $(document).on('click', 'a', function(event) {
47
+ // var container = $(this).closest('[data-pjax-container]')
48
+ // return $.pjax.click(event, container)
49
+ // })
50
+ //
51
+ // Returns false if pjax runs, otherwise nothing.
52
+ function handleClick(event, container, options) {
53
+ options = optionsFor(container, options)
54
+
55
+ var link = event.currentTarget
56
+
57
+ // Middle click, cmd click, and ctrl click should open
58
+ // links in a new tab as normal.
59
+ if ( event.which > 1 || event.metaKey )
60
+ return
61
+
62
+ // Ignore cross origin links
63
+ if ( location.protocol !== link.protocol || location.host !== link.host )
64
+ return
65
+
66
+ // Ignore anchors on the same page
67
+ if ( link.hash && link.href.replace(link.hash, '') ===
68
+ location.href.replace(location.hash, '') )
69
+ return
70
+
71
+ var defaults = {
72
+ url: link.href,
73
+ container: $(link).attr('data-pjax'),
74
+ clickedElement: $(link),
75
+ fragment: null
37
76
  }
38
77
 
39
- return this.live('click', function(event){
40
- // Middle click, cmd click, and ctrl click should open
41
- // links in a new tab as normal.
42
- if ( event.which > 1 || event.metaKey )
43
- return true
44
-
45
- var defaults = {
46
- url: (this.href || $(this).attr('data-href')),
47
- container: $(this).attr('data-pjax'),
48
- clickedElement: $(this),
49
- fragment: null
50
- }
51
-
52
- $.pjax($.extend({}, defaults, options))
78
+ $.pjax($.extend({}, defaults, options))
53
79
 
54
- event.preventDefault()
55
- })
80
+ event.preventDefault()
81
+ return false
56
82
  }
57
83
 
58
84
 
@@ -64,7 +90,7 @@ $.fn.pjax = function( container, options ) {
64
90
  //
65
91
  // Accepts these extra keys:
66
92
  //
67
- // container - Where to stick the response body. Must be a String.
93
+ // container - Where to stick the response body.
68
94
  // $(container).html(xhr.responseBody)
69
95
  // push - Whether to pushState the URL. Defaults to true (of course).
70
96
  // replace - Want to use replaceState instead? That's cool.
@@ -76,56 +102,116 @@ $.fn.pjax = function( container, options ) {
76
102
  //
77
103
  // Returns whatever $.ajax returns.
78
104
  var pjax = $.pjax = function( options ) {
79
- var $container = $(options.container),
80
- success = options.success || $.noop
105
+ options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)
106
+
107
+ if ( $.isFunction(options.url) ) {
108
+ options.url = options.url()
109
+ }
81
110
 
82
- // We don't want to let anyone override our success handler.
83
- delete options.success
111
+ // DEPRECATED: Save references to original event callbacks. However,
112
+ // listening for custom pjax:* events is prefered.
113
+ var oldBeforeSend = options.beforeSend,
114
+ oldComplete = options.complete,
115
+ oldSuccess = options.success,
116
+ oldError = options.error
84
117
 
85
- // We can't persist $objects using the history API so we must use
86
- // a String selector. Bail if we got anything else.
87
- if ( typeof options.container !== 'string' )
88
- throw "pjax container must be a string selector!"
118
+ options.context = findContainerFor(options.container)
89
119
 
90
- options = $.extend(true, {}, pjax.defaults, options)
120
+ var timeoutTimer
91
121
 
92
- if ( $.isFunction(options.url) ) {
93
- options.url = options.url()
122
+ options.beforeSend = function(xhr, settings) {
123
+ var context = this
124
+
125
+ if (settings.timeout > 0) {
126
+ timeoutTimer = setTimeout(function() {
127
+ var event = $.Event('pjax:timeout')
128
+ context.trigger(event, [xhr, options])
129
+ if (event.result !== false)
130
+ xhr.abort('timeout')
131
+ }, settings.timeout)
132
+
133
+ // Clear timeout setting so jquerys internal timeout isn't invoked
134
+ settings.timeout = 0
135
+ }
136
+
137
+ xhr.setRequestHeader('X-PJAX', 'true')
138
+
139
+ var result
140
+
141
+ // DEPRECATED: Invoke original `beforeSend` handler
142
+ if (oldBeforeSend) {
143
+ result = oldBeforeSend.apply(this, arguments)
144
+ if (result === false) return false
145
+ }
146
+
147
+ var event = $.Event('pjax:beforeSend')
148
+ this.trigger(event, [xhr, settings])
149
+ result = event.result
150
+ if (result === false) return false
151
+
152
+ this.trigger('pjax:start', [xhr, options])
153
+ // start.pjax is deprecated
154
+ this.trigger('start.pjax', [xhr, options])
94
155
  }
95
156
 
96
- options.context = $container
97
- options.success = function(data){
157
+ options.complete = function(xhr, textStatus) {
158
+ if (timeoutTimer)
159
+ clearTimeout(timeoutTimer)
160
+
161
+ // DEPRECATED: Invoke original `complete` handler
162
+ if (oldComplete) oldComplete.apply(this, arguments)
163
+
164
+ this.trigger('pjax:complete', [xhr, textStatus, options])
165
+
166
+ this.trigger('pjax:end', [xhr, options])
167
+ // end.pjax is deprecated
168
+ this.trigger('end.pjax', [xhr, options])
169
+ }
170
+
171
+ options.error = function(xhr, textStatus, errorThrown) {
172
+ // DEPRECATED: Invoke original `error` handler
173
+ if (oldError) oldError.apply(this, arguments)
174
+
175
+ var event = $.Event('pjax:error')
176
+ this.trigger(event, [xhr, textStatus, errorThrown, options])
177
+ if (textStatus !== 'abort' && event.result !== false)
178
+ window.location = options.url
179
+ }
180
+
181
+ options.success = function(data, status, xhr) {
182
+ var title, oldTitle = document.title
183
+
98
184
  if ( options.fragment ) {
99
185
  // If they specified a fragment, look for it in the response
100
186
  // and pull it out.
101
- var $fragment = $(data).find(options.fragment)
102
- if ( $fragment.length )
103
- data = $fragment.children()
104
- else
187
+ var html = $('<html>').html(data)
188
+ var $fragment = html.find(options.fragment)
189
+ if ( $fragment.length ) {
190
+ this.html($fragment.contents())
191
+
192
+ // If there's a <title> tag in the response, use it as
193
+ // the page's title. Otherwise, look for data-title and title attributes.
194
+ title = html.find('title').text() || $fragment.attr('title') || $fragment.data('title')
195
+ } else {
105
196
  return window.location = options.url
197
+ }
106
198
  } else {
107
- // If we got no data or an entire web page, go directly
108
- // to the page and let normal error handling happen.
109
- if ( !$.trim(data) || /<html/i.test(data) )
110
- return window.location = options.url
111
- }
112
-
113
- // Make it happen.
114
- this.html(data)
199
+ // If we got no data or an entire web page, go directly
200
+ // to the page and let normal error handling happen.
201
+ if ( !$.trim(data) || /<html/i.test(data) )
202
+ return window.location = options.url
115
203
 
116
- // If there's a <title> tag in the response, use it as
117
- // the page's title.
118
- var oldTitle = document.title,
119
- title = $.trim( this.find('title').remove().text() )
120
- if ( title ) document.title = title
204
+ this.html(data)
121
205
 
122
- // No <title>? Fragment? Look for data-title and title attributes.
123
- if ( !title && options.fragment ) {
124
- title = $fragment.attr('title') || $fragment.data('title')
206
+ // If there's a <title> tag in the response, use it as
207
+ // the page's title.
208
+ title = this.find('title').remove().text()
125
209
  }
126
210
 
211
+ if ( title ) document.title = $.trim(title)
212
+
127
213
  var state = {
128
- pjax: options.container,
214
+ pjax: this.selector,
129
215
  fragment: options.fragment,
130
216
  timeout: options.timeout
131
217
  }
@@ -136,6 +222,7 @@ var pjax = $.pjax = function( options ) {
136
222
  state.url = options.url + (/\?/.test(options.url) ? "&" : "?") + query
137
223
 
138
224
  if ( options.replace ) {
225
+ pjax.active = true
139
226
  window.history.replaceState(state, document.title, options.url)
140
227
  } else if ( options.push ) {
141
228
  // this extra replaceState before first push ensures good back
@@ -159,10 +246,13 @@ var pjax = $.pjax = function( options ) {
159
246
  window.location.href = hash
160
247
  }
161
248
 
162
- // Invoke their success handler if they gave us one.
163
- success.apply(this, arguments)
249
+ // DEPRECATED: Invoke original `success` handler
250
+ if (oldSuccess) oldSuccess.apply(this, arguments)
251
+
252
+ this.trigger('pjax:success', [data, status, xhr, options])
164
253
  }
165
254
 
255
+
166
256
  // Cancel the current request if we're already pjaxing
167
257
  var xhr = pjax.xhr
168
258
  if ( xhr && xhr.readyState < 4) {
@@ -178,8 +268,68 @@ var pjax = $.pjax = function( options ) {
178
268
  }
179
269
 
180
270
 
271
+ // Internal: Build options Object for arguments.
272
+ //
273
+ // For convenience the first parameter can be either the container or
274
+ // the options object.
275
+ //
276
+ // Examples
277
+ //
278
+ // optionsFor('#container')
279
+ // // => {container: '#container'}
280
+ //
281
+ // optionsFor('#container', {push: true})
282
+ // // => {container: '#container', push: true}
283
+ //
284
+ // optionsFor({container: '#container', push: true})
285
+ // // => {container: '#container', push: true}
286
+ //
287
+ // Returns options Object.
288
+ function optionsFor(container, options) {
289
+ // Both container and options
290
+ if ( container && options )
291
+ options.container = container
292
+
293
+ // First argument is options Object
294
+ else if ( $.isPlainObject(container) )
295
+ options = container
296
+
297
+ // Only container
298
+ else
299
+ options = {container: container}
300
+
301
+ // Find and validate container
302
+ if (options.container)
303
+ options.container = findContainerFor(options.container)
304
+
305
+ return options
306
+ }
307
+
308
+ // Internal: Find container element for a variety of inputs.
309
+ //
310
+ // Because we can't persist elements using the history API, we must be
311
+ // able to find a String selector that will consistently find the Element.
312
+ //
313
+ // container - A selector String, jQuery object, or DOM Element.
314
+ //
315
+ // Returns a jQuery object whose context is `document` and has a selector.
316
+ function findContainerFor(container) {
317
+ container = $(container)
318
+
319
+ if ( !container.length ) {
320
+ throw "no pjax container for " + container.selector
321
+ } else if ( container.selector !== '' && container.context === document ) {
322
+ return container
323
+ } else if ( container.attr('id') ) {
324
+ return $('#' + container.attr('id'))
325
+ } else {
326
+ throw "cant get selector for pjax container!"
327
+ }
328
+ }
329
+
330
+
181
331
  pjax.defaults = {
182
- timeout: 4000,
332
+ timeout: 650,
183
333
  push: true,
184
334
  replace: false,
185
335
  // We want the browser to maintain two separate internal caches: one for
@@ -187,27 +337,12 @@ pjax.defaults = {
187
337
  // adding this secret parameter, some browsers will often confuse the two.
188
338
  data: { _pjax: true },
189
339
  type: 'GET',
190
- dataType: 'html',
191
- beforeSend: function(xhr){
192
- this.trigger('pjax:start', [xhr, pjax.options])
193
- // start.pjax is deprecated
194
- this.trigger('start.pjax', [xhr, pjax.options])
195
- xhr.setRequestHeader('X-PJAX', 'true')
196
- },
197
- error: function(xhr, textStatus, errorThrown){
198
- if ( textStatus !== 'abort' ) {
199
- // console.log(xhr, textStatus, errorThrown)
200
- window.location = pjax.options.url
201
- }
202
-
203
- },
204
- complete: function(xhr){
205
- this.trigger('pjax:end', [xhr, pjax.options])
206
- // end.pjax is deprecated
207
- this.trigger('end.pjax', [xhr, pjax.options])
208
- }
340
+ dataType: 'html'
209
341
  }
210
342
 
343
+ // Export $.pjax.click
344
+ pjax.click = handleClick
345
+
211
346
 
212
347
  // Used to detect initial (useless) popstate.
213
348
  // If history.state exists, assume browser isn't going to fire initial popstate.
@@ -251,15 +386,45 @@ if ( $.inArray('state', $.event.props) < 0 )
251
386
  // Is pjax supported by this browser?
252
387
  $.support.pjax =
253
388
  window.history && window.history.pushState && window.history.replaceState
254
- // pushState isn't reliable on iOS yet.
255
- && !navigator.userAgent.match(/(iPod|iPhone|iPad|WebApps\/.+CFNetwork)/)
389
+ // pushState isn't reliable on iOS until 5.
390
+ && !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/)
256
391
 
257
392
 
258
393
  // Fall back to normalcy for older browsers.
259
394
  if ( !$.support.pjax ) {
260
395
  $.pjax = function( options ) {
261
- window.location = $.isFunction(options.url) ? options.url() : options.url
396
+ var url = $.isFunction(options.url) ? options.url() : options.url,
397
+ method = options.type ? options.type.toUpperCase() : 'GET'
398
+
399
+ var form = $('<form>', {
400
+ method: method === 'GET' ? 'GET' : 'POST',
401
+ action: url,
402
+ style: 'display:none'
403
+ })
404
+
405
+ if (method !== 'GET' && method !== 'POST') {
406
+ form.append($('<input>', {
407
+ type: 'hidden',
408
+ name: '_method',
409
+ value: method.toLowerCase()
410
+ }))
411
+ }
412
+
413
+ var data = options.data
414
+ if (typeof data === 'string') {
415
+ $.each(data.split('&'), function(index, value) {
416
+ var pair = value.split('=')
417
+ form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
418
+ })
419
+ } else if (typeof data === 'object') {
420
+ for (key in data)
421
+ form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
422
+ }
423
+
424
+ $(document.body).append(form)
425
+ form.submit()
262
426
  }
427
+ $.pjax.click = $.noop
263
428
  $.fn.pjax = function() { return this }
264
429
  }
265
430