From 72dded2a5ac4978dea37551a836c4b28b78ffc72 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Fri, 31 Aug 2018 11:56:56 +0100 Subject: [PATCH] Fix safari bug Fix #2452 --- app/javascript/packs/application-old.js | 1 + app/javascript/packs/application.js | 1 + .../shared/safari-11-file-xhr-workaround.js | 26 +++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 app/javascript/shared/safari-11-file-xhr-workaround.js diff --git a/app/javascript/packs/application-old.js b/app/javascript/packs/application-old.js index 7a2aa3e77..5bd38c5ea 100644 --- a/app/javascript/packs/application-old.js +++ b/app/javascript/packs/application-old.js @@ -10,6 +10,7 @@ import 'babel-polyfill'; import '../shared/sentry'; import '../shared/rails-ujs-fix'; +import '../shared/safari-11-file-xhr-workaround'; import '../shared/autocomplete'; // Start Rails helpers diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 8eebcb3a3..563e8a386 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -12,6 +12,7 @@ import 'babel-polyfill'; import '../shared/sentry'; import '../shared/rails-ujs-fix'; +import '../shared/safari-11-file-xhr-workaround'; import '../shared/autocomplete'; import '../new_design/buttons'; diff --git a/app/javascript/shared/safari-11-file-xhr-workaround.js b/app/javascript/shared/safari-11-file-xhr-workaround.js new file mode 100644 index 000000000..1cedc369e --- /dev/null +++ b/app/javascript/shared/safari-11-file-xhr-workaround.js @@ -0,0 +1,26 @@ +// iOS 11.3 Safari / macOS Safari 11.1 empty XHR bug workaround. +// This should work with every modern browser which supports ES5 (including IE9). +// https://stackoverflow.com/questions/49614091/safari-11-1-ajax-xhr-form-submission-fails-when-inputtype-file-is-empty +// https://github.com/rails/rails/issues/32440 + +document.addEventListener('ajax:before', function(e) { + let inputs = e.target.querySelectorAll('input[type="file"]:not([disabled])'); + inputs.forEach(function(input) { + if (input.files.length > 0) { + return; + } + input.setAttribute('data-safari-temp-disabled', 'true'); + input.setAttribute('disabled', ''); + }); +}); + +// You should call this by yourself when you aborted an ajax request by stopping a event in ajax:before hook. +document.addEventListener('ajax:beforeSend', function(e) { + let inputs = e.target.querySelectorAll( + 'input[type="file"][data-safari-temp-disabled]' + ); + inputs.forEach(function(input) { + input.removeAttribute('data-safari-temp-disabled'); + input.removeAttribute('disabled'); + }); +});