feat(): add ability to continue processing hardware back button events (#20613)

fixes #17824
This commit is contained in:
Liam DeBeasi
2020-04-27 12:58:37 -04:00
committed by GitHub
parent 429edb053b
commit 3821c0463a
8 changed files with 115 additions and 37 deletions

View File

@ -1,10 +1,11 @@
import { BackButtonEvent } from '../interface';
type Handler = () => Promise<any> | void | null;
type Handler = (processNextHandler: () => void) => Promise<any> | void | null;
interface HandlerRegister {
priority: number;
handler: Handler;
id: number;
}
export const startHardwareBackButton = () => {
@ -16,44 +17,52 @@ export const startHardwareBackButton = () => {
return;
}
const handlers: HandlerRegister[] = [];
let index = 0;
let handlers: HandlerRegister[] = [];
const ev: BackButtonEvent = new CustomEvent('ionBackButton', {
bubbles: false,
detail: {
register(priority: number, handler: Handler) {
handlers.push({ priority, handler });
handlers.push({ priority, handler, id: index++ });
}
}
});
doc.dispatchEvent(ev);
if (handlers.length > 0) {
let selectedPriority = Number.MIN_SAFE_INTEGER;
let selectedHandler: Handler | undefined;
handlers.forEach(({ priority, handler }) => {
if (priority >= selectedPriority) {
selectedPriority = priority;
selectedHandler = handler;
const executeAction = async (handlerRegister: HandlerRegister | undefined) => {
try {
if (handlerRegister && handlerRegister.handler) {
const result = handlerRegister.handler(processHandlers);
if (result != null) {
await result;
}
}
});
busy = true;
executeAction(selectedHandler).then(() => busy = false);
}
});
};
const executeAction = async (handler: Handler | undefined) => {
try {
if (handler) {
const result = handler();
if (result != null) {
await result;
} catch (e) {
console.error(e);
}
}
} catch (e) {
console.error(e);
}
};
const processHandlers = () => {
if (handlers.length > 0) {
let selectedHandler: HandlerRegister = {
priority: Number.MIN_SAFE_INTEGER,
handler: () => undefined,
id: -1
};
handlers.forEach(handler => {
if (handler.priority >= selectedHandler.priority) {
selectedHandler = handler;
}
});
busy = true;
handlers = handlers.filter(handler => handler.id !== selectedHandler.id);
executeAction(selectedHandler).then(() => busy = false);
}
};
processHandlers();
});
};
export const OVERLAY_BACK_BUTTON_PRIORITY = 100;