Do not enable disabled elements for XHR redirects

Fixes #29473.
This commit is contained in:
Patrik Bóna 2017-12-14 10:14:24 +01:00
parent 8541394e71
commit 8e07711d65
4 changed files with 37 additions and 2 deletions

View File

@ -8,7 +8,12 @@ Rails.handleDisabledElement = (e) ->
# Unified function to enable an element (link, button and form)
Rails.enableElement = (e) ->
element = if e instanceof Event then e.target else e
if e instanceof Event
return if isXhrRedirect(e)
element = e.target
else
element = e
if matches(element, Rails.linkDisableSelector)
enableLinkElement(element)
else if matches(element, Rails.buttonDisableSelector) or matches(element, Rails.formEnableSelector)
@ -80,3 +85,7 @@ enableFormElement = (element) ->
setData(element, 'ujs:enable-with', null) # clean up cache
element.disabled = false
setData(element, 'ujs:disabled', null)
isXhrRedirect = (event) ->
xhr = event.detail?[0]
xhr?.getResponseHeader("X-Xhr-Redirect")?

View File

@ -320,3 +320,20 @@ asyncTest('button[data-remote][data-disable] re-enables when `ajax:error` event
start()
}, 30)
})
asyncTest('do not enable elements for XHR redirects', 6, function() {
var link = $('a[data-disable]').attr('data-remote', true).attr('href', '/echo?with_xhr_redirect=true')
App.checkEnabledState(link, 'Click me')
link
.bindNative('ajax:send', function() {
App.checkDisabledState(link, 'Click me')
})
.triggerNative('click')
setTimeout(function() {
App.checkDisabledState(link, 'Click me')
start()
}, 30)
})

View File

@ -1,4 +1,5 @@
var App = App || {}
var Turbolinks = Turbolinks || {}
App.assertCallbackInvoked = function(callbackName) {
ok(true, callbackName + ' callback should have been invoked')
@ -116,3 +117,6 @@ $.fn.extend({
return this
}
})
Turbolinks.clearCache = function() {}
Turbolinks.visit = function() {}

View File

@ -64,7 +64,12 @@ class TestsController < ActionController::Base
if params[:content_type] && params[:content]
render inline: params[:content], content_type: params[:content_type]
elsif request.xhr?
render json: JSON.generate(data)
if params[:with_xhr_redirect]
response.set_header("X-Xhr-Redirect", "http://example.com/")
render inline: %{Turbolinks.clearCache()\nTurbolinks.visit("http://example.com/", {"action":"replace"})}
else
render json: JSON.generate(data)
end
elsif params[:iframe]
payload = JSON.generate(data).gsub("<", "&lt;").gsub(">", "&gt;")
html = <<-HTML