@viewfly/router 0.0.1-alpha.13 → 0.0.1-alpha.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/index.esm.js +57 -28
- package/bundles/index.js +57 -28
- package/bundles/providers/navigator.d.ts +6 -5
- package/bundles/providers/router.d.ts +1 -0
- package/package.json +5 -4
package/bundles/index.esm.js
CHANGED
|
@@ -31,24 +31,29 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
class Navigator {
|
|
34
|
-
constructor(
|
|
35
|
-
this.
|
|
34
|
+
constructor(baseUrl) {
|
|
35
|
+
this.baseUrl = baseUrl;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
function formatUrl(pathname, query) {
|
|
39
|
+
pathname = pathname.replace(/\/+/g, '/');
|
|
39
40
|
if (query) {
|
|
40
|
-
return pathname + '?' +
|
|
41
|
+
return pathname + '?' + formatQueryParams(query);
|
|
41
42
|
}
|
|
42
43
|
return pathname;
|
|
43
44
|
}
|
|
44
|
-
function
|
|
45
|
-
const map = new Map();
|
|
46
|
-
Object.keys(queryParam).forEach(key => {
|
|
47
|
-
map.set(key, queryParam[key]);
|
|
48
|
-
});
|
|
45
|
+
function formatQueryParams(queryParams) {
|
|
49
46
|
const params = [];
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
Object.keys(queryParams).forEach(key => {
|
|
48
|
+
const values = queryParams[key];
|
|
49
|
+
if (Array.isArray(values)) {
|
|
50
|
+
values.forEach(i => {
|
|
51
|
+
params.push(`${key}=${decodeURIComponent(i)}`);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
params.push(`${key}=${decodeURIComponent(values)}`);
|
|
56
|
+
}
|
|
52
57
|
});
|
|
53
58
|
return params.join('&');
|
|
54
59
|
}
|
|
@@ -56,30 +61,41 @@ let BrowserNavigator = class BrowserNavigator extends Navigator {
|
|
|
56
61
|
get pathname() {
|
|
57
62
|
return location.pathname;
|
|
58
63
|
}
|
|
59
|
-
constructor(
|
|
60
|
-
super(
|
|
64
|
+
constructor(baseUrl) {
|
|
65
|
+
super(baseUrl);
|
|
61
66
|
this.urlChangeEvent = new Subject();
|
|
62
67
|
this.subscription = new Subscription();
|
|
63
68
|
this.onUrlChanged = this.urlChangeEvent.asObservable();
|
|
64
69
|
this.subscription.add(fromEvent(window, 'popstate').subscribe(() => {
|
|
65
70
|
this.urlChangeEvent.next();
|
|
66
71
|
}));
|
|
72
|
+
if (!this.pathname.startsWith(this.baseUrl)) {
|
|
73
|
+
history.replaceState(null, '', this.baseUrl);
|
|
74
|
+
}
|
|
67
75
|
}
|
|
68
76
|
to(pathName, relative, queryParams) {
|
|
69
77
|
const url = this.join(pathName, relative, queryParams);
|
|
70
78
|
if (location.origin + url === location.href) {
|
|
71
79
|
return true;
|
|
72
80
|
}
|
|
73
|
-
history.pushState(null, '',
|
|
81
|
+
history.pushState(null, '', url);
|
|
82
|
+
this.urlChangeEvent.next();
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
replace(pathName, relative, queryParams) {
|
|
86
|
+
const url = this.join(pathName, relative, queryParams);
|
|
87
|
+
if (location.origin + url === location.href) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
history.replaceState(null, '', url);
|
|
74
91
|
this.urlChangeEvent.next();
|
|
75
92
|
return true;
|
|
76
93
|
}
|
|
77
94
|
join(pathname, relative, queryParams) {
|
|
78
|
-
var _a;
|
|
79
|
-
let beforePath = relative.beforePath;
|
|
80
95
|
if (pathname.startsWith('/')) {
|
|
81
|
-
return formatUrl(pathname, queryParams);
|
|
96
|
+
return formatUrl(this.baseUrl + pathname, queryParams);
|
|
82
97
|
}
|
|
98
|
+
let beforePath = relative.beforePath;
|
|
83
99
|
while (true) {
|
|
84
100
|
if (pathname.startsWith('./')) {
|
|
85
101
|
pathname = pathname.substring(2);
|
|
@@ -87,7 +103,13 @@ let BrowserNavigator = class BrowserNavigator extends Navigator {
|
|
|
87
103
|
}
|
|
88
104
|
if (pathname.startsWith('../')) {
|
|
89
105
|
pathname = pathname.substring(3);
|
|
90
|
-
|
|
106
|
+
if (relative.parent) {
|
|
107
|
+
beforePath = relative.parent.beforePath;
|
|
108
|
+
relative = relative.parent;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
beforePath = '';
|
|
112
|
+
}
|
|
91
113
|
if (!beforePath) {
|
|
92
114
|
break;
|
|
93
115
|
}
|
|
@@ -95,7 +117,7 @@ let BrowserNavigator = class BrowserNavigator extends Navigator {
|
|
|
95
117
|
}
|
|
96
118
|
break;
|
|
97
119
|
}
|
|
98
|
-
return formatUrl(beforePath + '/' + pathname, queryParams);
|
|
120
|
+
return formatUrl(this.baseUrl + '/' + beforePath + '/' + pathname, queryParams);
|
|
99
121
|
}
|
|
100
122
|
back() {
|
|
101
123
|
history.back();
|
|
@@ -117,9 +139,11 @@ BrowserNavigator = __decorate([
|
|
|
117
139
|
|
|
118
140
|
class Router {
|
|
119
141
|
get pathname() {
|
|
120
|
-
var _a;
|
|
121
142
|
if (this.parent) {
|
|
122
|
-
|
|
143
|
+
const name = this.parent.path.match(/[^\/?#]+/);
|
|
144
|
+
if (name) {
|
|
145
|
+
return name[0];
|
|
146
|
+
}
|
|
123
147
|
}
|
|
124
148
|
return '';
|
|
125
149
|
}
|
|
@@ -139,6 +163,9 @@ class Router {
|
|
|
139
163
|
navigateTo(path, params) {
|
|
140
164
|
this.navigator.to(path, this, params);
|
|
141
165
|
}
|
|
166
|
+
replaceTo(path, params) {
|
|
167
|
+
this.navigator.replace(path, this, params);
|
|
168
|
+
}
|
|
142
169
|
refresh(path) {
|
|
143
170
|
this.path = path;
|
|
144
171
|
this.refreshEvent.next();
|
|
@@ -203,7 +230,8 @@ function Link(props) {
|
|
|
203
230
|
const router = inject(Router);
|
|
204
231
|
function getActive() {
|
|
205
232
|
return props.exact ?
|
|
206
|
-
navigator.pathname === navigator.join(props.to, router)
|
|
233
|
+
(navigator.pathname === navigator.join(props.to, router) ||
|
|
234
|
+
(navigator.pathname + '/') === navigator.join(props.to, router)) :
|
|
207
235
|
navigator.pathname.startsWith(navigator.join(props.to, router));
|
|
208
236
|
}
|
|
209
237
|
const isActive = useSignal(getActive());
|
|
@@ -214,14 +242,15 @@ function Link(props) {
|
|
|
214
242
|
subscription.unsubscribe();
|
|
215
243
|
});
|
|
216
244
|
function navigate(ev) {
|
|
245
|
+
if ((!props.tag || props.tag === 'a') && props.target === '_blank') {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
217
248
|
ev.preventDefault();
|
|
218
249
|
router.navigateTo(props.to, props.queryParams);
|
|
219
250
|
}
|
|
220
251
|
return () => {
|
|
221
252
|
const Tag = props.tag || 'a';
|
|
222
|
-
const attrs = Object.assign({
|
|
223
|
-
target: '_blank'
|
|
224
|
-
}, props, Object.assign({ onClick: navigate }, props));
|
|
253
|
+
const attrs = Object.assign({}, props, Object.assign({ onClick: navigate }, props));
|
|
225
254
|
if (Tag === 'a') {
|
|
226
255
|
attrs.href = navigator.join(props.to, router, props.queryParams);
|
|
227
256
|
}
|
|
@@ -232,12 +261,12 @@ function Link(props) {
|
|
|
232
261
|
else if (typeof attrs.class === 'string') {
|
|
233
262
|
attrs.class += ' ' + props.active;
|
|
234
263
|
}
|
|
235
|
-
else if (typeof props.active === 'object') {
|
|
236
|
-
attrs.class[props.active] = true;
|
|
237
|
-
}
|
|
238
264
|
else if (Array.isArray(attrs.class)) {
|
|
239
265
|
attrs.class.push(props.active);
|
|
240
266
|
}
|
|
267
|
+
else if (typeof attrs.class === 'object') {
|
|
268
|
+
attrs.class[props.active] = true;
|
|
269
|
+
}
|
|
241
270
|
}
|
|
242
271
|
return jsx(Tag, Object.assign({}, attrs, { children: props.children }));
|
|
243
272
|
};
|
|
@@ -317,4 +346,4 @@ function RouterOutlet(props) {
|
|
|
317
346
|
};
|
|
318
347
|
}
|
|
319
348
|
|
|
320
|
-
export { BrowserNavigator, Link, Navigator, RootRouter, Router, RouterOutlet,
|
|
349
|
+
export { BrowserNavigator, Link, Navigator, RootRouter, Router, RouterOutlet, formatQueryParams, formatUrl };
|
package/bundles/index.js
CHANGED
|
@@ -33,24 +33,29 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
class Navigator {
|
|
36
|
-
constructor(
|
|
37
|
-
this.
|
|
36
|
+
constructor(baseUrl) {
|
|
37
|
+
this.baseUrl = baseUrl;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
function formatUrl(pathname, query) {
|
|
41
|
+
pathname = pathname.replace(/\/+/g, '/');
|
|
41
42
|
if (query) {
|
|
42
|
-
return pathname + '?' +
|
|
43
|
+
return pathname + '?' + formatQueryParams(query);
|
|
43
44
|
}
|
|
44
45
|
return pathname;
|
|
45
46
|
}
|
|
46
|
-
function
|
|
47
|
-
const map = new Map();
|
|
48
|
-
Object.keys(queryParam).forEach(key => {
|
|
49
|
-
map.set(key, queryParam[key]);
|
|
50
|
-
});
|
|
47
|
+
function formatQueryParams(queryParams) {
|
|
51
48
|
const params = [];
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
Object.keys(queryParams).forEach(key => {
|
|
50
|
+
const values = queryParams[key];
|
|
51
|
+
if (Array.isArray(values)) {
|
|
52
|
+
values.forEach(i => {
|
|
53
|
+
params.push(`${key}=${decodeURIComponent(i)}`);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
params.push(`${key}=${decodeURIComponent(values)}`);
|
|
58
|
+
}
|
|
54
59
|
});
|
|
55
60
|
return params.join('&');
|
|
56
61
|
}
|
|
@@ -58,30 +63,41 @@ exports.BrowserNavigator = class BrowserNavigator extends Navigator {
|
|
|
58
63
|
get pathname() {
|
|
59
64
|
return location.pathname;
|
|
60
65
|
}
|
|
61
|
-
constructor(
|
|
62
|
-
super(
|
|
66
|
+
constructor(baseUrl) {
|
|
67
|
+
super(baseUrl);
|
|
63
68
|
this.urlChangeEvent = new stream.Subject();
|
|
64
69
|
this.subscription = new stream.Subscription();
|
|
65
70
|
this.onUrlChanged = this.urlChangeEvent.asObservable();
|
|
66
71
|
this.subscription.add(stream.fromEvent(window, 'popstate').subscribe(() => {
|
|
67
72
|
this.urlChangeEvent.next();
|
|
68
73
|
}));
|
|
74
|
+
if (!this.pathname.startsWith(this.baseUrl)) {
|
|
75
|
+
history.replaceState(null, '', this.baseUrl);
|
|
76
|
+
}
|
|
69
77
|
}
|
|
70
78
|
to(pathName, relative, queryParams) {
|
|
71
79
|
const url = this.join(pathName, relative, queryParams);
|
|
72
80
|
if (location.origin + url === location.href) {
|
|
73
81
|
return true;
|
|
74
82
|
}
|
|
75
|
-
history.pushState(null, '',
|
|
83
|
+
history.pushState(null, '', url);
|
|
84
|
+
this.urlChangeEvent.next();
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
replace(pathName, relative, queryParams) {
|
|
88
|
+
const url = this.join(pathName, relative, queryParams);
|
|
89
|
+
if (location.origin + url === location.href) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
history.replaceState(null, '', url);
|
|
76
93
|
this.urlChangeEvent.next();
|
|
77
94
|
return true;
|
|
78
95
|
}
|
|
79
96
|
join(pathname, relative, queryParams) {
|
|
80
|
-
var _a;
|
|
81
|
-
let beforePath = relative.beforePath;
|
|
82
97
|
if (pathname.startsWith('/')) {
|
|
83
|
-
return formatUrl(pathname, queryParams);
|
|
98
|
+
return formatUrl(this.baseUrl + pathname, queryParams);
|
|
84
99
|
}
|
|
100
|
+
let beforePath = relative.beforePath;
|
|
85
101
|
while (true) {
|
|
86
102
|
if (pathname.startsWith('./')) {
|
|
87
103
|
pathname = pathname.substring(2);
|
|
@@ -89,7 +105,13 @@ exports.BrowserNavigator = class BrowserNavigator extends Navigator {
|
|
|
89
105
|
}
|
|
90
106
|
if (pathname.startsWith('../')) {
|
|
91
107
|
pathname = pathname.substring(3);
|
|
92
|
-
|
|
108
|
+
if (relative.parent) {
|
|
109
|
+
beforePath = relative.parent.beforePath;
|
|
110
|
+
relative = relative.parent;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
beforePath = '';
|
|
114
|
+
}
|
|
93
115
|
if (!beforePath) {
|
|
94
116
|
break;
|
|
95
117
|
}
|
|
@@ -97,7 +119,7 @@ exports.BrowserNavigator = class BrowserNavigator extends Navigator {
|
|
|
97
119
|
}
|
|
98
120
|
break;
|
|
99
121
|
}
|
|
100
|
-
return formatUrl(beforePath + '/' + pathname, queryParams);
|
|
122
|
+
return formatUrl(this.baseUrl + '/' + beforePath + '/' + pathname, queryParams);
|
|
101
123
|
}
|
|
102
124
|
back() {
|
|
103
125
|
history.back();
|
|
@@ -119,9 +141,11 @@ exports.BrowserNavigator = __decorate([
|
|
|
119
141
|
|
|
120
142
|
class Router {
|
|
121
143
|
get pathname() {
|
|
122
|
-
var _a;
|
|
123
144
|
if (this.parent) {
|
|
124
|
-
|
|
145
|
+
const name = this.parent.path.match(/[^\/?#]+/);
|
|
146
|
+
if (name) {
|
|
147
|
+
return name[0];
|
|
148
|
+
}
|
|
125
149
|
}
|
|
126
150
|
return '';
|
|
127
151
|
}
|
|
@@ -141,6 +165,9 @@ class Router {
|
|
|
141
165
|
navigateTo(path, params) {
|
|
142
166
|
this.navigator.to(path, this, params);
|
|
143
167
|
}
|
|
168
|
+
replaceTo(path, params) {
|
|
169
|
+
this.navigator.replace(path, this, params);
|
|
170
|
+
}
|
|
144
171
|
refresh(path) {
|
|
145
172
|
this.path = path;
|
|
146
173
|
this.refreshEvent.next();
|
|
@@ -205,7 +232,8 @@ function Link(props) {
|
|
|
205
232
|
const router = core.inject(Router);
|
|
206
233
|
function getActive() {
|
|
207
234
|
return props.exact ?
|
|
208
|
-
navigator.pathname === navigator.join(props.to, router)
|
|
235
|
+
(navigator.pathname === navigator.join(props.to, router) ||
|
|
236
|
+
(navigator.pathname + '/') === navigator.join(props.to, router)) :
|
|
209
237
|
navigator.pathname.startsWith(navigator.join(props.to, router));
|
|
210
238
|
}
|
|
211
239
|
const isActive = core.useSignal(getActive());
|
|
@@ -216,14 +244,15 @@ function Link(props) {
|
|
|
216
244
|
subscription.unsubscribe();
|
|
217
245
|
});
|
|
218
246
|
function navigate(ev) {
|
|
247
|
+
if ((!props.tag || props.tag === 'a') && props.target === '_blank') {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
219
250
|
ev.preventDefault();
|
|
220
251
|
router.navigateTo(props.to, props.queryParams);
|
|
221
252
|
}
|
|
222
253
|
return () => {
|
|
223
254
|
const Tag = props.tag || 'a';
|
|
224
|
-
const attrs = Object.assign({
|
|
225
|
-
target: '_blank'
|
|
226
|
-
}, props, Object.assign({ onClick: navigate }, props));
|
|
255
|
+
const attrs = Object.assign({}, props, Object.assign({ onClick: navigate }, props));
|
|
227
256
|
if (Tag === 'a') {
|
|
228
257
|
attrs.href = navigator.join(props.to, router, props.queryParams);
|
|
229
258
|
}
|
|
@@ -234,12 +263,12 @@ function Link(props) {
|
|
|
234
263
|
else if (typeof attrs.class === 'string') {
|
|
235
264
|
attrs.class += ' ' + props.active;
|
|
236
265
|
}
|
|
237
|
-
else if (typeof props.active === 'object') {
|
|
238
|
-
attrs.class[props.active] = true;
|
|
239
|
-
}
|
|
240
266
|
else if (Array.isArray(attrs.class)) {
|
|
241
267
|
attrs.class.push(props.active);
|
|
242
268
|
}
|
|
269
|
+
else if (typeof attrs.class === 'object') {
|
|
270
|
+
attrs.class[props.active] = true;
|
|
271
|
+
}
|
|
243
272
|
}
|
|
244
273
|
return jsxRuntime.jsx(Tag, Object.assign({}, attrs, { children: props.children }));
|
|
245
274
|
};
|
|
@@ -324,5 +353,5 @@ exports.Navigator = Navigator;
|
|
|
324
353
|
exports.RootRouter = RootRouter;
|
|
325
354
|
exports.Router = Router;
|
|
326
355
|
exports.RouterOutlet = RouterOutlet;
|
|
327
|
-
exports.
|
|
356
|
+
exports.formatQueryParams = formatQueryParams;
|
|
328
357
|
exports.formatUrl = formatUrl;
|
|
@@ -4,27 +4,28 @@ export interface QueryParams {
|
|
|
4
4
|
[key: string]: string | string[];
|
|
5
5
|
}
|
|
6
6
|
export declare abstract class Navigator {
|
|
7
|
-
|
|
8
|
-
protected constructor(
|
|
7
|
+
baseUrl: string;
|
|
8
|
+
protected constructor(baseUrl: string);
|
|
9
9
|
abstract onUrlChanged: Observable<void>;
|
|
10
10
|
abstract get pathname(): string;
|
|
11
11
|
abstract to(pathName: string, relative: Router, queryParams?: QueryParams): boolean;
|
|
12
|
+
abstract replace(pathName: string, relative: Router, queryParams?: QueryParams): boolean;
|
|
12
13
|
abstract join(pathName: string, relative: Router, queryParams?: QueryParams): string;
|
|
13
14
|
abstract back(): void;
|
|
14
15
|
abstract forward(): void;
|
|
15
16
|
abstract go(offset: number): void;
|
|
16
17
|
abstract destroy(): void;
|
|
17
18
|
}
|
|
18
|
-
export type QueryParam = Record<string, string | boolean | number>;
|
|
19
19
|
export declare function formatUrl(pathname: string, query?: QueryParams): string;
|
|
20
|
-
export declare function
|
|
20
|
+
export declare function formatQueryParams(queryParams: QueryParams): string;
|
|
21
21
|
export declare class BrowserNavigator extends Navigator {
|
|
22
22
|
onUrlChanged: Observable<void>;
|
|
23
23
|
get pathname(): string;
|
|
24
24
|
private urlChangeEvent;
|
|
25
25
|
private subscription;
|
|
26
|
-
constructor(
|
|
26
|
+
constructor(baseUrl: string);
|
|
27
27
|
to(pathName: string, relative: Router, queryParams?: QueryParams): boolean;
|
|
28
|
+
replace(pathName: string, relative: Router, queryParams?: QueryParams): boolean;
|
|
28
29
|
join(pathname: string, relative: Router, queryParams?: QueryParams): string;
|
|
29
30
|
back(): void;
|
|
30
31
|
forward(): void;
|
|
@@ -16,6 +16,7 @@ export declare class Router {
|
|
|
16
16
|
private refreshEvent;
|
|
17
17
|
constructor(navigator: Navigator, parent: Router | null, path: string);
|
|
18
18
|
navigateTo(path: string, params?: QueryParams): void;
|
|
19
|
+
replaceTo(path: string, params?: QueryParams): void;
|
|
19
20
|
refresh(path: string): void;
|
|
20
21
|
consumeConfig(routes: RouteConfig[]): {
|
|
21
22
|
remainingPath: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viewfly/router",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.15",
|
|
4
4
|
"description": "A routing library based on the Viewfly framework that can be run in the browser or Nodejs background.",
|
|
5
5
|
"main": "./bundles/index.js",
|
|
6
6
|
"module": "./bundles/index.esm.js",
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"keywords": [],
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@tanbo/stream": "^1.
|
|
16
|
-
"@viewfly/core": "^0.0.1-alpha.
|
|
15
|
+
"@tanbo/stream": "^1.2.0",
|
|
16
|
+
"@viewfly/core": "^0.0.1-alpha.15",
|
|
17
17
|
"url": "^0.11.1"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
@@ -33,5 +33,6 @@
|
|
|
33
33
|
},
|
|
34
34
|
"bugs": {
|
|
35
35
|
"url": "https://github.com/viewfly/viewfly.git/issues"
|
|
36
|
-
}
|
|
36
|
+
},
|
|
37
|
+
"gitHead": "8eccbdc9402ab506f98acb5946e19c16d8b74b43"
|
|
37
38
|
}
|