UNPKG

@relax.dev/router

Version:
196 lines (195 loc) 9.68 kB
import { Page } from './Page'; import { History } from './History'; import { Route as MyRoute } from './Route'; import { State } from './State'; import { EventEmitter } from 'tsee'; import { RouterConfig } from './RouterConfig'; import { Location } from './Location'; import { HistoryUpdateType, InfinityPanelIdTitle, PageParams, RouterGenericBase } from './Types'; import { Fixer } from './HotFixers'; export declare type RouteList<T extends RouterGenericBase = RouterGenericBase> = Partial<Record<T['pageId'], Page<T>>>; export declare type ReplaceUnknownRouteFn<T extends RouterGenericBase = RouterGenericBase> = (newRoute: MyRoute<T>, oldRoute?: MyRoute<T>) => MyRoute<T>; /** * @ignore */ export declare type UpdateEventFn<T extends RouterGenericBase = RouterGenericBase> = (newRoute: MyRoute<T>, oldRoute: MyRoute<T> | undefined, isNewRoute: boolean, type: HistoryUpdateType) => void; /** * @ignore */ export declare type EnterEventFn<T extends RouterGenericBase = RouterGenericBase> = (newRoute: MyRoute<T>, oldRoute?: MyRoute<T>) => void; /** * @ignore */ export declare type LeaveEventFn<T extends RouterGenericBase = RouterGenericBase> = (newRoute: MyRoute<T>, oldRoute: MyRoute<T>, isNewRoute: boolean, type: HistoryUpdateType) => void; export declare type RouterMiddleware<T extends RouterGenericBase = RouterGenericBase> = (route: MyRoute<T>, hash: string) => MyRoute<T>; export declare class Router<T extends RouterGenericBase = RouterGenericBase> extends EventEmitter<{ update: UpdateEventFn<T>; enter: EnterEventFn<T>; }> { routes: RouteList<T>; history: History<T>; enableLogging: boolean; defaultPage: string; defaultView: string; defaultRoot: string; defaultPanel: string; alwaysStartWithSlash: boolean; blankMiddleware: Array<RouterMiddleware<T>>; preventSameLocationChange: boolean; hotFixes: Set<Fixer>; hashParamName: string; /** * Значение window.location.hash которое было на момент старта роутера */ startHash: string; private deferOnGoBack; private startHistoryOffset; private started; private readonly infinityPanelCacheInstance; private readonly performBlankMiddleware; /** * * ```javascript * export const PAGE_MAIN = '/'; * export const PAGE_PERSIK = '/persik'; * export const PANEL_MAIN = 'panel_main'; * export const PANEL_PERSIK = 'panel_persik'; * export const VIEW_MAIN = 'view_main'; * const routes = { * [PAGE_MAIN]: new Page(PANEL_MAIN, VIEW_MAIN), * [PAGE_PERSIK]: new Page(PANEL_PERSIK, VIEW_MAIN), * }; * export const router = new Router(routes); * router.start(); * ``` * @param routes * @param routerConfig */ constructor(routes: RouteList<T>, routerConfig?: RouterConfig<T> | null); private static back; private static backTo; replacerUnknownRoute: ReplaceUnknownRouteFn<T>; private extractHashFromParam; private get currentHash(); start(hashParamName?: string): void; stop(): void; getCurrentRouteOrDef(): MyRoute<T>; getCurrentStateOrDef(): State<T>; log(...args: any): void; /** * Добавляет новую страницу в историю * @param pageId страница указанная в конструкторе {@link Router.constructor} * @param params можно получить из {@link Location.getParams} */ pushPage(pageId: T['pageId'], params?: PageParams): void; /** * Заменяет текущую страницу на переданную * @param pageId страница указанная в конструкторе {@link Router.constructor} * @param params можно получить из {@link Location.getParams} */ replacePage(pageId: T['pageId'], params?: PageParams): void; pushPageAfterPreviews(prevPageId: T['pageId'], pageId: T['pageId'], params?: PageParams): void; /** * Переход по истории назад */ popPage(): void; /** * Если x - число, то осуществляется переход на указанное количество шагов * Если x - строка, то в истории будет найдена страница с указанным pageId и осуществлен переход до нее * @param {string|number} x */ popPageTo(x: number | T['pageId']): void; popPageToAndPush(x: number, pageId: T['pageId'], params?: PageParams): void; popPageToAndReplace(x: number, pageId: T['pageId'], params?: PageParams): void; /** * История ломается когда открывается VKPay или пост из колокольчика */ isHistoryBroken(): boolean; /** * Способ починить историю браузера когда ее сломали снаружи из фрейма * например перейдя по колокольчику или открыв вкпей * проблема: миниап запущен фо фрейме и у него обшая исторя страниц с родительской страницей * все происходит хорошо когда только миниап пушит в историю страницы * [X1, X2, X3] * когда приходит родительская страница и пуши что-то в историю * [X1, X2, X3, Y1, Y1] * то случается беда, в истории перремешаны страницы, следующий popPage приведет в неожиданное место * в даннмо слусе ожидалось что popPage перейдет с X3 на X2, но фактически придут на Y1 * идея решения -- запушить снова все "нужные страницы поверх истории" * [X1, X2, X3, Y1, Y1, X1, X2, X3] */ fixBrokenHistory(): void; /** * @param modalId * @param params Будьте аккуратны с параметрами, не допускайте чтобы ваши параметры пересекались с параметрами страницы */ pushModal(modalId: T['modalId'], params?: PageParams): void; /** * @param popupId * @param params Будьте аккуратны с параметрами, не допускайте чтобы ваши параметры пересекались с параметрами страницы */ pushPopup(popupId: T['popupId'], params?: PageParams): void; /** * @param modalId * @param params Будьте аккуратны с параметрами, не допускайте чтобы ваши параметры пересекались с параметрами страницы */ replaceModal(modalId: T['modalId'], params?: PageParams): void; /** * @param popupId * @param params Будьте аккуратны с параметрами, не допускайте чтобы ваши параметры пересекались с параметрами страницы */ replacePopup(popupId: string, params?: PageParams): void; popPageIfModal(): void; popPageIfPopup(): void; /** * @deprecated use popPageIfHasOverlay */ popPageIfModalOrPopup(): void; popPageIfHasOverlay(): void; /** * @param pageId * @param fn * @return unsubscribe function */ onEnterPage(pageId: string, fn: UpdateEventFn): () => void; /** * @param pageId * @param fn * @return unsubscribe function */ onLeavePage(pageId: T['pageId'], fn: LeaveEventFn): () => void; getCurrentLocation(): Location<T>; getPreviousLocation(): Location<T> | undefined; /** * @param safety - true будет ждать события не дольше 700мс, если вы уверены что надо ждать дольше передайте false */ afterUpdate(safety?: boolean): Promise<void>; private static checkParams; private getDefaultRoute; private readonly onPopState; private replace; private push; /** * @param location значение window.location.hash * @private */ createRouteFromLocationWithReplace(location: T['pageId']): MyRoute<T>; private createRouteFromLocation; private static isErrorThrowingEnabled; /** * Чтобы отрендерить бесконечне панели надо знать их id * этот метод возвращает все id панелей которые хоть раз были отрендерены * это не эффективно, однако сейчас точно нельзя сказать когда панель нужна а когда нет * это обусловленно тем что панели надо убирать из дерева только после того как пройдет анимация vkui * кроме того панели могут убираться из середины, благодоря useThrottlingLocation.ts * * текущее решение -- рендерить все панели всегда * * @param viewId */ getInfinityPanelList(viewId: T['viewId']): Array<InfinityPanelIdTitle<T['panelId']>>; private static isSameLocation; private needPreventSameLocationChange; onVKWebAppChangeFragment(location: string): void; private hasFixer; }