mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 19:21:34 +08:00
feat(): add ability to continue processing hardware back button events (#20613)
fixes #17824
This commit is contained in:
@ -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;
|
||||
|
Reference in New Issue
Block a user