From 1e6f92377aaf0804cfd0ddb9b06da7b4c9dc355f Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Mon, 11 May 2020 15:21:26 -0400 Subject: [PATCH] fix(refresher): refresher completes even after switching to a new tab (#21236) --- core/src/components/refresher/refresher.tsx | 2 +- .../components/refresher/refresher.utils.ts | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/core/src/components/refresher/refresher.tsx b/core/src/components/refresher/refresher.tsx index 841b062ac1..eba25d540b 100644 --- a/core/src/components/refresher/refresher.tsx +++ b/core/src/components/refresher/refresher.tsx @@ -149,7 +149,7 @@ export class Refresher implements ComponentInterface { if (getIonMode(this) === 'ios') { await translateElement(el, undefined); } else { - await transitionEndAsync(this.el.querySelector('.refresher-refreshing-icon')); + await transitionEndAsync(this.el.querySelector('.refresher-refreshing-icon'), 200); } this.didRefresh = false; diff --git a/core/src/components/refresher/refresher.utils.ts b/core/src/components/refresher/refresher.utils.ts index 84fae83dda..b78d1228f5 100644 --- a/core/src/components/refresher/refresher.utils.ts +++ b/core/src/components/refresher/refresher.utils.ts @@ -148,7 +148,7 @@ export const handleScrollWhileRefreshing = ( export const translateElement = (el?: HTMLElement, value?: string) => { if (!el) { return Promise.resolve(); } - const trans = transitionEndAsync(el); + const trans = transitionEndAsync(el, 200); writeTask(() => { el.style.setProperty('transition', '0.2s all ease-out'); @@ -181,15 +181,17 @@ export const shouldUseNativeRefresher = (referenceEl: HTMLIonRefresherElement, m ); }; -export const transitionEndAsync = (el: HTMLElement | null) => { +export const transitionEndAsync = (el: HTMLElement | null, expectedDuration = 0) => { return new Promise(resolve => { - transitionEnd(el, resolve); + transitionEnd(el, expectedDuration, resolve); }); }; -const transitionEnd = (el: HTMLElement | null, callback: (ev?: TransitionEvent) => void) => { +const transitionEnd = (el: HTMLElement | null, expectedDuration = 0, callback: (ev?: TransitionEvent) => void) => { let unRegTrans: (() => void) | undefined; + let animationTimeout: any; const opts: any = { passive: true }; + const ANIMATION_FALLBACK_TIMEOUT = 500; const unregister = () => { if (unRegTrans) { @@ -197,8 +199,8 @@ const transitionEnd = (el: HTMLElement | null, callback: (ev?: TransitionEvent) } }; - const onTransitionEnd = (ev: Event) => { - if (el === ev.target) { + const onTransitionEnd = (ev?: Event) => { + if (ev === undefined || el === ev.target) { unregister(); callback(ev as TransitionEvent); } @@ -207,8 +209,13 @@ const transitionEnd = (el: HTMLElement | null, callback: (ev?: TransitionEvent) if (el) { el.addEventListener('webkitTransitionEnd', onTransitionEnd, opts); el.addEventListener('transitionend', onTransitionEnd, opts); + animationTimeout = setTimeout(onTransitionEnd, expectedDuration + ANIMATION_FALLBACK_TIMEOUT); unRegTrans = () => { + if (animationTimeout) { + clearTimeout(animationTimeout); + animationTimeout = undefined; + } el.removeEventListener('webkitTransitionEnd', onTransitionEnd, opts); el.removeEventListener('transitionend', onTransitionEnd, opts); };