good_job 4.13.0 → 4.13.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -0
  3. data/app/controllers/good_job/batches_controller.rb +1 -1
  4. data/app/controllers/good_job/cron_entries_controller.rb +3 -3
  5. data/app/controllers/good_job/frontends_controller.rb +15 -10
  6. data/app/controllers/good_job/jobs_controller.rb +7 -7
  7. data/app/controllers/good_job/pauses_controller.rb +2 -2
  8. data/app/frontend/good_job/application.js +23 -9
  9. data/app/frontend/good_job/modules/form_controller.js +11 -0
  10. data/app/frontend/good_job/vendor/turbo.js +34 -0
  11. data/app/models/good_job/batch.rb +8 -2
  12. data/app/models/good_job/batch_record.rb +35 -11
  13. data/app/models/good_job/job.rb +61 -29
  14. data/app/models/good_job/process.rb +2 -0
  15. data/app/models/good_job/setting.rb +2 -0
  16. data/app/views/good_job/batches/_jobs.erb +4 -4
  17. data/app/views/good_job/batches/_table.erb +2 -2
  18. data/app/views/good_job/batches/show.html.erb +1 -1
  19. data/app/views/good_job/cron_entries/index.html.erb +2 -2
  20. data/app/views/good_job/jobs/_table.erb +12 -9
  21. data/app/views/good_job/jobs/show.html.erb +4 -4
  22. data/app/views/good_job/pauses/_group.html.erb +1 -1
  23. data/app/views/good_job/pauses/_pause.html.erb +1 -1
  24. data/app/views/good_job/shared/_filter.erb +4 -14
  25. data/app/views/good_job/shared/_navbar.erb +6 -6
  26. data/app/views/layouts/good_job/application.html.erb +10 -6
  27. data/config/brakeman.ignore +25 -25
  28. data/lib/generators/good_job/templates/install/migrations/create_good_jobs.rb.erb +1 -1
  29. data/lib/generators/good_job/templates/update/migrations/05_add_index_good_jobs_finished_at_for_cleanup.rb.erb +17 -0
  30. data/lib/generators/good_job/templates/update/migrations/06_remove_extraneous_finished_at_index.rb.erb +17 -0
  31. data/lib/good_job/version.rb +1 -1
  32. data/lib/good_job.rb +5 -1
  33. metadata +6 -4
  34. data/app/frontend/good_job/modules/document_ready.js +0 -7
  35. data/app/frontend/good_job/vendor/rails_ujs.js +0 -7
@@ -85,7 +85,7 @@ class CreateGoodJobs < ActiveRecord::Migration<%= migration_version %>
85
85
  add_index :good_jobs, [:concurrency_key, :created_at], name: :index_good_jobs_on_concurrency_key_and_created_at
86
86
  add_index :good_jobs, [:cron_key, :created_at], where: "(cron_key IS NOT NULL)", name: :index_good_jobs_on_cron_key_and_created_at_cond
87
87
  add_index :good_jobs, [:cron_key, :cron_at], where: "(cron_key IS NOT NULL)", unique: true, name: :index_good_jobs_on_cron_key_and_cron_at_cond
88
- add_index :good_jobs, [:finished_at], where: "retried_good_job_id IS NULL AND finished_at IS NOT NULL", name: :index_good_jobs_jobs_on_finished_at
88
+ add_index :good_jobs, [:finished_at], where: "finished_at IS NOT NULL", name: :index_good_jobs_jobs_on_finished_at_only
89
89
  add_index :good_jobs, [:priority, :created_at], order: { priority: "DESC NULLS LAST", created_at: :asc },
90
90
  where: "finished_at IS NULL", name: :index_good_jobs_jobs_on_priority_created_at_when_unfinished
91
91
  add_index :good_jobs, [:priority, :created_at], order: { priority: "ASC NULLS LAST", created_at: :asc },
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddIndexGoodJobsFinishedAtForCleanup < ActiveRecord::Migration<%= migration_version %>
4
+ disable_ddl_transaction!
5
+
6
+ def change
7
+ reversible do |dir|
8
+ dir.up do
9
+ # Ensure this incremental update migration is idempotent
10
+ # with monolithic install migration.
11
+ return if connection.index_exists? :good_jobs, [:finished_at], name: :index_good_jobs_jobs_on_finished_at_only
12
+ end
13
+ end
14
+
15
+ add_index :good_jobs, [:finished_at], where: "finished_at IS NOT NULL", name: :index_good_jobs_jobs_on_finished_at_only, algorithm: :concurrently
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RemoveExtraneousFinishedAtIndex < ActiveRecord::Migration<%= migration_version %>
4
+ disable_ddl_transaction!
5
+
6
+ def change
7
+ reversible do |dir|
8
+ dir.up do
9
+ # Ensure this incremental update migration is idempotent
10
+ # with monolithic install migration.
11
+ return unless connection.index_exists? :good_jobs, [:finished_at], name: :index_good_jobs_jobs_on_finished_at
12
+ end
13
+ end
14
+
15
+ remove_index :good_jobs, [:finished_at], where: "retried_good_job_id IS NULL AND finished_at IS NOT NULL", name: :index_good_jobs_jobs_on_finished_at, algorithm: :concurrently
16
+ end
17
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GoodJob
4
4
  # GoodJob gem version.
5
- VERSION = '4.13.0'
5
+ VERSION = '4.13.2'
6
6
 
7
7
  # GoodJob version as Gem::Version object
8
8
  GEM_VERSION = Gem::Version.new(VERSION)
data/lib/good_job.rb CHANGED
@@ -217,6 +217,8 @@ module GoodJob
217
217
  jobs_query = GoodJob::Job.finished_before(timestamp).order(finished_at: :asc).limit(in_batches_of)
218
218
  jobs_query = jobs_query.succeeded unless include_discarded
219
219
  loop do
220
+ break if GoodJob.current_thread_shutting_down?
221
+
220
222
  active_job_ids = jobs_query.pluck(:active_job_id)
221
223
  break if active_job_ids.empty?
222
224
 
@@ -230,6 +232,8 @@ module GoodJob
230
232
  batches_query = GoodJob::BatchRecord.finished_before(timestamp).limit(in_batches_of)
231
233
  batches_query = batches_query.succeeded unless include_discarded
232
234
  loop do
235
+ break if GoodJob.current_thread_shutting_down?
236
+
233
237
  deleted = batches_query.delete_all
234
238
  break if deleted.zero?
235
239
 
@@ -290,7 +294,7 @@ module GoodJob
290
294
  # For use in tests/CI to validate GoodJob is up-to-date.
291
295
  # @return [Boolean]
292
296
  def self.migrated?
293
- GoodJob::Job.job_class_index_migrated?
297
+ GoodJob::Job.historic_finished_at_index_migrated?
294
298
  end
295
299
 
296
300
  # Pause job execution for a given queue or job class.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: good_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.13.0
4
+ version: 4.13.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Sheldon
@@ -269,7 +269,7 @@ files:
269
269
  - app/frontend/good_job/modules/async_values_controller.js
270
270
  - app/frontend/good_job/modules/charts.js
271
271
  - app/frontend/good_job/modules/checkbox_toggle.js
272
- - app/frontend/good_job/modules/document_ready.js
272
+ - app/frontend/good_job/modules/form_controller.js
273
273
  - app/frontend/good_job/modules/html_legend_plugin.js
274
274
  - app/frontend/good_job/modules/live_poll.js
275
275
  - app/frontend/good_job/modules/popovers.js
@@ -280,8 +280,8 @@ files:
280
280
  - app/frontend/good_job/vendor/bootstrap/bootstrap.min.css
281
281
  - app/frontend/good_job/vendor/chartjs/chart.min.js
282
282
  - app/frontend/good_job/vendor/es_module_shims.js
283
- - app/frontend/good_job/vendor/rails_ujs.js
284
283
  - app/frontend/good_job/vendor/stimulus.js
284
+ - app/frontend/good_job/vendor/turbo.js
285
285
  - app/helpers/good_job/application_helper.rb
286
286
  - app/helpers/good_job/icons_helper.rb
287
287
  - app/models/concerns/good_job/advisory_lockable.rb
@@ -352,6 +352,8 @@ files:
352
352
  - lib/generators/good_job/templates/update/migrations/02_add_jobs_finished_at_to_good_job_batches.rb.erb
353
353
  - lib/generators/good_job/templates/update/migrations/03_add_index_good_jobs_concurrency_key_created_at.rb.erb
354
354
  - lib/generators/good_job/templates/update/migrations/04_add_index_good_jobs_job_class.rb.erb
355
+ - lib/generators/good_job/templates/update/migrations/05_add_index_good_jobs_finished_at_for_cleanup.rb.erb
356
+ - lib/generators/good_job/templates/update/migrations/06_remove_extraneous_finished_at_index.rb.erb
355
357
  - lib/generators/good_job/update_generator.rb
356
358
  - lib/good_job.rb
357
359
  - lib/good_job/active_job_extensions/batches.rb
@@ -424,7 +426,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
424
426
  - !ruby/object:Gem::Version
425
427
  version: '0'
426
428
  requirements: []
427
- rubygems_version: 3.6.9
429
+ rubygems_version: 4.0.2
428
430
  specification_version: 4
429
431
  summary: A multithreaded, Postgres-based ActiveJob backend for Ruby on Rails
430
432
  test_files: []
@@ -1,7 +0,0 @@
1
- export default function documentReady(callback) {
2
- if (document.readyState !== "loading") {
3
- callback();
4
- } else {
5
- document.addEventListener("DOMContentLoaded", callback);
6
- }
7
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * Minified by jsDelivr using Terser v5.15.1.
3
- * Original file: /npm/@rails/ujs@7.0.4-2/lib/assets/compiled/rails-ujs.js
4
- *
5
- * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
6
- */
7
- (function(){(function(){(function(){this.Rails={linkClickSelector:"a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]",buttonClickSelector:{selector:"button[data-remote]:not([form]), button[data-confirm]:not([form])",exclude:"form button"},inputChangeSelector:"select[data-remote], input[data-remote], textarea[data-remote]",formSubmitSelector:"form:not([data-turbo=true])",formInputClickSelector:"form:not([data-turbo=true]) input[type=submit], form:not([data-turbo=true]) input[type=image], form:not([data-turbo=true]) button[type=submit], form:not([data-turbo=true]) button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])",formDisableSelector:"input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled",formEnableSelector:"input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled",fileInputSelector:"input[name][type=file]:not([disabled])",linkDisableSelector:"a[data-disable-with], a[data-disable]",buttonDisableSelector:"button[data-remote][data-disable-with], button[data-remote][data-disable]"}}).call(this)}).call(this);var t=this.Rails;(function(){(function(){var e;e=null,t.loadCSPNonce=function(){var t;return e=null!=(t=document.querySelector("meta[name=csp-nonce]"))?t.content:void 0},t.cspNonce=function(){return null!=e?e:t.loadCSPNonce()}}).call(this),function(){var e;e=Element.prototype.matches||Element.prototype.matchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector||Element.prototype.webkitMatchesSelector,t.matches=function(t,n){return null!=n.exclude?e.call(t,n.selector)&&!e.call(t,n.exclude):e.call(t,n)},t.getData=function(t,e){var n;return null!=(n=t._ujsData)?n[e]:void 0},t.setData=function(t,e,n){return null==t._ujsData&&(t._ujsData={}),t._ujsData[e]=n},t.$=function(t){return Array.prototype.slice.call(document.querySelectorAll(t))}}.call(this),function(){var e,n,a;e=t.$,a=t.csrfToken=function(){var t;return(t=document.querySelector("meta[name=csrf-token]"))&&t.content},n=t.csrfParam=function(){var t;return(t=document.querySelector("meta[name=csrf-param]"))&&t.content},t.CSRFProtection=function(t){var e;if(null!=(e=a()))return t.setRequestHeader("X-CSRF-Token",e)},t.refreshCSRFTokens=function(){var t,r;if(r=a(),t=n(),null!=r&&null!=t)return e('form input[name="'+t+'"]').forEach((function(t){return t.value=r}))}}.call(this),function(){var e,n,a,r;a=t.matches,"function"!=typeof(e=window.CustomEvent)&&((e=function(t,e){var n;return(n=document.createEvent("CustomEvent")).initCustomEvent(t,e.bubbles,e.cancelable,e.detail),n}).prototype=window.Event.prototype,r=e.prototype.preventDefault,e.prototype.preventDefault=function(){var t;return t=r.call(this),this.cancelable&&!this.defaultPrevented&&Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}}),t}),n=t.fire=function(t,n,a){var r;return r=new e(n,{bubbles:!0,cancelable:!0,detail:a}),t.dispatchEvent(r),!r.defaultPrevented},t.stopEverything=function(t){return n(t.target,"ujs:everythingStopped"),t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation()},t.delegate=function(t,e,n,r){return t.addEventListener(n,(function(t){var n;for(n=t.target;n instanceof Element&&!a(n,e);)n=n.parentNode;if(n instanceof Element&&!1===r.call(n,t))return t.preventDefault(),t.stopPropagation()}))}}.call(this),function(){var e,n,a,r,o,i;r=t.cspNonce,n=t.CSRFProtection,t.fire,e={"*":"*/*",text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript",script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},t.ajax=function(t){var e;return t=o(t),e=a(t,(function(){var n,a;return a=i(null!=(n=e.response)?n:e.responseText,e.getResponseHeader("Content-Type")),2===Math.floor(e.status/100)?"function"==typeof t.success&&t.success(a,e.statusText,e):"function"==typeof t.error&&t.error(a,e.statusText,e),"function"==typeof t.complete?t.complete(e,e.statusText):void 0})),!(null!=t.beforeSend&&!t.beforeSend(e,t))&&(e.readyState===XMLHttpRequest.OPENED?e.send(t.data):void 0)},o=function(t){return t.url=t.url||location.href,t.type=t.type.toUpperCase(),"GET"===t.type&&t.data&&(t.url.indexOf("?")<0?t.url+="?"+t.data:t.url+="&"+t.data),null==e[t.dataType]&&(t.dataType="*"),t.accept=e[t.dataType],"*"!==t.dataType&&(t.accept+=", */*; q=0.01"),t},a=function(t,e){var a;return(a=new XMLHttpRequest).open(t.type,t.url,!0),a.setRequestHeader("Accept",t.accept),"string"==typeof t.data&&a.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),t.crossDomain||(a.setRequestHeader("X-Requested-With","XMLHttpRequest"),n(a)),a.withCredentials=!!t.withCredentials,a.onreadystatechange=function(){if(a.readyState===XMLHttpRequest.DONE)return e(a)},a},i=function(t,e){var n,a;if("string"==typeof t&&"string"==typeof e)if(e.match(/\bjson\b/))try{t=JSON.parse(t)}catch(t){}else if(e.match(/\b(?:java|ecma)script\b/))(a=document.createElement("script")).setAttribute("nonce",r()),a.text=t,document.head.appendChild(a).parentNode.removeChild(a);else if(e.match(/\b(xml|html|svg)\b/)){n=new DOMParser,e=e.replace(/;.+/,"");try{t=n.parseFromString(t,e)}catch(t){}}return t},t.href=function(t){return t.href},t.isCrossDomain=function(t){var e,n;(e=document.createElement("a")).href=location.href,n=document.createElement("a");try{return n.href=t,!((!n.protocol||":"===n.protocol)&&!n.host||e.protocol+"//"+e.host==n.protocol+"//"+n.host)}catch(t){return t,!0}}}.call(this),function(){var e,n;e=t.matches,n=function(t){return Array.prototype.slice.call(t)},t.serializeElement=function(t,a){var r,o;return r=[t],e(t,"form")&&(r=n(t.elements)),o=[],r.forEach((function(t){if(t.name&&!t.disabled&&!e(t,"fieldset[disabled] *"))return e(t,"select")?n(t.options).forEach((function(e){if(e.selected)return o.push({name:t.name,value:e.value})})):t.checked||-1===["radio","checkbox","submit"].indexOf(t.type)?o.push({name:t.name,value:t.value}):void 0})),a&&o.push(a),o.map((function(t){return null!=t.name?encodeURIComponent(t.name)+"="+encodeURIComponent(t.value):t})).join("&")},t.formElements=function(t,a){return e(t,"form")?n(t.elements).filter((function(t){return e(t,a)})):n(t.querySelectorAll(a))}}.call(this),function(){var e,n,a;n=t.fire,a=t.stopEverything,t.handleConfirm=function(t){if(!e(this))return a(t)},t.confirm=function(t,e){return confirm(t)},e=function(e){var a,r,o;if(!(o=e.getAttribute("data-confirm")))return!0;if(a=!1,n(e,"confirm")){try{a=t.confirm(o,e)}catch(t){}r=n(e,"confirm:complete",[a])}return a&&r}}.call(this),function(){var e,n,a,r,o,i,l,u,c,s,d,m;s=t.matches,u=t.getData,d=t.setData,m=t.stopEverything,l=t.formElements,t.handleDisabledElement=function(t){if(this,this.disabled)return m(t)},t.enableElement=function(e){var n;if(e instanceof Event){if(c(e))return;n=e.target}else n=e;return s(n,t.linkDisableSelector)?i(n):s(n,t.buttonDisableSelector)||s(n,t.formEnableSelector)?r(n):s(n,t.formSubmitSelector)?o(n):void 0},t.disableElement=function(r){var o;return o=r instanceof Event?r.target:r,s(o,t.linkDisableSelector)?a(o):s(o,t.buttonDisableSelector)||s(o,t.formDisableSelector)?e(o):s(o,t.formSubmitSelector)?n(o):void 0},a=function(t){var e;if(!u(t,"ujs:disabled"))return null!=(e=t.getAttribute("data-disable-with"))&&(d(t,"ujs:enable-with",t.innerHTML),t.innerHTML=e),t.addEventListener("click",m),d(t,"ujs:disabled",!0)},i=function(t){var e;return null!=(e=u(t,"ujs:enable-with"))&&(t.innerHTML=e,d(t,"ujs:enable-with",null)),t.removeEventListener("click",m),d(t,"ujs:disabled",null)},n=function(n){return l(n,t.formDisableSelector).forEach(e)},e=function(t){var e;if(!u(t,"ujs:disabled"))return null!=(e=t.getAttribute("data-disable-with"))&&(s(t,"button")?(d(t,"ujs:enable-with",t.innerHTML),t.innerHTML=e):(d(t,"ujs:enable-with",t.value),t.value=e)),t.disabled=!0,d(t,"ujs:disabled",!0)},o=function(e){return l(e,t.formEnableSelector).forEach(r)},r=function(t){var e;return null!=(e=u(t,"ujs:enable-with"))&&(s(t,"button")?t.innerHTML=e:t.value=e,d(t,"ujs:enable-with",null)),t.disabled=!1,d(t,"ujs:disabled",null)},c=function(t){var e,n;return null!=(null!=(n=null!=(e=t.detail)?e[0]:void 0)?n.getResponseHeader("X-Xhr-Redirect"):void 0)}}.call(this),function(){var e;e=t.stopEverything,t.handleMethod=function(n){var a,r,o,i,l,u,c;if(c=(u=this).getAttribute("data-method"))return l=t.href(u),r=t.csrfToken(),a=t.csrfParam(),o=document.createElement("form"),i="<input name='_method' value='"+c+"' type='hidden' />",null==a||null==r||t.isCrossDomain(l)||(i+="<input name='"+a+"' value='"+r+"' type='hidden' />"),i+='<input type="submit" />',o.method="post",o.action=l,o.target=u.target,o.innerHTML=i,o.style.display="none",document.body.appendChild(o),o.querySelector('[type="submit"]').click(),e(n)}}.call(this),function(){var e,n,a,r,o,i,l,u,c,s=[].slice;i=t.matches,a=t.getData,u=t.setData,n=t.fire,c=t.stopEverything,e=t.ajax,r=t.isCrossDomain,l=t.serializeElement,o=function(t){var e;return null!=(e=t.getAttribute("data-remote"))&&"false"!==e},t.handleRemote=function(d){var m,f,p,b,h,v,S;return!o(b=this)||(n(b,"ajax:before")?(S=b.getAttribute("data-with-credentials"),p=b.getAttribute("data-type")||"script",i(b,t.formSubmitSelector)?(m=a(b,"ujs:submit-button"),h=a(b,"ujs:submit-button-formmethod")||b.method,v=a(b,"ujs:submit-button-formaction")||b.getAttribute("action")||location.href,"GET"===h.toUpperCase()&&(v=v.replace(/\?.*$/,"")),"multipart/form-data"===b.enctype?(f=new FormData(b),null!=m&&f.append(m.name,m.value)):f=l(b,m),u(b,"ujs:submit-button",null),u(b,"ujs:submit-button-formmethod",null),u(b,"ujs:submit-button-formaction",null)):i(b,t.buttonClickSelector)||i(b,t.inputChangeSelector)?(h=b.getAttribute("data-method"),v=b.getAttribute("data-url"),f=l(b,b.getAttribute("data-params"))):(h=b.getAttribute("data-method"),v=t.href(b),f=b.getAttribute("data-params")),e({type:h||"GET",url:v,data:f,dataType:p,beforeSend:function(t,e){return n(b,"ajax:beforeSend",[t,e])?n(b,"ajax:send",[t]):(n(b,"ajax:stopped"),!1)},success:function(){var t;return t=1<=arguments.length?s.call(arguments,0):[],n(b,"ajax:success",t)},error:function(){var t;return t=1<=arguments.length?s.call(arguments,0):[],n(b,"ajax:error",t)},complete:function(){var t;return t=1<=arguments.length?s.call(arguments,0):[],n(b,"ajax:complete",t)},crossDomain:r(v),withCredentials:null!=S&&"false"!==S}),c(d)):(n(b,"ajax:stopped"),!1))},t.formSubmitButtonClick=function(t){var e,n;if(n=(e=this).form)return e.name&&u(n,"ujs:submit-button",{name:e.name,value:e.value}),u(n,"ujs:formnovalidate-button",e.formNoValidate),u(n,"ujs:submit-button-formaction",e.getAttribute("formaction")),u(n,"ujs:submit-button-formmethod",e.getAttribute("formmethod"))},t.preventInsignificantClick=function(t){var e,n,a;if(this,a=(this.getAttribute("data-method")||"GET").toUpperCase(),e=this.getAttribute("data-params"),n=(t.metaKey||t.ctrlKey)&&"GET"===a&&!e,null!=t.button&&0!==t.button||n)return t.stopImmediatePropagation()}}.call(this),function(){var e,n,a,r,o,i,l,u,c,s,d,m,f,p,b;if(i=t.fire,a=t.delegate,u=t.getData,e=t.$,b=t.refreshCSRFTokens,n=t.CSRFProtection,f=t.loadCSPNonce,o=t.enableElement,r=t.disableElement,s=t.handleDisabledElement,c=t.handleConfirm,p=t.preventInsignificantClick,m=t.handleRemote,l=t.formSubmitButtonClick,d=t.handleMethod,"undefined"!=typeof jQuery&&null!==jQuery&&null!=jQuery.ajax){if(jQuery.rails)throw new Error("If you load both jquery_ujs and rails-ujs, use rails-ujs only.");jQuery.rails=t,jQuery.ajaxPrefilter((function(t,e,a){if(!t.crossDomain)return n(a)}))}t.start=function(){if(window._rails_loaded)throw new Error("rails-ujs has already been loaded!");return window.addEventListener("pageshow",(function(){return e(t.formEnableSelector).forEach((function(t){if(u(t,"ujs:disabled"))return o(t)})),e(t.linkDisableSelector).forEach((function(t){if(u(t,"ujs:disabled"))return o(t)}))})),a(document,t.linkDisableSelector,"ajax:complete",o),a(document,t.linkDisableSelector,"ajax:stopped",o),a(document,t.buttonDisableSelector,"ajax:complete",o),a(document,t.buttonDisableSelector,"ajax:stopped",o),a(document,t.linkClickSelector,"click",p),a(document,t.linkClickSelector,"click",s),a(document,t.linkClickSelector,"click",c),a(document,t.linkClickSelector,"click",r),a(document,t.linkClickSelector,"click",m),a(document,t.linkClickSelector,"click",d),a(document,t.buttonClickSelector,"click",p),a(document,t.buttonClickSelector,"click",s),a(document,t.buttonClickSelector,"click",c),a(document,t.buttonClickSelector,"click",r),a(document,t.buttonClickSelector,"click",m),a(document,t.inputChangeSelector,"change",s),a(document,t.inputChangeSelector,"change",c),a(document,t.inputChangeSelector,"change",m),a(document,t.formSubmitSelector,"submit",s),a(document,t.formSubmitSelector,"submit",c),a(document,t.formSubmitSelector,"submit",m),a(document,t.formSubmitSelector,"submit",(function(t){return setTimeout((function(){return r(t)}),13)})),a(document,t.formSubmitSelector,"ajax:send",r),a(document,t.formSubmitSelector,"ajax:complete",o),a(document,t.formInputClickSelector,"click",p),a(document,t.formInputClickSelector,"click",s),a(document,t.formInputClickSelector,"click",c),a(document,t.formInputClickSelector,"click",l),document.addEventListener("DOMContentLoaded",b),document.addEventListener("DOMContentLoaded",f),window._rails_loaded=!0},window.Rails===t&&i(document,"rails:attachBindings")&&t.start()}.call(this)}).call(this),"object"==typeof module&&module.exports?module.exports=t:"function"==typeof define&&define.amd&&define(t)}).call(this);