1 line
41 KiB
Plaintext
1 line
41 KiB
Plaintext
{"version":3,"sources":["webpack:///./src/helpers/schedulers/debounce.ts","webpack:///./src/lib/rootScope.ts","webpack:///./src/helpers/touchSupport.ts","webpack:///./src/components/ripple.ts","webpack:///./src/config/debug.ts","webpack:///./src/helpers/schedulers.ts","webpack:///./src/helpers/cancellablePromise.ts","webpack:///./src/config/modes.ts","webpack:///./src/helpers/eventListenerBase.ts","webpack:///./src/helpers/dom/isInDOM.ts","webpack:///./src/helpers/sequentialDom.ts"],"names":["debounce","fn","ms","shouldRunFirst","shouldRunLast","waitingTimeout","args","clearTimeout","setTimeout","RootScope","super","_overlayIsActive","myId","idle","isIDLE","deactivated","focusPromise","Promise","resolve","focusResolve","connectionStatus","peerId","config","forwarded_count_max","edit_time_limit","pinned_dialogs_count_max","pinned_infolder_count_max","message_length_max","caption_length_max","this","addEventListener","e","id","status","name","darkModeMediaQuery","window","matchMedia","checkDarkMode","systemTheme","matches","dispatchEvent","setTheme","addListener","err","isNight","getTheme","colorScheme","document","head","querySelector","setAttribute","documentElement","classList","toggle","value","settings","theme","themes","find","t","rootScope","isTouchSupported","DocumentTouch","rippleClickId","ripple","elem","callback","onEnd","prepend","add","r","createElement","handler","contains","drawRipple","clientX","clientY","startTime","Date","now","clickId","duration","getComputedStyle","getPropertyValue","replace","elapsedTime","cb","mutate","remove","delay","Math","max","removeEventListener","touchStartFired","requestAnimationFrame","rect","getBoundingClientRect","clickX","left","clickY","top","size","sqrt","abs","height","width","x","y","style","append","isRippleUnneeded","target","includes","tagName","touchEnd","animationsEnabled","touches","length","once","cancelBubble","stopPropagation","passive","button","dataset","DEBUG","debug","MOUNT_CLASS_TO","self","throttle","isPending","interval","_args","setInterval","clearInterval","pause","fastRafCallbacks","rafPromise","fastRaf","push","currentCallbacks","undefined","forEach","fastRafPromise","then","doubleRaf","deferredPromise","deferredHelper","isFulfilled","isRejected","notify","notifyAll","lastNotify","listeners","addNotifyListener","deferred","reject","finally","cancel","Object","assign","Modes","test","location","search","indexOf","http","ssl","multipleConnections","asServiceWorker","EventListenerBase","reuseResults","_constructor","listenerResults","options","hasOwnProperty","pop","obj","i","findAndSplice","l","arr","slice","listener","findIndex","isInDOM","element","isConnected","sequentialDom","promises","raf","bind","scheduled","kind","promise","scheduleFlush","do","read","write"],"mappings":"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","file":"18.43480c9a8c2bff48880d.chunk.js","sourcesContent":["// * Jolly Cobra's schedulers\r\n\r\nimport { AnyToVoidFunction } from \"../../types\";\r\n\r\nexport default function debounce<F extends AnyToVoidFunction>(\r\n fn: F,\r\n ms: number,\r\n shouldRunFirst = true,\r\n shouldRunLast = true,\r\n) {\r\n let waitingTimeout: number | null = null;\r\n\r\n return (...args: Parameters<F>) => {\r\n if(waitingTimeout) {\r\n clearTimeout(waitingTimeout);\r\n waitingTimeout = null;\r\n } else if(shouldRunFirst) {\r\n // @ts-ignore\r\n fn(...args);\r\n }\r\n\r\n waitingTimeout = setTimeout(() => {\r\n if(shouldRunLast) {\r\n // @ts-ignore\r\n fn(...args);\r\n }\r\n\r\n waitingTimeout = null;\r\n }, ms) as any;\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 { Message, StickerSet, Update, NotifyPeer, PeerNotifySettings, ConstructorDeclMap, Config } from \"../layer\";\r\nimport type { MyDocument } from \"./appManagers/appDocsManager\";\r\nimport type { AppMessagesManager, Dialog, MessagesStorage } from \"./appManagers/appMessagesManager\";\r\nimport type { Poll, PollResults } from \"./appManagers/appPollsManager\";\r\nimport type { MyDialogFilter } from \"./storages/filters\";\r\nimport type { UserTyping } from \"./appManagers/appProfileManager\";\r\nimport type Chat from \"../components/chat/chat\";\r\nimport type { UserAuth } from \"./mtproto/mtproto_config\";\r\nimport type { State, Theme } from \"./appManagers/appStateManager\";\r\nimport type { MyDraftMessage } from \"./appManagers/appDraftsManager\";\r\nimport type { PushSubscriptionNotify } from \"./mtproto/webPushApiManager\";\r\nimport type { PushNotificationObject } from \"./serviceWorker/push\";\r\nimport type { ConnectionStatusChange } from \"./mtproto/connectionStatus\";\r\nimport EventListenerBase from \"../helpers/eventListenerBase\";\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\n\r\nexport type BroadcastEvents = {\r\n 'user_update': number,\r\n 'user_auth': UserAuth,\r\n 'peer_changed': number,\r\n 'peer_changing': Chat,\r\n 'peer_pinned_messages': {peerId: number, mids?: number[], pinned?: boolean, unpinAll?: true},\r\n 'peer_pinned_hidden': {peerId: number, maxId: number},\r\n 'peer_typings': {peerId: number, typings: UserTyping[]},\r\n 'peer_block': {peerId: number, blocked: boolean},\r\n 'peer_title_edit': number,\r\n 'peer_bio_edit': number,\r\n\r\n 'filter_delete': MyDialogFilter,\r\n 'filter_update': MyDialogFilter,\r\n 'filter_order': number[],\r\n \r\n 'dialog_draft': {peerId: number, draft: MyDraftMessage | undefined, index: number},\r\n 'dialog_unread': {peerId: number},\r\n 'dialog_flush': {peerId: number},\r\n 'dialog_drop': {peerId: number, dialog?: Dialog},\r\n 'dialog_migrate': {migrateFrom: number, migrateTo: number},\r\n //'dialog_top': Dialog,\r\n 'dialog_notify_settings': Dialog,\r\n 'dialogs_multiupdate': {[peerId: string]: Dialog},\r\n 'dialogs_archived_unread': {count: number},\r\n \r\n 'history_append': {storage: MessagesStorage, peerId: number, mid: number},\r\n 'history_update': {storage: MessagesStorage, peerId: number, mid: number},\r\n 'history_reply_markup': {peerId: number},\r\n 'history_multiappend': AppMessagesManager['newMessagesToHandle'],\r\n 'history_delete': {peerId: number, msgs: {[mid: number]: true}},\r\n 'history_forbidden': number,\r\n 'history_reload': number,\r\n 'history_focus': {peerId: number, mid?: number},\r\n //'history_request': void,\r\n \r\n 'message_edit': {storage: MessagesStorage, peerId: number, mid: number},\r\n 'message_views': {mid: number, views: number},\r\n 'message_sent': {storage: MessagesStorage, tempId: number, tempMessage: any, mid: number},\r\n 'messages_pending': void,\r\n 'messages_read': void,\r\n 'messages_downloaded': {peerId: number, mids: number[]},\r\n 'messages_media_read': {peerId: number, mids: number[]},\r\n\r\n 'replies_updated': Message.message,\r\n\r\n 'scheduled_new': {peerId: number, mid: number},\r\n 'scheduled_delete': {peerId: number, mids: number[]},\r\n\r\n 'album_edit': {peerId: number, groupId: string, deletedMids: number[]},\r\n\r\n 'stickers_installed': StickerSet.stickerSet,\r\n 'stickers_deleted': StickerSet.stickerSet,\r\n\r\n 'audio_play': {doc: MyDocument, mid: number, peerId: number},\r\n 'audio_pause': void,\r\n \r\n 'state_cleared': void,\r\n 'state_synchronized': number | void,\r\n 'state_synchronizing': number | void,\r\n \r\n 'contacts_update': number,\r\n 'avatar_update': number,\r\n 'chat_full_update': number,\r\n 'poll_update': {poll: Poll, results: PollResults},\r\n 'chat_update': number,\r\n 'invalidate_participants': number,\r\n //'channel_settings': {channelId: number},\r\n 'webpage_updated': {id: string, msgs: number[]},\r\n\r\n 'download_progress': any,\r\n 'connection_status_change': ConnectionStatusChange,\r\n 'settings_updated': {key: string, value: any},\r\n 'draft_updated': {peerId: number, threadId: number, draft: MyDraftMessage | undefined},\r\n\r\n 'event-heavy-animation-start': void,\r\n 'event-heavy-animation-end': void,\r\n\r\n 'im_mount': void,\r\n 'im_tab_change': number,\r\n\r\n 'idle': boolean,\r\n\r\n 'overlay_toggle': boolean,\r\n\r\n 'background_change': void,\r\n\r\n 'privacy_update': Update.updatePrivacy,\r\n\r\n 'notify_settings': Update.updateNotifySettings,\r\n 'notify_peer_type_settings': {key: Exclude<NotifyPeer['_'], 'notifyPeer'>, settings: PeerNotifySettings},\r\n\r\n 'language_change': string,\r\n \r\n 'theme_change': void,\r\n\r\n 'instance_activated': void,\r\n 'instance_deactivated': void,\r\n\r\n 'push_notification_click': PushNotificationObject,\r\n 'push_init': PushSubscriptionNotify,\r\n 'push_subscribe': PushSubscriptionNotify,\r\n 'push_unsubscribe': PushSubscriptionNotify,\r\n\r\n 'emoji_recent': string\r\n};\r\n\r\nexport class RootScope extends EventListenerBase<{\r\n [name in Update['_']]: (update: ConstructorDeclMap[name]) => void\r\n} & {\r\n [name in keyof BroadcastEvents]: (e: BroadcastEvents[name]) => void\r\n}> {\r\n private _overlayIsActive: boolean = false;\r\n public myId = 0;\r\n public idle = {\r\n isIDLE: true,\r\n deactivated: false,\r\n focusPromise: Promise.resolve(),\r\n focusResolve: () => {}\r\n };\r\n public connectionStatus: {[name: string]: ConnectionStatusChange} = {};\r\n public settings: State['settings'];\r\n public peerId = 0;\r\n public systemTheme: Theme['name'];\r\n public config: Partial<Config.config> = {\r\n forwarded_count_max: 100,\r\n edit_time_limit: 86400 * 2,\r\n pinned_dialogs_count_max: 5,\r\n pinned_infolder_count_max: 100,\r\n message_length_max: 4096,\r\n caption_length_max: 1024,\r\n };\r\n\r\n constructor() {\r\n super();\r\n\r\n this.addEventListener('peer_changed', (peerId) => {\r\n this.peerId = peerId;\r\n });\r\n\r\n this.addEventListener('user_auth', (e) => {\r\n this.myId = e.id;\r\n });\r\n\r\n this.addEventListener('connection_status_change', (e) => {\r\n const status = e;\r\n this.connectionStatus[e.name] = status;\r\n });\r\n\r\n this.addEventListener('idle', (isIDLE) => {\r\n if(isIDLE) {\r\n this.idle.focusPromise = new Promise((resolve) => {\r\n this.idle.focusResolve = resolve;\r\n });\r\n } else {\r\n this.idle.focusResolve();\r\n }\r\n });\r\n }\r\n\r\n public setThemeListener() {\r\n try {\r\n const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\r\n const checkDarkMode = () => {\r\n //const theme = this.getTheme();\r\n this.systemTheme = darkModeMediaQuery.matches ? 'night' : 'day';\r\n //const newTheme = this.getTheme();\r\n\r\n if(this.myId) {\r\n this.dispatchEvent('theme_change');\r\n } else {\r\n this.setTheme();\r\n }\r\n };\r\n\r\n if('addEventListener' in darkModeMediaQuery) {\r\n darkModeMediaQuery.addEventListener('change', checkDarkMode);\r\n } else if('addListener' in darkModeMediaQuery) {\r\n (darkModeMediaQuery as any).addListener(checkDarkMode);\r\n }\r\n\r\n checkDarkMode();\r\n } catch(err) {\r\n\r\n }\r\n }\r\n\r\n public setTheme() {\r\n const isNight = this.getTheme().name === 'night';\r\n const colorScheme = document.head.querySelector('[name=\"color-scheme\"]');\r\n if(colorScheme) {\r\n colorScheme.setAttribute('content', isNight ? 'dark' : 'light');\r\n }\r\n\r\n document.documentElement.classList.toggle('night', isNight);\r\n }\r\n\r\n get overlayIsActive() {\r\n return this._overlayIsActive;\r\n }\r\n\r\n set overlayIsActive(value: boolean) {\r\n this._overlayIsActive = value;\r\n this.dispatchEvent('overlay_toggle', value);\r\n }\r\n\r\n public getTheme(name: Theme['name'] = this.settings.theme === 'system' ? this.systemTheme : this.settings.theme) {\r\n return this.settings.themes.find(t => t.name === name);\r\n }\r\n}\r\n\r\nconst rootScope = new RootScope();\r\nMOUNT_CLASS_TO.rootScope = rootScope;\r\nexport default rootScope;\r\n\r\n/* rootScope.addEventListener('album_edit', (e) => {\r\n \r\n});\r\n\r\nrootScope.addEventListener<'album_edit'>('album_edit', (e) => {\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\n// @ts-ignore\r\nexport const isTouchSupported = ('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch)/* || true */;","/*\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 {isTouchSupported} from \"../helpers/touchSupport\";\r\nimport rootScope from \"../lib/rootScope\";\r\n\r\nlet rippleClickId = 0;\r\nexport function ripple(elem: HTMLElement, callback: (id: number) => Promise<boolean | void> = () => Promise.resolve(), onEnd: (id: number) => void = null, prepend = false) {\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<number>;\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(!isTouchSupported) {\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\r\n // TODO: rename this variable\r\n let touchStartFired = false;\r\n if(isTouchSupported) {\r\n let touchEnd = () => {\r\n handler && handler();\r\n };\r\n \r\n elem.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 elem.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 elem.removeEventListener('touchend', touchEnd);\r\n }, {once: true});\r\n }, {passive: true});\r\n } else {\r\n elem.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(elem.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 Modes from \"./modes\";\r\n\r\nexport const DEBUG = process.env.NODE_ENV !== 'production' || Modes.debug;\r\nconst ctx: any = typeof(window) !== 'undefined' ? window : self;\r\nexport const MOUNT_CLASS_TO: any = DEBUG || true/* && false */ ? ctx : {};\r\nexport default DEBUG;\r\n\r\n//let m = DEBUG;\r\n/* if(!DEBUG) {\r\n ctx.sandpitTurtle = () => {\r\n //if(!m) {\r\n for(let i in MOUNT_CLASS_TO) {\r\n ctx[i] = MOUNT_CLASS_TO[i];\r\n }\r\n //m = true;\r\n //}\r\n \r\n //DEBUG = !DEBUG;\r\n };\r\n} */\r\n\r\n/* export const superDebug = (object: any, key: string) => {\r\n var d = object[key];\r\n var beforeStr = '', afterStr = '';\r\n for(var r of d) {\r\n beforeStr += r.before.hex + '\\n';\r\n afterStr += r.after.hex + '\\n';\r\n }\r\n\r\n beforeStr = beforeStr.trim();\r\n afterStr = afterStr.trim();\r\n //var beforeStr = d.map(r => r.before.hex).join('\\n');\r\n //var afterStr = d.map(r => r.after.hex).join('\\n');\r\n\r\n var dada = (name: string, str: string) => {\r\n var a = document.createElement('a');\r\n a.target = '_blank';\r\n a.download = name + '.txt';\r\n a.href = URL.createObjectURL(new Blob([str], {\r\n type: 'text/plain'\r\n }));\r\n document.body.append(a);\r\n a.click();\r\n };\r\n\r\n dada(key + '_' + 'before', beforeStr);\r\n dada(key + '_' + 'after', afterStr);\r\n}\r\n\r\nMOUNT_CLASS_TO.superDebug = superDebug; */\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\n// * Jolly Cobra's schedulers\r\nimport { AnyToVoidFunction, NoneToVoidFunction } from \"../types\";\r\nimport _debounce from './schedulers/debounce';\r\n\r\n//type Scheduler = typeof requestAnimationFrame | typeof onTickEnd | typeof runNow;\r\n\r\nconst debounce = _debounce;\r\nexport {debounce};\r\n\r\nexport function throttle<F extends AnyToVoidFunction>(\r\n fn: F,\r\n ms: number,\r\n shouldRunFirst = true,\r\n) {\r\n let interval: number | null = null;\r\n let isPending: boolean;\r\n let args: Parameters<F>;\r\n\r\n return (..._args: Parameters<F>) => {\r\n isPending = true;\r\n args = _args;\r\n\r\n if(!interval) {\r\n if(shouldRunFirst) {\r\n isPending = false;\r\n // @ts-ignore\r\n fn(...args);\r\n }\r\n\r\n interval = setInterval(() => {\r\n if (!isPending) {\r\n clearInterval(interval!);\r\n interval = null;\r\n return;\r\n }\r\n\r\n isPending = false;\r\n // @ts-ignore\r\n fn(...args);\r\n }, ms) as any;\r\n }\r\n };\r\n}\r\n\r\n/* export function throttleWithRaf<F extends AnyToVoidFunction>(fn: F) {\r\n return throttleWith(fastRaf, fn);\r\n}\r\n\r\nexport function throttleWithTickEnd<F extends AnyToVoidFunction>(fn: F) {\r\n return throttleWith(onTickEnd, fn);\r\n}\r\n\r\nexport function throttleWithNow<F extends AnyToVoidFunction>(fn: F) {\r\n return throttleWith(runNow, fn);\r\n}\r\n\r\nexport function throttleWith<F extends AnyToVoidFunction>(schedulerFn: Scheduler, fn: F) {\r\n let waiting = false;\r\n let args: Parameters<F>;\r\n\r\n return (..._args: Parameters<F>) => {\r\n args = _args;\r\n\r\n if (!waiting) {\r\n waiting = true;\r\n\r\n schedulerFn(() => {\r\n waiting = false;\r\n // @ts-ignore\r\n fn(...args);\r\n });\r\n }\r\n };\r\n}\r\n\r\nexport function onTickEnd(cb: NoneToVoidFunction) {\r\n Promise.resolve().then(cb);\r\n}\r\n\r\nfunction runNow(fn: NoneToVoidFunction) {\r\n fn();\r\n} */\r\n\r\nexport const pause = (ms: number) => new Promise<void>((resolve) => {\r\n setTimeout(resolve, ms);\r\n});\r\n\r\nlet fastRafCallbacks: NoneToVoidFunction[] | undefined;\r\nexport function fastRaf(callback: NoneToVoidFunction) {\r\n if(!fastRafCallbacks) {\r\n fastRafCallbacks = [callback];\r\n\r\n requestAnimationFrame(() => {\r\n const currentCallbacks = fastRafCallbacks!;\r\n fastRafCallbacks = undefined;\r\n currentCallbacks.forEach((cb) => cb());\r\n });\r\n } else {\r\n fastRafCallbacks.push(callback);\r\n }\r\n}\r\n\r\nlet rafPromise: Promise<DOMHighResTimeStamp>;\r\nexport function fastRafPromise() {\r\n if(rafPromise) return rafPromise;\r\n\r\n rafPromise = new Promise(requestAnimationFrame);\r\n rafPromise.then(() => {\r\n rafPromise = undefined;\r\n });\r\n\r\n return rafPromise;\r\n}\r\n\r\nexport function doubleRaf() {\r\n return new Promise<void>((resolve) => {\r\n fastRaf(() => {\r\n fastRaf(resolve);\r\n });\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\nexport interface CancellablePromise<T> extends Promise<T> {\r\n resolve?: (value: T) => void,\r\n reject?: (...args: any[]) => void,\r\n cancel?: () => void,\r\n\r\n notify?: (...args: any[]) => void,\r\n notifyAll?: (...args: any[]) => void,\r\n lastNotify?: any,\r\n listeners?: Array<(...args: any[]) => void>,\r\n addNotifyListener?: (callback: (...args: any[]) => void) => void,\r\n\r\n isFulfilled?: boolean,\r\n isRejected?: boolean\r\n}\r\n\r\nexport function deferredPromise<T>() {\r\n let deferredHelper: any = {\r\n isFulfilled: false, \r\n isRejected: false,\r\n\r\n notify: () => {}, \r\n notifyAll: (...args: any[]) => {\r\n deferredHelper.lastNotify = args;\r\n deferredHelper.listeners.forEach((callback: any) => callback(...args));\r\n }, \r\n\r\n lastNotify: undefined,\r\n listeners: [],\r\n addNotifyListener: (callback: (...args: any[]) => void) => {\r\n if(deferredHelper.lastNotify) {\r\n callback(...deferredHelper.lastNotify);\r\n }\r\n\r\n deferredHelper.listeners.push(callback);\r\n }\r\n };\r\n\r\n let deferred: CancellablePromise<T> = new Promise<T>((resolve, reject) => {\r\n deferredHelper.resolve = (value: T) => {\r\n if(deferred.isFulfilled) return;\r\n\r\n deferred.isFulfilled = true;\r\n resolve(value);\r\n };\r\n \r\n deferredHelper.reject = (...args: any[]) => {\r\n if(deferred.isRejected) return;\r\n \r\n deferred.isRejected = true;\r\n reject(...args);\r\n };\r\n });\r\n\r\n // @ts-ignore\r\n /* deferred.then = (resolve: (value: T) => any, reject: (...args: any[]) => any) => {\r\n const n = deferredPromise<ReturnType<typeof resolve>>();\r\n \r\n }; */\r\n\r\n deferred.finally(() => {\r\n deferred.notify = null;\r\n deferred.listeners.length = 0;\r\n deferred.lastNotify = null;\r\n\r\n if(deferred.cancel) {\r\n deferred.cancel = () => {};\r\n }\r\n });\r\n\r\n Object.assign(deferred, deferredHelper);\r\n\r\n return deferred;\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 * Originally from:\r\n * https://github.com/zhukov/webogram\r\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\nconst Modes = {\r\n test: location.search.indexOf('test=1') > 0/* || true */,\r\n debug: location.search.indexOf('debug=1') > 0,\r\n http: false, //location.search.indexOf('http=1') > 0,\r\n ssl: true, // location.search.indexOf('ssl=1') > 0 || location.protocol === 'https:' && location.search.indexOf('ssl=0') === -1,\r\n multipleConnections: true,\r\n asServiceWorker: false\r\n};\r\n\r\n \r\n \r\n \r\n\r\nexport default Modes;\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\n//import { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport type { ArgumentTypes, SuperReturnType } from \"../types\";\r\n\r\n// class EventSystem {\r\n// wm: WeakMap<any, Record<any, Set<any>>> = new WeakMap();\r\n\r\n// add(target: any, event: any, listener: any) {\r\n// let listeners = this.wm.get(target);\r\n// if (listeners === undefined) {\r\n// listeners = {};\r\n// }\r\n// let listenersForEvent = listeners[event];\r\n// if (listenersForEvent === undefined) {\r\n// listenersForEvent = new Set();\r\n// }\r\n// listenersForEvent.add(listener);\r\n// listeners[event] = listenersForEvent;\r\n// //target.addEventListener(event, listener);\r\n// this.wm.set(target, listeners);\r\n// };\r\n\r\n// remove(target: any, event: any, listener: any) {\r\n// let listeners = this.wm.get(target);\r\n// if (!listeners) return;\r\n// let listenersForEvent = listeners[event];\r\n// if (!listenersForEvent) return;\r\n// listenersForEvent.delete(listener);\r\n// };\r\n \r\n// /* fire(target, event) {\r\n// let listeners = this.wm.get(target);\r\n// if (!listeners) return;\r\n// let listenersForEvent = listeners[event];\r\n// if (!listenersForEvent) return;\r\n// for (let handler of handlers) {\r\n// setTimeout(handler, 0, event, target); // we use a setTimeout here because we want event triggering to be asynchronous. \r\n// }\r\n// }; */\r\n// }\r\n\r\n// console.log = () => {};\r\n\r\n// const e = new EventSystem();\r\n// MOUNT_CLASS_TO.e = e;\r\n\r\n/**\r\n * Better not to remove listeners during setting\r\n * Should add listener callback only once\r\n */\r\n\r\n// type EventLitenerCallback<T> = (data: T) => \r\n// export default class EventListenerBase<Listeners extends {[name: string]: Function}> {\r\nexport default class EventListenerBase<Listeners extends Record<string, Function>> {\r\n protected listeners: Partial<{\r\n [k in keyof Listeners]: Array<{callback: Listeners[k], options: boolean | AddEventListenerOptions}>\r\n }>;\r\n protected listenerResults: Partial<{\r\n [k in keyof Listeners]: ArgumentTypes<Listeners[k]>\r\n }>;\r\n\r\n private reuseResults: boolean;\r\n\r\n constructor(reuseResults?: boolean) {\r\n this._constructor(reuseResults);\r\n }\r\n\r\n public _constructor(reuseResults = false): any {\r\n this.reuseResults = reuseResults;\r\n this.listeners = {};\r\n this.listenerResults = {};\r\n }\r\n\r\n public addEventListener<T extends keyof Listeners>(name: T, callback: Listeners[T], options?: boolean | AddEventListenerOptions) {\r\n (this.listeners[name] ?? (this.listeners[name] = [])).push({callback, options}); // ! add before because if you don't, you won't be able to delete it from callback\r\n\r\n if(this.listenerResults.hasOwnProperty(name)) {\r\n callback(...this.listenerResults[name]);\r\n \r\n if((options as AddEventListenerOptions)?.once) {\r\n this.listeners[name].pop();\r\n return;\r\n }\r\n }\r\n \r\n //e.add(this, name, {callback, once});\r\n }\r\n\r\n public addMultipleEventsListeners(obj: {\r\n [name in keyof Listeners]?: Listeners[name]\r\n }) {\r\n for(const i in obj) {\r\n this.addEventListener(i, obj[i]);\r\n }\r\n }\r\n\r\n public removeEventListener<T extends keyof Listeners>(name: T, callback: Listeners[T], options?: boolean | AddEventListenerOptions) {\r\n if(this.listeners[name]) {\r\n this.listeners[name].findAndSplice(l => l.callback === callback);\r\n }\r\n //e.remove(this, name, callback);\r\n }\r\n\r\n // * must be protected, but who cares\r\n public dispatchEvent<T extends keyof Listeners>(name: T, ...args: ArgumentTypes<Listeners[T]>) {\r\n if(this.reuseResults) {\r\n this.listenerResults[name] = args;\r\n }\r\n\r\n const arr: Array<SuperReturnType<Listeners[typeof name]>> = [];\r\n\r\n /* let a = e.wm.get(this)[name];\r\n if(!a) return arr;\r\n const listeners = [...a]; */\r\n const listeners = this.listeners[name];\r\n if(listeners) {\r\n // ! this one will guarantee execution even if delete another listener during setting\r\n const left = listeners.slice();\r\n left.forEach((listener) => {\r\n const index = listeners.findIndex((l) => l.callback === listener.callback);\r\n if(index === -1) {\r\n return;\r\n }\r\n\r\n arr.push(listener.callback(...args));\r\n\r\n if((listener.options as AddEventListenerOptions)?.once) {\r\n this.removeEventListener(name, listener.callback);\r\n }\r\n });\r\n\r\n /* for(let i = 0, length = listeners.length; i < length; ++i) {\r\n const listener = listeners[i];\r\n arr.push(listener.callback(...args));\r\n\r\n if(listener.once) {\r\n listeners.splice(i, 1);\r\n --i;\r\n --length;\r\n }\r\n } */\r\n }\r\n\r\n return arr;\r\n }\r\n\r\n public cleanup() {\r\n this.listeners = {}; \r\n this.listenerResults = {};\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 * Originally from:\r\n * https://github.com/zhukov/webogram\r\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\n/* export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {\r\n if(!element) {\r\n return false;\r\n }\r\n\r\n parentNode = parentNode || document.body;\r\n if(element === parentNode) {\r\n return true;\r\n }\r\n return isInDOM(element.parentNode as HTMLElement, parentNode);\r\n} */\r\nexport default function isInDOM(element: Element): boolean {\r\n return element?.isConnected;\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 { 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<void>,\r\n write: CancellablePromise<void>\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<void>();\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 promise = isInDOM(element) ? this.mutate() : Promise.resolve();\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 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"],"sourceRoot":""} |