mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 19:21:34 +08:00

Issue number: internal --------- ## What is the current behavior? - `LogLevel` throws error `Error: Cannot access ambient const enums when 'isolatedModules' is enabled` - Several existing console warns and errors are not calling the function that respects the `logLevel` config ## What is the new behavior? - Remove `const` from the `enum` to work with `isolatedModules` - Update `console.warn`s to `printIonWarning` - Update `console.error`s to `printIonError` ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information Dev build: `8.5.5-dev.11744729748.174bf7e0` --------- Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
141 lines
4.0 KiB
TypeScript
141 lines
4.0 KiB
TypeScript
import { win } from '@utils/browser';
|
|
import type { CloseWatcher } from '@utils/browser';
|
|
import { printIonError } from '@utils/logging';
|
|
|
|
import { config } from '../global/config';
|
|
|
|
// TODO(FW-2832): type
|
|
type Handler = (processNextHandler: () => void) => Promise<any> | void | null;
|
|
|
|
export interface BackButtonEventDetail {
|
|
register(priority: number, handler: (processNextHandler: () => void) => Promise<any> | void): void;
|
|
}
|
|
|
|
export type BackButtonEvent = CustomEvent<BackButtonEventDetail>;
|
|
|
|
interface HandlerRegister {
|
|
priority: number;
|
|
handler: Handler;
|
|
id: number;
|
|
}
|
|
|
|
/**
|
|
* CloseWatcher is a newer API that lets
|
|
* use detect the hardware back button event
|
|
* in a web browser: https://caniuse.com/?search=closewatcher
|
|
* However, not every browser supports it yet.
|
|
*
|
|
* This needs to be a function so that we can
|
|
* check the config once it has been set.
|
|
* Otherwise, this code would be evaluated the
|
|
* moment this file is evaluated which could be
|
|
* before the config is set.
|
|
*/
|
|
export const shouldUseCloseWatcher = () =>
|
|
config.get('experimentalCloseWatcher', false) && win !== undefined && 'CloseWatcher' in win;
|
|
|
|
/**
|
|
* When hardwareBackButton: false in config,
|
|
* we need to make sure we also block the default
|
|
* webview behavior. If we don't then it will be
|
|
* possible for users to navigate backward while
|
|
* an overlay is still open. Additionally, it will
|
|
* give the appearance that the hardwareBackButton
|
|
* config is not working as the page transition
|
|
* will still happen.
|
|
*/
|
|
export const blockHardwareBackButton = () => {
|
|
document.addEventListener('backbutton', () => {}); // eslint-disable-line
|
|
};
|
|
|
|
export const startHardwareBackButton = () => {
|
|
const doc = document;
|
|
let busy = false;
|
|
|
|
const backButtonCallback = () => {
|
|
if (busy) {
|
|
return;
|
|
}
|
|
|
|
let index = 0;
|
|
let handlers: HandlerRegister[] = [];
|
|
const ev: BackButtonEvent = new CustomEvent('ionBackButton', {
|
|
bubbles: false,
|
|
detail: {
|
|
register(priority: number, handler: Handler) {
|
|
handlers.push({ priority, handler, id: index++ });
|
|
},
|
|
},
|
|
});
|
|
doc.dispatchEvent(ev);
|
|
|
|
const executeAction = async (handlerRegister: HandlerRegister | undefined) => {
|
|
try {
|
|
if (handlerRegister?.handler) {
|
|
const result = handlerRegister.handler(processHandlers);
|
|
if (result != null) {
|
|
await result;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
printIonError('[ion-app] - Exception in startHardwareBackButton:', 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();
|
|
};
|
|
|
|
/**
|
|
* If the CloseWatcher is defined then
|
|
* we don't want to also listen for the native
|
|
* backbutton event otherwise we may get duplicate
|
|
* events firing.
|
|
*/
|
|
if (shouldUseCloseWatcher()) {
|
|
let watcher: CloseWatcher | undefined;
|
|
|
|
const configureWatcher = () => {
|
|
watcher?.destroy();
|
|
watcher = new win!.CloseWatcher!();
|
|
|
|
/**
|
|
* Once a close request happens
|
|
* the watcher gets destroyed.
|
|
* As a result, we need to re-configure
|
|
* the watcher so we can respond to other
|
|
* close requests.
|
|
*/
|
|
watcher!.onclose = () => {
|
|
backButtonCallback();
|
|
configureWatcher();
|
|
};
|
|
};
|
|
|
|
configureWatcher();
|
|
} else {
|
|
doc.addEventListener('backbutton', backButtonCallback);
|
|
}
|
|
};
|
|
|
|
export const OVERLAY_BACK_BUTTON_PRIORITY = 100;
|
|
export const MENU_BACK_BUTTON_PRIORITY = 99; // 1 less than overlay priority since menu is displayed behind overlays
|