@lexriver/dome 1.3.0 → 1.4.0
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/README.md +1 -0
- package/jest.config.js +0 -0
- package/out/AnimatedArray.d.ts +29 -27
- package/out/AnimatedArray.js +51 -44
- package/out/AnimatedTable.d.ts +38 -38
- package/out/AnimatedTable.js +91 -91
- package/out/AnimatedText.d.ts +13 -13
- package/out/AnimatedText.js +24 -24
- package/out/Animation.d.ts +4 -4
- package/out/Animation.js +0 -0
- package/out/Dome.d.ts +9 -9
- package/out/Dome.js +295 -295
- package/out/DomeComponent.d.ts +19 -19
- package/out/DomeComponent.js +44 -44
- package/out/DomeManipulator.d.ts +48 -48
- package/out/DomeManipulator.js +329 -329
- package/out/DomeRouter.console-test.d.ts +0 -0
- package/out/DomeRouter.console-test.js +44 -44
- package/out/DomeRouter.d.ts +36 -36
- package/out/DomeRouter.js +227 -227
- package/out/LongestCommonSubsequence.d.ts +15 -15
- package/out/LongestCommonSubsequence.js +164 -164
- package/out/index.d.ts +12 -12
- package/out/index.js +14 -14
- package/out/temp-test.d.ts +1 -1
- package/out/temp-test.js +20 -20
- package/package.json +1 -1
- package/src/AnimatedArray.ts +11 -0
- package/src/AnimatedTable.ts +0 -0
- package/src/AnimatedText.ts +0 -0
- package/src/Animation.ts +0 -0
- package/src/Dome.ts +0 -0
- package/src/DomeComponent.ts +0 -0
- package/src/DomeManipulator.ts +0 -0
- package/src/DomeRouter.console-test.ts +0 -0
- package/src/DomeRouter.ts +0 -0
- package/src/LongestCommonSubsequence.ts +0 -0
- package/src/index.ts +0 -0
- package/src/temp-test.ts +0 -0
- package/tsconfig.json +0 -0
|
File without changes
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// //import { DomeRouter } from "./DomeRouter"
|
|
3
|
-
// function getRouteSlices(route:string){
|
|
4
|
-
// return route.split('/').filter(x => x.length>0)
|
|
5
|
-
// }
|
|
6
|
-
// function checkUrlMatchRouteAndGetParameters(url:string, route:string, exactMatch:boolean = true):Map<string,string>|undefined{
|
|
7
|
-
// // this function is purely for export
|
|
8
|
-
// const urlSlices = getRouteSlices(url)
|
|
9
|
-
// const routeSlices = getRouteSlices(route)
|
|
10
|
-
// if(exactMatch && routeSlices.length !== urlSlices.length) return undefined
|
|
11
|
-
// // all routeSlices must match for !exactMatch
|
|
12
|
-
// const extractedParameters = new Map<string,string>()
|
|
13
|
-
// for(let i=0;i<routeSlices.length;i++){
|
|
14
|
-
// let cRouteSlice = routeSlices[i]
|
|
15
|
-
// let cUrlSlice = urlSlices[i] // could be undefined
|
|
16
|
-
// //console.info('\t\t cRouteSlice=', cRouteSlice, 'cUrlSlice=', cUrlSlice)
|
|
17
|
-
// if(cRouteSlice.startsWith(':')){
|
|
18
|
-
// // we have a param name
|
|
19
|
-
// if(cUrlSlice === undefined){
|
|
20
|
-
// return undefined
|
|
21
|
-
// }
|
|
22
|
-
// // we have some variable, save it
|
|
23
|
-
// extractedParameters.set(cRouteSlice.substring(1), cUrlSlice)
|
|
24
|
-
// } else {
|
|
25
|
-
// // no param name
|
|
26
|
-
// if(cRouteSlice !== cUrlSlice){
|
|
27
|
-
// return undefined
|
|
28
|
-
// }
|
|
29
|
-
// }
|
|
30
|
-
// }
|
|
31
|
-
// return extractedParameters
|
|
32
|
-
// }
|
|
33
|
-
// DomeRouter.onRoute('/', true, ()=>{ console.log('exact /')})
|
|
34
|
-
// DomeRouter.onRoute('/', false, ()=>{ console.log('notexact /')})
|
|
35
|
-
// DomeRouter.onRoute('/test', true, ()=>{ console.log('exact /test')})
|
|
36
|
-
// DomeRouter.onRoute('/test/:id', true, (p)=>{ console.log('exact /test/:id', 'params=', p)})
|
|
37
|
-
// DomeRouter.onRoute('/test/:id', false, (p)=>{ console.log('notexact /test/:id', 'params=', p)})
|
|
38
|
-
// DomeRouter.onRoute('/test', false, ()=>{ console.log('notexact /test')})
|
|
39
|
-
// DomeRouter.onRoute('/test/:id/:id2', true, (p)=>{ console.log('exact /test/:id/:id2', 'params=', p)})
|
|
40
|
-
// let testRoute = '//test/34/st'
|
|
41
|
-
// console.log('** testing route:', testRoute)
|
|
42
|
-
// DomeRouter.execute(testRoute)
|
|
43
|
-
// //expect(!true).toBeTruthy()
|
|
44
|
-
//console.log(checkUrlMatchRouteAndGetParameters('/get-product/123', '/get-product/:id/:id2', false))
|
|
1
|
+
"use strict";
|
|
2
|
+
// //import { DomeRouter } from "./DomeRouter"
|
|
3
|
+
// function getRouteSlices(route:string){
|
|
4
|
+
// return route.split('/').filter(x => x.length>0)
|
|
5
|
+
// }
|
|
6
|
+
// function checkUrlMatchRouteAndGetParameters(url:string, route:string, exactMatch:boolean = true):Map<string,string>|undefined{
|
|
7
|
+
// // this function is purely for export
|
|
8
|
+
// const urlSlices = getRouteSlices(url)
|
|
9
|
+
// const routeSlices = getRouteSlices(route)
|
|
10
|
+
// if(exactMatch && routeSlices.length !== urlSlices.length) return undefined
|
|
11
|
+
// // all routeSlices must match for !exactMatch
|
|
12
|
+
// const extractedParameters = new Map<string,string>()
|
|
13
|
+
// for(let i=0;i<routeSlices.length;i++){
|
|
14
|
+
// let cRouteSlice = routeSlices[i]
|
|
15
|
+
// let cUrlSlice = urlSlices[i] // could be undefined
|
|
16
|
+
// //console.info('\t\t cRouteSlice=', cRouteSlice, 'cUrlSlice=', cUrlSlice)
|
|
17
|
+
// if(cRouteSlice.startsWith(':')){
|
|
18
|
+
// // we have a param name
|
|
19
|
+
// if(cUrlSlice === undefined){
|
|
20
|
+
// return undefined
|
|
21
|
+
// }
|
|
22
|
+
// // we have some variable, save it
|
|
23
|
+
// extractedParameters.set(cRouteSlice.substring(1), cUrlSlice)
|
|
24
|
+
// } else {
|
|
25
|
+
// // no param name
|
|
26
|
+
// if(cRouteSlice !== cUrlSlice){
|
|
27
|
+
// return undefined
|
|
28
|
+
// }
|
|
29
|
+
// }
|
|
30
|
+
// }
|
|
31
|
+
// return extractedParameters
|
|
32
|
+
// }
|
|
33
|
+
// DomeRouter.onRoute('/', true, ()=>{ console.log('exact /')})
|
|
34
|
+
// DomeRouter.onRoute('/', false, ()=>{ console.log('notexact /')})
|
|
35
|
+
// DomeRouter.onRoute('/test', true, ()=>{ console.log('exact /test')})
|
|
36
|
+
// DomeRouter.onRoute('/test/:id', true, (p)=>{ console.log('exact /test/:id', 'params=', p)})
|
|
37
|
+
// DomeRouter.onRoute('/test/:id', false, (p)=>{ console.log('notexact /test/:id', 'params=', p)})
|
|
38
|
+
// DomeRouter.onRoute('/test', false, ()=>{ console.log('notexact /test')})
|
|
39
|
+
// DomeRouter.onRoute('/test/:id/:id2', true, (p)=>{ console.log('exact /test/:id/:id2', 'params=', p)})
|
|
40
|
+
// let testRoute = '//test/34/st'
|
|
41
|
+
// console.log('** testing route:', testRoute)
|
|
42
|
+
// DomeRouter.execute(testRoute)
|
|
43
|
+
// //expect(!true).toBeTruthy()
|
|
44
|
+
//console.log(checkUrlMatchRouteAndGetParameters('/get-product/123', '/get-product/:id/:id2', false))
|
package/out/DomeRouter.d.ts
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
export declare type RouteAction = (params: {
|
|
2
|
-
[key: string]: string;
|
|
3
|
-
}, url: string) => void | Promise<void>;
|
|
4
|
-
interface HistoryUrl {
|
|
5
|
-
url: string;
|
|
6
|
-
scroll: number;
|
|
7
|
-
}
|
|
8
|
-
export declare module DomeRouter {
|
|
9
|
-
let maxHistoryUrlsCount: number;
|
|
10
|
-
function navigate(url: string): void;
|
|
11
|
-
function goBack(): void;
|
|
12
|
-
function goForward(): void;
|
|
13
|
-
function changeUrl(url: string): void;
|
|
14
|
-
function getCurrentUrl(): string | HistoryUrl;
|
|
15
|
-
/**
|
|
16
|
-
* get previous page url navigated by router
|
|
17
|
-
* @param previousPageIndex 0=previousPage, 1=previousPage-1, etc
|
|
18
|
-
*/
|
|
19
|
-
function getPreviousPageUrl(previousPageIndex?: number): string | undefined;
|
|
20
|
-
function reloadCurrentPage(addToHistory?: boolean): void;
|
|
21
|
-
function resolveUrl(url?: string, addToHistory?: boolean): void;
|
|
22
|
-
function onRoute(route: string, exactMatch: boolean, action: RouteAction): void;
|
|
23
|
-
function onNotFound(action: () => void): void;
|
|
24
|
-
/**
|
|
25
|
-
* Check if url matched route.
|
|
26
|
-
* example: /get-product/445345, /get-product/:productId, true ==> Map([productId:445345])
|
|
27
|
-
* example: /get-product/123, /another-route, true ==> undefined
|
|
28
|
-
* example: /articles, /articles, true ==> Map()
|
|
29
|
-
* example: /articles/some-article, /articles, false ==> Map()
|
|
30
|
-
* @param url
|
|
31
|
-
* @param route
|
|
32
|
-
* @param exactMatch
|
|
33
|
-
*/
|
|
34
|
-
function checkUrlMatchRouteAndGetParameters(url: string, route: string, exactMatch?: boolean): Object | undefined;
|
|
35
|
-
}
|
|
36
|
-
export {};
|
|
1
|
+
export declare type RouteAction = (params: {
|
|
2
|
+
[key: string]: string;
|
|
3
|
+
}, url: string) => void | Promise<void>;
|
|
4
|
+
interface HistoryUrl {
|
|
5
|
+
url: string;
|
|
6
|
+
scroll: number;
|
|
7
|
+
}
|
|
8
|
+
export declare module DomeRouter {
|
|
9
|
+
let maxHistoryUrlsCount: number;
|
|
10
|
+
function navigate(url: string): void;
|
|
11
|
+
function goBack(): void;
|
|
12
|
+
function goForward(): void;
|
|
13
|
+
function changeUrl(url: string): void;
|
|
14
|
+
function getCurrentUrl(): string | HistoryUrl;
|
|
15
|
+
/**
|
|
16
|
+
* get previous page url navigated by router
|
|
17
|
+
* @param previousPageIndex 0=previousPage, 1=previousPage-1, etc
|
|
18
|
+
*/
|
|
19
|
+
function getPreviousPageUrl(previousPageIndex?: number): string | undefined;
|
|
20
|
+
function reloadCurrentPage(addToHistory?: boolean): void;
|
|
21
|
+
function resolveUrl(url?: string, addToHistory?: boolean): void;
|
|
22
|
+
function onRoute(route: string, exactMatch: boolean, action: RouteAction): void;
|
|
23
|
+
function onNotFound(action: () => void): void;
|
|
24
|
+
/**
|
|
25
|
+
* Check if url matched route.
|
|
26
|
+
* example: /get-product/445345, /get-product/:productId, true ==> Map([productId:445345])
|
|
27
|
+
* example: /get-product/123, /another-route, true ==> undefined
|
|
28
|
+
* example: /articles, /articles, true ==> Map()
|
|
29
|
+
* example: /articles/some-article, /articles, false ==> Map()
|
|
30
|
+
* @param url
|
|
31
|
+
* @param route
|
|
32
|
+
* @param exactMatch
|
|
33
|
+
*/
|
|
34
|
+
function checkUrlMatchRouteAndGetParameters(url: string, route: string, exactMatch?: boolean): Object | undefined;
|
|
35
|
+
}
|
|
36
|
+
export {};
|
package/out/DomeRouter.js
CHANGED
|
@@ -1,227 +1,227 @@
|
|
|
1
|
-
import { DomeManipulator } from "./DomeManipulator";
|
|
2
|
-
const filename = '[DomeRouter]';
|
|
3
|
-
export var DomeRouter;
|
|
4
|
-
(function (DomeRouter) {
|
|
5
|
-
const historyUrls = [];
|
|
6
|
-
DomeRouter.maxHistoryUrlsCount = 20;
|
|
7
|
-
const allRoutes = [];
|
|
8
|
-
let onNotFoundAction = undefined;
|
|
9
|
-
window.addEventListener('popstate', async (e) => {
|
|
10
|
-
//console.log(filename, 'window.popstate event', e, 'historyUrl=', historyUrls)
|
|
11
|
-
await executeAsync();
|
|
12
|
-
await DomeManipulator.scrollToAsync({
|
|
13
|
-
pxFromTop: getScrollPositionForUrl(window.location.pathname)
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
function getScrollPositionForUrl(url) {
|
|
17
|
-
// well, let's find the last url? or which index?
|
|
18
|
-
let result = 0;
|
|
19
|
-
for (let item of historyUrls) {
|
|
20
|
-
if (item.url === url) {
|
|
21
|
-
result = item.scroll;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return result;
|
|
25
|
-
}
|
|
26
|
-
function navigate(url) {
|
|
27
|
-
window.history.pushState(null, '', url);
|
|
28
|
-
addUrlToHistory(url);
|
|
29
|
-
executeAsync();
|
|
30
|
-
DomeManipulator.scrollToTop();
|
|
31
|
-
}
|
|
32
|
-
DomeRouter.navigate = navigate;
|
|
33
|
-
function goBack() {
|
|
34
|
-
window.history.go(-1);
|
|
35
|
-
}
|
|
36
|
-
DomeRouter.goBack = goBack;
|
|
37
|
-
function goForward() {
|
|
38
|
-
window.history.go(+1);
|
|
39
|
-
}
|
|
40
|
-
DomeRouter.goForward = goForward;
|
|
41
|
-
function changeUrl(url) {
|
|
42
|
-
window.history.replaceState(null, '', url);
|
|
43
|
-
if (historyUrls.length > 0) {
|
|
44
|
-
historyUrls[historyUrls.length - 1].url = url;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
DomeRouter.changeUrl = changeUrl;
|
|
48
|
-
function addUrlToHistory(url) {
|
|
49
|
-
historyUrls.push({ url, scroll: 0 });
|
|
50
|
-
while (historyUrls.length > DomeRouter.maxHistoryUrlsCount) {
|
|
51
|
-
historyUrls.shift();
|
|
52
|
-
}
|
|
53
|
-
// save scroll position to previous url
|
|
54
|
-
if (historyUrls.length > 1) {
|
|
55
|
-
historyUrls[historyUrls.length - 2].scroll = DomeManipulator.getCurrentScrollPosition();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function getCurrentUrl() {
|
|
59
|
-
return historyUrls.length > 0 ? historyUrls[historyUrls.length - 1] : window.location.pathname;
|
|
60
|
-
}
|
|
61
|
-
DomeRouter.getCurrentUrl = getCurrentUrl;
|
|
62
|
-
/**
|
|
63
|
-
* get previous page url navigated by router
|
|
64
|
-
* @param previousPageIndex 0=previousPage, 1=previousPage-1, etc
|
|
65
|
-
*/
|
|
66
|
-
function getPreviousPageUrl(previousPageIndex = 0) {
|
|
67
|
-
//if(historyUrls.length==0) return undefined
|
|
68
|
-
let index = historyUrls.length - 2 - previousPageIndex;
|
|
69
|
-
if (index >= 0 && index < historyUrls.length)
|
|
70
|
-
return historyUrls[index].url;
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
DomeRouter.getPreviousPageUrl = getPreviousPageUrl;
|
|
74
|
-
function reloadCurrentPage(addToHistory = false) {
|
|
75
|
-
if (addToHistory)
|
|
76
|
-
addUrlToHistory(window.location.pathname);
|
|
77
|
-
executeAsync();
|
|
78
|
-
}
|
|
79
|
-
DomeRouter.reloadCurrentPage = reloadCurrentPage;
|
|
80
|
-
function resolveUrl(url = window.location.pathname, addToHistory = true) {
|
|
81
|
-
if (addToHistory)
|
|
82
|
-
addUrlToHistory(window.location.pathname);
|
|
83
|
-
executeAsync(url);
|
|
84
|
-
}
|
|
85
|
-
DomeRouter.resolveUrl = resolveUrl;
|
|
86
|
-
function onRoute(route, exactMatch, action) {
|
|
87
|
-
if (route[0] !== '/')
|
|
88
|
-
throw new Error('Please provide correct route. route=' + route);
|
|
89
|
-
let routeSlices = getRouteSlices(route);
|
|
90
|
-
allRoutes.push({ routeSlices, exactMatch, action });
|
|
91
|
-
}
|
|
92
|
-
DomeRouter.onRoute = onRoute;
|
|
93
|
-
function getRouteSlices(route) {
|
|
94
|
-
//return route.split('/').filter(x => x.length>0).map(x => decodeURIComponent(x))
|
|
95
|
-
return route.split('/').map(x => decodeURIComponent(x));
|
|
96
|
-
}
|
|
97
|
-
function onNotFound(action) {
|
|
98
|
-
onNotFoundAction = action;
|
|
99
|
-
}
|
|
100
|
-
DomeRouter.onNotFound = onNotFound;
|
|
101
|
-
/**
|
|
102
|
-
* Check if url matched route.
|
|
103
|
-
* example: /get-product/445345, /get-product/:productId, true ==> Map([productId:445345])
|
|
104
|
-
* example: /get-product/123, /another-route, true ==> undefined
|
|
105
|
-
* example: /articles, /articles, true ==> Map()
|
|
106
|
-
* example: /articles/some-article, /articles, false ==> Map()
|
|
107
|
-
* @param url
|
|
108
|
-
* @param route
|
|
109
|
-
* @param exactMatch
|
|
110
|
-
*/
|
|
111
|
-
function checkUrlMatchRouteAndGetParameters(url, route, exactMatch = true) {
|
|
112
|
-
// this function is purely for export
|
|
113
|
-
const urlSlices = getRouteSlices(url);
|
|
114
|
-
const routeSlices = getRouteSlices(route);
|
|
115
|
-
if (exactMatch && routeSlices.length !== urlSlices.length)
|
|
116
|
-
return undefined;
|
|
117
|
-
// all routeSlices must match for !exactMatch
|
|
118
|
-
//const extractedParameters = new Map<string,string>()
|
|
119
|
-
const extractedParameters = {};
|
|
120
|
-
for (let i = 0; i < routeSlices.length; i++) {
|
|
121
|
-
let cRouteSlice = routeSlices[i];
|
|
122
|
-
let cUrlSlice = urlSlices[i]; // could be undefined
|
|
123
|
-
//console.info('\t\t cRouteSlice=', cRouteSlice, 'cUrlSlice=', cUrlSlice)
|
|
124
|
-
if (cRouteSlice.startsWith(':')) {
|
|
125
|
-
// we have a param name
|
|
126
|
-
if (cUrlSlice === undefined) {
|
|
127
|
-
return undefined;
|
|
128
|
-
}
|
|
129
|
-
const [name, value] = parseToNameAndValue(cRouteSlice, cUrlSlice);
|
|
130
|
-
extractedParameters[name] = value;
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
// no param name
|
|
134
|
-
if (cRouteSlice !== cUrlSlice) {
|
|
135
|
-
return undefined;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return extractedParameters;
|
|
140
|
-
}
|
|
141
|
-
DomeRouter.checkUrlMatchRouteAndGetParameters = checkUrlMatchRouteAndGetParameters;
|
|
142
|
-
/**
|
|
143
|
-
* parse name with type or without type
|
|
144
|
-
* :quantity
|
|
145
|
-
* :quantity<number>
|
|
146
|
-
* :quantity<float>
|
|
147
|
-
* :quantity<int>
|
|
148
|
-
*
|
|
149
|
-
* @param name string that starts with `:`
|
|
150
|
-
* @param value string that contains value
|
|
151
|
-
*/
|
|
152
|
-
function parseToNameAndValue(name, value) {
|
|
153
|
-
if (!name)
|
|
154
|
-
throw new Error('no name');
|
|
155
|
-
// parse name with type
|
|
156
|
-
// :quantity<number>
|
|
157
|
-
// :lat<float>
|
|
158
|
-
// :count<int>
|
|
159
|
-
const haveMatch = name.match(/:(.+)<(.+)>/);
|
|
160
|
-
if (haveMatch) {
|
|
161
|
-
const paramName = haveMatch[1];
|
|
162
|
-
const paramType = haveMatch[2].toLowerCase();
|
|
163
|
-
if (paramType == 'int') {
|
|
164
|
-
return [paramName, parseInt(value)];
|
|
165
|
-
}
|
|
166
|
-
else if (paramType == 'float') {
|
|
167
|
-
return [paramName, parseFloat(value)];
|
|
168
|
-
}
|
|
169
|
-
else if (paramType == 'number') {
|
|
170
|
-
return [paramName, Number(value)];
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
return [paramName, value];
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
return [name.substring(1), value];
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
async function executeAsync(url = window.location.pathname) {
|
|
181
|
-
//const url = window.location.pathname
|
|
182
|
-
const urlSlices = getRouteSlices(url);
|
|
183
|
-
// urlSlices = show, category, 345
|
|
184
|
-
let countOfFoundRoutes = 0;
|
|
185
|
-
for (let route of allRoutes) {
|
|
186
|
-
//console.info('\t route=', route.routeSlices, route.exactMatch)
|
|
187
|
-
// route.routeSlices = show, category, :categoryId
|
|
188
|
-
if (route.exactMatch && route.routeSlices.length != urlSlices.length)
|
|
189
|
-
continue;
|
|
190
|
-
// all routeSlices must match for !exactMatch
|
|
191
|
-
let matched = true;
|
|
192
|
-
//let extractedParameters = new Map<string,string>()
|
|
193
|
-
const extractedParameters = {};
|
|
194
|
-
for (let i = 0; i < route.routeSlices.length; i++) {
|
|
195
|
-
let cRouteSlice = route.routeSlices[i];
|
|
196
|
-
let cUrlSlice = urlSlices[i]; // could be undefined
|
|
197
|
-
//console.info('\t\t cRouteSlice=', cRouteSlice, 'cUrlSlice=', cUrlSlice)
|
|
198
|
-
if (cRouteSlice && typeof cRouteSlice === 'string' && cRouteSlice.startsWith(':')) {
|
|
199
|
-
// we have a param name
|
|
200
|
-
if (cUrlSlice === undefined) {
|
|
201
|
-
matched = false;
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
// we have some variable, save it
|
|
205
|
-
const [name, value] = parseToNameAndValue(cRouteSlice, cUrlSlice);
|
|
206
|
-
extractedParameters[name] = value;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
// no param name
|
|
210
|
-
if (cRouteSlice !== cUrlSlice) {
|
|
211
|
-
matched = false;
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
if (matched) {
|
|
217
|
-
countOfFoundRoutes++;
|
|
218
|
-
//console.log('DomeRouter', 'executeAsync', url, route, extractedParameters)
|
|
219
|
-
await route.action(extractedParameters, url);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
if (countOfFoundRoutes == 0 && onNotFoundAction) {
|
|
223
|
-
//console.log('DomeRouter', 'onNotFoundAction()')
|
|
224
|
-
onNotFoundAction();
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
})(DomeRouter || (DomeRouter = {}));
|
|
1
|
+
import { DomeManipulator } from "./DomeManipulator";
|
|
2
|
+
const filename = '[DomeRouter]';
|
|
3
|
+
export var DomeRouter;
|
|
4
|
+
(function (DomeRouter) {
|
|
5
|
+
const historyUrls = [];
|
|
6
|
+
DomeRouter.maxHistoryUrlsCount = 20;
|
|
7
|
+
const allRoutes = [];
|
|
8
|
+
let onNotFoundAction = undefined;
|
|
9
|
+
window.addEventListener('popstate', async (e) => {
|
|
10
|
+
//console.log(filename, 'window.popstate event', e, 'historyUrl=', historyUrls)
|
|
11
|
+
await executeAsync();
|
|
12
|
+
await DomeManipulator.scrollToAsync({
|
|
13
|
+
pxFromTop: getScrollPositionForUrl(window.location.pathname)
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
function getScrollPositionForUrl(url) {
|
|
17
|
+
// well, let's find the last url? or which index?
|
|
18
|
+
let result = 0;
|
|
19
|
+
for (let item of historyUrls) {
|
|
20
|
+
if (item.url === url) {
|
|
21
|
+
result = item.scroll;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
function navigate(url) {
|
|
27
|
+
window.history.pushState(null, '', url);
|
|
28
|
+
addUrlToHistory(url);
|
|
29
|
+
executeAsync();
|
|
30
|
+
DomeManipulator.scrollToTop();
|
|
31
|
+
}
|
|
32
|
+
DomeRouter.navigate = navigate;
|
|
33
|
+
function goBack() {
|
|
34
|
+
window.history.go(-1);
|
|
35
|
+
}
|
|
36
|
+
DomeRouter.goBack = goBack;
|
|
37
|
+
function goForward() {
|
|
38
|
+
window.history.go(+1);
|
|
39
|
+
}
|
|
40
|
+
DomeRouter.goForward = goForward;
|
|
41
|
+
function changeUrl(url) {
|
|
42
|
+
window.history.replaceState(null, '', url);
|
|
43
|
+
if (historyUrls.length > 0) {
|
|
44
|
+
historyUrls[historyUrls.length - 1].url = url;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
DomeRouter.changeUrl = changeUrl;
|
|
48
|
+
function addUrlToHistory(url) {
|
|
49
|
+
historyUrls.push({ url, scroll: 0 });
|
|
50
|
+
while (historyUrls.length > DomeRouter.maxHistoryUrlsCount) {
|
|
51
|
+
historyUrls.shift();
|
|
52
|
+
}
|
|
53
|
+
// save scroll position to previous url
|
|
54
|
+
if (historyUrls.length > 1) {
|
|
55
|
+
historyUrls[historyUrls.length - 2].scroll = DomeManipulator.getCurrentScrollPosition();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function getCurrentUrl() {
|
|
59
|
+
return historyUrls.length > 0 ? historyUrls[historyUrls.length - 1] : window.location.pathname;
|
|
60
|
+
}
|
|
61
|
+
DomeRouter.getCurrentUrl = getCurrentUrl;
|
|
62
|
+
/**
|
|
63
|
+
* get previous page url navigated by router
|
|
64
|
+
* @param previousPageIndex 0=previousPage, 1=previousPage-1, etc
|
|
65
|
+
*/
|
|
66
|
+
function getPreviousPageUrl(previousPageIndex = 0) {
|
|
67
|
+
//if(historyUrls.length==0) return undefined
|
|
68
|
+
let index = historyUrls.length - 2 - previousPageIndex;
|
|
69
|
+
if (index >= 0 && index < historyUrls.length)
|
|
70
|
+
return historyUrls[index].url;
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
DomeRouter.getPreviousPageUrl = getPreviousPageUrl;
|
|
74
|
+
function reloadCurrentPage(addToHistory = false) {
|
|
75
|
+
if (addToHistory)
|
|
76
|
+
addUrlToHistory(window.location.pathname);
|
|
77
|
+
executeAsync();
|
|
78
|
+
}
|
|
79
|
+
DomeRouter.reloadCurrentPage = reloadCurrentPage;
|
|
80
|
+
function resolveUrl(url = window.location.pathname, addToHistory = true) {
|
|
81
|
+
if (addToHistory)
|
|
82
|
+
addUrlToHistory(window.location.pathname);
|
|
83
|
+
executeAsync(url);
|
|
84
|
+
}
|
|
85
|
+
DomeRouter.resolveUrl = resolveUrl;
|
|
86
|
+
function onRoute(route, exactMatch, action) {
|
|
87
|
+
if (route[0] !== '/')
|
|
88
|
+
throw new Error('Please provide correct route. route=' + route);
|
|
89
|
+
let routeSlices = getRouteSlices(route);
|
|
90
|
+
allRoutes.push({ routeSlices, exactMatch, action });
|
|
91
|
+
}
|
|
92
|
+
DomeRouter.onRoute = onRoute;
|
|
93
|
+
function getRouteSlices(route) {
|
|
94
|
+
//return route.split('/').filter(x => x.length>0).map(x => decodeURIComponent(x))
|
|
95
|
+
return route.split('/').map(x => decodeURIComponent(x));
|
|
96
|
+
}
|
|
97
|
+
function onNotFound(action) {
|
|
98
|
+
onNotFoundAction = action;
|
|
99
|
+
}
|
|
100
|
+
DomeRouter.onNotFound = onNotFound;
|
|
101
|
+
/**
|
|
102
|
+
* Check if url matched route.
|
|
103
|
+
* example: /get-product/445345, /get-product/:productId, true ==> Map([productId:445345])
|
|
104
|
+
* example: /get-product/123, /another-route, true ==> undefined
|
|
105
|
+
* example: /articles, /articles, true ==> Map()
|
|
106
|
+
* example: /articles/some-article, /articles, false ==> Map()
|
|
107
|
+
* @param url
|
|
108
|
+
* @param route
|
|
109
|
+
* @param exactMatch
|
|
110
|
+
*/
|
|
111
|
+
function checkUrlMatchRouteAndGetParameters(url, route, exactMatch = true) {
|
|
112
|
+
// this function is purely for export
|
|
113
|
+
const urlSlices = getRouteSlices(url);
|
|
114
|
+
const routeSlices = getRouteSlices(route);
|
|
115
|
+
if (exactMatch && routeSlices.length !== urlSlices.length)
|
|
116
|
+
return undefined;
|
|
117
|
+
// all routeSlices must match for !exactMatch
|
|
118
|
+
//const extractedParameters = new Map<string,string>()
|
|
119
|
+
const extractedParameters = {};
|
|
120
|
+
for (let i = 0; i < routeSlices.length; i++) {
|
|
121
|
+
let cRouteSlice = routeSlices[i];
|
|
122
|
+
let cUrlSlice = urlSlices[i]; // could be undefined
|
|
123
|
+
//console.info('\t\t cRouteSlice=', cRouteSlice, 'cUrlSlice=', cUrlSlice)
|
|
124
|
+
if (cRouteSlice.startsWith(':')) {
|
|
125
|
+
// we have a param name
|
|
126
|
+
if (cUrlSlice === undefined) {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
const [name, value] = parseToNameAndValue(cRouteSlice, cUrlSlice);
|
|
130
|
+
extractedParameters[name] = value;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// no param name
|
|
134
|
+
if (cRouteSlice !== cUrlSlice) {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return extractedParameters;
|
|
140
|
+
}
|
|
141
|
+
DomeRouter.checkUrlMatchRouteAndGetParameters = checkUrlMatchRouteAndGetParameters;
|
|
142
|
+
/**
|
|
143
|
+
* parse name with type or without type
|
|
144
|
+
* :quantity
|
|
145
|
+
* :quantity<number>
|
|
146
|
+
* :quantity<float>
|
|
147
|
+
* :quantity<int>
|
|
148
|
+
*
|
|
149
|
+
* @param name string that starts with `:`
|
|
150
|
+
* @param value string that contains value
|
|
151
|
+
*/
|
|
152
|
+
function parseToNameAndValue(name, value) {
|
|
153
|
+
if (!name)
|
|
154
|
+
throw new Error('no name');
|
|
155
|
+
// parse name with type
|
|
156
|
+
// :quantity<number>
|
|
157
|
+
// :lat<float>
|
|
158
|
+
// :count<int>
|
|
159
|
+
const haveMatch = name.match(/:(.+)<(.+)>/);
|
|
160
|
+
if (haveMatch) {
|
|
161
|
+
const paramName = haveMatch[1];
|
|
162
|
+
const paramType = haveMatch[2].toLowerCase();
|
|
163
|
+
if (paramType == 'int') {
|
|
164
|
+
return [paramName, parseInt(value)];
|
|
165
|
+
}
|
|
166
|
+
else if (paramType == 'float') {
|
|
167
|
+
return [paramName, parseFloat(value)];
|
|
168
|
+
}
|
|
169
|
+
else if (paramType == 'number') {
|
|
170
|
+
return [paramName, Number(value)];
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
return [paramName, value];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
return [name.substring(1), value];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async function executeAsync(url = window.location.pathname) {
|
|
181
|
+
//const url = window.location.pathname
|
|
182
|
+
const urlSlices = getRouteSlices(url);
|
|
183
|
+
// urlSlices = show, category, 345
|
|
184
|
+
let countOfFoundRoutes = 0;
|
|
185
|
+
for (let route of allRoutes) {
|
|
186
|
+
//console.info('\t route=', route.routeSlices, route.exactMatch)
|
|
187
|
+
// route.routeSlices = show, category, :categoryId
|
|
188
|
+
if (route.exactMatch && route.routeSlices.length != urlSlices.length)
|
|
189
|
+
continue;
|
|
190
|
+
// all routeSlices must match for !exactMatch
|
|
191
|
+
let matched = true;
|
|
192
|
+
//let extractedParameters = new Map<string,string>()
|
|
193
|
+
const extractedParameters = {};
|
|
194
|
+
for (let i = 0; i < route.routeSlices.length; i++) {
|
|
195
|
+
let cRouteSlice = route.routeSlices[i];
|
|
196
|
+
let cUrlSlice = urlSlices[i]; // could be undefined
|
|
197
|
+
//console.info('\t\t cRouteSlice=', cRouteSlice, 'cUrlSlice=', cUrlSlice)
|
|
198
|
+
if (cRouteSlice && typeof cRouteSlice === 'string' && cRouteSlice.startsWith(':')) {
|
|
199
|
+
// we have a param name
|
|
200
|
+
if (cUrlSlice === undefined) {
|
|
201
|
+
matched = false;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
// we have some variable, save it
|
|
205
|
+
const [name, value] = parseToNameAndValue(cRouteSlice, cUrlSlice);
|
|
206
|
+
extractedParameters[name] = value;
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// no param name
|
|
210
|
+
if (cRouteSlice !== cUrlSlice) {
|
|
211
|
+
matched = false;
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (matched) {
|
|
217
|
+
countOfFoundRoutes++;
|
|
218
|
+
//console.log('DomeRouter', 'executeAsync', url, route, extractedParameters)
|
|
219
|
+
await route.action(extractedParameters, url);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (countOfFoundRoutes == 0 && onNotFoundAction) {
|
|
223
|
+
//console.log('DomeRouter', 'onNotFoundAction()')
|
|
224
|
+
onNotFoundAction();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
})(DomeRouter || (DomeRouter = {}));
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export declare module LongestCommonSubsequence {
|
|
2
|
-
function getLongestCommonSubsequence(set1: string[], set2: string[]): string[];
|
|
3
|
-
function getPatch({ oldArray, newArray, onRemove, onAdd }: {
|
|
4
|
-
oldArray: string[];
|
|
5
|
-
newArray: string[];
|
|
6
|
-
onRemove: (index: number, item: string) => void;
|
|
7
|
-
onAdd: (index: number, item: string) => void;
|
|
8
|
-
}): number;
|
|
9
|
-
function getPatchOrdered({ oldArray, newArray, onRemove, onAdd }: {
|
|
10
|
-
oldArray: string[];
|
|
11
|
-
newArray: string[];
|
|
12
|
-
onRemove: (index: number, item: string) => void;
|
|
13
|
-
onAdd: (index: number, item: string) => void;
|
|
14
|
-
}): number;
|
|
15
|
-
}
|
|
1
|
+
export declare module LongestCommonSubsequence {
|
|
2
|
+
function getLongestCommonSubsequence(set1: string[], set2: string[]): string[];
|
|
3
|
+
function getPatch({ oldArray, newArray, onRemove, onAdd }: {
|
|
4
|
+
oldArray: string[];
|
|
5
|
+
newArray: string[];
|
|
6
|
+
onRemove: (index: number, item: string) => void;
|
|
7
|
+
onAdd: (index: number, item: string) => void;
|
|
8
|
+
}): number;
|
|
9
|
+
function getPatchOrdered({ oldArray, newArray, onRemove, onAdd }: {
|
|
10
|
+
oldArray: string[];
|
|
11
|
+
newArray: string[];
|
|
12
|
+
onRemove: (index: number, item: string) => void;
|
|
13
|
+
onAdd: (index: number, item: string) => void;
|
|
14
|
+
}): number;
|
|
15
|
+
}
|