summaryrefslogtreecommitdiff
path: root/packages/frontend/src/lib
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2025-03-19 18:06:22 +0900
committersyuilo <4439005+syuilo@users.noreply.github.com>2025-03-19 18:06:22 +0900
commit81ac71f7e59623625369aaff75a8712923450b80 (patch)
treec36eb84c0724121db8d2381cbb8fab0593ff53ea /packages/frontend/src/lib
parentbetter import paths (diff)
downloadmisskey-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.ts94
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);
});
}
}