From 73bbfe57beff131cfb97c4be2140df72b88615dd Mon Sep 17 00:00:00 2001 From: Alexander Varney Date: Mon, 30 Nov 2020 18:52:12 -0500 Subject: [PATCH 1/5] handle '%' in unencoded URL --- packages/url-persistence/src/index.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/url-persistence/src/index.ts b/packages/url-persistence/src/index.ts index 9069f05..bde5ba0 100644 --- a/packages/url-persistence/src/index.ts +++ b/packages/url-persistence/src/index.ts @@ -29,7 +29,7 @@ const deserialize = (params, serializers: ISerializers | undefined): object => { throw new Error(err); } } else { - paramsObject[key] = decodeURI(params[key]); + paramsObject[key] = decodeURIComponent(params[key]); } }); return paramsObject; @@ -52,7 +52,7 @@ const serialize = (params, serializers: ISerializers | undefined): string => { throw new Error(err); } } else { - paramsString += `${key}=${encodeURI(params[key])}&`; + paramsString += `${key}=${encodeURIComponent(params[key])}&`; } }); @@ -68,7 +68,10 @@ function URLPersistence( const params = parse(location.search); const name = decodeURIComponent(location.pathname); const paramsObject = deserialize(params, options?.serializers); - API.currentState = { name: name as S, params: paramsObject as P }; + API.currentState = { + name: name as S, + params: (paramsObject) as P, + }; }); const API = observable( From 33cf8700f82b363f639aaaa43b9ae3c87ac363c5 Mon Sep 17 00:00:00 2001 From: Alexander Varney Date: Wed, 2 Dec 2020 11:59:37 -0500 Subject: [PATCH 2/5] version with tests --- packages/url-persistence/src/index.test.ts | 8 ++++++++ packages/url-persistence/src/index.ts | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/url-persistence/src/index.test.ts b/packages/url-persistence/src/index.test.ts index 45ef340..38cd02f 100644 --- a/packages/url-persistence/src/index.test.ts +++ b/packages/url-persistence/src/index.test.ts @@ -157,6 +157,14 @@ describe('with URL persistence', () => { expect(window.location.hash).toBe('#/work?activity=daydreaming'); }); + it('should update query params with special chars', () => { + stateMachineRouter.emit(ACTION.goToWork); + stateMachineRouter.emit(ACTION.slack, { activity: '%+-/!@#$^&*() text' }); + expect(window.location.hash).toBe( + '#/work?activity=%25%2B-%2F!%40%23%24%5E%26*()%20text' + ); + }); + it('should nullify query params', () => { stateMachineRouter.emit(ACTION.goToWork); stateMachineRouter.emit(ACTION.slack, { activity: null }); diff --git a/packages/url-persistence/src/index.ts b/packages/url-persistence/src/index.ts index bde5ba0..4aabc1d 100644 --- a/packages/url-persistence/src/index.ts +++ b/packages/url-persistence/src/index.ts @@ -29,7 +29,12 @@ const deserialize = (params, serializers: ISerializers | undefined): object => { throw new Error(err); } } else { - paramsObject[key] = decodeURIComponent(params[key]); + try { + paramsObject[key] = decodeURIComponent(params[key]); + } catch(err) { + paramsObject[key] = params[key] + } + } }); return paramsObject; @@ -85,6 +90,8 @@ function URLPersistence( const params = { ...toJS(currentState.params) }; const paramsString: string = serialize(params, options?.serializers); + console.log(paramsString); + const toURL = `${name}${paramsString !== '' ? `?${paramsString}` : ''}`; if (window.location.hash.split('#')[1] !== toURL) { history.push(toURL); From 1781c81130dcbcfc50f851a017db87118c60d7bd Mon Sep 17 00:00:00 2001 From: Alexander Varney Date: Wed, 2 Dec 2020 12:00:43 -0500 Subject: [PATCH 3/5] remove console log --- packages/url-persistence/src/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/url-persistence/src/index.ts b/packages/url-persistence/src/index.ts index 4aabc1d..b0ec7fc 100644 --- a/packages/url-persistence/src/index.ts +++ b/packages/url-persistence/src/index.ts @@ -90,8 +90,6 @@ function URLPersistence( const params = { ...toJS(currentState.params) }; const paramsString: string = serialize(params, options?.serializers); - console.log(paramsString); - const toURL = `${name}${paramsString !== '' ? `?${paramsString}` : ''}`; if (window.location.hash.split('#')[1] !== toURL) { history.push(toURL); From 5aab4290c733b525620a1af702c1d75b35b1ef14 Mon Sep 17 00:00:00 2001 From: Alexander Varney Date: Wed, 2 Dec 2020 12:33:21 -0500 Subject: [PATCH 4/5] remove try-catch logic, add new test --- packages/url-persistence/src/index.test.ts | 9 +++++++++ packages/url-persistence/src/index.ts | 5 ----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/url-persistence/src/index.test.ts b/packages/url-persistence/src/index.test.ts index 38cd02f..492b029 100644 --- a/packages/url-persistence/src/index.test.ts +++ b/packages/url-persistence/src/index.test.ts @@ -165,6 +165,15 @@ describe('with URL persistence', () => { ); }); + it('should read state from query params with special chars', async () => { + window.location.hash = + '/work?activity=%25%2B-%2F!%40%23%24%5E%26*()%20text'; + await ms(10); + expect(stateMachineRouter.currentState.params.activity).toBe( + '%+-/!@#$^&*() text' + ); + }); + it('should nullify query params', () => { stateMachineRouter.emit(ACTION.goToWork); stateMachineRouter.emit(ACTION.slack, { activity: null }); diff --git a/packages/url-persistence/src/index.ts b/packages/url-persistence/src/index.ts index b0ec7fc..16d0d95 100644 --- a/packages/url-persistence/src/index.ts +++ b/packages/url-persistence/src/index.ts @@ -29,12 +29,7 @@ const deserialize = (params, serializers: ISerializers | undefined): object => { throw new Error(err); } } else { - try { - paramsObject[key] = decodeURIComponent(params[key]); - } catch(err) { paramsObject[key] = params[key] - } - } }); return paramsObject; From 70bb8d37e949fc718443d63ee74d2b75c2bb84a0 Mon Sep 17 00:00:00 2001 From: Alexander Varney Date: Wed, 2 Dec 2020 12:40:34 -0500 Subject: [PATCH 5/5] fix formatting --- packages/url-persistence/src/index.test.ts | 16 ++++++++-------- packages/url-persistence/src/index.ts | 5 +---- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/url-persistence/src/index.test.ts b/packages/url-persistence/src/index.test.ts index 492b029..3e2bd81 100644 --- a/packages/url-persistence/src/index.test.ts +++ b/packages/url-persistence/src/index.test.ts @@ -165,14 +165,14 @@ describe('with URL persistence', () => { ); }); - it('should read state from query params with special chars', async () => { - window.location.hash = - '/work?activity=%25%2B-%2F!%40%23%24%5E%26*()%20text'; - await ms(10); - expect(stateMachineRouter.currentState.params.activity).toBe( - '%+-/!@#$^&*() text' - ); - }); + it('should read state from query params with special chars', async () => { + window.location.hash = + '/work?activity=%25%2B-%2F!%40%23%24%5E%26*()%20text'; + await ms(10); + expect(stateMachineRouter.currentState.params.activity).toBe( + '%+-/!@#$^&*() text' + ); + }); it('should nullify query params', () => { stateMachineRouter.emit(ACTION.goToWork); diff --git a/packages/url-persistence/src/index.ts b/packages/url-persistence/src/index.ts index 16d0d95..bf903d5 100644 --- a/packages/url-persistence/src/index.ts +++ b/packages/url-persistence/src/index.ts @@ -68,10 +68,7 @@ function URLPersistence( const params = parse(location.search); const name = decodeURIComponent(location.pathname); const paramsObject = deserialize(params, options?.serializers); - API.currentState = { - name: name as S, - params: (paramsObject) as P, - }; + API.currentState = { name: name as S, params: paramsObject as P }; }); const API = observable(