@bitstillery/mithril 3.4.1 → 3.4.2
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/api/router.ts +15 -23
- package/package.json +1 -1
- package/pathname/compileTemplate.ts +4 -1
package/api/router.ts
CHANGED
|
@@ -53,7 +53,7 @@ interface MountRedraw {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
interface RouteOptions {
|
|
56
|
-
/** When true,
|
|
56
|
+
/** When true, bumps remountNonce once so the resolver fragment key changes for that navigation (e.g. Link). */
|
|
57
57
|
remount?: boolean
|
|
58
58
|
replace?: boolean
|
|
59
59
|
state?: any
|
|
@@ -80,8 +80,8 @@ export default function router($window: any, mountRedraw: MountRedraw) {
|
|
|
80
80
|
let currentPath: string | undefined
|
|
81
81
|
let lastUpdate: ((comp: any) => void) | null = null
|
|
82
82
|
let routeSetResolve: (() => void) | null = null
|
|
83
|
-
|
|
84
|
-
let
|
|
83
|
+
/** Incremented only when route.set(..., { remount: true }); fragment key is m-route-${remountNonce}. */
|
|
84
|
+
let remountNonce = 0
|
|
85
85
|
|
|
86
86
|
const RouterRoot: ComponentType = {
|
|
87
87
|
onremove: function () {
|
|
@@ -94,21 +94,15 @@ export default function router($window: any, mountRedraw: MountRedraw) {
|
|
|
94
94
|
// if (!hasBeenResolved) return
|
|
95
95
|
|
|
96
96
|
// Pass currentPath in attrs so RouteResolver.render can use it for routePath.
|
|
97
|
-
//
|
|
98
|
-
//
|
|
97
|
+
// No vnode key on the route component: same resolved component updates in place when path/query
|
|
98
|
+
// changes; apps sync state via attrs/onupdate. Do not use attrs.key from merged query (?key=...).
|
|
99
99
|
const routeAttrs = {...attrs, routePath: currentPath || attrs.routePath}
|
|
100
|
-
const
|
|
101
|
-
const vnode = Vnode(component, vnodeKey, routeAttrs, null, null, null)
|
|
100
|
+
const vnode = Vnode(component, undefined, routeAttrs, null, null, null)
|
|
102
101
|
if (currentResolver) {
|
|
103
102
|
const result = currentResolver.render!(vnode as any)
|
|
104
|
-
//
|
|
105
|
-
// (
|
|
106
|
-
|
|
107
|
-
const fragmentKey = remountPath ?? currentPath ?? undefined
|
|
108
|
-
if (remountPath && fragmentKey != null) {
|
|
109
|
-
return hyperscript.fragment({key: fragmentKey}, result)
|
|
110
|
-
}
|
|
111
|
-
return result
|
|
103
|
+
// Always wrap in a keyed fragment (stable shape). Key only changes when remountNonce bumps
|
|
104
|
+
// (route.set with remount: true), not on ordinary URL updates.
|
|
105
|
+
return hyperscript.fragment({key: 'm-route-' + remountNonce}, result)
|
|
112
106
|
}
|
|
113
107
|
// Wrap in a fragment to preserve existing key semantics
|
|
114
108
|
return [vnode]
|
|
@@ -188,7 +182,10 @@ export default function router($window: any, mountRedraw: MountRedraw) {
|
|
|
188
182
|
const path = decodeURIComponentSafe(prefix).slice(route.prefix.length)
|
|
189
183
|
const data = parsePathname(path)
|
|
190
184
|
|
|
191
|
-
|
|
185
|
+
const histState = $window?.history?.state
|
|
186
|
+
if (histState != null && typeof histState === 'object' && !Array.isArray(histState)) {
|
|
187
|
+
Object.assign(data.params, histState)
|
|
188
|
+
}
|
|
192
189
|
|
|
193
190
|
function reject(e: any) {
|
|
194
191
|
console.error(e)
|
|
@@ -248,10 +245,6 @@ export default function router($window: any, mountRedraw: MountRedraw) {
|
|
|
248
245
|
}
|
|
249
246
|
attrs = data.params
|
|
250
247
|
currentPath = path
|
|
251
|
-
if (pendingRemount) {
|
|
252
|
-
remountPath = path
|
|
253
|
-
pendingRemount = false
|
|
254
|
-
}
|
|
255
248
|
lastUpdate = null
|
|
256
249
|
routeSetResolve?.()
|
|
257
250
|
routeSetResolve = null
|
|
@@ -339,10 +332,9 @@ export default function router($window: any, mountRedraw: MountRedraw) {
|
|
|
339
332
|
}
|
|
340
333
|
lastUpdate = null
|
|
341
334
|
|
|
342
|
-
if (
|
|
343
|
-
|
|
335
|
+
if (options?.remount) {
|
|
336
|
+
remountNonce++
|
|
344
337
|
}
|
|
345
|
-
pendingRemount = options?.remount ?? false
|
|
346
338
|
|
|
347
339
|
path = buildPathname(path, data || {})
|
|
348
340
|
if (!ready || !$window) {
|
package/package.json
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import parsePathname from './parse'
|
|
2
2
|
|
|
3
|
+
/** Path segments, :params, and regexp escapes (shared by compileTemplate). */
|
|
4
|
+
const TEMPLATE_PATH_TO_REGEXP = /:([^/.-]+)(\.{3}|\.(?!\.)|-)?|[\\^$*+.()|[\]{}]/g
|
|
5
|
+
|
|
3
6
|
interface CompiledTemplate {
|
|
4
7
|
(data: {path: string; params: Record<string, any>}): boolean
|
|
5
8
|
}
|
|
@@ -20,7 +23,7 @@ export default function compileTemplate(template: string): CompiledTemplate {
|
|
|
20
23
|
// `:lang-:locale` in routes. This is all merged into one pass so I
|
|
21
24
|
// don't also accidentally escape `-` and make it harder to detect it to
|
|
22
25
|
// ban it from template parameters.
|
|
23
|
-
|
|
26
|
+
TEMPLATE_PATH_TO_REGEXP,
|
|
24
27
|
function (m, key, extra) {
|
|
25
28
|
if (key == null) return '\\' + m
|
|
26
29
|
keys.push({k: key, r: extra === '...'})
|