@lightningjs/blits 1.20.0 → 1.21.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/CHANGELOG.md +18 -0
- package/index.d.ts +51 -0
- package/package.json +2 -2
- package/src/engines/L3/element.js +14 -3
- package/src/engines/L3/launch.js +22 -3
- package/src/lib/codegenerator/generator.js +22 -2
- package/src/lib/reactivity/effect.js +5 -3
- package/src/lib/reactivity/reactive.js +8 -4
- package/src/lib/templateparser/parser.js +5 -0
- package/src/lib/templateparser/parser.test.js +21 -0
- package/src/router/router.js +37 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.21.0
|
|
4
|
+
|
|
5
|
+
_27 feb 2025_
|
|
6
|
+
|
|
7
|
+
- Added functionality for keeping query params when navigating back in the router
|
|
8
|
+
- Exposed more info in reactive router state
|
|
9
|
+
- Added `range`-attribute to for-loop
|
|
10
|
+
- Fixed issue when setting `alpha` to truthy or false values
|
|
11
|
+
- Upgraded to renderer v2.13.0
|
|
12
|
+
|
|
13
|
+
## v1.20.1
|
|
14
|
+
|
|
15
|
+
_14 feb 2025_
|
|
16
|
+
|
|
17
|
+
- Added error message when root element in template contains a `:for`-attribute
|
|
18
|
+
- Added workaround fix for shader caching issue
|
|
19
|
+
- Upgraded to renderer v2.12.1
|
|
20
|
+
|
|
3
21
|
## v1.20.0
|
|
4
22
|
|
|
5
23
|
_12 feb 2025_
|
package/index.d.ts
CHANGED
|
@@ -799,8 +799,59 @@ declare module '@lightningjs/blits' {
|
|
|
799
799
|
* and cleaned up
|
|
800
800
|
*
|
|
801
801
|
* Defaults to `200` (mb)
|
|
802
|
+
* @deprecated
|
|
803
|
+
* Deprecated: use `gpuMemory` launch setting instead
|
|
802
804
|
*/
|
|
803
805
|
gpuMemoryLimit?: number,
|
|
806
|
+
/**
|
|
807
|
+
* Configures the gpu memory settings used by the renderer
|
|
808
|
+
*/
|
|
809
|
+
gpuMemory: {
|
|
810
|
+
/**
|
|
811
|
+
* Maximum GPU memory threshold (in `mb`) after which
|
|
812
|
+
* the renderer will immediately start cleaning up textures to free
|
|
813
|
+
* up graphical memory
|
|
814
|
+
*
|
|
815
|
+
* When setting to `0`, texture memory management is disabled
|
|
816
|
+
*
|
|
817
|
+
* @default `200`
|
|
818
|
+
*/
|
|
819
|
+
max: number,
|
|
820
|
+
/**
|
|
821
|
+
* Target threshold of GPU memory usage, defined as a fraction of
|
|
822
|
+
* the max threshold. The renderer will attempt to keep memory
|
|
823
|
+
* usage below this target by cleaning up non-renderable textures
|
|
824
|
+
*
|
|
825
|
+
* @default `0.8`
|
|
826
|
+
*/
|
|
827
|
+
target: 0.8,
|
|
828
|
+
/**
|
|
829
|
+
* Interval at which regular texture cleanups occur (in `ms`)
|
|
830
|
+
*
|
|
831
|
+
* @default `5000`
|
|
832
|
+
*/
|
|
833
|
+
cleanupInterval: 5000,
|
|
834
|
+
/**
|
|
835
|
+
* Baseline GPU memory usage of the App (in `mb`), without rendering any
|
|
836
|
+
* textures. This value will be used as a basis when calculating
|
|
837
|
+
* the total memory usage towards the max and target memory
|
|
838
|
+
* usage
|
|
839
|
+
*
|
|
840
|
+
* @default `25`
|
|
841
|
+
*/
|
|
842
|
+
baseline: 25,
|
|
843
|
+
/**
|
|
844
|
+
* Whether or not the max threshold should be considered
|
|
845
|
+
* as a strict number that can not be exceeded in any way
|
|
846
|
+
*
|
|
847
|
+
* When set to `true`, new textures won't be created when the
|
|
848
|
+
* max threshold has been reached, until agressive texture cleanup
|
|
849
|
+
* has brought the memory back down
|
|
850
|
+
*
|
|
851
|
+
* @default false
|
|
852
|
+
*/
|
|
853
|
+
strict: false,
|
|
854
|
+
},
|
|
804
855
|
/**
|
|
805
856
|
* Defines which mode the renderer should operate in: `webgl` or `canvas`
|
|
806
857
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightningjs/blits",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.21.0",
|
|
4
4
|
"description": "Blits: The Lightning 3 App Development Framework",
|
|
5
5
|
"bin": "bin/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@lightningjs/msdf-generator": "^1.1.1",
|
|
55
|
-
"@lightningjs/renderer": "^2.
|
|
55
|
+
"@lightningjs/renderer": "^2.13.0"
|
|
56
56
|
},
|
|
57
57
|
"repository": {
|
|
58
58
|
"type": "git",
|
|
@@ -22,6 +22,9 @@ import { Log } from '../../lib/log.js'
|
|
|
22
22
|
import symbols from '../../lib/symbols.js'
|
|
23
23
|
import Settings from '../../settings.js'
|
|
24
24
|
|
|
25
|
+
// temporary counter to work around shader caching issues
|
|
26
|
+
let counter = 0
|
|
27
|
+
|
|
25
28
|
const createPaddingObject = (padding, direction) => {
|
|
26
29
|
if (padding === undefined) {
|
|
27
30
|
return { start: 0, end: 0, oppositeStart: 0, oppositeEnd: 0 }
|
|
@@ -309,7 +312,7 @@ const propsTransformer = {
|
|
|
309
312
|
}
|
|
310
313
|
},
|
|
311
314
|
set alpha(v) {
|
|
312
|
-
if (this.raw['show'] === undefined || this.raw['show']
|
|
315
|
+
if (this.raw['show'] === undefined || this.raw['show'] == true) {
|
|
313
316
|
this.props['alpha'] = v
|
|
314
317
|
}
|
|
315
318
|
},
|
|
@@ -330,14 +333,21 @@ const propsTransformer = {
|
|
|
330
333
|
if (this.element.node === undefined) {
|
|
331
334
|
this.props['shader'] = renderer.createShader('DynamicShader', {
|
|
332
335
|
effects: v.map((effect) => {
|
|
333
|
-
|
|
336
|
+
// temporary add counter to work around shader caching issues
|
|
337
|
+
return renderer.createEffect(
|
|
338
|
+
effect.type,
|
|
339
|
+
effect.props,
|
|
340
|
+
effect.type + this.element.counter
|
|
341
|
+
)
|
|
334
342
|
}),
|
|
335
343
|
})
|
|
336
344
|
} else {
|
|
337
345
|
for (let i = 0; i < v.length; i++) {
|
|
338
|
-
|
|
346
|
+
// temporary add counter to work around shader caching issues
|
|
347
|
+
const target = this.element.node.shader.props[v[i].type + this.element.counter]
|
|
339
348
|
const props = Object.keys(v[i].props)
|
|
340
349
|
|
|
350
|
+
if (target == undefined) continue
|
|
341
351
|
for (let j = 0; j < props.length; j++) {
|
|
342
352
|
target[props[j]] = v[i].props[props[j]]
|
|
343
353
|
}
|
|
@@ -642,5 +652,6 @@ export default (config, component) => {
|
|
|
642
652
|
scheduledTransitions: {},
|
|
643
653
|
config,
|
|
644
654
|
component,
|
|
655
|
+
counter: counter++,
|
|
645
656
|
})
|
|
646
657
|
}
|
package/src/engines/L3/launch.js
CHANGED
|
@@ -42,6 +42,27 @@ const textRenderEngines = (settings) => {
|
|
|
42
42
|
if (renderMode === 'canvas') return [CanvasTextRenderer]
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
const textureMemorySettings = (settings) => {
|
|
46
|
+
const gpuMemory = {
|
|
47
|
+
...{
|
|
48
|
+
max: 200,
|
|
49
|
+
target: 0.8,
|
|
50
|
+
cleanupInterval: 5000,
|
|
51
|
+
baseline: 25,
|
|
52
|
+
strict: false,
|
|
53
|
+
},
|
|
54
|
+
...('gpuMemory' in settings === true ? settings.gpuMemory : {}),
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
criticalThreshold: gpuMemory.max * 1024 * 1024, // convert from mb to bytes
|
|
59
|
+
targetThresholdLevel: gpuMemory.target,
|
|
60
|
+
cleanupInterval: gpuMemory.cleanupInterval,
|
|
61
|
+
baselineMemoryAllocation: gpuMemory.baseline * 1024 * 1024, // convert from mb to bytes
|
|
62
|
+
doNotExceedCriticalThreshold: gpuMemory.strict,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
45
66
|
export default (App, target, settings = {}) => {
|
|
46
67
|
renderer = new RendererMain(
|
|
47
68
|
{
|
|
@@ -62,13 +83,11 @@ export default (App, target, settings = {}) => {
|
|
|
62
83
|
clearColor: (settings.canvasColor && colors.normalize(settings.canvasColor)) || 0x00000000,
|
|
63
84
|
inspector: settings.inspector === true ? Inspector : undefined,
|
|
64
85
|
boundsMargin: settings.viewportMargin || 0,
|
|
65
|
-
// gpu memory limit, converted from mb to bytes - defaults to 200mb
|
|
66
|
-
txMemByteThreshold:
|
|
67
|
-
'gpuMemoryLimit' in settings ? settings.gpuMemoryLimit * 1024 * 1024 : 200 * 1024 * 1024,
|
|
68
86
|
renderEngine: renderEngine(settings),
|
|
69
87
|
fontEngines: textRenderEngines(settings),
|
|
70
88
|
canvas: settings.canvas,
|
|
71
89
|
textureProcessingTimeLimit: settings.textureProcessingTimeLimit,
|
|
90
|
+
textureMemory: textureMemorySettings(settings),
|
|
72
91
|
},
|
|
73
92
|
target
|
|
74
93
|
)
|
|
@@ -291,6 +291,9 @@ const generateComponentCode = function (
|
|
|
291
291
|
const generateForLoopCode = function (templateObject, parent) {
|
|
292
292
|
const forLoop = templateObject[':for']
|
|
293
293
|
delete templateObject[':for']
|
|
294
|
+
const range = templateObject['range'] || templateObject[':range'] || '{}'
|
|
295
|
+
delete templateObject['range']
|
|
296
|
+
delete templateObject[':range']
|
|
294
297
|
|
|
295
298
|
const key = templateObject['key']
|
|
296
299
|
const forKey = interpolate(key, 'scope.')
|
|
@@ -340,10 +343,19 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
340
343
|
|
|
341
344
|
ctx.renderCode.push(`
|
|
342
345
|
const created${forStartCounter} = []
|
|
346
|
+
|
|
347
|
+
let from${forStartCounter}
|
|
348
|
+
let to${forStartCounter}
|
|
349
|
+
|
|
343
350
|
const forloop${forStartCounter} = (collection = [], elms, created) => {
|
|
344
351
|
const rawCollection = getRaw(collection)
|
|
345
352
|
const keys = new Set()
|
|
346
353
|
let l = rawCollection.length
|
|
354
|
+
|
|
355
|
+
const range = ${interpolate(range)} || {}
|
|
356
|
+
from${forStartCounter} = range['from'] || 0
|
|
357
|
+
to${forStartCounter} = 'to' in range ? range['to'] : rawCollection.length
|
|
358
|
+
|
|
347
359
|
while(l--) {
|
|
348
360
|
const ${item} = rawCollection[l]
|
|
349
361
|
`)
|
|
@@ -354,7 +366,9 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
354
366
|
`)
|
|
355
367
|
}
|
|
356
368
|
ctx.renderCode.push(`
|
|
357
|
-
|
|
369
|
+
if(l < to${forStartCounter} && l >= from${forStartCounter}) {
|
|
370
|
+
keys.add('' + ${interpolate(key, '') || 'l'})
|
|
371
|
+
}
|
|
358
372
|
}
|
|
359
373
|
`)
|
|
360
374
|
|
|
@@ -368,6 +382,7 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
368
382
|
const length = rawCollection.length
|
|
369
383
|
const effects = []
|
|
370
384
|
for(let __index = 0; __index < length; __index++) {
|
|
385
|
+
if(__index < from${forStartCounter} || __index >= to${forStartCounter}) continue
|
|
371
386
|
const scope = Object.create(component)
|
|
372
387
|
parent = ${parent}
|
|
373
388
|
scope['${item}'] = rawCollection[__index]
|
|
@@ -488,6 +503,10 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
488
503
|
effectKey = effectKey.match(/[^.]+$/)[0]
|
|
489
504
|
}
|
|
490
505
|
|
|
506
|
+
// get the reference to range from and to
|
|
507
|
+
const effectKeysRegex = /\$([^,} ]+)/g
|
|
508
|
+
const effectKeys = [...range.matchAll(effectKeysRegex)].map((match) => `'${match[1]}'`)
|
|
509
|
+
|
|
491
510
|
ctx.renderCode.push(`
|
|
492
511
|
let forEffects${forStartCounter}
|
|
493
512
|
effect(() => {
|
|
@@ -497,7 +516,7 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
497
516
|
result[2],
|
|
498
517
|
':for'
|
|
499
518
|
)}, elms, created${forStartCounter})
|
|
500
|
-
}, '${effectKey}' )
|
|
519
|
+
}, ['${effectKey}', ${effectKeys.join(',')}] )
|
|
501
520
|
`)
|
|
502
521
|
|
|
503
522
|
outerScopeEffects.forEach((effect) => {
|
|
@@ -520,6 +539,7 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
520
539
|
effect(() => {
|
|
521
540
|
void ${refs.join(', ')}
|
|
522
541
|
for(let __index = 0; __index < ${interpolate(result[2])}.length; __index++) {
|
|
542
|
+
if(__index < from${forStartCounter} || __index >= to${forStartCounter}) continue
|
|
523
543
|
const scope = {}
|
|
524
544
|
scope['${index}'] = __index
|
|
525
545
|
scope['${item}'] = ${interpolate(result[2])}[__index]
|
|
@@ -49,9 +49,11 @@ export const track = (target, key, global = false) => {
|
|
|
49
49
|
if (paused) {
|
|
50
50
|
return
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
// note: nesting the conditions like this seems to perform better ¯\_(ツ)_/¯
|
|
53
|
+
if (Array.isArray(currentKey) === true) {
|
|
54
|
+
if (currentKey.includes(key) === false) return
|
|
55
|
+
} else if (currentKey !== null && key !== currentKey) return
|
|
56
|
+
|
|
55
57
|
let effectsMap = objectMap.get(target)
|
|
56
58
|
if (!effectsMap) {
|
|
57
59
|
effectsMap = new Map()
|
|
@@ -101,10 +101,14 @@ const reactiveProxy = (original, _parent = null, _key, global) => {
|
|
|
101
101
|
const rawValue = getRaw(value)
|
|
102
102
|
|
|
103
103
|
let result = true
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
let isEqual = false
|
|
105
|
+
|
|
106
|
+
// We need to check that the oldRawValue is also an array before we do the deep equal check
|
|
107
|
+
if (Array.isArray(rawValue) === true && Array.isArray(oldRawValue) === true) {
|
|
108
|
+
isEqual = deepEqualArray(oldRawValue, rawValue)
|
|
109
|
+
} else if (oldRawValue === rawValue) {
|
|
110
|
+
isEqual = true
|
|
111
|
+
}
|
|
108
112
|
|
|
109
113
|
if (isEqual === false) {
|
|
110
114
|
if (typeof value === 'object') {
|
|
@@ -239,6 +239,7 @@ export default (template = '', componentName, parentComponent, filePath = null)
|
|
|
239
239
|
#2: There must be exactly one top-level element (an element at level 0). This element may either be a self-closing
|
|
240
240
|
element or an opening tag followed by a closing tag. If more than one top-level element is encountered, an error
|
|
241
241
|
should be thrown.
|
|
242
|
+
But the top-level element can not have :for attribute.
|
|
242
243
|
*/
|
|
243
244
|
const format = (parsedData) => {
|
|
244
245
|
let stack = []
|
|
@@ -254,6 +255,10 @@ export default (template = '', componentName, parentComponent, filePath = null)
|
|
|
254
255
|
if (rootElementDefined) {
|
|
255
256
|
throw TemplateStructureError('MultipleTopLevelTags', element)
|
|
256
257
|
}
|
|
258
|
+
// Check for :for attribute on root level element
|
|
259
|
+
if (element[':for'] !== undefined) {
|
|
260
|
+
throw TemplateStructureError('ForAttributeOnRootElement', element)
|
|
261
|
+
}
|
|
257
262
|
rootElementDefined = true
|
|
258
263
|
}
|
|
259
264
|
|
|
@@ -1388,3 +1388,24 @@ test('Parse template with color and effects attributes and parsing should conver
|
|
|
1388
1388
|
)
|
|
1389
1389
|
assert.end()
|
|
1390
1390
|
})
|
|
1391
|
+
|
|
1392
|
+
test('Parse template with :for attribute on root element and parsing should fail', (assert) => {
|
|
1393
|
+
const template = `
|
|
1394
|
+
<Element :for="item in $items">
|
|
1395
|
+
<Text content="$item.name" />
|
|
1396
|
+
</Element>
|
|
1397
|
+
`
|
|
1398
|
+
|
|
1399
|
+
try {
|
|
1400
|
+
parser(template)
|
|
1401
|
+
assert.fail('Parser should throw TemplateStructureError:ForAttributeOnRootElement')
|
|
1402
|
+
} catch (error) {
|
|
1403
|
+
assert.equal(error.name, 'TemplateStructureError', 'Parser should throw TemplateStructureError')
|
|
1404
|
+
assert.ok(
|
|
1405
|
+
error.message.startsWith('ForAttributeOnRootElement'),
|
|
1406
|
+
'Parser should throw TemplateStructureError:ForAttributeOnRootElement'
|
|
1407
|
+
)
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
assert.end()
|
|
1411
|
+
})
|
package/src/router/router.js
CHANGED
|
@@ -25,7 +25,13 @@ import Focus from '../focus.js'
|
|
|
25
25
|
import Announcer from '../announcer/announcer.js'
|
|
26
26
|
|
|
27
27
|
export let currentRoute
|
|
28
|
-
export const state = reactive({
|
|
28
|
+
export const state = reactive({
|
|
29
|
+
path: '',
|
|
30
|
+
navigating: false,
|
|
31
|
+
data: null,
|
|
32
|
+
params: null,
|
|
33
|
+
hash: '',
|
|
34
|
+
})
|
|
29
35
|
|
|
30
36
|
const cacheMap = new WeakMap()
|
|
31
37
|
const history = []
|
|
@@ -38,8 +44,9 @@ let previousFocus
|
|
|
38
44
|
export const getHash = () => {
|
|
39
45
|
const hashParts = (document.location.hash || '/').replace(/^#/, '').split('?')
|
|
40
46
|
return {
|
|
41
|
-
|
|
47
|
+
path: hashParts[0],
|
|
42
48
|
queryParams: new URLSearchParams(hashParts[1]),
|
|
49
|
+
hash: document.location.hash,
|
|
43
50
|
}
|
|
44
51
|
}
|
|
45
52
|
|
|
@@ -108,7 +115,6 @@ export const matchHash = (path, routes = []) => {
|
|
|
108
115
|
if (!matchingRoute.data) {
|
|
109
116
|
matchingRoute.data = {}
|
|
110
117
|
}
|
|
111
|
-
currentRoute = matchingRoute
|
|
112
118
|
}
|
|
113
119
|
|
|
114
120
|
return matchingRoute
|
|
@@ -117,9 +123,16 @@ export const matchHash = (path, routes = []) => {
|
|
|
117
123
|
export const navigate = async function () {
|
|
118
124
|
state.navigating = true
|
|
119
125
|
if (this.parent[symbols.routes]) {
|
|
120
|
-
|
|
121
|
-
const { hash, queryParams } = getHash()
|
|
122
|
-
let route = matchHash(
|
|
126
|
+
let previousRoute = currentRoute ? Object.assign({}, currentRoute) : undefined
|
|
127
|
+
const { hash, path, queryParams } = getHash()
|
|
128
|
+
let route = matchHash(path, this.parent[symbols.routes])
|
|
129
|
+
|
|
130
|
+
// Adding the location hash to the route if it exists.
|
|
131
|
+
if (hash !== null) {
|
|
132
|
+
route.hash = hash
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
currentRoute = route
|
|
123
136
|
let beforeHookOutput
|
|
124
137
|
if (route) {
|
|
125
138
|
if (route.hooks) {
|
|
@@ -149,6 +162,7 @@ export const navigate = async function () {
|
|
|
149
162
|
}
|
|
150
163
|
|
|
151
164
|
let holder
|
|
165
|
+
let routeData
|
|
152
166
|
let { view, focus } = cacheMap.get(route) || {}
|
|
153
167
|
|
|
154
168
|
if (!view) {
|
|
@@ -164,13 +178,17 @@ export const navigate = async function () {
|
|
|
164
178
|
queryParamsData[queryParamsEntries[i][0]] = queryParamsEntries[i][1]
|
|
165
179
|
}
|
|
166
180
|
|
|
181
|
+
routeData = {
|
|
182
|
+
...navigationData,
|
|
183
|
+
...route.data,
|
|
184
|
+
...queryParamsData,
|
|
185
|
+
}
|
|
186
|
+
|
|
167
187
|
// merge props with potential route params, navigation data and route data to be injected into the component instance
|
|
168
188
|
const props = {
|
|
169
189
|
...this[symbols.props],
|
|
170
190
|
...route.params,
|
|
171
|
-
...
|
|
172
|
-
...route.data,
|
|
173
|
-
...queryParamsData,
|
|
191
|
+
...routeData,
|
|
174
192
|
}
|
|
175
193
|
|
|
176
194
|
view = await route.component({ props }, holder, this)
|
|
@@ -236,9 +254,14 @@ export const navigate = async function () {
|
|
|
236
254
|
if (oldView) {
|
|
237
255
|
removeView(previousRoute, oldView, route.transition.out)
|
|
238
256
|
}
|
|
257
|
+
|
|
258
|
+
previousRoute = undefined
|
|
239
259
|
}
|
|
240
260
|
|
|
241
261
|
state.path = route.path
|
|
262
|
+
state.params = route.params
|
|
263
|
+
state.hash = hash
|
|
264
|
+
state.data = routeData
|
|
242
265
|
|
|
243
266
|
// apply in transition
|
|
244
267
|
if (route.transition.in) {
|
|
@@ -320,7 +343,8 @@ const setOrAnimate = (node, transition, shouldAnimate = true) => {
|
|
|
320
343
|
export const to = (location, data = {}, options = {}) => {
|
|
321
344
|
navigationData = data
|
|
322
345
|
overrideOptions = options
|
|
323
|
-
|
|
346
|
+
|
|
347
|
+
window.location.hash = location
|
|
324
348
|
}
|
|
325
349
|
|
|
326
350
|
export const back = function () {
|
|
@@ -328,13 +352,8 @@ export const back = function () {
|
|
|
328
352
|
if (route && currentRoute !== route) {
|
|
329
353
|
// set indicator that we are navigating back (to prevent adding page to history stack)
|
|
330
354
|
navigatingBack = true
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
Object.keys(route.params).forEach((item) => {
|
|
334
|
-
targetRoutePath = targetRoutePath.replace(`:${item}`, route.params[item])
|
|
335
|
-
})
|
|
336
|
-
}
|
|
337
|
-
to(targetRoutePath)
|
|
355
|
+
|
|
356
|
+
to(route.hash, route.data, route.options)
|
|
338
357
|
return true
|
|
339
358
|
}
|
|
340
359
|
|
|
@@ -348,6 +367,7 @@ export const back = function () {
|
|
|
348
367
|
|
|
349
368
|
const hashEnd = /(\/:?[\w%\s-]+)$/
|
|
350
369
|
let path = currentRoute.path
|
|
370
|
+
|
|
351
371
|
let level = path.split('/').length
|
|
352
372
|
|
|
353
373
|
// On root return
|