mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
6.6 KiB
165 lines
6.6 KiB
/*!
|
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
*/
|
|
import { w as win, d as doc } from './index9.js';
|
|
import { K as Keyboard, a as KeyboardResize } from './keyboard2.js';
|
|
|
|
/**
|
|
* The element that resizes when the keyboard opens
|
|
* is going to depend on the resize mode
|
|
* which is why we check that here.
|
|
*/
|
|
const getResizeContainer = (resizeMode) => {
|
|
/**
|
|
* If doc is undefined then we are
|
|
* in an SSR environment, so the keyboard
|
|
* adjustment does not apply.
|
|
* If the webview does not resize then there
|
|
* is no container to resize.
|
|
*/
|
|
if (doc === undefined || resizeMode === KeyboardResize.None || resizeMode === undefined) {
|
|
return null;
|
|
}
|
|
/**
|
|
* The three remaining resize modes: Native, Ionic, and Body
|
|
* all cause `ion-app` to resize, so we can listen for changes
|
|
* on that. In the event `ion-app` is not available then
|
|
* we can fall back to `body`.
|
|
*/
|
|
const ionApp = doc.querySelector('ion-app');
|
|
return ionApp !== null && ionApp !== void 0 ? ionApp : doc.body;
|
|
};
|
|
/**
|
|
* Get the height of ion-app or body.
|
|
* This is used for determining if the webview
|
|
* has resized before the keyboard closed.
|
|
* */
|
|
const getResizeContainerHeight = (resizeMode) => {
|
|
const containerElement = getResizeContainer(resizeMode);
|
|
return containerElement === null ? 0 : containerElement.clientHeight;
|
|
};
|
|
/**
|
|
* Creates a controller that tracks and reacts to opening or closing the keyboard.
|
|
*
|
|
* @internal
|
|
* @param keyboardChangeCallback A function to call when the keyboard opens or closes.
|
|
*/
|
|
const createKeyboardController = async (keyboardChangeCallback) => {
|
|
let keyboardWillShowHandler;
|
|
let keyboardWillHideHandler;
|
|
let keyboardVisible;
|
|
/**
|
|
* This lets us determine if the webview content
|
|
* has resized as a result of the keyboard.
|
|
*/
|
|
let initialResizeContainerHeight;
|
|
const init = async () => {
|
|
const resizeOptions = await Keyboard.getResizeMode();
|
|
const resizeMode = resizeOptions === undefined ? undefined : resizeOptions.mode;
|
|
keyboardWillShowHandler = () => {
|
|
/**
|
|
* We need to compute initialResizeContainerHeight right before
|
|
* the keyboard opens to guarantee the resize container is visible.
|
|
* The resize container may not be visible if we compute this
|
|
* as soon as the keyboard controller is created.
|
|
* We should only need to do this once to avoid additional clientHeight
|
|
* computations.
|
|
*/
|
|
if (initialResizeContainerHeight === undefined) {
|
|
initialResizeContainerHeight = getResizeContainerHeight(resizeMode);
|
|
}
|
|
keyboardVisible = true;
|
|
fireChangeCallback(keyboardVisible, resizeMode);
|
|
};
|
|
keyboardWillHideHandler = () => {
|
|
keyboardVisible = false;
|
|
fireChangeCallback(keyboardVisible, resizeMode);
|
|
};
|
|
win === null || win === void 0 ? void 0 : win.addEventListener('keyboardWillShow', keyboardWillShowHandler);
|
|
win === null || win === void 0 ? void 0 : win.addEventListener('keyboardWillHide', keyboardWillHideHandler);
|
|
};
|
|
const fireChangeCallback = (state, resizeMode) => {
|
|
if (keyboardChangeCallback) {
|
|
keyboardChangeCallback(state, createResizePromiseIfNeeded(resizeMode));
|
|
}
|
|
};
|
|
/**
|
|
* Code responding to keyboard lifecycles may need
|
|
* to show/hide content once the webview has
|
|
* resized as a result of the keyboard showing/hiding.
|
|
* createResizePromiseIfNeeded provides a way for code to wait for the
|
|
* resize event that was triggered as a result of the keyboard.
|
|
*/
|
|
const createResizePromiseIfNeeded = (resizeMode) => {
|
|
if (
|
|
/**
|
|
* If we are in an SSR environment then there is
|
|
* no window to resize. Additionally, if there
|
|
* is no resize mode or the resize mode is "None"
|
|
* then initialResizeContainerHeight will be 0
|
|
*/
|
|
initialResizeContainerHeight === 0 ||
|
|
/**
|
|
* If the keyboard is closed before the webview resizes initially
|
|
* then the webview will never resize.
|
|
*/
|
|
initialResizeContainerHeight === getResizeContainerHeight(resizeMode)) {
|
|
return;
|
|
}
|
|
/**
|
|
* Get the resize container so we can
|
|
* attach the ResizeObserver below to
|
|
* the correct element.
|
|
*/
|
|
const containerElement = getResizeContainer(resizeMode);
|
|
if (containerElement === null) {
|
|
return;
|
|
}
|
|
/**
|
|
* Some part of the web content should resize,
|
|
* and we need to listen for a resize.
|
|
*/
|
|
return new Promise((resolve) => {
|
|
const callback = () => {
|
|
/**
|
|
* As per the spec, the ResizeObserver
|
|
* will fire when observation starts if
|
|
* the observed element is rendered and does not
|
|
* have a size of 0 x 0. However, the watched element
|
|
* may or may not have resized by the time this first
|
|
* callback is fired. As a result, we need to check
|
|
* the dimensions of the element.
|
|
*
|
|
* https://www.w3.org/TR/resize-observer/#intro
|
|
*/
|
|
if (containerElement.clientHeight === initialResizeContainerHeight) {
|
|
/**
|
|
* The resize happened, so stop listening
|
|
* for resize on this element.
|
|
*/
|
|
ro.disconnect();
|
|
resolve();
|
|
}
|
|
};
|
|
/**
|
|
* In Capacitor there can be delay between when the window
|
|
* resizes and when the container element resizes, so we cannot
|
|
* rely on a 'resize' event listener on the window.
|
|
* Instead, we need to determine when the container
|
|
* element resizes using a ResizeObserver.
|
|
*/
|
|
const ro = new ResizeObserver(callback);
|
|
ro.observe(containerElement);
|
|
});
|
|
};
|
|
const destroy = () => {
|
|
win === null || win === void 0 ? void 0 : win.removeEventListener('keyboardWillShow', keyboardWillShowHandler);
|
|
win === null || win === void 0 ? void 0 : win.removeEventListener('keyboardWillHide', keyboardWillHideHandler);
|
|
keyboardWillShowHandler = keyboardWillHideHandler = undefined;
|
|
};
|
|
const isKeyboardVisible = () => keyboardVisible;
|
|
await init();
|
|
return { init, destroy, isKeyboardVisible };
|
|
};
|
|
|
|
export { createKeyboardController as c };
|
|
|