From 88bfe6dcc8024d72d30588bfd18c41089b6409de Mon Sep 17 00:00:00 2001 From: Jeldrik Hanschke Date: Tue, 25 May 2021 21:51:02 +0200 Subject: [PATCH 1/2] refactor to async/await instead of callbacks in BsModal --- addon/components/bs-modal.js | 134 ++++++++++++++++------------------- 1 file changed, 62 insertions(+), 72 deletions(-) diff --git a/addon/components/bs-modal.js b/addon/components/bs-modal.js index e26bbf85b..757921113 100644 --- a/addon/components/bs-modal.js +++ b/addon/components/bs-modal.js @@ -12,6 +12,10 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import arg from '../utils/decorators/arg'; import { tracked } from '@glimmer/tracking'; +function nextRunloop() { + return new Promise((resolve) => next(resolve)); +} + /** Component for creating [Bootstrap modals](http://getbootstrap.com/javascript/#modals) with custom markup. @@ -416,7 +420,7 @@ export default class Modal extends Component { * @method show * @private */ - show() { + async show() { if (this._isOpen) { return; } @@ -425,36 +429,34 @@ export default class Modal extends Component { this.addBodyClass(); this.resize(); - let callback = () => { - if (this.isDestroyed) { + this.inDom = true; + + await this.handleBackdrop(); + + if (this.isDestroyed) { + return; + } + + this.checkScrollbar(); + this.setScrollbar(); + + schedule('afterRender', async () => { + let modalEl = this.modalElement; + if (!modalEl) { return; } - this.checkScrollbar(); - this.setScrollbar(); - - schedule('afterRender', () => { - let modalEl = this.modalElement; - if (!modalEl) { - return; - } - - modalEl.scrollTop = 0; - this.adjustDialog(); - this.showModal = true; - this.args.onShow?.(); - - if (this.usesTransition) { - transitionEnd(this.modalElement, this.transitionDuration).then(() => { - this.args.onShown?.(); - }); - } else { - this.args.onShown?.(); - } - }); - }; - this.inDom = true; - this.handleBackdrop(callback); + modalEl.scrollTop = 0; + this.adjustDialog(); + this.showModal = true; + this.args.onShow?.(); + + if (this.usesTransition) { + await transitionEnd(this.modalElement, this.transitionDuration); + } + + this.args.onShown?.(); + }); } /** @@ -463,7 +465,7 @@ export default class Modal extends Component { * @method hide * @private */ - hide() { + async hide() { if (!this._isOpen) { return; } @@ -473,10 +475,10 @@ export default class Modal extends Component { this.showModal = false; if (this.usesTransition) { - transitionEnd(this.modalElement, this.transitionDuration).then(() => this.hideModal()); - } else { - this.hideModal(); + await transitionEnd(this.modalElement, this.transitionDuration); } + + this.hideModal(); } /** @@ -485,18 +487,18 @@ export default class Modal extends Component { * @method hideModal * @private */ - hideModal() { + async hideModal() { if (this.isDestroyed) { return; } - this.handleBackdrop(() => { - this.removeBodyClass(); - this.resetAdjustments(); - this.resetScrollbar(); - this.inDom = false; - this.args.onHidden?.(); - }); + await this.handleBackdrop(); + + this.removeBodyClass(); + this.resetAdjustments(); + this.resetScrollbar(); + this.inDom = false; + this.args.onHidden?.(); } /** @@ -506,45 +508,33 @@ export default class Modal extends Component { * @param callback * @private */ - handleBackdrop(callback) { - let doAnimate = this.usesTransition; + async handleBackdrop() { + const { usesTransition } = this; if (this.open && this.backdrop) { this.showBackdrop = true; - if (!callback) { - return; - } + await nextRunloop(); - next(() => { - let backdrop = this.backdropElement; - assert('Backdrop element should be in DOM', backdrop); - if (doAnimate) { - transitionEnd(backdrop, this.backdropTransitionDuration).then(callback); - } else { - callback(); - } - }); + if (usesTransition) { + const { backdropElement } = this; + assert('Backdrop element should be in DOM', backdropElement); + + await transitionEnd(backdropElement, this.backdropTransitionDuration); + } } else if (!this.open && this.backdrop) { - let backdrop = this.backdropElement; - assert('Backdrop element should be in DOM', backdrop); - - let callbackRemove = () => { - if (this.isDestroyed) { - return; - } - this.showBackdrop = false; - if (callback) { - callback.call(this); - } - }; - if (doAnimate) { - transitionEnd(backdrop, this.backdropTransitionDuration).then(callbackRemove); - } else { - callbackRemove(); + if (usesTransition) { + const { backdropElement } = this; + assert('Backdrop element should be in DOM', backdropElement); + + await transitionEnd(backdropElement, this.backdropTransitionDuration); + } + + if (this.isDestroyed) { + return; } - } else if (callback) { - next(this, callback); + + this.showBackdrop = false; } } From 0899b2be787426761bdc7283ad7c7ab74cf5a3aa Mon Sep 17 00:00:00 2001 From: Jeldrik Hanschke Date: Wed, 26 May 2021 17:34:46 +0200 Subject: [PATCH 2/2] await afterRender runloop queue --- addon/components/bs-modal.js | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/addon/components/bs-modal.js b/addon/components/bs-modal.js index 757921113..f2c56df13 100644 --- a/addon/components/bs-modal.js +++ b/addon/components/bs-modal.js @@ -16,6 +16,10 @@ function nextRunloop() { return new Promise((resolve) => next(resolve)); } +function afterRender() { + return new Promise((resolve) => schedule('afterRender', resolve)); +} + /** Component for creating [Bootstrap modals](http://getbootstrap.com/javascript/#modals) with custom markup. @@ -440,23 +444,23 @@ export default class Modal extends Component { this.checkScrollbar(); this.setScrollbar(); - schedule('afterRender', async () => { - let modalEl = this.modalElement; - if (!modalEl) { - return; - } + await afterRender(); + + const { modalElement } = this; + if (!modalElement) { + return; + } - modalEl.scrollTop = 0; - this.adjustDialog(); - this.showModal = true; - this.args.onShow?.(); + modalElement.scrollTop = 0; + this.adjustDialog(); + this.showModal = true; + this.args.onShow?.(); - if (this.usesTransition) { - await transitionEnd(this.modalElement, this.transitionDuration); - } + if (this.usesTransition) { + await transitionEnd(modalElement, this.transitionDuration); + } - this.args.onShown?.(); - }); + this.args.onShown?.(); } /** @@ -478,7 +482,7 @@ export default class Modal extends Component { await transitionEnd(this.modalElement, this.transitionDuration); } - this.hideModal(); + await this.hideModal(); } /**