104 lines
3.0 KiB
TypeScript
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);
|
|
}
|
|
}
|