refactor(all): async/await

This commit is contained in:
Manu Mtz.-Almeida
2018-03-24 03:24:57 +01:00
parent ee1aaafd73
commit e20f76c3b1
10 changed files with 113 additions and 138 deletions

View File

@ -93,12 +93,12 @@ export class Gesture {
}; };
} }
componentWillLoad() { async componentWillLoad() {
return this.gestureCtrl.create({ this.gesture = await this.gestureCtrl.create({
name: this.gestureName, name: this.gestureName,
priority: this.gesturePriority, priority: this.gesturePriority,
disableScroll: this.disableScroll disableScroll: this.disableScroll
}).then((gesture) => this.gesture = gesture); });
} }
componentDidLoad() { componentDidLoad() {

View File

@ -15,10 +15,9 @@ export class InfiniteScroll {
private thrPx = 0; private thrPx = 0;
private thrPc = 0; private thrPc = 0;
private scrollEl: HTMLIonScrollElement|null = null; private scrollEl: HTMLIonScrollElement|undefined;
private didFire = false; private didFire = false;
private isBusy = false; private isBusy = false;
private init = false;
@Element() private el: HTMLElement; @Element() private el: HTMLElement;
@State() isLoading = false; @State() isLoading = false;
@ -82,19 +81,14 @@ export class InfiniteScroll {
*/ */
@Event() ionInfinite: EventEmitter; @Event() ionInfinite: EventEmitter;
componentWillLoad() { async componentWillLoad() {
const scrollEl = this.el.closest('ion-scroll'); const scrollEl = this.el.closest('ion-scroll');
return scrollEl.componentOnReady().then((el) => { if (scrollEl) {
this.scrollEl = el; this.scrollEl = await scrollEl.componentOnReady();
}); }
} }
componentDidLoad() { componentDidLoad() {
if (this.init) {
console.warn('instance was already initialized');
return;
}
this.init = true;
this.thresholdChanged(this.threshold); this.thresholdChanged(this.threshold);
this.enableScrollEvents(!this.disabled); this.enableScrollEvents(!this.disabled);
if (this.position === Position.Top) { if (this.position === Position.Top) {
@ -103,7 +97,7 @@ export class InfiniteScroll {
} }
componentDidUnload() { componentDidUnload() {
this.scrollEl = null; this.scrollEl = undefined;
} }
@Listen('scroll', {enabled: false}) @Listen('scroll', {enabled: false})

View File

@ -144,12 +144,12 @@ export class Loading implements OverlayInterface {
* Present the loading overlay after it has been created. * Present the loading overlay after it has been created.
*/ */
@Method() @Method()
present(): Promise<void> { async present(): Promise<void> {
return present(this, 'loadingEnter', iosEnterAnimation, mdEnterAnimation, undefined).then(() => { await present(this, 'loadingEnter', iosEnterAnimation, mdEnterAnimation, undefined);
if (this.duration > 0) { if (this.duration > 0) {
this.durationTimeout = setTimeout(() => this.dismiss(), this.duration + 10); this.durationTimeout = setTimeout(() => this.dismiss(), this.duration + 10);
} }
});
} }
/** /**

View File

@ -24,8 +24,8 @@ export class MenuToggle {
} }
@Listen('child:click') @Listen('child:click')
onClick() { async onClick() {
getMenuController().then(menuCtrl => { const menuCtrl = await getMenuController();
if (menuCtrl) { if (menuCtrl) {
const menu = menuCtrl.get(this.menu); const menu = menuCtrl.get(this.menu);
if (menu && menu.isActive()) { if (menu && menu.isActive()) {
@ -33,13 +33,12 @@ export class MenuToggle {
} }
} }
return false; return false;
});
} }
@Listen('body:ionMenuChange') @Listen('body:ionMenuChange')
@Listen('body:ionSplitPaneVisible') @Listen('body:ionSplitPaneVisible')
updateVisibility() { async updateVisibility() {
return getMenuController().then(menuCtrl => { const menuCtrl = await getMenuController();
if (menuCtrl) { if (menuCtrl) {
const menu = menuCtrl.get(this.menu); const menu = menuCtrl.get(this.menu);
if (menu && menu.isActive()) { if (menu && menu.isActive()) {
@ -48,7 +47,6 @@ export class MenuToggle {
} }
} }
this.visible = false; this.visible = false;
});
} }
hostData() { hostData() {
@ -62,10 +60,10 @@ export class MenuToggle {
} }
function getMenuController(): Promise<HTMLIonMenuControllerElement> { function getMenuController(): Promise<HTMLIonMenuControllerElement|undefined> {
const menuControllerElement = document.querySelector('ion-menu-controller'); const menuControllerElement = document.querySelector('ion-menu-controller');
if (!menuControllerElement) { if (!menuControllerElement) {
return Promise.resolve(null); return Promise.resolve(undefined);
} }
return menuControllerElement.componentOnReady(); return menuControllerElement.componentOnReady();
} }

View File

@ -14,7 +14,6 @@ import { Side, assert, isRightSide } from '../../utils/helpers';
}) })
export class Menu { export class Menu {
private gestureBlocker: string;
private animation: Animation|undefined; private animation: Animation|undefined;
private isPane = false; private isPane = false;
private _isOpen = false; private _isOpen = false;
@ -121,10 +120,8 @@ export class Menu {
@Event() protected ionMenuChange: EventEmitter<MenuChangeEventDetail>; @Event() protected ionMenuChange: EventEmitter<MenuChangeEventDetail>;
componentWillLoad() { async componentWillLoad() {
return this.lazyMenuCtrl.componentOnReady().then(menu => { this.menuCtrl = await this.lazyMenuCtrl.componentOnReady();
this.menuCtrl = menu;
});
} }
componentDidLoad() { componentDidLoad() {
@ -212,16 +209,17 @@ export class Menu {
return this.menuCtrl._setOpen(this, shouldOpen, animated); return this.menuCtrl._setOpen(this, shouldOpen, animated);
} }
_setOpen(shouldOpen: boolean, animated = true): Promise<boolean> { async _setOpen(shouldOpen: boolean, animated = true): Promise<boolean> {
// If the menu is disabled or it is currenly being animated, let's do nothing // If the menu is disabled or it is currenly being animated, let's do nothing
if (!this.isActive() || this.isAnimating || (shouldOpen === this._isOpen)) { if (!this.isActive() || this.isAnimating || (shouldOpen === this._isOpen)) {
return Promise.resolve(this._isOpen); return this._isOpen;
} }
this.beforeAnimation(); this.beforeAnimation();
return this.loadAnimation() await this.loadAnimation();
.then(() => this.startAnimation(shouldOpen, animated)) await this.startAnimation(shouldOpen, animated);
.then(() => this.afterAnimation(shouldOpen)); await this.afterAnimation(shouldOpen);
return shouldOpen;
} }
@Method() @Method()
@ -229,24 +227,22 @@ export class Menu {
return !this.disabled && !this.isPane; return !this.disabled && !this.isPane;
} }
private loadAnimation(): Promise<void> { private async loadAnimation(): Promise<void> {
// Menu swipe animation takes the menu's inner width as parameter, // Menu swipe animation takes the menu's inner width as parameter,
// If `offsetWidth` changes, we need to create a new animation. // If `offsetWidth` changes, we need to create a new animation.
const width = this.menuInnerEl.offsetWidth; const width = this.menuInnerEl.offsetWidth;
if (width === this.width && this.animation !== null) { if (width === this.width && this.animation !== null) {
return Promise.resolve(); return;
} }
this.width = width;
// Destroy existing animation // Destroy existing animation
if (this.animation) { if (this.animation) {
this.animation.destroy(); this.animation.destroy();
this.animation = null; this.animation = null;
} }
this.width = width;
// Create new animation // Create new animation
return this.menuCtrl.createAnimation(this.type, this).then(ani => { this.animation = await this.menuCtrl.createAnimation(this.type, this);
this.animation = ani;
});
} }
private startAnimation(shouldOpen: boolean, animated: boolean): Promise<Animation> { private startAnimation(shouldOpen: boolean, animated: boolean): Promise<Animation> {
@ -359,7 +355,7 @@ export class Menu {
this.isAnimating = true; this.isAnimating = true;
} }
private afterAnimation(isOpen: boolean): boolean { private afterAnimation(isOpen: boolean) {
assert(this.isAnimating, '_before() should be called while animating'); assert(this.isAnimating, '_before() should be called while animating');
// keep opening/closing the menu disabled for a touch more yet // keep opening/closing the menu disabled for a touch more yet
@ -373,9 +369,6 @@ export class Menu {
this.enableListener(this, 'body:click', isOpen); this.enableListener(this, 'body:click', isOpen);
if (isOpen) { if (isOpen) {
// disable swipe to go back gesture
this.gestureBlocker = GESTURE_BLOCKER;
// add css class // add css class
this.contentEl.classList.add(MENU_CONTENT_OPEN); this.contentEl.classList.add(MENU_CONTENT_OPEN);
@ -383,9 +376,6 @@ export class Menu {
this.ionOpen.emit(); this.ionOpen.emit();
} else { } else {
// enable swipe to go back gesture
this.gestureBlocker = null;
// remove css classes // remove css classes
this.el.classList.remove(SHOW_MENU); this.el.classList.remove(SHOW_MENU);
this.contentEl.classList.remove(MENU_CONTENT_OPEN); this.contentEl.classList.remove(MENU_CONTENT_OPEN);
@ -394,7 +384,6 @@ export class Menu {
// emit close event // emit close event
this.ionClose.emit(); this.ionClose.emit();
} }
return isOpen;
} }
private updateState() { private updateState() {
@ -461,7 +450,6 @@ export class Menu {
'threshold': 10, 'threshold': 10,
'attachTo': 'window', 'attachTo': 'window',
'disableScroll': true, 'disableScroll': true,
'block': this.gestureBlocker
}}/> }}/>
]); ]);
} }
@ -482,7 +470,6 @@ function checkEdgeSide(posX: number, isRightSide: boolean, maxEdgeStart: number)
const SHOW_MENU = 'show-menu'; const SHOW_MENU = 'show-menu';
const SHOW_BACKDROP = 'show-backdrop'; const SHOW_BACKDROP = 'show-backdrop';
const MENU_CONTENT_OPEN = 'menu-content-open'; const MENU_CONTENT_OPEN = 'menu-content-open';
const GESTURE_BLOCKER = 'goback-swipe';
export interface MenuChangeEvent { export interface MenuChangeEvent {
target: HTMLIonMenuElement; target: HTMLIonMenuElement;

View File

@ -164,7 +164,7 @@ export class Modal implements OverlayInterface {
* Present the modal overlay after it has been created. * Present the modal overlay after it has been created.
*/ */
@Method() @Method()
present(): Promise<void> { async present(): Promise<void> {
if (this.presented) { if (this.presented) {
return Promise.resolve(); return Promise.resolve();
} }
@ -177,18 +177,17 @@ export class Modal implements OverlayInterface {
...getClassList(this.cssClass), ...getClassList(this.cssClass),
'ion-page' 'ion-page'
]; ];
return attachComponent(this.delegate, container, this.component, classes, data) this.usersElement = await attachComponent(this.delegate, container, this.component, classes, data);
.then(el => this.usersElement = el) return present(this, 'modalEnter', iosEnterAnimation, mdEnterAnimation);
.then(() => present(this, 'modalEnter', iosEnterAnimation, mdEnterAnimation));
} }
/** /**
* Dismiss the modal overlay after it has been presented. * Dismiss the modal overlay after it has been presented.
*/ */
@Method() @Method()
dismiss(data?: any, role?: string): Promise<void> { async dismiss(data?: any, role?: string): Promise<void> {
return dismiss(this, data, role, 'modalLeave', iosLeaveAnimation, mdLeaveAnimation) await dismiss(this, data, role, 'modalLeave', iosLeaveAnimation, mdLeaveAnimation);
.then(() => detachComponent(this.delegate, this.usersElement)); await detachComponent(this.delegate, this.usersElement);
} }
/** /**

View File

@ -144,13 +144,12 @@ export class Picker implements OverlayInterface {
* Present the picker overlay after it has been created. * Present the picker overlay after it has been created.
*/ */
@Method() @Method()
present(): Promise<void> { async present(): Promise<void> {
return present(this, 'pickerEnter', iosEnterAnimation, iosEnterAnimation, undefined).then(() => { await present(this, 'pickerEnter', iosEnterAnimation, iosEnterAnimation, undefined);
// If there is a duration, dismiss after that amount of time
if (this.duration > 10) { if (this.duration > 0) {
this.durationTimeout = setTimeout(() => this.dismiss(), this.duration); this.durationTimeout = setTimeout(() => this.dismiss(), this.duration);
} }
});
} }
/** /**

View File

@ -174,7 +174,7 @@ export class Popover implements OverlayInterface {
* Present the popover overlay after it has been created. * Present the popover overlay after it has been created.
*/ */
@Method() @Method()
present(): Promise<void> { async present(): Promise<void> {
if (this.presented) { if (this.presented) {
return Promise.reject('df'); return Promise.reject('df');
} }
@ -187,18 +187,17 @@ export class Popover implements OverlayInterface {
...getClassList(this.cssClass), ...getClassList(this.cssClass),
'popover-viewport' 'popover-viewport'
]; ];
return attachComponent(this.delegate, container, this.component, classes, data) this.usersElement = await attachComponent(this.delegate, container, this.component, classes, data);
.then(el => this.usersElement = el) return present(this, 'popoverEnter', iosEnterAnimation, mdEnterAnimation, this.ev);
.then(() => present(this, 'popoverEnter', iosEnterAnimation, mdEnterAnimation, this.ev));
} }
/** /**
* Dismiss the popover overlay after it has been presented. * Dismiss the popover overlay after it has been presented.
*/ */
@Method() @Method()
dismiss(data?: any, role?: string): Promise<void> { async dismiss(data?: any, role?: string): Promise<void> {
return dismiss(this, data, role, 'popoverLeave', iosLeaveAnimation, mdLeaveAnimation, this.ev) await dismiss(this, data, role, 'popoverLeave', iosLeaveAnimation, mdLeaveAnimation, this.ev);
.then(() => detachComponent(this.delegate, this.usersElement)); await detachComponent(this.delegate, this.usersElement);
} }
/** /**

View File

@ -80,29 +80,26 @@ export class Router {
} }
@Method() @Method()
navChanged(isPop: boolean): Promise<boolean> { async navChanged(isPop: boolean): Promise<boolean> {
if (this.busy) { if (this.busy) {
return Promise.resolve(false); return false;
} }
console.debug('[IN] nav changed -> update URL'); console.debug('[IN] nav changed -> update URL');
const { ids, pivot } = readNavState(document.body); const { ids, pivot } = readNavState(document.body);
const chain = routerIDsToChain(ids, this.routes); const chain = routerIDsToChain(ids, this.routes);
if (!chain) { if (!chain) {
console.warn('no matching URL for ', ids.map(i => i.id)); console.warn('no matching URL for ', ids.map(i => i.id));
return Promise.resolve(false); return false;
} }
const path = chainToPath(chain); const path = chainToPath(chain);
this.setPath(path, isPop); this.setPath(path, isPop);
const promise = (chain.length > ids.length) if (chain.length > ids.length) {
? this.writeNavState(pivot, chain.slice(ids.length), 0) await this.writeNavState(pivot, chain.slice(ids.length), 0);
: Promise.resolve(true); }
return promise.then(() => {
this.emitRouteChange(path, null); this.emitRouteChange(path, null);
return true; return true;
});
} }
@Method() @Method()
@ -113,9 +110,9 @@ export class Router {
return this.writeNavStateRoot(path, backDirection ? -1 : 1); return this.writeNavStateRoot(path, backDirection ? -1 : 1);
} }
private writeNavStateRoot(path: string[], direction: number): Promise<boolean> { private async writeNavStateRoot(path: string[], direction: number): Promise<boolean> {
if (this.busy) { if (this.busy) {
return Promise.resolve(false); return false;
} }
const redirect = routeRedirect(path, this.redirects); const redirect = routeRedirect(path, this.redirects);
let redirectFrom: string[] = null; let redirectFrom: string[] = null;
@ -125,23 +122,26 @@ export class Router {
path = redirect.to; path = redirect.to;
} }
const chain = routerPathToChain(path, this.routes); const chain = routerPathToChain(path, this.routes);
return this.writeNavState(document.body, chain, direction).then(changed => { const changed = await this.writeNavState(document.body, chain, direction);
if (changed) { if (changed) {
this.emitRouteChange(path, redirectFrom); this.emitRouteChange(path, redirectFrom);
} }
return changed; return changed;
});
} }
private writeNavState(node: any, chain: RouteChain, direction: number): Promise<boolean> { private async writeNavState(node: any, chain: RouteChain, direction: number): Promise<boolean> {
if (this.busy) { if (this.busy) {
return Promise.resolve(false); return false;
} }
try {
this.busy = true; this.busy = true;
return writeNavState(node, chain, 0, direction).then(changed => { const changed = await writeNavState(node, chain, 0, direction);
this.busy = false; this.busy = false;
return changed; return changed;
}); } catch (e) {
this.busy = false;
throw e;
}
} }
private setPath(path: string[], isPop: boolean) { private setPath(path: string[], isPop: boolean) {

View File

@ -53,7 +53,7 @@ export function removeLastOverlay(overlays: OverlayMap) {
return toRemove ? toRemove.dismiss() : Promise.resolve(); return toRemove ? toRemove.dismiss() : Promise.resolve();
} }
export function present( export async function present(
overlay: OverlayInterface, overlay: OverlayInterface,
name: string, name: string,
iosEnterAnimation: AnimationBuilder, iosEnterAnimation: AnimationBuilder,
@ -61,7 +61,7 @@ export function present(
opts?: any opts?: any
) { ) {
if (overlay.presented) { if (overlay.presented) {
return Promise.resolve(); return;
} }
overlay.presented = true; overlay.presented = true;
overlay.willPresent.emit(); overlay.willPresent.emit();
@ -71,12 +71,12 @@ export function present(
? overlay.enterAnimation ? overlay.enterAnimation
: overlay.config.get(name, overlay.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation); : overlay.config.get(name, overlay.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
return overlayAnimation(overlay, animationBuilder, overlay.el, opts).then(() => { await overlayAnimation(overlay, animationBuilder, overlay.el, opts);
overlay.didPresent.emit(); overlay.didPresent.emit();
});
} }
export function dismiss( export async function dismiss(
overlay: OverlayInterface, overlay: OverlayInterface,
data: any|undefined, data: any|undefined,
role: string|undefined, role: string|undefined,
@ -86,7 +86,7 @@ export function dismiss(
opts?: any opts?: any
): Promise<void> { ): Promise<void> {
if (!overlay.presented) { if (!overlay.presented) {
return Promise.resolve(); return;
} }
overlay.presented = false; overlay.presented = false;
@ -96,36 +96,35 @@ export function dismiss(
? overlay.leaveAnimation ? overlay.leaveAnimation
: overlay.config.get(name, overlay.mode === 'ios' ? iosLeaveAnimation : mdLeaveAnimation); : overlay.config.get(name, overlay.mode === 'ios' ? iosLeaveAnimation : mdLeaveAnimation);
return overlayAnimation(overlay, animationBuilder, overlay.el, opts).then(() => { await overlayAnimation(overlay, animationBuilder, overlay.el, opts);
overlay.didDismiss.emit({data, role}); overlay.didDismiss.emit({data, role});
overlay.el.remove(); overlay.el.remove();
});
} }
function overlayAnimation( async function overlayAnimation(
overlay: OverlayInterface, overlay: OverlayInterface,
animationBuilder: AnimationBuilder, animationBuilder: AnimationBuilder,
baseEl: HTMLElement, baseEl: HTMLElement,
opts: any opts: any
): Promise<void> { ): Promise<void> {
if (overlay.keyboardClose) {
closeKeyboard();
}
if (overlay.animation) { if (overlay.animation) {
overlay.animation.destroy(); overlay.animation.destroy();
overlay.animation = undefined; overlay.animation = undefined;
} }
if (overlay.keyboardClose) { const animation = overlay.animation = await overlay.animationCtrl.create(animationBuilder, baseEl, opts);
closeKeyboard();
}
return overlay.animationCtrl.create(animationBuilder, baseEl, opts).then(animation => {
overlay.animation = animation; overlay.animation = animation;
if (!overlay.willAnimate) { if (!overlay.willAnimate) {
animation.duration(0); animation.duration(0);
} }
return animation.playAsync(); await animation.playAsync();
}).then(animation => {
animation.destroy(); animation.destroy();
overlay.animation = undefined; overlay.animation = undefined;
});
} }
export function autoFocus(containerEl: HTMLElement): HTMLElement|null { export function autoFocus(containerEl: HTMLElement): HTMLElement|null {