From 78f75744e3141437d5c08fc70bc0f1a319912449 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Wed, 5 Jun 2019 15:29:06 +0000 Subject: [PATCH] javascript: fix payload of ActiveStorage events missing on IE 11 Under some circumstances (like dispatching events just before a page navigation), IE 11 events will be dispatched twice by the browser: once with the payload, and a second time without. To prevent these errors, ignore the events if the payload is missing. --- app/javascript/shared/activestorage/ujs.js | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/app/javascript/shared/activestorage/ujs.js b/app/javascript/shared/activestorage/ujs.js index f9908dd89..72d464b26 100644 --- a/app/javascript/shared/activestorage/ujs.js +++ b/app/javascript/shared/activestorage/ujs.js @@ -6,11 +6,25 @@ const PROGRESS_EVENT = 'direct-upload:progress'; const ERROR_EVENT = 'direct-upload:error'; const END_EVENT = 'direct-upload:end'; -addEventListener(INITIALIZE_EVENT, ({ target, detail: { id, file } }) => { +function addUploadEventListener(type, handler) { + addEventListener(type, event => { + // Internet Explorer and Edge will sometime replay Javascript events + // that were dispatched just before a page navigation (!), but without + // the event payload. + // + // Ignore these replayed events. + const isEventValid = event && event.detail && event.detail.id != undefined; + if (!isEventValid) return; + + handler(event); + }); +} + +addUploadEventListener(INITIALIZE_EVENT, ({ target, detail: { id, file } }) => { ProgressBar.init(target, id, file); }); -addEventListener(START_EVENT, ({ target, detail: { id } }) => { +addUploadEventListener(START_EVENT, ({ target, detail: { id } }) => { ProgressBar.start(id); const button = target.form.querySelector('button.primary'); if (button) { @@ -18,14 +32,14 @@ addEventListener(START_EVENT, ({ target, detail: { id } }) => { } }); -addEventListener(PROGRESS_EVENT, ({ detail: { id, progress } }) => { +addUploadEventListener(PROGRESS_EVENT, ({ detail: { id, progress } }) => { ProgressBar.progress(id, progress); }); -addEventListener(ERROR_EVENT, ({ detail: { id, error } }) => { +addUploadEventListener(ERROR_EVENT, ({ detail: { id, error } }) => { ProgressBar.error(id, error); }); -addEventListener(END_EVENT, ({ detail: { id } }) => { +addUploadEventListener(END_EVENT, ({ detail: { id } }) => { ProgressBar.end(id); });