Skip to content

Commit

Permalink
Merge pull request #1528 from kaliber5/refactor-bs-modal-to-use-async…
Browse files Browse the repository at this point in the history
…-await-instead-of-callbacks

refactor to async/await instead of callbacks in BsModal
  • Loading branch information
simonihmig committed May 26, 2021
2 parents 54c67a6 + 0899b2b commit f64e675
Showing 1 changed file with 68 additions and 74 deletions.
142 changes: 68 additions & 74 deletions addon/components/bs-modal.js
Expand Up @@ -12,6 +12,14 @@ 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));
}

function afterRender() {
return new Promise((resolve) => schedule('afterRender', resolve));
}

/**
Component for creating [Bootstrap modals](http://getbootstrap.com/javascript/#modals) with custom markup.
Expand Down Expand Up @@ -416,7 +424,7 @@ export default class Modal extends Component {
* @method show
* @private
*/
show() {
async show() {
if (this._isOpen) {
return;
}
Expand All @@ -425,36 +433,34 @@ export default class Modal extends Component {
this.addBodyClass();
this.resize();

let callback = () => {
if (this.isDestroyed) {
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);

await this.handleBackdrop();

if (this.isDestroyed) {
return;
}

this.checkScrollbar();
this.setScrollbar();

await afterRender();

const { modalElement } = this;
if (!modalElement) {
return;
}

modalElement.scrollTop = 0;
this.adjustDialog();
this.showModal = true;
this.args.onShow?.();

if (this.usesTransition) {
await transitionEnd(modalElement, this.transitionDuration);
}

this.args.onShown?.();
}

/**
Expand All @@ -463,7 +469,7 @@ export default class Modal extends Component {
* @method hide
* @private
*/
hide() {
async hide() {
if (!this._isOpen) {
return;
}
Expand All @@ -473,10 +479,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);
}

await this.hideModal();
}

/**
Expand All @@ -485,18 +491,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?.();
}

/**
Expand All @@ -506,45 +512,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();

if (usesTransition) {
const { backdropElement } = this;
assert('Backdrop element should be in DOM', backdropElement);

next(() => {
let backdrop = this.backdropElement;
assert('Backdrop element should be in DOM', backdrop);
if (doAnimate) {
transitionEnd(backdrop, this.backdropTransitionDuration).then(callback);
} else {
callback();
}
});
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);
}
} else if (callback) {
next(this, callback);

if (this.isDestroyed) {
return;
}

this.showBackdrop = false;
}
}

Expand Down

0 comments on commit f64e675

Please sign in to comment.