{"version":3,"sources":["webpack:///./src/helpers/sequentialDom.ts","webpack:///./src/helpers/dom/isSwipingBackSafari.ts","webpack:///./src/components/ripple.ts","webpack:///./src/helpers/dom/clickEvent.ts","webpack:///./src/components/button.ts","webpack:///./src/components/misc.ts","webpack:///./src/components/appNavigationController.ts","webpack:///./src/helpers/dom/dispatchEvent.ts"],"names":["sequentialDom","promises","raf","bind","scheduled","kind","callback","promise","this","scheduleFlush","undefined","then","do","element","isConnected","mutate","Promise","resolve","read","write","isSwipingBackSafari","e","TouchEvent","touches","clientX","rippleClickId","ripple","elem","onEnd","prepend","attachListenerTo","querySelector","classList","add","r","document","createElement","handler","contains","drawRipple","clientY","startTime","Date","now","clickId","duration","window","getComputedStyle","getPropertyValue","replace","elapsedTime","cb","remove","delay","Math","max","setTimeout","removeEventListener","touchStartFired","requestAnimationFrame","rect","getBoundingClientRect","clickX","left","clickY","top","size","sqrt","abs","height","width","x","y","style","append","isRippleUnneeded","target","includes","tagName","touchEnd","addEventListener","settings","animationsEnabled","length","once","cancelBubble","stopPropagation","passive","button","dataset","CLICK_EVENT_NAME","attachClickEvent","options","listenerSetter","touchMouseDown","detachClickEvent","simulateClickEvent","className","asDiv","icon","noRipple","rippleSquare","onlyMobile","disabled","setAttribute","text","putPreloader","returnDiv","html","div","innerHTML","appendChild","insertAdjacentHTML","lastElementChild","setButtonLoader","removeAttribute","onMouseMove","openedMenu","diffX","right","diffY","bottom","closeBtnMenu","onClick","parentElement","menuOverlay","dispatchEvent","openedMenuOnClose","removeByType","openBtnMenu","menuElement","onClose","pushItem","type","onPop","canAnimate","insertBefore","positionMenu","pageX","pageY","side","additionalPadding","getScrollWidthFromElement","Array","from","children","find","scrollWidth","menuWidth","scrollHeight","menuHeight","body","windowWidth","windowHeight","paddingTop","paddingRight","paddingBottom","paddingLeft","isMobile","verticalSide","maxTop","maxLeft","minLeft","sides","min","intermediateX","intermediateY","possibleSides","_cancelContextMenuOpening","_cancelContextMenuOpeningTimeout","cancelContextMenuOpening","clearTimeout","attachContextMenuListener","removeManual","timeout","capture","onCancel","appNavigationController","navigations","id","manual","log","debug","currentHash","location","hash","isPossibleSwipe","onHashChange","replaceState","state","pushState","item","pop","handleItem","key","onEscape","back","history","scrollRestoration","good","noBlurOnPop","i","index","ret","findItemByType","backByItem","indexOf","splice","noHistory","push","onItemAdded","unshift","origin","pathname","single","simulateEvent","name","event","Event","bubbles","cancelable"],"mappings":"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","file":"3.793e215e3d9630206e52.chunk.js","sourcesContent":["/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { fastRaf } from \"./schedulers\";\r\nimport { CancellablePromise, deferredPromise } from \"./cancellablePromise\";\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport isInDOM from \"./dom/isInDOM\";\r\n\r\nclass SequentialDom {\r\n private promises: Partial<{\r\n read: CancellablePromise,\r\n write: CancellablePromise\r\n }> = {};\r\n private raf = fastRaf.bind(null);\r\n private scheduled = false;\r\n\r\n private do(kind: keyof SequentialDom['promises'], callback?: VoidFunction) {\r\n let promise = this.promises[kind];\r\n if(!promise) {\r\n this.scheduleFlush();\r\n promise = this.promises[kind] = deferredPromise();\r\n }\r\n\r\n if(callback !== undefined) {\r\n promise.then(() => callback());\r\n }\r\n \r\n return promise;\r\n }\r\n\r\n public measure(callback?: VoidFunction) {\r\n return this.do('read', callback);\r\n }\r\n\r\n public mutate(callback?: VoidFunction) {\r\n return this.do('write', callback);\r\n }\r\n\r\n /**\r\n * Will fire instantly if element is not connected\r\n * @param element \r\n * @param callback \r\n */\r\n public mutateElement(element: HTMLElement, callback?: VoidFunction) {\r\n const isConnected = isInDOM(element);\r\n const promise = isConnected ? this.mutate() : Promise.resolve();\r\n\r\n if(callback !== undefined) {\r\n if(isConnected) {\r\n callback();\r\n } else {\r\n promise.then(() => callback());\r\n }\r\n }\r\n\r\n return promise;\r\n }\r\n\r\n private scheduleFlush() {\r\n if(!this.scheduled) {\r\n this.scheduled = true;\r\n\r\n this.raf(() => {\r\n this.promises.read && this.promises.read.resolve();\r\n this.promises.write && this.promises.write.resolve();\r\n\r\n this.scheduled = false;\r\n this.promises = {};\r\n });\r\n }\r\n }\r\n}\r\n\r\nconst sequentialDom = new SequentialDom();\r\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.sequentialDom = sequentialDom);\r\nexport default sequentialDom;\r\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport { IS_MOBILE_SAFARI } from \"../../environment/userAgent\";\n\nexport default function isSwipingBackSafari(e: TouchEvent | MouseEvent) {\n return IS_MOBILE_SAFARI && e instanceof TouchEvent && e.touches[0].clientX < 30;\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport findUpClassName from \"../helpers/dom/findUpClassName\";\r\nimport sequentialDom from \"../helpers/sequentialDom\";\r\nimport {IS_TOUCH_SUPPORTED} from \"../environment/touchSupport\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport findUpAsChild from \"../helpers/dom/findUpAsChild\";\r\n\r\nlet rippleClickId = 0;\r\nexport function ripple(\r\n elem: HTMLElement, \r\n callback: (id: number) => Promise = () => Promise.resolve(), \r\n onEnd: (id: number) => void = null, \r\n prepend = false,\r\n attachListenerTo = elem\r\n) {\r\n //return;\r\n if(elem.querySelector('.c-ripple')) return;\r\n elem.classList.add('rp');\r\n \r\n let r = document.createElement('div');\r\n r.classList.add('c-ripple');\r\n\r\n const isSquare = elem.classList.contains('rp-square');\r\n if(isSquare) {\r\n r.classList.add('is-square');\r\n }\r\n\r\n elem[prepend ? 'prepend' : 'append'](r);\r\n\r\n let handler: () => void;\r\n //let animationEndPromise: Promise;\r\n const drawRipple = (clientX: number, clientY: number) => {\r\n const startTime = Date.now();\r\n const elem = document.createElement('div');\r\n\r\n const clickId = rippleClickId++;\r\n \r\n //console.log('ripple drawRipple');\r\n \r\n const duration = +window.getComputedStyle(r).getPropertyValue('--ripple-duration').replace('s', '') * 1000;\r\n //console.log('ripple duration', duration);\r\n\r\n handler = () => {\r\n //handler = () => animationEndPromise.then((duration) => {\r\n //console.log('ripple animation was:', duration);\r\n\r\n //const duration = isSquare || mediaSizes.isMobile ? 200 : 700;\r\n //return;\r\n let elapsedTime = Date.now() - startTime;\r\n const cb = () => {\r\n //console.log('ripple elapsedTime total pre-remove:', Date.now() - startTime);\r\n sequentialDom.mutate(() => {\r\n elem.remove();\r\n });\r\n \r\n if(onEnd) onEnd(clickId);\r\n };\r\n if(elapsedTime < duration) {\r\n let delay = Math.max(duration - elapsedTime, duration / 2);\r\n setTimeout(() => elem.classList.add('hiding'), Math.max(delay - duration / 2, 0));\r\n\r\n setTimeout(cb, delay);\r\n } else {\r\n elem.classList.add('hiding');\r\n setTimeout(cb, duration / 2);\r\n }\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.removeEventListener('contextmenu', handler);\r\n }\r\n\r\n handler = null;\r\n touchStartFired = false;\r\n };\r\n //});\r\n\r\n callback && callback(clickId);\r\n\r\n /* callback().then((bad) => {\r\n if(bad) {\r\n span.remove();\r\n return;\r\n } */\r\n \r\n //console.log('ripple after promise', Date.now() - startTime);\r\n //console.log('ripple tooSlow:', tooSlow);\r\n /* if(tooSlow) {\r\n span.remove();\r\n return;\r\n } */\r\n\r\n window.requestAnimationFrame(() => {\r\n const rect = r.getBoundingClientRect();\r\n elem.classList.add('c-ripple__circle');\r\n\r\n const clickX = clientX - rect.left;\r\n const clickY = clientY - rect.top;\r\n\r\n const radius = Math.sqrt((Math.abs(clickY - rect.height / 2) + rect.height / 2) ** 2 + (Math.abs(clickX - rect.width / 2) + rect.width / 2) ** 2);\r\n const size = radius;\r\n\r\n // center of circle\r\n const x = clickX - size / 2;\r\n const y = clickY - size / 2;\r\n\r\n //console.log('ripple click', offsetFromCenter, size, clickX, clickY);\r\n\r\n elem.style.width = elem.style.height = size + 'px';\r\n elem.style.left = x + 'px';\r\n elem.style.top = y + 'px';\r\n\r\n // нижний код выполняется с задержкой\r\n /* animationEndPromise = new Promise((resolve) => {\r\n span.addEventListener('animationend', () => {\r\n // 713 -> 700\r\n resolve(((Date.now() - startTime) / 100 | 0) * 100);\r\n }, {once: true});\r\n }); */\r\n \r\n // нижний код не всегда включает анимацию ПРИ КЛИКЕ НА ТАЧПАД БЕЗ ТАПТИК ЭНЖИНА\r\n /* span.style.display = 'none';\r\n r.append(span);\r\n duration = +window.getComputedStyle(span).getPropertyValue('animation-duration').replace('s', '') * 1000;\r\n span.style.display = ''; */\r\n\r\n r.append(elem);\r\n\r\n //r.classList.add('active');\r\n //handler();\r\n });\r\n //});\r\n };\r\n\r\n const isRippleUnneeded = (e: Event) => e.target !== elem && (\r\n ['BUTTON', 'A'].includes((e.target as HTMLElement).tagName) \r\n || findUpClassName(e.target as HTMLElement, 'c-ripple') !== r\r\n ) && (\r\n attachListenerTo === elem \r\n || !findUpAsChild(e.target, attachListenerTo)\r\n );\r\n\r\n // TODO: rename this variable\r\n let touchStartFired = false;\r\n if(IS_TOUCH_SUPPORTED) {\r\n let touchEnd = () => {\r\n handler && handler();\r\n };\r\n \r\n attachListenerTo.addEventListener('touchstart', (e) => {\r\n if(!rootScope.settings.animationsEnabled) {\r\n return;\r\n }\r\n\r\n //console.log('ripple touchstart', e);\r\n if(e.touches.length > 1 || touchStartFired || isRippleUnneeded(e)) {\r\n return;\r\n }\r\n \r\n //console.log('touchstart', e);\r\n touchStartFired = true;\r\n \r\n let {clientX, clientY} = e.touches[0];\r\n drawRipple(clientX, clientY);\r\n attachListenerTo.addEventListener('touchend', touchEnd, {once: true});\r\n \r\n window.addEventListener('touchmove', (e) => {\r\n e.cancelBubble = true;\r\n e.stopPropagation();\r\n touchEnd();\r\n attachListenerTo.removeEventListener('touchend', touchEnd);\r\n }, {once: true});\r\n }, {passive: true});\r\n } else {\r\n attachListenerTo.addEventListener('mousedown', (e) => {\r\n if(![0, 2].includes(e.button)) { // only left and right buttons\r\n return;\r\n }\r\n\r\n if(!rootScope.settings.animationsEnabled) {\r\n return;\r\n }\r\n //console.log('ripple mousedown', e, e.target, findUpClassName(e.target as HTMLElement, 'c-ripple') === r);\r\n\r\n if(attachListenerTo.dataset.ripple === '0' || isRippleUnneeded(e)) {\r\n return;\r\n } else if(touchStartFired) {\r\n touchStartFired = false;\r\n return;\r\n }\r\n \r\n let {clientX, clientY} = e;\r\n drawRipple(clientX, clientY);\r\n window.addEventListener('mouseup', handler, {once: true, passive: true});\r\n window.addEventListener('contextmenu', handler, {once: true, passive: true});\r\n }, {passive: true});\r\n }\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport type ListenerSetter from \"../listenerSetter\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../../environment/touchSupport\";\r\nimport simulateEvent from \"./dispatchEvent\";\r\n\r\nexport const CLICK_EVENT_NAME: 'mousedown' /* | 'touchend' */ | 'click' = (IS_TOUCH_SUPPORTED ? 'mousedown' : 'click') as any;\r\nexport type AttachClickOptions = AddEventListenerOptions & Partial<{listenerSetter: ListenerSetter, touchMouseDown: true}>;\r\nexport function attachClickEvent(elem: HTMLElement | Window, callback: (e: /* TouchEvent | */MouseEvent) => void, options: AttachClickOptions = {}) {\r\n const add = options.listenerSetter ? options.listenerSetter.add(elem) : elem.addEventListener.bind(elem);\r\n // const remove = options.listenerSetter ? options.listenerSetter.removeManual.bind(options.listenerSetter, elem) : elem.removeEventListener.bind(elem);\r\n\r\n options.touchMouseDown = true;\r\n /* if(options.touchMouseDown && CLICK_EVENT_NAME === 'touchend') {\r\n add('mousedown', callback, options);\r\n } else if(CLICK_EVENT_NAME === 'touchend') {\r\n const o = {...options, once: true};\r\n\r\n const onTouchStart = (e: TouchEvent) => {\r\n const onTouchMove = (e: TouchEvent) => {\r\n remove('touchmove', onTouchMove, o);\r\n remove('touchend', onTouchEnd, o);\r\n };\r\n \r\n const onTouchEnd = (e: TouchEvent) => {\r\n remove('touchmove', onTouchMove, o);\r\n callback(e);\r\n if(options.once) {\r\n remove('touchstart', onTouchStart);\r\n }\r\n };\r\n \r\n add('touchend', onTouchEnd, o);\r\n add('touchmove', onTouchMove, o);\r\n };\r\n\r\n add('touchstart', onTouchStart);\r\n } else {\r\n add(CLICK_EVENT_NAME, callback, options);\r\n } */\r\n add(CLICK_EVENT_NAME, callback, options);\r\n}\r\n\r\nexport function detachClickEvent(elem: HTMLElement, callback: (e: /* TouchEvent | */MouseEvent) => void, options?: AddEventListenerOptions) {\r\n // if(CLICK_EVENT_NAME === 'touchend') {\r\n // elem.removeEventListener('touchstart', callback, options);\r\n // } else {\r\n elem.removeEventListener(CLICK_EVENT_NAME, callback, options);\r\n // }\r\n}\r\n\r\nexport function simulateClickEvent(elem: HTMLElement) {\r\n simulateEvent(elem, CLICK_EVENT_NAME);\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { i18n, LangPackKey } from \"../lib/langPack\";\r\nimport { ripple } from \"./ripple\";\r\n\r\nexport type ButtonOptions = Partial<{\r\n noRipple: true, \r\n onlyMobile: true, \r\n icon: string, \r\n rippleSquare: true, \r\n text: LangPackKey, \r\n disabled: boolean,\r\n asDiv: boolean\r\n}>;\r\n\r\nconst Button = (className: string, options: ButtonOptions = {}) => {\r\n const button: HTMLButtonElement = document.createElement(options.asDiv ? 'div' : 'button') as any;\r\n button.className = className + (options.icon ? ' tgico-' + options.icon : '');\r\n\r\n if(!options.noRipple) {\r\n if(options.rippleSquare) {\r\n button.classList.add('rp-square');\r\n }\r\n\r\n ripple(button);\r\n }\r\n\r\n if(options.onlyMobile) {\r\n button.classList.add('only-handhelds');\r\n }\r\n\r\n if(options.disabled) {\r\n button.setAttribute('disabled', 'true');\r\n }\r\n\r\n if(options.text) {\r\n button.append(i18n(options.text));\r\n }\r\n\r\n return button;\r\n};\r\n\r\nexport default Button;\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport { CLICK_EVENT_NAME } from \"../helpers/dom/clickEvent\";\r\nimport ListenerSetter from \"../helpers/listenerSetter\";\r\nimport mediaSizes from \"../helpers/mediaSizes\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport { IS_APPLE, IS_MOBILE_SAFARI } from \"../environment/userAgent\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport appNavigationController from \"./appNavigationController\";\r\n\r\nexport function putPreloader(elem: Element, returnDiv = false): HTMLElement {\r\n const html = `\r\n \r\n \r\n `;\r\n\r\n if(returnDiv) {\r\n const div = document.createElement('div');\r\n div.classList.add('preloader');\r\n div.innerHTML = html;\r\n\r\n if(elem) {\r\n elem.appendChild(div);\r\n }\r\n\r\n return div;\r\n }\r\n \r\n elem.insertAdjacentHTML('beforeend', html);\r\n return elem.lastElementChild as HTMLElement;\r\n}\r\n\r\nMOUNT_CLASS_TO.putPreloader = putPreloader;\r\n\r\nexport function setButtonLoader(elem: HTMLButtonElement, icon = 'check') {\r\n elem.classList.remove('tgico-' + icon);\r\n elem.disabled = true;\r\n putPreloader(elem);\r\n\r\n return () => {\r\n elem.innerHTML = '';\r\n elem.classList.add('tgico-' + icon);\r\n elem.removeAttribute('disabled');\r\n };\r\n}\r\n\r\n/* export function parseMenuButtonsTo(to: {[name: string]: HTMLElement}, elements: HTMLCollection | NodeListOf) {\r\n Array.from(elements).forEach(el => {\r\n const match = el.className.match(/(?:^|\\s)menu-(.+?)(?:$|\\s)/);\r\n if(!match) return;\r\n to[match[1]] = el as HTMLElement;\r\n });\r\n} */\r\n\r\nlet onMouseMove = (e: MouseEvent) => {\r\n let rect = openedMenu.getBoundingClientRect();\r\n let {clientX, clientY} = e;\r\n \r\n let diffX = clientX >= rect.right ? clientX - rect.right : rect.left - clientX;\r\n let diffY = clientY >= rect.bottom ? clientY - rect.bottom : rect.top - clientY;\r\n \r\n if(diffX >= 100 || diffY >= 100) {\r\n closeBtnMenu();\r\n //openedMenu.parentElement.click();\r\n }\r\n //console.log('mousemove', diffX, diffY);\r\n};\r\n\r\nconst onClick = (e: MouseEvent | TouchEvent) => {\r\n //cancelEvent(e);\r\n closeBtnMenu();\r\n};\r\n\r\n// ! no need in this due to the same handler in appNavigationController\r\n/* const onKeyDown = (e: KeyboardEvent) => {\r\n if(e.key === 'Escape') {\r\n closeBtnMenu();\r\n cancelEvent(e);\r\n }\r\n}; */\r\n\r\nexport const closeBtnMenu = () => {\r\n if(openedMenu) {\r\n openedMenu.classList.remove('active');\r\n openedMenu.parentElement.classList.remove('menu-open');\r\n //openedMenu.previousElementSibling.remove(); // remove overlay\r\n if(menuOverlay) menuOverlay.remove();\r\n openedMenu = null;\r\n\r\n rootScope.dispatchEvent('context_menu_toggle', false);\r\n }\r\n \r\n if(openedMenuOnClose) {\r\n openedMenuOnClose();\r\n openedMenuOnClose = null;\r\n }\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.removeEventListener('mousemove', onMouseMove);\r\n //window.removeEventListener('keydown', onKeyDown, {capture: true});\r\n window.removeEventListener('contextmenu', onClick);\r\n }\r\n\r\n document.removeEventListener(CLICK_EVENT_NAME, onClick);\r\n\r\n if(!IS_MOBILE_SAFARI) {\r\n appNavigationController.removeByType('menu');\r\n }\r\n};\r\n\r\nwindow.addEventListener('resize', () => {\r\n if(openedMenu) {\r\n closeBtnMenu();\r\n }\r\n \r\n /* if(openedMenu && (openedMenu.style.top || openedMenu.style.left)) {\r\n const rect = openedMenu.getBoundingClientRect();\r\n const {innerWidth, innerHeight} = window;\r\n\r\n console.log(innerWidth, innerHeight, rect);\r\n } */\r\n});\r\n\r\nlet openedMenu: HTMLElement = null, openedMenuOnClose: () => void = null, menuOverlay: HTMLElement = null;\r\nexport function openBtnMenu(menuElement: HTMLElement, onClose?: () => void) {\r\n closeBtnMenu();\r\n\r\n if(!IS_MOBILE_SAFARI) {\r\n appNavigationController.pushItem({\r\n type: 'menu',\r\n onPop: (canAnimate) => {\r\n closeBtnMenu();\r\n }\r\n });\r\n }\r\n \r\n openedMenu = menuElement;\r\n openedMenu.classList.add('active');\r\n openedMenu.parentElement.classList.add('menu-open');\r\n\r\n if(!menuOverlay) {\r\n menuOverlay = document.createElement('div');\r\n menuOverlay.classList.add('btn-menu-overlay');\r\n\r\n // ! because this event must be canceled, and can't cancel on menu click (below)\r\n menuOverlay.addEventListener(CLICK_EVENT_NAME, (e) => {\r\n cancelEvent(e);\r\n onClick(e);\r\n });\r\n }\r\n\r\n openedMenu.parentElement.insertBefore(menuOverlay, openedMenu);\r\n\r\n //document.body.classList.add('disable-hover');\r\n \r\n openedMenuOnClose = onClose;\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.addEventListener('mousemove', onMouseMove);\r\n //window.addEventListener('keydown', onKeyDown, {capture: true});\r\n window.addEventListener('contextmenu', onClick, {once: true});\r\n }\r\n\r\n /* // ! because this event must be canceled, and can't cancel on menu click (below)\r\n overlay.addEventListener(CLICK_EVENT_NAME, (e) => {\r\n cancelEvent(e);\r\n onClick(e);\r\n }); */\r\n \r\n // ! safari iOS doesn't handle window click event on overlay, idk why\r\n document.addEventListener(CLICK_EVENT_NAME, onClick);\r\n\r\n rootScope.dispatchEvent('context_menu_toggle', true);\r\n}\r\n\r\nexport type MenuPositionPadding = {\r\n top?: number, \r\n right?: number, \r\n bottom?: number, \r\n left?: number\r\n};\r\n\r\nconst PADDING_TOP = 8;\r\nconst PADDING_BOTTOM = PADDING_TOP;\r\nconst PADDING_LEFT = 8;\r\nconst PADDING_RIGHT = PADDING_LEFT;\r\nexport function positionMenu({pageX, pageY}: MouseEvent | Touch, elem: HTMLElement, side?: 'left' | 'right' | 'center', additionalPadding?: MenuPositionPadding) {\r\n //let {clientX, clientY} = e;\r\n\r\n // * side mean the OPEN side\r\n\r\n const getScrollWidthFromElement = (Array.from(elem.children) as HTMLElement[]).find(element => element.classList.contains('btn-menu-item') && !element.classList.contains('hide')) || elem;\r\n\r\n let {scrollWidth: menuWidth} = getScrollWidthFromElement;\r\n let {scrollHeight: menuHeight} = elem;\r\n //let {innerWidth: windowWidth, innerHeight: windowHeight} = window;\r\n const rect = document.body.getBoundingClientRect();\r\n const windowWidth = rect.width;\r\n const windowHeight = rect.height;\r\n\r\n let paddingTop = PADDING_TOP, paddingRight = PADDING_RIGHT, paddingBottom = PADDING_BOTTOM, paddingLeft = PADDING_LEFT;\r\n if(additionalPadding) {\r\n if(additionalPadding.top) paddingTop += additionalPadding.top;\r\n if(additionalPadding.right) paddingRight += additionalPadding.right;\r\n if(additionalPadding.bottom) paddingBottom += additionalPadding.bottom;\r\n if(additionalPadding.left) paddingLeft += additionalPadding.left;\r\n }\r\n\r\n side = mediaSizes.isMobile ? 'right' : 'left';\r\n let verticalSide: 'top' /* | 'bottom' */ | 'center' = 'top';\r\n\r\n const maxTop = windowHeight - menuHeight - paddingBottom;\r\n const maxLeft = windowWidth - menuWidth - paddingRight;\r\n const minTop = paddingTop;\r\n const minLeft = paddingLeft;\r\n\r\n const getSides = () => {\r\n return {\r\n x: {\r\n left: pageX,\r\n right: Math.min(maxLeft, pageX - menuWidth)\r\n },\r\n intermediateX: side === 'right' ? minLeft : maxLeft,\r\n //intermediateX: clientX < windowWidth / 2 ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,\r\n y: {\r\n top: pageY,\r\n bottom: pageY - menuHeight\r\n },\r\n //intermediateY: verticalSide === 'top' ? paddingTop : windowHeight - menuHeight - paddingTop,\r\n // intermediateY: pageY < (windowHeight / 2) ? paddingTop : windowHeight - menuHeight - paddingBottom,\r\n intermediateY: maxTop,\r\n };\r\n };\r\n\r\n const sides = getSides();\r\n\r\n const possibleSides = {\r\n x: {\r\n left: (sides.x.left + menuWidth + paddingRight) <= windowWidth,\r\n right: sides.x.right >= paddingLeft\r\n },\r\n y: {\r\n top: (sides.y.top + menuHeight + paddingBottom) <= windowHeight,\r\n bottom: (sides.y.bottom - paddingBottom) >= paddingBottom\r\n }\r\n };\r\n\r\n /* if(side === undefined) {\r\n if((clientX + menuWidth + PADDING_LEFT) > windowWidth) {\r\n side = 'right';\r\n }\r\n } */\r\n\r\n {\r\n /* const x = sides.x;\r\n\r\n const s = Object.keys(x) as (keyof typeof possibleSides.x)[];\r\n if(side) {\r\n s.findAndSplice(s => s === side);\r\n s.unshift(side);\r\n }\r\n\r\n const possibleSide = s.find(s => possibleSides.x[s]); */\r\n let left: number;\r\n /* if(possibleSide) {\r\n left = x[possibleSide];\r\n side = possibleSide;\r\n } else {\r\n left = sides.intermediateX;\r\n side = undefined;\r\n } */\r\n left = possibleSides.x[side] ? sides.x[side] : (side = 'center', sides.intermediateX);\r\n \r\n elem.style.left = left + 'px';\r\n }\r\n\r\n /* if((clientY + menuHeight + PADDING_TOP) > windowHeight) {\r\n elem.style.top = clamp(clientY - menuHeight, PADDING_TOP, windowHeight - menuHeight - PADDING_TOP) + 'px';\r\n // elem.style.top = (innerHeight - scrollHeight - PADDING_TOP) + 'px';\r\n verticalSide = 'bottom';\r\n } else {\r\n elem.style.top = Math.max(PADDING_TOP, clientY) + 'px';\r\n verticalSide = 'top';\r\n } */\r\n\r\n {\r\n let top: number;\r\n\r\n top = possibleSides.y[verticalSide] ? sides.y[verticalSide] : (verticalSide = 'center', sides.intermediateY);\r\n \r\n elem.style.top = top + 'px';\r\n }\r\n \r\n elem.className = elem.className.replace(/(top|center|bottom)-(left|center|right)/g, '');\r\n elem.classList.add(\r\n //(verticalSide === 'center' ? verticalSide : (verticalSide === 'bottom' ? 'top' : 'bottom')) +\r\n (verticalSide === 'center' ? verticalSide : 'bottom') +\r\n '-' +\r\n (side === 'center' ? side : (side === 'left' ? 'right' : 'left')));\r\n\r\n return {\r\n width: menuWidth,\r\n height: menuHeight\r\n };\r\n}\r\n\r\nlet _cancelContextMenuOpening = false, _cancelContextMenuOpeningTimeout = 0;\r\nexport function cancelContextMenuOpening() {\r\n if(_cancelContextMenuOpeningTimeout) {\r\n clearTimeout(_cancelContextMenuOpeningTimeout);\r\n }\r\n \r\n _cancelContextMenuOpeningTimeout = window.setTimeout(() => {\r\n _cancelContextMenuOpeningTimeout = 0;\r\n _cancelContextMenuOpening = false;\r\n }, .4e3);\r\n\r\n _cancelContextMenuOpening = true;\r\n}\r\n\r\nexport function attachContextMenuListener(element: HTMLElement, callback: (e: Touch | MouseEvent) => void, listenerSetter?: ListenerSetter) {\r\n const add = listenerSetter ? listenerSetter.add(element) : element.addEventListener.bind(element);\r\n const remove = listenerSetter ? listenerSetter.removeManual.bind(listenerSetter, element) : element.removeEventListener.bind(element);\r\n\r\n if(IS_APPLE && IS_TOUCH_SUPPORTED) {\r\n let timeout: number;\r\n\r\n const options: EventListenerOptions = {capture: true};\r\n\r\n const onCancel = () => {\r\n clearTimeout(timeout);\r\n // @ts-ignore\r\n remove('touchmove', onCancel, options);\r\n // @ts-ignore\r\n remove('touchend', onCancel, options);\r\n // @ts-ignore\r\n remove('touchcancel', onCancel, options);\r\n };\r\n\r\n add('touchstart', (e: TouchEvent) => {\r\n if(e.touches.length > 1) {\r\n onCancel();\r\n return;\r\n }\r\n \r\n add('touchmove', onCancel, options);\r\n add('touchend', onCancel, options);\r\n add('touchcancel', onCancel, options);\r\n\r\n timeout = window.setTimeout(() => {\r\n if(_cancelContextMenuOpening) {\r\n onCancel();\r\n return;\r\n }\r\n\r\n callback(e.touches[0]);\r\n onCancel();\r\n\r\n if(openedMenu) {\r\n element.addEventListener('touchend', cancelEvent, {once: true}); // * fix instant closing\r\n }\r\n }, .4e3);\r\n });\r\n\r\n /* if(!isSafari) {\r\n add('contextmenu', (e: any) => {\r\n cancelEvent(e);\r\n }, {passive: false, capture: true});\r\n } */\r\n } else {\r\n add('contextmenu', IS_TOUCH_SUPPORTED ? (e: any) => {\r\n callback(e);\r\n\r\n if(openedMenu) {\r\n element.addEventListener('touchend', cancelEvent, {once: true}); // * fix instant closing\r\n }\r\n } : callback);\r\n }\r\n};\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport { IS_MOBILE_SAFARI } from \"../environment/userAgent\";\r\nimport { logger } from \"../lib/logger\";\r\nimport blurActiveElement from \"../helpers/dom/blurActiveElement\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport isSwipingBackSafari from \"../helpers/dom/isSwipingBackSafari\";\r\nimport indexOfAndSplice from \"../helpers/array/indexOfAndSplice\";\r\n\r\nexport type NavigationItem = {\r\n type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' | \r\n 'esg' | 'multiselect' | 'input-helper' | 'autocomplete-helper' | 'markup' | \r\n 'global-search' | 'voice' | 'mobile-search' | 'filters',\r\n onPop: (canAnimate: boolean) => boolean | void,\r\n onEscape?: () => boolean,\r\n noHistory?: boolean,\r\n noBlurOnPop?: boolean,\r\n};\r\n\r\nexport class AppNavigationController {\r\n private navigations: Array = [];\r\n private id = Date.now();\r\n private manual = false;\r\n private log = logger('NC');\r\n private debug = true;\r\n private currentHash = window.location.hash;\r\n public onHashChange: () => void;\r\n\r\n constructor() {\r\n let isPossibleSwipe = false;\r\n window.addEventListener('popstate', (e) => {\r\n this.debug && this.log('popstate', e, isPossibleSwipe);\r\n\r\n if(window.location.hash !== this.currentHash) {\r\n this.onHashChange && this.onHashChange();\r\n this.replaceState();\r\n return;\r\n }\r\n this.currentHash = window.location.hash;\r\n\r\n const id: number = e.state;\r\n if(id !== this.id/* && !this.navigations.length */) {\r\n this.pushState();\r\n return;\r\n }\r\n\r\n const item = this.navigations.pop();\r\n if(!item) {\r\n this.pushState();\r\n return;\r\n }\r\n\r\n this.manual = !isPossibleSwipe;\r\n this.handleItem(item);\r\n //this.pushState(); // * prevent adding forward arrow\r\n });\r\n\r\n window.addEventListener('keydown', (e) => {\r\n const item = this.navigations[this.navigations.length - 1];\r\n if(!item) return;\r\n if(e.key === 'Escape' && (item.onEscape ? item.onEscape() : true)) {\r\n cancelEvent(e);\r\n this.back(item.type);\r\n }\r\n }, {capture: true, passive: false});\r\n\r\n if(IS_MOBILE_SAFARI) {\r\n const options = {passive: true};\r\n window.addEventListener('touchstart', (e) => {\r\n if(e.touches.length > 1) return;\r\n this.debug && this.log('touchstart');\r\n\r\n if(isSwipingBackSafari(e)) {\r\n isPossibleSwipe = true;\r\n\r\n window.addEventListener('touchend', () => {\r\n setTimeout(() => {\r\n isPossibleSwipe = false;\r\n }, 100);\r\n }, {passive: true, once: true});\r\n }\r\n\r\n /* const detach = () => {\r\n window.removeEventListener('touchend', onTouchEnd);\r\n window.removeEventListener('touchmove', onTouchMove);\r\n };\r\n\r\n let moved = false;\r\n const onTouchMove = (e: TouchEvent) => {\r\n this.debug && this.log('touchmove');\r\n if(e.touches.length > 1) {\r\n detach();\r\n return;\r\n }\r\n\r\n moved = true;\r\n };\r\n\r\n const onTouchEnd = (e: TouchEvent) => {\r\n this.debug && this.log('touchend');\r\n if(e.touches.length > 1 || !moved) {\r\n detach();\r\n return;\r\n }\r\n\r\n isPossibleSwipe = true;\r\n doubleRaf().then(() => {\r\n isPossibleSwipe = false;\r\n });\r\n\r\n detach();\r\n };\r\n\r\n window.addEventListener('touchend', onTouchEnd, options);\r\n window.addEventListener('touchmove', onTouchMove, options); */\r\n }, options);\r\n }\r\n\r\n history.scrollRestoration = 'manual';\r\n\r\n this.pushState(); // * push init state\r\n }\r\n\r\n private handleItem(item: NavigationItem) {\r\n const good = item.onPop(!this.manual ? false : undefined);\r\n this.debug && this.log('popstate, navigation:', item, this.navigations);\r\n if(good === false) {\r\n this.pushItem(item);\r\n } else if(!item.noBlurOnPop) {\r\n blurActiveElement(); // no better place for it\r\n }\r\n\r\n this.manual = false;\r\n }\r\n\r\n public findItemByType(type: NavigationItem['type']) {\r\n for(let i = this.navigations.length - 1; i >= 0; --i) {\r\n const item = this.navigations[i];\r\n if(item.type === type) {\r\n return {item, index: i};\r\n }\r\n }\r\n }\r\n\r\n public back(type?: NavigationItem['type']) {\r\n if(type) {\r\n const ret = this.findItemByType(type);\r\n if(ret) {\r\n this.backByItem(ret.item, ret.index);\r\n return;\r\n }\r\n }\r\n\r\n history.back();\r\n }\r\n\r\n public backByItem(item: NavigationItem, index = this.navigations.indexOf(item)) {\r\n this.manual = true;\r\n // ! commented because 'popstate' event will be fired with delay\r\n //if(index !== (this.navigations.length - 1)) {\r\n this.navigations.splice(index, 1);\r\n this.handleItem(item);\r\n //}\r\n }\r\n\r\n private onItemAdded(item: NavigationItem) {\r\n this.debug && this.log('pushstate', item, this.navigations);\r\n\r\n if(!item.noHistory) {\r\n this.pushState();\r\n }\r\n }\r\n\r\n public pushItem(item: NavigationItem) {\r\n this.navigations.push(item);\r\n this.onItemAdded(item);\r\n }\r\n\r\n public unshiftItem(item: NavigationItem) {\r\n this.navigations.unshift(item);\r\n this.onItemAdded(item);\r\n }\r\n\r\n private pushState() {\r\n this.manual = false;\r\n history.pushState(this.id, '');\r\n }\r\n\r\n public replaceState() {\r\n history.replaceState(this.id, '', location.origin + location.pathname);\r\n }\r\n\r\n public removeItem(item: NavigationItem) {\r\n if(!item) {\r\n return;\r\n }\r\n \r\n indexOfAndSplice(this.navigations, item);\r\n }\r\n\r\n public removeByType(type: NavigationItem['type'], single = false) {\r\n for(let i = this.navigations.length - 1; i >= 0; --i) {\r\n const item = this.navigations[i];\r\n if(item.type === type) {\r\n this.navigations.splice(i, 1);\r\n\r\n if(single) {\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nconst appNavigationController = new AppNavigationController();\r\nMOUNT_CLASS_TO.appNavigationController = appNavigationController;\r\nexport default appNavigationController;\r\n","export default function simulateEvent(elem: EventTarget, name: string) {\n const event = new Event(name, {bubbles: true, cancelable: true});\n elem.dispatchEvent(event);\n}\n"],"sourceRoot":""}