tweb-i2p/src/helpers/overlayClickHandler.ts
2022-08-10 21:50:25 +02:00

104 lines
3.0 KiB
TypeScript

/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import appNavigationController, {NavigationItem} from '../components/appNavigationController';
import IS_TOUCH_SUPPORTED from '../environment/touchSupport';
import {IS_MOBILE_SAFARI} from '../environment/userAgent';
import cancelEvent from './dom/cancelEvent';
import {CLICK_EVENT_NAME} from './dom/clickEvent';
import findUpAsChild from './dom/findUpAsChild';
import EventListenerBase from './eventListenerBase';
export default class OverlayClickHandler extends EventListenerBase<{
toggle: (open: boolean) => void
}> {
protected element: HTMLElement;
protected overlay: HTMLElement;
protected listenerOptions: AddEventListenerOptions;
constructor(
protected navigationType: NavigationItem['type'],
protected withOverlay?: boolean
) {
super(false);
this.listenerOptions = withOverlay ? undefined : {capture: true};
}
protected onClick = (e: MouseEvent | TouchEvent) => {
if(this.element && findUpAsChild(e.target, this.element)) {
return;
}
cancelEvent(e);
this.close();
};
public close() {
if(this.element) {
this.overlay?.remove();
this.element = undefined;
this.dispatchEvent('toggle', false);
}
if(!IS_TOUCH_SUPPORTED) {
// window.removeEventListener('keydown', onKeyDown, {capture: true});
window.removeEventListener('contextmenu', this.onClick);
}
document.removeEventListener(CLICK_EVENT_NAME, this.onClick, this.listenerOptions);
if(!IS_MOBILE_SAFARI) {
appNavigationController.removeByType(this.navigationType);
}
}
public open(element: HTMLElement) {
this.close();
if(!IS_MOBILE_SAFARI) {
appNavigationController.pushItem({
type: this.navigationType,
onPop: (canAnimate) => {
this.close();
}
});
}
this.element = element;
if(!this.overlay && this.withOverlay) {
this.overlay = document.createElement('div');
this.overlay.classList.add('btn-menu-overlay');
// ! because this event must be canceled, and can't cancel on menu click (below)
this.overlay.addEventListener(CLICK_EVENT_NAME, (e) => {
cancelEvent(e);
this.onClick(e);
});
}
this.overlay && this.element.parentElement.insertBefore(this.overlay, this.element);
// document.body.classList.add('disable-hover');
if(!IS_TOUCH_SUPPORTED) {
// window.addEventListener('keydown', onKeyDown, {capture: true});
window.addEventListener('contextmenu', this.onClick, {once: true});
}
/* // ! because this event must be canceled, and can't cancel on menu click (below)
overlay.addEventListener(CLICK_EVENT_NAME, (e) => {
cancelEvent(e);
onClick(e);
}); */
// ! safari iOS doesn't handle window click event on overlay, idk why
document.addEventListener(CLICK_EVENT_NAME, this.onClick, this.listenerOptions);
this.dispatchEvent('toggle', true);
}
}