diff options
| author | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-03-19 18:06:22 +0900 |
|---|---|---|
| committer | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-03-19 18:06:22 +0900 |
| commit | 81ac71f7e59623625369aaff75a8712923450b80 (patch) | |
| tree | c36eb84c0724121db8d2381cbb8fab0593ff53ea /packages/frontend/src/lib | |
| parent | better import paths (diff) | |
| download | misskey-81ac71f7e59623625369aaff75a8712923450b80.tar.gz misskey-81ac71f7e59623625369aaff75a8712923450b80.tar.bz2 misskey-81ac71f7e59623625369aaff75a8712923450b80.zip | |
refactor(frontend): router refactoring
Diffstat (limited to 'packages/frontend/src/lib')
| -rw-r--r-- | packages/frontend/src/lib/nirax.ts | 94 |
1 files changed, 51 insertions, 43 deletions
diff --git a/packages/frontend/src/lib/nirax.ts b/packages/frontend/src/lib/nirax.ts index cc20d497e6..8783874bc2 100644 --- a/packages/frontend/src/lib/nirax.ts +++ b/packages/frontend/src/lib/nirax.ts @@ -5,7 +5,7 @@ // NIRAX --- A lightweight router -import { onMounted, shallowRef } from 'vue'; +import { onBeforeUnmount, onMounted, shallowRef } from 'vue'; import { EventEmitter } from 'eventemitter3'; import type { Component, ShallowRef } from 'vue'; @@ -45,28 +45,28 @@ type ParsedPath = (string | { optional?: boolean; })[]; -export type RouterEvent = { +export type RouterEvents = { change: (ctx: { - beforePath: string; - path: string; - resolved: Resolved; + beforeFullPath: string; + fullPath: string; + resolved: PathResolvedResult; }) => void; replace: (ctx: { - path: string; + fullPath: string; }) => void; push: (ctx: { - beforePath: string; - path: string; + beforeFullPath: string; + fullPath: string; route: RouteDef | null; props: Map<string, string> | null; }) => void; same: () => void; }; -export type Resolved = { +export type PathResolvedResult = { route: RouteDef; props: Map<string, string | boolean>; - child?: Resolved; + child?: PathResolvedResult; redirected?: boolean; /** @internal */ @@ -102,39 +102,39 @@ function parsePath(path: string): ParsedPath { return res; } -export class Nirax<DEF extends RouteDef[]> extends EventEmitter<RouterEvent> { +export class Nirax<DEF extends RouteDef[]> extends EventEmitter<RouterEvents> { private routes: DEF; - public current: Resolved; - public currentRef: ShallowRef<Resolved>; + public current: PathResolvedResult; + public currentRef: ShallowRef<PathResolvedResult>; public currentRoute: ShallowRef<RouteDef>; - private currentPath: string; + private currentFullPath: string; // /foo/bar?baz=qux#hash private isLoggedIn: boolean; private notFoundPageComponent: Component; private redirectCount = 0; - public navHook: ((path: string, flag?: RouterFlag) => boolean) | null = null; + public navHook: ((fullPath: string, flag?: RouterFlag) => boolean) | null = null; - constructor(routes: DEF, currentPath: Nirax<DEF>['currentPath'], isLoggedIn: boolean, notFoundPageComponent: Component) { + constructor(routes: DEF, currentFullPath: Nirax<DEF>['currentFullPath'], isLoggedIn: boolean, notFoundPageComponent: Component) { super(); this.routes = routes; - this.current = this.resolve(currentPath)!; + this.current = this.resolve(currentFullPath)!; this.currentRef = shallowRef(this.current); this.currentRoute = shallowRef(this.current.route); - this.currentPath = currentPath; + this.currentFullPath = currentFullPath; this.isLoggedIn = isLoggedIn; this.notFoundPageComponent = notFoundPageComponent; } public init() { - const res = this.navigate(this.currentPath, false); + const res = this.navigate(this.currentFullPath, false); this.emit('replace', { - path: res._parsedRoute.fullPath, + fullPath: res._parsedRoute.fullPath, }); } - public resolve(path: string): Resolved | null { - const fullPath = path; + public resolve(fullPath: string): PathResolvedResult | null { + let path = fullPath; let queryString: string | null = null; let hash: string | null = null; if (path[0] === '/') path = path.substring(1); @@ -153,7 +153,7 @@ export class Nirax<DEF extends RouteDef[]> extends EventEmitter<RouterEvent> { hash, }; - function check(routes: RouteDef[], _parts: string[]): Resolved | null { + function check(routes: RouteDef[], _parts: string[]): PathResolvedResult | null { forEachRouteLoop: for (const route of routes) { let parts = [..._parts]; @@ -256,14 +256,14 @@ export class Nirax<DEF extends RouteDef[]> extends EventEmitter<RouterEvent> { return check(this.routes, _parts); } - private navigate(path: string, emitChange = true, _redirected = false): Resolved { - const beforePath = this.currentPath; - this.currentPath = path; + private navigate(fullPath: string, emitChange = true, _redirected = false): PathResolvedResult { + const beforeFullPath = this.currentFullPath; + this.currentFullPath = fullPath; - const res = this.resolve(this.currentPath); + const res = this.resolve(this.currentFullPath); if (res == null) { - throw new Error('no route found for: ' + path); + throw new Error('no route found for: ' + fullPath); } if ('redirect' in res.route) { @@ -291,8 +291,8 @@ export class Nirax<DEF extends RouteDef[]> extends EventEmitter<RouterEvent> { if (emitChange && res.route.path !== '/:(*)') { this.emit('change', { - beforePath, - path, + beforeFullPath, + fullPath, resolved: res, }); } @@ -304,37 +304,45 @@ export class Nirax<DEF extends RouteDef[]> extends EventEmitter<RouterEvent> { }; } - public getCurrentPath() { - return this.currentPath; + public getCurrentFullPath() { + return this.currentFullPath; } - public push(path: string, flag?: RouterFlag) { - const beforePath = this.currentPath; - if (path === beforePath) { + public push(fullPath: string, flag?: RouterFlag) { + const beforeFullPath = this.currentFullPath; + if (fullPath === beforeFullPath) { this.emit('same'); return; } if (this.navHook) { - const cancel = this.navHook(path, flag); + const cancel = this.navHook(fullPath, flag); if (cancel) return; } - const res = this.navigate(path); + const res = this.navigate(fullPath); if (res.route.path === '/:(*)') { - location.href = path; + location.href = fullPath; } else { this.emit('push', { - beforePath, - path: res._parsedRoute.fullPath, + beforeFullPath, + fullPath: res._parsedRoute.fullPath, route: res.route, props: res.props, }); } } - public replace(path: string) { - const res = this.navigate(path); + public replace(fullPath: string) { + const res = this.navigate(fullPath); this.emit('replace', { - path: res._parsedRoute.fullPath, + fullPath: res._parsedRoute.fullPath, + }); + } + + public useListener<E extends keyof RouterEvents, L = RouterEvents[E]>(event: E, listener: L) { + this.addListener(event, listener); + + onBeforeUnmount(() => { + this.removeListener(event, listener); }); } } |