saasufy-components 2.5.1 → 2.6.1
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 +98 -31
- 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,117 @@ 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
|
-
|
|
129
|
-
let
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
153
|
+
let maxRedirects = Number(this.getAttribute('max-redirects') || DEFAULT_MAX_REDIRECTS);
|
|
154
|
+
|
|
155
|
+
let redirectCount;
|
|
156
|
+
for (redirectCount = 0; redirectCount < maxRedirects; redirectCount++) {
|
|
157
|
+
let authRedirect = this.socket && this.socket.authState === 'authenticated' ?
|
|
158
|
+
pageTemplate.getAttribute('auth-redirect') : null;
|
|
159
|
+
let noAuthRedirect = this.socket && this.socket.authState !== 'authenticated' ?
|
|
160
|
+
pageTemplate.getAttribute('no-auth-redirect') : null;
|
|
161
|
+
|
|
162
|
+
if (
|
|
163
|
+
(authRedirect != null || noAuthRedirect != null) &&
|
|
164
|
+
this.socket &&
|
|
165
|
+
this.socket.authState !== 'authenticated' &&
|
|
166
|
+
this.socket.state !== this.socket.OPEN
|
|
167
|
+
) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
let redirect = pageTemplate.getAttribute('redirect');
|
|
172
|
+
|
|
173
|
+
if (authRedirect == null && noAuthRedirect == null && redirect == null) break;
|
|
174
|
+
|
|
175
|
+
let hardRedirect = pageTemplate.hasAttribute('hard-redirect');
|
|
176
|
+
|
|
177
|
+
if (authRedirect != null) {
|
|
178
|
+
if (hardRedirect) {
|
|
179
|
+
location.hash = authRedirect;
|
|
180
|
+
return;
|
|
140
181
|
}
|
|
182
|
+
routeArgs = this.computeRouteArgs(pagePath, regExp, params);
|
|
183
|
+
pagePath = this.substituteRouteAgs(authRedirect, routeArgs);
|
|
184
|
+
let result = this.getMatchingPage(pagePath, 'auth-redirect');
|
|
185
|
+
pageTemplate = result.pageTemplate;
|
|
186
|
+
route = result.route;
|
|
187
|
+
regExp = result.regExp;
|
|
188
|
+
params = result.params;
|
|
189
|
+
} else if (noAuthRedirect != null) {
|
|
190
|
+
if (hardRedirect) {
|
|
191
|
+
location.hash = noAuthRedirect;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
routeArgs = this.computeRouteArgs(pagePath, regExp, params);
|
|
195
|
+
pagePath = this.substituteRouteAgs(noAuthRedirect, routeArgs);
|
|
196
|
+
let result = this.getMatchingPage(pagePath, 'no-auth-redirect');
|
|
197
|
+
pageTemplate = result.pageTemplate;
|
|
198
|
+
route = result.route;
|
|
199
|
+
regExp = result.regExp;
|
|
200
|
+
params = result.params;
|
|
141
201
|
} else {
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
location.hash = noAuthRedirect;
|
|
146
|
-
return;
|
|
147
|
-
} else {
|
|
148
|
-
pageTemplate = this.pages[noAuthRedirect];
|
|
149
|
-
}
|
|
202
|
+
if (hardRedirect) {
|
|
203
|
+
location.hash = redirect;
|
|
204
|
+
return;
|
|
150
205
|
}
|
|
206
|
+
routeArgs = this.computeRouteArgs(pagePath, regExp, params);
|
|
207
|
+
pagePath = this.substituteRouteAgs(redirect, routeArgs);
|
|
208
|
+
let result = this.getMatchingPage(pagePath, 'redirect');
|
|
209
|
+
pageTemplate = result.pageTemplate;
|
|
210
|
+
route = result.route;
|
|
211
|
+
regExp = result.regExp;
|
|
212
|
+
params = result.params;
|
|
151
213
|
}
|
|
152
214
|
}
|
|
153
215
|
|
|
154
|
-
|
|
216
|
+
if (redirectCount >= maxRedirects) {
|
|
217
|
+
throw new Error(
|
|
218
|
+
`The number of redirects exceeded the maximum amount of ${maxRedirects}`
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
155
222
|
if (route) {
|
|
156
223
|
routeArgs = this.computeRouteArgs(pagePath, regExp, params);
|
|
157
224
|
} else {
|