@inglorious/web 6.4.2 → 6.5.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/README.md +4 -0
- package/package.json +1 -1
- package/src/form/handlers.js +1 -1
- package/src/form/helpers.js +1 -1
- package/src/router/handlers.js +45 -0
- package/types/router.d.ts +15 -0
package/README.md
CHANGED
|
@@ -1045,6 +1045,10 @@ api.notify("navigate", "/users/456")
|
|
|
1045
1045
|
// Or navigate back in history
|
|
1046
1046
|
api.notify("navigate", -1)
|
|
1047
1047
|
|
|
1048
|
+
// Go back, or to "/users" when the app was opened on this page and has
|
|
1049
|
+
// nothing of its own to go back to (a deep link, a fresh tab)
|
|
1050
|
+
api.notify("back", "/users")
|
|
1051
|
+
|
|
1048
1052
|
// With options
|
|
1049
1053
|
api.notify("navigate", {
|
|
1050
1054
|
to: "/users/456",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/web",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.5.1",
|
|
4
4
|
"description": "A new web framework that leverages the power of the Inglorious Store combined with the performance and simplicity of lit-html.",
|
|
5
5
|
"author": "Matteo Antony Mistretta <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"contributors": [
|
package/src/form/handlers.js
CHANGED
package/src/form/helpers.js
CHANGED
package/src/router/handlers.js
CHANGED
|
@@ -8,6 +8,8 @@ import { toCamelCase } from "@inglorious/utils/data-structures/string.js"
|
|
|
8
8
|
|
|
9
9
|
const SKIP_FULL_MATCH_GROUP = 1 // .match() result at index 0 is the full string
|
|
10
10
|
const REMOVE_COLON_PREFIX = 1
|
|
11
|
+
const FIRST_HISTORY_INDEX = 0 // The entry an app starts on, and the fallback for an entry that carries no index.
|
|
12
|
+
const PUSH_HISTORY_STEP = 1 // How far a push advances the index. A replacement leaves it where it is.
|
|
11
13
|
|
|
12
14
|
export function createHandlers(routeConfig) {
|
|
13
15
|
/**
|
|
@@ -25,6 +27,18 @@ export function createHandlers(routeConfig) {
|
|
|
25
27
|
* @param {Api} api - The application API.
|
|
26
28
|
*/
|
|
27
29
|
init(entity, payload, api) {
|
|
30
|
+
/* Stamp the entry the app starts on, so that reloading keeps the app in
|
|
31
|
+
its place in the session history instead of restarting the count.
|
|
32
|
+
`withTransitions` reads this index back to tell a push from a traversal
|
|
33
|
+
and in which direction, so it has to be set before anything navigates. */
|
|
34
|
+
if (window.history.state?.idx == null) {
|
|
35
|
+
window.history.replaceState(
|
|
36
|
+
{ ...window.history.state, idx: FIRST_HISTORY_INDEX },
|
|
37
|
+
"",
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
entity.idx = window.history.state?.idx ?? FIRST_HISTORY_INDEX
|
|
41
|
+
|
|
28
42
|
// Handle initial route
|
|
29
43
|
const { pathname, search } = window.location
|
|
30
44
|
const initialPath = pathname + search
|
|
@@ -107,6 +121,9 @@ export function createHandlers(routeConfig) {
|
|
|
107
121
|
}
|
|
108
122
|
|
|
109
123
|
updateRouter(entity, route)
|
|
124
|
+
// Adopt the index of the entry just traversed, so the next push counts
|
|
125
|
+
// from where the history actually is rather than from where it was.
|
|
126
|
+
entity.idx = window.history.state?.idx ?? FIRST_HISTORY_INDEX
|
|
110
127
|
|
|
111
128
|
api.notify("routeChange", {
|
|
112
129
|
route: entity.route,
|
|
@@ -184,6 +201,10 @@ export function createHandlers(routeConfig) {
|
|
|
184
201
|
// Prepare history state
|
|
185
202
|
const historyState = {
|
|
186
203
|
...state,
|
|
204
|
+
/* Written before the notification that triggers the render, so that
|
|
205
|
+
anything reading the history entry during that render sees the new
|
|
206
|
+
index. `withTransitions` depends on this ordering. */
|
|
207
|
+
idx: replace ? entity.idx : entity.idx + PUSH_HISTORY_STEP,
|
|
187
208
|
route: entity.route,
|
|
188
209
|
params: entity.params,
|
|
189
210
|
query: entity.query,
|
|
@@ -193,10 +214,34 @@ export function createHandlers(routeConfig) {
|
|
|
193
214
|
// Navigate
|
|
194
215
|
const method = replace ? "replaceState" : "pushState"
|
|
195
216
|
history[method](historyState, "", path)
|
|
217
|
+
// Advance the counter as well as stamping the entry, or the next push
|
|
218
|
+
// writes the same index and reads as a replacement.
|
|
219
|
+
entity.idx = historyState.idx
|
|
196
220
|
|
|
197
221
|
api.notify("routeChange", historyState)
|
|
198
222
|
},
|
|
199
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Goes back one entry when the app has an entry of its own to go back to,
|
|
226
|
+
* and otherwise navigates to the fallback in place. An app opened on a deep
|
|
227
|
+
* link starts at the first index, where `history.back()` would leave the
|
|
228
|
+
* app or do nothing at all.
|
|
229
|
+
* @param {RouterEntity} entity - The router entity.
|
|
230
|
+
* @param {string|{to: string, params?: object, state?: object}} [fallback] - Where to go when there is nothing to go back to.
|
|
231
|
+
* @param {Api} api - The application API.
|
|
232
|
+
*/
|
|
233
|
+
back(entity, fallback, api) {
|
|
234
|
+
if (entity.idx > FIRST_HISTORY_INDEX) {
|
|
235
|
+
history.back()
|
|
236
|
+
return
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (fallback == null) return
|
|
240
|
+
|
|
241
|
+
const options = typeof fallback === "string" ? { to: fallback } : fallback
|
|
242
|
+
api.notify(`#${entity.id}:navigate`, { ...options, replace: true })
|
|
243
|
+
},
|
|
244
|
+
|
|
200
245
|
/**
|
|
201
246
|
* Handles successful loading of a lazily-loaded route module.
|
|
202
247
|
* Registers the loaded type in the runtime type registry via `api.setType`
|
package/types/router.d.ts
CHANGED
|
@@ -38,6 +38,8 @@ export interface RouterEntity {
|
|
|
38
38
|
query?: QueryParams
|
|
39
39
|
/** The hash from the current URL. */
|
|
40
40
|
hash?: string
|
|
41
|
+
/** The position of the current entry in the session history, counted from the entry the app started on. */
|
|
42
|
+
idx?: number
|
|
41
43
|
/** Whether a route is currently loading asynchronously. */
|
|
42
44
|
isLoading?: boolean
|
|
43
45
|
/** An error that occurred during route loading. */
|
|
@@ -104,6 +106,19 @@ export interface RouterType {
|
|
|
104
106
|
api: Api,
|
|
105
107
|
): void | Promise<void>
|
|
106
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Goes back one history entry when the app pushed one, and otherwise
|
|
111
|
+
* navigates to the fallback, replacing the current entry.
|
|
112
|
+
* @param {RouterEntity} entity - The router entity.
|
|
113
|
+
* @param {string|Omit<NavigatePayload, "replace">} [fallback] - Where to go when there is nothing to go back to.
|
|
114
|
+
* @param {StoreApi} api - The store API.
|
|
115
|
+
*/
|
|
116
|
+
back(
|
|
117
|
+
entity: RouterEntity,
|
|
118
|
+
fallback: string | Omit<NavigatePayload, "replace"> | undefined,
|
|
119
|
+
api: Api,
|
|
120
|
+
): void
|
|
121
|
+
|
|
107
122
|
/**
|
|
108
123
|
* Synchronizes the router entity's state with data from a routing event,
|
|
109
124
|
* typically triggered by a `popstate` event (browser back/forward).
|