Skip to content

Commit 87da562

Browse files
Merge pull request #244 from rdkcentral/feature/router
Feature/router
2 parents 0accb42 + 1f1fa30 commit 87da562

File tree

8 files changed

+125
-18
lines changed

8 files changed

+125
-18
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## v4.4.0
4+
5+
*18 june 2021*
6+
7+
- Router updates
8+
- Added showing loading page between shared instances with `on()` provider
9+
- Fixed wrong historyState object on shared instance
10+
- Fixed hash to route mismatch on hash with trailing slash
11+
- Fixed showing bootPage before unknown hash
12+
- Fixed focus issues with shared state on routes with same page type
13+
- Fixed memoryleak on shared routes with lazyCreate disabled
14+
15+
316
## v4.3.3
417

518
*7 may 2021*

src/Router/index.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
isString,
2626
getQueryStringParams,
2727
symbols,
28+
cleanHash,
2829
} from './utils/helpers'
2930

3031
import {
@@ -121,6 +122,12 @@ const start = () => {
121122
}
122123

123124
if (routeExists(bootKey)) {
125+
if (hash && !isDirectLoad) {
126+
if (!getRouteByHash(hash)) {
127+
navigate('*', { failedHash: hash })
128+
return
129+
}
130+
}
124131
navigate(
125132
bootKey,
126133
{
@@ -198,7 +205,7 @@ export const navigate = (url, args = {}, store) => {
198205
}
199206

200207
const queue = (hash, args = {}, store) => {
201-
hash = hash.replace(/^#/, '')
208+
hash = cleanHash(hash)
202209
if (!navigateQueue.has(hash)) {
203210
for (let request of navigateQueue.values()) {
204211
request.cancel()
@@ -217,7 +224,7 @@ const queue = (hash, args = {}, store) => {
217224
* @returns {Promise<void>}
218225
*/
219226
const handleHashChange = async override => {
220-
const hash = (override || getHash()).replace(/^#/, '')
227+
const hash = cleanHash(override || getHash())
221228
const queueId = decodeURIComponent(hash)
222229
let request = navigateQueue.get(queueId)
223230

@@ -299,6 +306,13 @@ const resolveHashChange = request => {
299306
}
300307
// if there is a component attached to the route
301308
if (component) {
309+
// to prevent shared state issues between same routes
310+
// we force page to root state
311+
const activePage = getActivePage()
312+
if (activePage) {
313+
activePage._setState('')
314+
}
315+
302316
if (isPage(component, stage)) {
303317
load(request).then(() => {
304318
app._refocus()

src/Router/model/Request.js

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,67 @@ import { createRegister } from '../utils/register'
2222
import Log from '../../Log'
2323

2424
export default class Request {
25-
constructor(hash, navArgs, storeCaller) {
25+
constructor(hash = '', navArgs, storeCaller) {
26+
/**
27+
* Hash we navigate to
28+
* @type {string}
29+
* @private
30+
*/
2631
this._hash = hash
32+
33+
/**
34+
* Do we store previous hash in history
35+
* @type {boolean}
36+
* @private
37+
*/
2738
this._storeCaller = storeCaller
39+
40+
/**
41+
* Request and navigate data
42+
* @type {Map}
43+
* @private
44+
*/
2845
this._register = new Map()
46+
47+
/**
48+
* Flag if the instance is created due to
49+
* this request
50+
* @type {boolean}
51+
* @private
52+
*/
2953
this._isCreated = false
54+
55+
/**
56+
* Flag if the instance is shared between
57+
* previous and current request
58+
* @type {boolean}
59+
* @private
60+
*/
3061
this._isSharedInstance = false
62+
63+
/**
64+
* Flag if the request has been cancelled
65+
* @type {boolean}
66+
* @private
67+
*/
3168
this._cancelled = false
3269

70+
/**
71+
* if instance is shared between requests we copy state object
72+
* from instance before the new request overrides state
73+
* @type {null}
74+
* @private
75+
*/
76+
this._copiedHistoryState = null
77+
3378
// if there are arguments attached to navigate()
3479
// we store them in new request
3580
if (isObject(navArgs)) {
3681
this._register = createRegister(navArgs)
3782
} else if (isBoolean(navArgs)) {
83+
// if second navigate() argument is explicitly
84+
// set to false we prevent the calling page
85+
// from ending up in history
3886
this._storeCaller = navArgs
3987
}
4088
// @todo: remove because we can simply check
@@ -114,4 +162,12 @@ export default class Request {
114162
get isCancelled() {
115163
return this._cancelled
116164
}
165+
166+
set copiedHistoryState(v) {
167+
this._copiedHistoryState = v
168+
}
169+
170+
get copiedHistoryState() {
171+
return this._copiedHistoryState
172+
}
117173
}

src/Router/utils/helpers.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ export const isPromise = method => {
6969
return isObject(result) && isFunction(result.then)
7070
}
7171

72+
export const cleanHash = (hash = '') => {
73+
return hash.replace(/^#/, '').replace(/\/+$/, '')
74+
}
75+
7276
export const getConfigMap = () => {
7377
const routerSettings = Settings.get('platform', 'router')
7478
const isObj = isObject(routerSettings)

src/Router/utils/history.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const updateHistory = request => {
4949
if (store) {
5050
const toStore = hash.replace(/^\//, '')
5151
const location = locationInHistory(toStore)
52-
const stateObject = getStateObject(getActivePage())
52+
const stateObject = getStateObject(getActivePage(), request)
5353
const routerConfig = getRouterConfig()
5454

5555
// store hash if it's not a part of history or flag for
@@ -102,8 +102,14 @@ export const replaceHistoryState = (state = null, hash) => {
102102
}
103103
}
104104

105-
const getStateObject = page => {
106-
if (page && isFunction(page.historyState)) {
105+
const getStateObject = (page, request) => {
106+
// if the new request shared instance with the
107+
// previous request we used the copied state object
108+
if (request.isSharedInstance) {
109+
if (request.copiedHistoryState) {
110+
return request.copiedHistoryState
111+
}
112+
} else if (page && isFunction(page.historyState)) {
107113
return page.historyState()
108114
}
109115
return null

src/Router/utils/loader.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ import {
3131
} from './router'
3232

3333
import Log from '../../Log'
34-
import { isBoolean, isComponentConstructor, symbols } from './helpers'
35-
import { getProvider, hasProvider, isPageExpired, types, addPersistData } from './provider'
34+
import { isBoolean, isComponentConstructor, isFunction, symbols } from './helpers'
35+
import { getProvider, hasProvider, isPageExpired, dataHooks, addPersistData } from './provider'
3636
import { createComponent } from './components'
3737
import { executeTransition } from './transition'
3838
import { getActiveWidget } from './widgets'
@@ -120,7 +120,7 @@ const loader = async request => {
120120
}
121121
}
122122

123-
// If type is not a constructor
123+
// If page is Lightning Component instance
124124
if (!isConstruct) {
125125
request.page = type
126126
// if we have have a data route for current page
@@ -136,6 +136,12 @@ const loader = async request => {
136136
// and check platform settings in we want to re-use instance
137137
if (route.path === currentRoute) {
138138
request.isSharedInstance = true
139+
// since we're re-using the instance we must attach
140+
// historyState to the request to prevent it from
141+
// being overridden.
142+
if (isFunction(request.page.historyState)) {
143+
request.copiedHistoryState = request.page.historyState()
144+
}
139145
}
140146
} else {
141147
request.page = createComponent(stage, type)
@@ -162,7 +168,7 @@ const loader = async request => {
162168
request.provider = provider
163169
request.providerType = loadType
164170

165-
await types[request.isSharedInstance ? 'shared' : loadType](request)
171+
await dataHooks[loadType](request)
166172

167173
// we early exit if the current request is expired
168174
if (hash !== getLastHash()) {

src/Router/utils/provider.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import emit from './emit'
2424

2525
export let previousState
2626

27-
export const types = {
27+
export const dataHooks = {
2828
on: request => {
2929
previousState = app.state || ''
3030
app._setState('Loading')
@@ -41,10 +41,6 @@ export const types = {
4141
}
4242
return Promise.resolve()
4343
},
44-
// on route share instance
45-
shared: request => {
46-
return execProvider(request)
47-
},
4844
}
4945

5046
const execProvider = (request, emitProvided) => {

src/Router/utils/router.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
isFunction,
2626
isPage,
2727
symbols,
28+
cleanHash,
2829
} from './helpers'
2930
import { step, navigateQueue } from '../index'
3031
import { createRoute, getOption } from './route'
@@ -204,8 +205,7 @@ const setup = config => {
204205
init(config)
205206
}
206207
config.routes.forEach(r => {
207-
// strip leading slash
208-
const path = r.path.replace(/\/+$/, '')
208+
const path = cleanHash(r.path)
209209
if (!routeExists(path)) {
210210
const route = createRoute(r)
211211
routes.set(path, route)
@@ -366,9 +366,21 @@ const cleanUp = (page, request) => {
366366

367367
let doCleanup = false
368368

369+
// if this request is executed due to a step back in history
370+
// and we have configured to destroy active page when we go back
371+
// in history or lazyDestory is enabled
369372
if (isFromHistory && (destroyOnBack || lazyDestroy)) {
370373
doCleanup = true
371-
} else if (lazyDestroy && !keepAlive) {
374+
}
375+
376+
// clean up if lazyDestroy is enabled and the keepAlive flag
377+
// in navigation register is false
378+
if (lazyDestroy && !keepAlive) {
379+
doCleanup = true
380+
}
381+
382+
// if the current and new request share the same route blueprint
383+
if (activeRoute === request.route.path) {
372384
doCleanup = true
373385
}
374386

0 commit comments

Comments
 (0)