saasufy-components 2.5.1 → 2.6.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/app-router.js +92 -28
- package/package.json +1 -1
package/app-router.js
CHANGED
|
@@ -2,6 +2,7 @@ import { toSafeHTML, renderTemplate, debouncer } from './utils.js';
|
|
|
2
2
|
import { SocketConsumer } from './socket.js';
|
|
3
3
|
|
|
4
4
|
const DEFAULT_DEBOUNCE_DELAY = 100;
|
|
5
|
+
const DEFAULT_MAX_REDIRECTS = 5;
|
|
5
6
|
|
|
6
7
|
export class AppRouter extends SocketConsumer {
|
|
7
8
|
constructor() {
|
|
@@ -52,7 +53,8 @@ export class AppRouter extends SocketConsumer {
|
|
|
52
53
|
static get observedAttributes() {
|
|
53
54
|
return [
|
|
54
55
|
'default-page',
|
|
55
|
-
'debounce-delay'
|
|
56
|
+
'debounce-delay',
|
|
57
|
+
'max-redirects'
|
|
56
58
|
];
|
|
57
59
|
}
|
|
58
60
|
|
|
@@ -106,52 +108,114 @@ export class AppRouter extends SocketConsumer {
|
|
|
106
108
|
this.connectConsumer.kill();
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
getMatchingRouteInfo(pagePath) {
|
|
112
|
+
return this.pageRouteInfos.find(
|
|
113
|
+
({ regExp }) => pagePath.match(regExp)
|
|
114
|
+
) || {};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
getMatchingPage(pagePath, routeType, noThrow) {
|
|
118
|
+
let { route, regExp, params } = this.getMatchingRouteInfo(pagePath);
|
|
119
|
+
let pageTemplate = this.pages[route];
|
|
120
|
+
if (!pageTemplate && !noThrow) {
|
|
121
|
+
throw new Error(`The specified ${routeType}${pagePath ? ` ${pagePath}` : ''} did not match any route`);
|
|
122
|
+
}
|
|
123
|
+
return { pageTemplate, route, regExp, params };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
substituteRouteAgs(route, routeArgs) {
|
|
127
|
+
for (let [ key, value ] of Object.entries(routeArgs || {})) {
|
|
128
|
+
route = route.replace(new RegExp(`:${key}\\b`, 'g'), value);
|
|
129
|
+
}
|
|
130
|
+
return route;
|
|
131
|
+
}
|
|
132
|
+
|
|
109
133
|
renderCurrentPage() {
|
|
110
134
|
let routerViewport = this.shadowRoot.querySelector('slot[name="viewport"]').assignedNodes()[0];
|
|
111
135
|
if (!routerViewport) return;
|
|
112
136
|
|
|
113
|
-
let
|
|
114
|
-
let pagePath = hash.replace(this.hashStartRegex, '');
|
|
115
|
-
|
|
116
|
-
let { route, regExp, params } = this.pageRouteInfos.find(
|
|
117
|
-
({ regExp }) => pagePath.match(regExp)
|
|
118
|
-
) || {};
|
|
137
|
+
let routeArgs;
|
|
138
|
+
let pagePath = location.hash.replace(this.hashStartRegex, '');
|
|
139
|
+
let { pageTemplate, route, regExp, params } = this.getMatchingPage(pagePath, 'path', true);
|
|
119
140
|
|
|
120
|
-
let pageTemplate = this.pages[route];
|
|
121
141
|
if (!pageTemplate) {
|
|
122
142
|
let defaultPage = this.getAttribute('default-page');
|
|
123
143
|
if (!defaultPage) return;
|
|
124
|
-
|
|
144
|
+
routeArgs = this.computeRouteArgs(pagePath, regExp, params);
|
|
145
|
+
pagePath = this.substituteRouteAgs(defaultPage, routeArgs);
|
|
146
|
+
let result = this.getMatchingPage(pagePath, 'default-page');
|
|
147
|
+
pageTemplate = result.pageTemplate;
|
|
148
|
+
route = result.route;
|
|
149
|
+
regExp = result.regExp;
|
|
150
|
+
params = result.params;
|
|
125
151
|
};
|
|
126
152
|
|
|
127
|
-
let
|
|
128
|
-
let authRedirect = pageTemplate.getAttribute('auth-redirect');
|
|
129
|
-
let hardRedirect = pageTemplate.hasAttribute('hard-redirect');
|
|
153
|
+
let maxRedirects = Number(this.getAttribute('max-redirects') || DEFAULT_MAX_REDIRECTS);
|
|
130
154
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
155
|
+
let redirectCount;
|
|
156
|
+
for (redirectCount = 0; redirectCount < maxRedirects; redirectCount++) {
|
|
157
|
+
let redirect = pageTemplate.getAttribute('redirect');
|
|
158
|
+
let noAuthRedirect = pageTemplate.getAttribute('no-auth-redirect');
|
|
159
|
+
let authRedirect = pageTemplate.getAttribute('auth-redirect');
|
|
160
|
+
|
|
161
|
+
if (!redirect && !noAuthRedirect && !authRedirect) break;
|
|
162
|
+
|
|
163
|
+
let hardRedirect = pageTemplate.hasAttribute('hard-redirect');
|
|
164
|
+
|
|
165
|
+
if (redirect) {
|
|
166
|
+
if (hardRedirect) {
|
|
167
|
+
location.hash = redirect;
|
|
168
|
+
return;
|
|
140
169
|
}
|
|
170
|
+
routeArgs = this.computeRouteArgs(pagePath, regExp, params);
|
|
171
|
+
pagePath = this.substituteRouteAgs(redirect, routeArgs);
|
|
172
|
+
let result = this.getMatchingPage(pagePath, 'redirect');
|
|
173
|
+
pageTemplate = result.pageTemplate;
|
|
174
|
+
route = result.route;
|
|
175
|
+
regExp = result.regExp;
|
|
176
|
+
params = result.params;
|
|
141
177
|
} else {
|
|
142
|
-
if (this.socket
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
178
|
+
if (this.socket && (authRedirect || noAuthRedirect)) {
|
|
179
|
+
if (this.socket.authState === 'authenticated') {
|
|
180
|
+
if (authRedirect) {
|
|
181
|
+
if (hardRedirect) {
|
|
182
|
+
location.hash = authRedirect;
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
routeArgs = this.computeRouteArgs(pagePath, regExp, params);
|
|
186
|
+
pagePath = this.substituteRouteAgs(authRedirect, routeArgs);
|
|
187
|
+
let result = this.getMatchingPage(pagePath, 'auth-redirect');
|
|
188
|
+
pageTemplate = result.pageTemplate;
|
|
189
|
+
route = result.route;
|
|
190
|
+
regExp = result.regExp;
|
|
191
|
+
params = result.params;
|
|
192
|
+
}
|
|
147
193
|
} else {
|
|
148
|
-
|
|
194
|
+
if (this.socket.state !== this.socket.OPEN) return;
|
|
195
|
+
if (noAuthRedirect) {
|
|
196
|
+
if (hardRedirect) {
|
|
197
|
+
location.hash = noAuthRedirect;
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
routeArgs = this.computeRouteArgs(pagePath, regExp, params);
|
|
201
|
+
pagePath = this.substituteRouteAgs(noAuthRedirect, routeArgs);
|
|
202
|
+
let result = this.getMatchingPage(pagePath, 'no-auth-redirect');
|
|
203
|
+
pageTemplate = result.pageTemplate;
|
|
204
|
+
route = result.route;
|
|
205
|
+
regExp = result.regExp;
|
|
206
|
+
params = result.params;
|
|
207
|
+
}
|
|
149
208
|
}
|
|
150
209
|
}
|
|
151
210
|
}
|
|
152
211
|
}
|
|
153
212
|
|
|
154
|
-
|
|
213
|
+
if (redirectCount >= maxRedirects) {
|
|
214
|
+
throw new Error(
|
|
215
|
+
`The number of redirects exceeded the maximum amount of ${maxRedirects}`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
155
219
|
if (route) {
|
|
156
220
|
routeArgs = this.computeRouteArgs(pagePath, regExp, params);
|
|
157
221
|
} else {
|