/
input-shims.ts
92 lines (75 loc) · 3.11 KB
/
input-shims.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import type { Config } from '../../interface';
import { findClosestIonContent } from '../content';
import { componentOnReady } from '../helpers';
import { enableHideCaretOnScroll } from './hacks/hide-caret';
import { enableInputBlurring } from './hacks/input-blurring';
import { enableScrollAssist } from './hacks/scroll-assist';
import { enableScrollPadding } from './hacks/scroll-padding';
const INPUT_BLURRING = true;
const SCROLL_ASSIST = true;
const SCROLL_PADDING = true;
const HIDE_CARET = true;
export const startInputShims = (config: Config) => {
const doc = document;
const keyboardHeight = config.getNumber('keyboardHeight', 290);
const scrollAssist = config.getBoolean('scrollAssist', true);
const hideCaret = config.getBoolean('hideCaretOnScroll', true);
const inputBlurring = config.getBoolean('inputBlurring', true);
const scrollPadding = config.getBoolean('scrollPadding', true);
const inputs = Array.from(doc.querySelectorAll('ion-input, ion-textarea')) as HTMLElement[];
const hideCaretMap = new WeakMap<HTMLElement, () => void>();
const scrollAssistMap = new WeakMap<HTMLElement, () => void>();
const registerInput = async (componentEl: HTMLElement) => {
await new Promise((resolve) => componentOnReady(componentEl, resolve));
const inputRoot = componentEl.shadowRoot || componentEl;
const inputEl = inputRoot.querySelector('input') || inputRoot.querySelector('textarea');
const scrollEl = findClosestIonContent(componentEl);
const footerEl = !scrollEl ? (componentEl.closest('ion-footer') as HTMLIonFooterElement | null) : null;
if (!inputEl) {
return;
}
if (HIDE_CARET && !!scrollEl && hideCaret && !hideCaretMap.has(componentEl)) {
const rmFn = enableHideCaretOnScroll(componentEl, inputEl, scrollEl);
hideCaretMap.set(componentEl, rmFn);
}
if (SCROLL_ASSIST && (!!scrollEl || !!footerEl) && scrollAssist && !scrollAssistMap.has(componentEl)) {
const rmFn = enableScrollAssist(componentEl, inputEl, scrollEl, footerEl, keyboardHeight);
scrollAssistMap.set(componentEl, rmFn);
}
};
const unregisterInput = (componentEl: HTMLElement) => {
if (HIDE_CARET && hideCaret) {
const fn = hideCaretMap.get(componentEl);
if (fn) {
fn();
}
hideCaretMap.delete(componentEl);
}
if (SCROLL_ASSIST && scrollAssist) {
const fn = scrollAssistMap.get(componentEl);
if (fn) {
fn();
}
scrollAssistMap.delete(componentEl);
}
};
if (inputBlurring && INPUT_BLURRING) {
enableInputBlurring();
}
if (scrollPadding && SCROLL_PADDING) {
enableScrollPadding(keyboardHeight);
}
// Input might be already loaded in the DOM before ion-device-hacks did.
// At this point we need to look for all of the inputs not registered yet
// and register them.
for (const input of inputs) {
registerInput(input);
}
doc.addEventListener('ionInputDidLoad', ((ev: InputEvent) => {
registerInput(ev.detail);
}) as any);
doc.addEventListener('ionInputDidUnload', ((ev: InputEvent) => {
unregisterInput(ev.detail);
}) as any);
};
type InputEvent = CustomEvent<HTMLElement>;