navigation-stack 0.5.3 → 0.6.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/CHANGELOG.md +16 -0
- package/README.md +144 -282
- package/karma.conf.cjs +1 -1
- package/lib/cjs/NavigationStack.js +138 -49
- package/lib/cjs/data-storage/DataStorage.js +7 -6
- package/lib/cjs/environment/InMemoryEnvironment.js +6 -0
- package/lib/cjs/{session/ServerSideRenderSession.js → environment/ServerSideRenderEnvironment.js} +5 -6
- package/lib/cjs/environment/WebBrowserEnvironment.js +6 -0
- package/lib/cjs/environment/log/InMemoryLog.js +23 -0
- package/lib/cjs/environment/log/WebBrowserLog.js +22 -0
- package/lib/cjs/{session → environment}/navigation/InMemoryNavigation.js +16 -5
- package/lib/cjs/{session → environment}/navigation/ServerSideNavigation.js +16 -7
- package/lib/cjs/{session → environment}/navigation/WebBrowserNavigation.js +48 -8
- package/lib/cjs/{session/navigation/error/ServerSideNavigationError.js → environment/navigation/error/ServerSideRedirectError.js} +2 -2
- package/lib/cjs/environment/scroll-position/WebBrowserScrollPosition.js +15 -0
- package/lib/cjs/getLocationBaseFromLocation.js +14 -0
- package/lib/cjs/getLocationUrl.js +3 -5
- package/lib/cjs/index.js +10 -16
- package/lib/cjs/navigationBlockers.js +34 -32
- package/lib/cjs/navigationBlockersEvaluation.js +150 -0
- package/lib/cjs/parseInputLocation.js +2 -2
- package/lib/cjs/parseQueryFromSearch.js +3 -6
- package/lib/cjs/parseQueryString.js +77 -0
- package/lib/cjs/scroll-position/ScrollPositionAutoSaver.js +7 -6
- package/lib/cjs/scroll-position/ScrollPositionRestoration.js +31 -27
- package/lib/cjs/scroll-position/ScrollPositionSaver.js +6 -4
- package/lib/cjs/session/Session.js +61 -26
- package/lib/cjs/session/subscription/Subscription.js +36 -18
- package/lib/cjs/stringifyQuery.js +66 -0
- package/lib/cjs/stringifyQueryAsSearch.js +14 -0
- package/lib/esm/NavigationStack.js +138 -49
- package/lib/esm/data-storage/DataStorage.js +7 -6
- package/lib/esm/environment/InMemoryEnvironment.js +6 -0
- package/lib/esm/environment/ServerSideRenderEnvironment.js +10 -0
- package/lib/esm/environment/WebBrowserEnvironment.js +6 -0
- package/lib/esm/environment/log/InMemoryLog.js +17 -0
- package/lib/esm/environment/log/WebBrowserLog.js +16 -0
- package/lib/esm/{session → environment}/navigation/InMemoryNavigation.js +16 -5
- package/lib/esm/{session → environment}/navigation/ServerSideNavigation.js +16 -7
- package/lib/esm/{session → environment}/navigation/WebBrowserNavigation.js +48 -8
- package/lib/esm/{session/navigation/error/ServerSideNavigationError.js → environment/navigation/error/ServerSideRedirectError.js} +1 -1
- package/lib/esm/environment/scroll-position/WebBrowserScrollPosition.js +15 -0
- package/lib/esm/getLocationBaseFromLocation.js +9 -0
- package/lib/esm/getLocationUrl.js +2 -5
- package/lib/esm/index.js +5 -8
- package/lib/esm/navigationBlockers.js +34 -32
- package/lib/esm/navigationBlockersEvaluation.js +145 -0
- package/lib/esm/parseInputLocation.js +2 -2
- package/lib/esm/parseQueryFromSearch.js +2 -6
- package/lib/esm/parseQueryString.js +72 -0
- package/lib/esm/scroll-position/ScrollPositionAutoSaver.js +7 -6
- package/lib/esm/scroll-position/ScrollPositionRestoration.js +31 -27
- package/lib/esm/scroll-position/ScrollPositionSaver.js +6 -4
- package/lib/esm/session/Session.js +61 -26
- package/lib/esm/session/subscription/Subscription.js +36 -18
- package/lib/esm/stringifyQuery.js +61 -0
- package/lib/esm/stringifyQueryAsSearch.js +8 -0
- package/lib/index.d.ts +180 -34
- package/package.json +4 -7
- package/src/NavigationStack.js +166 -56
- package/src/data-storage/DataStorage.js +9 -6
- package/src/environment/InMemoryEnvironment.js +6 -0
- package/src/environment/ServerSideRenderEnvironment.js +10 -0
- package/src/environment/WebBrowserEnvironment.js +6 -0
- package/src/environment/log/InMemoryLog.js +20 -0
- package/src/environment/log/WebBrowserLog.js +18 -0
- package/src/{session → environment}/navigation/InMemoryNavigation.js +16 -5
- package/src/{session → environment}/navigation/ServerSideNavigation.js +16 -7
- package/src/{session → environment}/navigation/WebBrowserNavigation.js +48 -8
- package/src/{session/navigation/error/ServerSideNavigationError.js → environment/navigation/error/ServerSideRedirectError.js} +1 -1
- package/src/environment/scroll-position/WebBrowserScrollPosition.js +15 -0
- package/src/getLocationBaseFromLocation.js +7 -0
- package/src/getLocationUrl.js +2 -5
- package/src/index.js +10 -13
- package/src/navigationBlockers.js +55 -34
- package/src/navigationBlockersEvaluation.js +161 -0
- package/src/parseInputLocation.js +2 -2
- package/src/parseQueryFromSearch.js +2 -6
- package/src/parseQueryString.js +81 -0
- package/src/scroll-position/ScrollPositionAutoSaver.js +10 -6
- package/src/scroll-position/ScrollPositionRestoration.js +36 -30
- package/src/scroll-position/ScrollPositionSaver.js +6 -4
- package/src/scroll-position/index.js +1 -1
- package/src/session/Session.js +68 -24
- package/src/session/subscription/Subscription.js +36 -11
- package/src/stringifyQuery.js +71 -0
- package/src/stringifyQueryAsSearch.js +9 -0
- package/test/NavigationStack.addBasePath.test.js +50 -0
- package/test/{redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.test.js → NavigationStack.blockNonProgrammaticNavigationIfRequired.test.js} +51 -63
- package/test/{redux/middleware/createProgrammaticNavigationBlockerMiddleware.test.js → NavigationStack.blockProgrammaticNavigationIfRequired.test.js} +98 -78
- package/test/NavigationStack.general.test.js +68 -0
- package/test/NavigationStack.parseInputLocation.test.js +52 -0
- package/test/NavigationStack.removeBasePath.test.js +69 -0
- package/test/NavigationStack.test.js +97 -29
- package/test/data-storage/LocationDataStorage.test.js +3 -2
- package/test/index.js +7 -31
- package/test/index.test.js +4 -5
- package/test/parseQueryFromSearch.test.js +19 -0
- package/test/parseQueryString.test.js +18 -0
- package/test/scroll-position/ScrollPositionRestoration.test.js +34 -13
- package/test/scroll-position/createApp.js +8 -8
- package/test/scroll-position/withScrollableContainerAtIndexPageWithDisabledAutomaticScrollPositionRestoration.js +4 -4
- package/test/session/{InMemorySession.test.js → Session.InMemoryEnvironment.test.js} +10 -9
- package/test/session/{ServerSession.test.js → Session.ServerSideRenderEnvironment.test.js} +5 -4
- package/test/session/{WebBrowserSession.test.js → Session.WebBrowserEnvironment.test.js} +63 -13
- package/test/shouldWarn.js +44 -0
- package/test/stringifyQuery.test.js +65 -0
- package/types/index.d.ts +180 -34
- package/types/tsconfig.json +0 -1
- package/data-storage/package.json +0 -7
- package/lib/cjs/createSearchFromQuery.js +0 -13
- package/lib/cjs/debug.js +0 -12
- package/lib/cjs/redux/ActionTypes.js +0 -14
- package/lib/cjs/redux/ActionTypesInternal.js +0 -8
- package/lib/cjs/redux/Actions.js +0 -28
- package/lib/cjs/redux/createMiddlewares.js +0 -60
- package/lib/cjs/redux/index.js +0 -13
- package/lib/cjs/redux/internalLocationReducer.js +0 -14
- package/lib/cjs/redux/locationReducer.js +0 -13
- package/lib/cjs/redux/middleware/createAddInputLocationBasePathMiddleware.js +0 -32
- package/lib/cjs/redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.js +0 -113
- package/lib/cjs/redux/middleware/createProgrammaticNavigationBlockerMiddleware.js +0 -94
- package/lib/cjs/redux/middleware/createRemoveOutputLocationBasePathMiddleware.js +0 -30
- package/lib/cjs/redux/middleware/createUpdateInternalLocationMiddleware.js +0 -73
- package/lib/cjs/redux/middleware/navigationOperationMiddleware.js +0 -40
- package/lib/cjs/redux/middleware/parseInputLocationMiddleware.js +0 -29
- package/lib/cjs/redux/middleware/updateLocationMiddleware.js +0 -34
- package/lib/cjs/session/InMemorySession.js +0 -22
- package/lib/cjs/session/WebBrowserSession.js +0 -20
- package/lib/data-storage/index.d.ts +0 -35
- package/lib/esm/createSearchFromQuery.js +0 -8
- package/lib/esm/debug.js +0 -7
- package/lib/esm/redux/ActionTypes.js +0 -9
- package/lib/esm/redux/ActionTypesInternal.js +0 -3
- package/lib/esm/redux/Actions.js +0 -22
- package/lib/esm/redux/createMiddlewares.js +0 -54
- package/lib/esm/redux/index.js +0 -4
- package/lib/esm/redux/internalLocationReducer.js +0 -8
- package/lib/esm/redux/locationReducer.js +0 -7
- package/lib/esm/redux/middleware/createAddInputLocationBasePathMiddleware.js +0 -27
- package/lib/esm/redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.js +0 -108
- package/lib/esm/redux/middleware/createProgrammaticNavigationBlockerMiddleware.js +0 -88
- package/lib/esm/redux/middleware/createRemoveOutputLocationBasePathMiddleware.js +0 -25
- package/lib/esm/redux/middleware/createUpdateInternalLocationMiddleware.js +0 -68
- package/lib/esm/redux/middleware/navigationOperationMiddleware.js +0 -35
- package/lib/esm/redux/middleware/parseInputLocationMiddleware.js +0 -24
- package/lib/esm/redux/middleware/updateLocationMiddleware.js +0 -28
- package/lib/esm/session/InMemorySession.js +0 -15
- package/lib/esm/session/ServerSideRenderSession.js +0 -11
- package/lib/esm/session/WebBrowserSession.js +0 -13
- package/lib/redux/index.d.ts +0 -90
- package/lib/scroll-position/index.d.ts +0 -107
- package/redux/package.json +0 -7
- package/scroll-position/package.json +0 -7
- package/src/createSearchFromQuery.js +0 -9
- package/src/debug.js +0 -8
- package/src/redux/ActionTypes.js +0 -9
- package/src/redux/ActionTypesInternal.js +0 -3
- package/src/redux/Actions.js +0 -27
- package/src/redux/createMiddlewares.js +0 -65
- package/src/redux/index.js +0 -4
- package/src/redux/internalLocationReducer.js +0 -9
- package/src/redux/locationReducer.js +0 -8
- package/src/redux/middleware/createAddInputLocationBasePathMiddleware.js +0 -27
- package/src/redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.js +0 -119
- package/src/redux/middleware/createProgrammaticNavigationBlockerMiddleware.js +0 -94
- package/src/redux/middleware/createRemoveOutputLocationBasePathMiddleware.js +0 -26
- package/src/redux/middleware/createUpdateInternalLocationMiddleware.js +0 -72
- package/src/redux/middleware/navigationOperationMiddleware.js +0 -34
- package/src/redux/middleware/parseInputLocationMiddleware.js +0 -23
- package/src/redux/middleware/updateLocationMiddleware.js +0 -28
- package/src/session/InMemorySession.js +0 -13
- package/src/session/ServerSideRenderSession.js +0 -9
- package/src/session/WebBrowserSession.js +0 -13
- package/test/middlewareTestUtil.js +0 -31
- package/test/redux/Action.test.js +0 -73
- package/test/redux/ActionTypes.test.js +0 -13
- package/test/redux/createMiddlewares.test.js +0 -96
- package/test/redux/index.test.js +0 -10
- package/test/redux/locationReducer.test.js +0 -39
- package/test/redux/middleware/createAddInputLocationBasePathMiddleware.test.js +0 -40
- package/test/redux/middleware/createRemoveOutputLocationBasePathMiddleware.test.js +0 -51
- package/test/redux/middleware/navigationOperationMiddleware.test.js +0 -78
- package/test/redux/middleware/parseInputLocationMiddleware.test.js +0 -62
- package/test/testUtil.js +0 -3
- package/types/data-storage/index.d.ts +0 -35
- package/types/redux/index.d.ts +0 -90
- package/types/scroll-position/index.d.ts +0 -107
- /package/lib/cjs/{session → environment}/lifecycle/InMemorySessionLifecycle.js +0 -0
- /package/lib/cjs/{session → environment}/lifecycle/WebBrowserSessionLifecycle.js +0 -0
- /package/lib/cjs/{session → environment}/lifecycle/page-lifecycle/PageLifecycle.js +0 -0
- /package/lib/cjs/{session → environment}/lifecycle/page-lifecycle/PageLifecycleInstance.js +0 -0
- /package/lib/cjs/{session → environment}/lifecycle/page-lifecycle/supportsConstructableEventTarget.js +0 -0
- /package/lib/cjs/{session → environment}/navigation/error/NavigationOutOfBoundsError.js +0 -0
- /package/lib/cjs/{session → environment}/navigation/operation/operations.js +0 -0
- /package/lib/esm/{session → environment}/lifecycle/InMemorySessionLifecycle.js +0 -0
- /package/lib/esm/{session → environment}/lifecycle/WebBrowserSessionLifecycle.js +0 -0
- /package/lib/esm/{session → environment}/lifecycle/page-lifecycle/PageLifecycle.js +0 -0
- /package/lib/esm/{session → environment}/lifecycle/page-lifecycle/PageLifecycleInstance.js +0 -0
- /package/lib/esm/{session → environment}/lifecycle/page-lifecycle/supportsConstructableEventTarget.js +0 -0
- /package/lib/esm/{session → environment}/navigation/error/NavigationOutOfBoundsError.js +0 -0
- /package/lib/esm/{session → environment}/navigation/operation/operations.js +0 -0
- /package/src/{session → environment}/lifecycle/InMemorySessionLifecycle.js +0 -0
- /package/src/{session → environment}/lifecycle/WebBrowserSessionLifecycle.js +0 -0
- /package/src/{session → environment}/lifecycle/page-lifecycle/PageLifecycle.js +0 -0
- /package/src/{session → environment}/lifecycle/page-lifecycle/PageLifecycleInstance.js +0 -0
- /package/src/{session → environment}/lifecycle/page-lifecycle/supportsConstructableEventTarget.js +0 -0
- /package/src/{session → environment}/navigation/error/NavigationOutOfBoundsError.js +0 -0
- /package/src/{session → environment}/navigation/operation/operations.js +0 -0
- /package/test/{parseInputLocationMiddleware.test.js → parseInputLocation.test.js} +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import delay from 'delay';
|
|
2
2
|
|
|
3
3
|
import NavigationStack from '../src/NavigationStack';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import InMemoryEnvironment from '../src/environment/InMemoryEnvironment';
|
|
5
|
+
import WebBrowserEnvironment from '../src/environment/WebBrowserEnvironment';
|
|
6
6
|
|
|
7
7
|
describe('NavigationStack', () => {
|
|
8
8
|
let navigationStack;
|
|
9
9
|
|
|
10
10
|
beforeEach(() => {
|
|
11
|
-
navigationStack = new NavigationStack(
|
|
11
|
+
navigationStack = new NavigationStack(InMemoryEnvironment);
|
|
12
12
|
navigationStack.init('/initial');
|
|
13
13
|
});
|
|
14
14
|
|
|
@@ -54,7 +54,7 @@ describe('NavigationStack (WebBrowserSession)', () => {
|
|
|
54
54
|
beforeEach(() => {
|
|
55
55
|
window.history.replaceState(null, null, '/initial');
|
|
56
56
|
|
|
57
|
-
navigationStack = new NavigationStack(
|
|
57
|
+
navigationStack = new NavigationStack(WebBrowserEnvironment);
|
|
58
58
|
|
|
59
59
|
navigationStack.init();
|
|
60
60
|
});
|
|
@@ -68,21 +68,21 @@ describe('NavigationStack (WebBrowserSession)', () => {
|
|
|
68
68
|
|
|
69
69
|
it('should allow calling `init()` without an argument, and then support `push` and `shift` navigation operations', async () => {
|
|
70
70
|
navigationStack.push('/new');
|
|
71
|
-
await delay(
|
|
71
|
+
await delay(100);
|
|
72
72
|
expect(navigationStack.current()).to.include({
|
|
73
73
|
pathname: '/new',
|
|
74
74
|
index: 1,
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
navigationStack.shift(-1);
|
|
78
|
-
await delay(
|
|
78
|
+
await delay(100);
|
|
79
79
|
expect(navigationStack.current()).to.include({
|
|
80
80
|
pathname: '/initial',
|
|
81
81
|
index: 0,
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
navigationStack.shift(+1);
|
|
85
|
-
await delay(
|
|
85
|
+
await delay(100);
|
|
86
86
|
expect(navigationStack.current()).to.include({
|
|
87
87
|
pathname: '/new',
|
|
88
88
|
index: 1,
|
|
@@ -91,12 +91,81 @@ describe('NavigationStack (WebBrowserSession)', () => {
|
|
|
91
91
|
|
|
92
92
|
it('should allow calling `init()` without an argument, and then support `replace` navigation operation', async () => {
|
|
93
93
|
navigationStack.replace('/new');
|
|
94
|
-
await delay(
|
|
94
|
+
await delay(100);
|
|
95
95
|
expect(navigationStack.current()).to.include({
|
|
96
96
|
pathname: '/new',
|
|
97
97
|
index: 0,
|
|
98
98
|
});
|
|
99
99
|
});
|
|
100
|
+
|
|
101
|
+
it('should not allow calling `init()` multiple times', () => {
|
|
102
|
+
expect(() => {
|
|
103
|
+
navigationStack.init('/new');
|
|
104
|
+
}).to.throw('Already initialized');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should restart a previously-started session', async () => {
|
|
108
|
+
navigationStack.push('/new');
|
|
109
|
+
navigationStack.stop();
|
|
110
|
+
|
|
111
|
+
// Simulate the user refreshing the page in a web browser.
|
|
112
|
+
// In such case, `window.history` will be retained
|
|
113
|
+
// but every javascript variable will be recreated from scratch.
|
|
114
|
+
navigationStack = new NavigationStack(WebBrowserEnvironment);
|
|
115
|
+
|
|
116
|
+
navigationStack.init();
|
|
117
|
+
|
|
118
|
+
// A publicly-exposed `location` object doesn't have an `operation` property.
|
|
119
|
+
// expect(navigationStack.current().operation).to.equal('init');
|
|
120
|
+
|
|
121
|
+
expect(navigationStack.current().pathname).to.equal('/new');
|
|
122
|
+
expect(navigationStack.current().index).to.equal(1);
|
|
123
|
+
|
|
124
|
+
navigationStack.shift(-1);
|
|
125
|
+
|
|
126
|
+
await delay(100);
|
|
127
|
+
|
|
128
|
+
expect(navigationStack.current().pathname).to.equal('/initial');
|
|
129
|
+
expect(navigationStack.current().index).to.equal(0);
|
|
130
|
+
|
|
131
|
+
navigationStack.shift(1);
|
|
132
|
+
|
|
133
|
+
await delay(100);
|
|
134
|
+
|
|
135
|
+
expect(navigationStack.current().pathname).to.equal('/new');
|
|
136
|
+
expect(navigationStack.current().index).to.equal(1);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
describe('NavigationStack.addNavigationBlocker', () => {
|
|
141
|
+
let navigationStack;
|
|
142
|
+
|
|
143
|
+
afterEach(() => {
|
|
144
|
+
// Even if a test errors, the `NavigationStack` should still be stopped
|
|
145
|
+
// in order to remove the potential "popstate" listener so that it doesn't
|
|
146
|
+
// interfere with other tests.
|
|
147
|
+
navigationStack.stop();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('should add/remove navigation blocker', () => {
|
|
151
|
+
navigationStack = new NavigationStack(InMemoryEnvironment);
|
|
152
|
+
|
|
153
|
+
navigationStack.init('/initial');
|
|
154
|
+
|
|
155
|
+
expect(navigationStack.current().pathname).to.equal('/initial');
|
|
156
|
+
|
|
157
|
+
const removeNavigationBlocker = navigationStack.addNavigationBlocker(
|
|
158
|
+
() => true,
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
navigationStack.push('/new');
|
|
162
|
+
expect(navigationStack.current().pathname).to.equal('/initial');
|
|
163
|
+
|
|
164
|
+
removeNavigationBlocker();
|
|
165
|
+
|
|
166
|
+
navigationStack.push('/new');
|
|
167
|
+
expect(navigationStack.current().pathname).to.equal('/new');
|
|
168
|
+
});
|
|
100
169
|
});
|
|
101
170
|
|
|
102
171
|
describe('NavigationStack.subscribe', () => {
|
|
@@ -110,7 +179,7 @@ describe('NavigationStack.subscribe', () => {
|
|
|
110
179
|
});
|
|
111
180
|
|
|
112
181
|
it('should subscribe to location changes', () => {
|
|
113
|
-
navigationStack = new NavigationStack(
|
|
182
|
+
navigationStack = new NavigationStack(InMemoryEnvironment);
|
|
114
183
|
|
|
115
184
|
const listener = sinon.spy();
|
|
116
185
|
|
|
@@ -165,7 +234,7 @@ describe('NavigationStack.subscribe', () => {
|
|
|
165
234
|
it('should subscribe to location changes (WebBrowserSession)', () => {
|
|
166
235
|
window.history.replaceState(null, null, '/initial');
|
|
167
236
|
|
|
168
|
-
navigationStack = new NavigationStack(
|
|
237
|
+
navigationStack = new NavigationStack(WebBrowserEnvironment);
|
|
169
238
|
|
|
170
239
|
const listener = sinon.spy();
|
|
171
240
|
|
|
@@ -198,9 +267,7 @@ describe('NavigationStack.stop()', () => {
|
|
|
198
267
|
sandbox.spy(window, 'addEventListener');
|
|
199
268
|
sandbox.spy(window, 'removeEventListener');
|
|
200
269
|
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
const navigationStack = new NavigationStack(session);
|
|
270
|
+
const navigationStack = new NavigationStack(WebBrowserEnvironment);
|
|
204
271
|
|
|
205
272
|
// This subscription won't be "unsubscribed" by the code.
|
|
206
273
|
// It is expected to be "unsubscribed" automatically on `navigationStack.stop()`
|
|
@@ -237,12 +304,13 @@ describe('NavigationStack', () => {
|
|
|
237
304
|
});
|
|
238
305
|
|
|
239
306
|
it('should support `basePath`', () => {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
navigationStack = new NavigationStack(session, {
|
|
307
|
+
navigationStack = new NavigationStack(InMemoryEnvironment, {
|
|
243
308
|
basePath: '/base',
|
|
244
309
|
});
|
|
245
310
|
|
|
311
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
312
|
+
const session = navigationStack._session;
|
|
313
|
+
|
|
246
314
|
navigationStack.init('/initial');
|
|
247
315
|
|
|
248
316
|
navigationStack.push('/new');
|
|
@@ -257,7 +325,7 @@ describe('NavigationStack', () => {
|
|
|
257
325
|
});
|
|
258
326
|
});
|
|
259
327
|
|
|
260
|
-
describe('NavigationStack (
|
|
328
|
+
describe('NavigationStack (manageScrollPosition: true)', () => {
|
|
261
329
|
let navigationStack;
|
|
262
330
|
|
|
263
331
|
afterEach(() => {
|
|
@@ -270,9 +338,9 @@ describe('NavigationStack (maintainScrollPosition: true)', () => {
|
|
|
270
338
|
navigationStack.stop();
|
|
271
339
|
});
|
|
272
340
|
|
|
273
|
-
it('should support `
|
|
274
|
-
navigationStack = new NavigationStack(
|
|
275
|
-
|
|
341
|
+
it('should support `manageScrollPosition: true` option', async () => {
|
|
342
|
+
navigationStack = new NavigationStack(WebBrowserEnvironment, {
|
|
343
|
+
manageScrollPosition: true,
|
|
276
344
|
});
|
|
277
345
|
|
|
278
346
|
// Start with the "/initial" page.
|
|
@@ -283,7 +351,7 @@ describe('NavigationStack (maintainScrollPosition: true)', () => {
|
|
|
283
351
|
|
|
284
352
|
// "/initial" page rendered.
|
|
285
353
|
// Restore scroll position (no saved scroll position to restore).
|
|
286
|
-
await navigationStack.locationRendered();
|
|
354
|
+
await navigationStack.locationRendered(navigationStack.current());
|
|
287
355
|
|
|
288
356
|
// Create a content <div/> that "overflows" the window so that it becomes scrollable.
|
|
289
357
|
const content = document.createElement('div');
|
|
@@ -301,7 +369,7 @@ describe('NavigationStack (maintainScrollPosition: true)', () => {
|
|
|
301
369
|
// Wait a bit for `ScrollPositionRestoration` to save the scroll position
|
|
302
370
|
// because it does that "asynchronously", i.e. in an "immediate" timeout
|
|
303
371
|
// as a way of "throttling" scroll events.
|
|
304
|
-
await delay(
|
|
372
|
+
await delay(100);
|
|
305
373
|
|
|
306
374
|
// Go to "/new" page.
|
|
307
375
|
navigationStack.push('/new');
|
|
@@ -319,7 +387,7 @@ describe('NavigationStack (maintainScrollPosition: true)', () => {
|
|
|
319
387
|
|
|
320
388
|
// "/new" page rendered.
|
|
321
389
|
// Restore scroll position (no saved scroll position to restore).
|
|
322
|
-
await navigationStack.locationRendered();
|
|
390
|
+
await navigationStack.locationRendered(navigationStack.current());
|
|
323
391
|
|
|
324
392
|
// It should've reset page scroll position.
|
|
325
393
|
expect(window.pageYOffset).to.equal(0);
|
|
@@ -341,7 +409,7 @@ describe('NavigationStack (maintainScrollPosition: true)', () => {
|
|
|
341
409
|
// Wait a bit for `ScrollPositionRestoration` to save the scroll position
|
|
342
410
|
// because it does that "asynchronously", i.e. in an "immediate" timeout
|
|
343
411
|
// as a way of "throttling" scroll events.
|
|
344
|
-
await delay(
|
|
412
|
+
await delay(100);
|
|
345
413
|
|
|
346
414
|
// Register the scrollable container on the "/new" page.
|
|
347
415
|
const untrackScrollableContainer = navigationStack.addScrollableContainer(
|
|
@@ -354,7 +422,7 @@ describe('NavigationStack (maintainScrollPosition: true)', () => {
|
|
|
354
422
|
|
|
355
423
|
// "/new-2" page rendered.
|
|
356
424
|
// Restore scroll position (no saved scroll position to restore).
|
|
357
|
-
await navigationStack.locationRendered();
|
|
425
|
+
await navigationStack.locationRendered(navigationStack.current());
|
|
358
426
|
|
|
359
427
|
// Check that it has reset the scroll position inside the scrollable container.
|
|
360
428
|
expect(scrollableContainer.scrollTop).to.equal(0);
|
|
@@ -366,11 +434,11 @@ describe('NavigationStack (maintainScrollPosition: true)', () => {
|
|
|
366
434
|
navigationStack.shift(-1);
|
|
367
435
|
|
|
368
436
|
// Wait for the web browser to emit a "popstate" event from `window.history.go(-1)` navigation.
|
|
369
|
-
await delay(
|
|
437
|
+
await delay(100);
|
|
370
438
|
|
|
371
439
|
// "/new" page rendered.
|
|
372
440
|
// Restore scroll position.
|
|
373
|
-
await navigationStack.locationRendered();
|
|
441
|
+
await navigationStack.locationRendered(navigationStack.current());
|
|
374
442
|
|
|
375
443
|
// Check that it has restored the scroll position inside the scrollable container.
|
|
376
444
|
expect(scrollableContainer.scrollTop).to.be.closeTo(1000, 0.5);
|
|
@@ -382,7 +450,7 @@ describe('NavigationStack (maintainScrollPosition: true)', () => {
|
|
|
382
450
|
navigationStack.shift(-1);
|
|
383
451
|
|
|
384
452
|
// Wait for the web browser to emit a "popstate" event from `window.history.go(-1)` navigation.
|
|
385
|
-
await delay(
|
|
453
|
+
await delay(100);
|
|
386
454
|
|
|
387
455
|
// The scrollable container is only present at the "/new" or "/new-2" pages so remove it now.
|
|
388
456
|
document.body.removeChild(scrollableContainer);
|
|
@@ -391,7 +459,7 @@ describe('NavigationStack (maintainScrollPosition: true)', () => {
|
|
|
391
459
|
|
|
392
460
|
// "/initial" page rendered.
|
|
393
461
|
// Restore scroll position.
|
|
394
|
-
await navigationStack.locationRendered();
|
|
462
|
+
await navigationStack.locationRendered(navigationStack.current());
|
|
395
463
|
|
|
396
464
|
// Check that it has restored page scroll position.
|
|
397
465
|
expect(window.pageYOffset).to.be.closeTo(1000, 0.5);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import LocationDataStorage from '../../src/data-storage/LocationDataStorage';
|
|
2
|
-
import
|
|
2
|
+
import InMemoryEnvironment from '../../src/environment/InMemoryEnvironment';
|
|
3
|
+
import Session from '../../src/session/Session';
|
|
3
4
|
|
|
4
5
|
describe('LocationDataStorage', () => {
|
|
5
6
|
let session;
|
|
@@ -12,7 +13,7 @@ describe('LocationDataStorage', () => {
|
|
|
12
13
|
beforeEach(() => {
|
|
13
14
|
window.sessionStorage.clear();
|
|
14
15
|
|
|
15
|
-
session = new
|
|
16
|
+
session = new Session(InMemoryEnvironment);
|
|
16
17
|
stateStorage = new LocationDataStorage(session, {
|
|
17
18
|
namespace: 'test',
|
|
18
19
|
});
|
package/test/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import dirtyChai from 'dirty-chai';
|
|
2
2
|
|
|
3
|
+
import { stubWarn } from './shouldWarn';
|
|
4
|
+
|
|
3
5
|
// `dirty-chai` package is used to create functions like `.to.be.true()`
|
|
4
6
|
// from `chai` `expect` properties like `.to.be.true`.
|
|
5
7
|
//
|
|
@@ -18,39 +20,13 @@ srcContext.keys().forEach(srcContext);
|
|
|
18
20
|
const testsContext = require.context('.', true, /\.test\.js$/);
|
|
19
21
|
testsContext.keys().forEach(testsContext);
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
/* eslint-disable no-console */
|
|
23
|
-
sinon.stub(console, 'warn').callsFake((message) => {
|
|
24
|
-
let expected = false;
|
|
25
|
-
|
|
26
|
-
console.warn.expected.forEach((about) => {
|
|
27
|
-
if (message.includes(about)) {
|
|
28
|
-
console.warn.warned[about] = true;
|
|
29
|
-
expected = true;
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
if (expected) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
23
|
+
let unstubWarn;
|
|
36
24
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
console.warn.expected = [];
|
|
42
|
-
console.warn.warned = Object.create(null);
|
|
43
|
-
console.warn.threw = false;
|
|
44
|
-
/* eslint-enable no-console */
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
unstubWarn = stubWarn();
|
|
45
27
|
});
|
|
46
28
|
|
|
47
29
|
afterEach(() => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
console.warn.restore();
|
|
51
|
-
|
|
52
|
-
if (!threw && expected.length) {
|
|
53
|
-
expect(warned).to.have.keys(expected);
|
|
54
|
-
}
|
|
55
|
-
/* eslint-enable no-console */
|
|
30
|
+
unstubWarn();
|
|
31
|
+
unstubWarn = undefined;
|
|
56
32
|
});
|
package/test/index.test.js
CHANGED
|
@@ -11,11 +11,10 @@ describe('index', () => {
|
|
|
11
11
|
expect(exports.parseLocationUrl).to.exist();
|
|
12
12
|
expect(exports.parseInputLocation).to.exist();
|
|
13
13
|
expect(exports.NavigationStack).to.exist();
|
|
14
|
-
expect(exports.
|
|
15
|
-
expect(exports.
|
|
16
|
-
expect(exports.
|
|
17
|
-
expect(exports.
|
|
18
|
-
expect(exports.ServerSideNavigationError).to.exist();
|
|
14
|
+
expect(exports.InMemoryEnvironment).to.exist();
|
|
15
|
+
expect(exports.WebBrowserEnvironment).to.exist();
|
|
16
|
+
expect(exports.ServerSideRenderEnvironment).to.exist();
|
|
17
|
+
expect(exports.ServerSideRedirectError).to.exist();
|
|
19
18
|
expect(exports.NavigationOutOfBoundsError).to.exist();
|
|
20
19
|
});
|
|
21
20
|
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import parseQueryFromSearch from '../src/parseQueryFromSearch';
|
|
2
|
+
|
|
3
|
+
describe('parseQueryFromSearch', () => {
|
|
4
|
+
it('should parse query object from `location.search', () => {
|
|
5
|
+
expect(parseQueryFromSearch('')).to.deep.equal({});
|
|
6
|
+
expect(parseQueryFromSearch('?')).to.deep.equal({});
|
|
7
|
+
expect(parseQueryFromSearch('?a')).to.deep.equal({ a: null });
|
|
8
|
+
expect(parseQueryFromSearch('?=a')).to.deep.equal({});
|
|
9
|
+
expect(parseQueryFromSearch('?a=b')).to.deep.equal({ a: 'b' });
|
|
10
|
+
expect(parseQueryFromSearch('?a=b&c=d')).to.deep.equal({ a: 'b', c: 'd' });
|
|
11
|
+
expect(parseQueryFromSearch('?a=b+c%20d')).to.deep.equal({ a: 'b c d' });
|
|
12
|
+
expect(parseQueryFromSearch('?a=b+c%20d')).to.deep.equal({ a: 'b c d' });
|
|
13
|
+
// Ivalid percent-encoding is ignored.
|
|
14
|
+
expect(parseQueryFromSearch('?a=b%0&c=d')).to.deep.equal({
|
|
15
|
+
a: 'b%0',
|
|
16
|
+
c: 'd',
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import parseQueryString from '../src/parseQueryString';
|
|
2
|
+
|
|
3
|
+
describe('parseQueryString', () => {
|
|
4
|
+
it('should parse query object from a query string', () => {
|
|
5
|
+
expect(parseQueryString('')).to.deep.equal({});
|
|
6
|
+
expect(parseQueryString('a')).to.deep.equal({ a: null });
|
|
7
|
+
expect(parseQueryString('=a')).to.deep.equal({});
|
|
8
|
+
expect(parseQueryString('a=b')).to.deep.equal({ a: 'b' });
|
|
9
|
+
expect(parseQueryString('a=b&c=d')).to.deep.equal({ a: 'b', c: 'd' });
|
|
10
|
+
expect(parseQueryString('a=b+c%20d')).to.deep.equal({ a: 'b c d' });
|
|
11
|
+
expect(parseQueryString('a=b+c%20d')).to.deep.equal({ a: 'b c d' });
|
|
12
|
+
// Ivalid percent-encoding is ignored.
|
|
13
|
+
expect(parseQueryString('a=b%0&c=d')).to.deep.equal({
|
|
14
|
+
a: 'b%0',
|
|
15
|
+
c: 'd',
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -8,7 +8,7 @@ import delay from './delay';
|
|
|
8
8
|
import { setEventListener, triggerEvent } from './mockPageLifecycle';
|
|
9
9
|
import runApp from './runApp';
|
|
10
10
|
import withScrollableContainerAtIndexPageWithDisabledAutomaticScrollPositionRestoration from './withScrollableContainerAtIndexPageWithDisabledAutomaticScrollPositionRestoration';
|
|
11
|
-
import PageLifecycle from '../../src/
|
|
11
|
+
import PageLifecycle from '../../src/environment/lifecycle/page-lifecycle/PageLifecycleInstance';
|
|
12
12
|
|
|
13
13
|
describe('ScrollPositionRestoration', () => {
|
|
14
14
|
let unlisten;
|
|
@@ -130,16 +130,22 @@ describe('ScrollPositionRestoration', () => {
|
|
|
130
130
|
});
|
|
131
131
|
|
|
132
132
|
describe('custom behavior', () => {
|
|
133
|
-
it('should allow scroll
|
|
133
|
+
it('should allow disabling scroll position reset when just the URL query parameters change', (done) => {
|
|
134
134
|
const app = addScrollableContainerWithAnchors(
|
|
135
135
|
createApp({
|
|
136
|
-
|
|
137
|
-
location,
|
|
136
|
+
shouldChangePageScrollPositionOnLocationChange: (
|
|
138
137
|
prevLocation,
|
|
138
|
+
location,
|
|
139
139
|
) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
// Is allowed to set the initial scroll position.
|
|
141
|
+
if (!prevLocation) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
// Can set scroll position if the new location has a different `pathname`.
|
|
145
|
+
// If it has the same `pathame`, the scroll position won't be set
|
|
146
|
+
// and the previous one will be retained, hereby avoiding scroll position "jumping"
|
|
147
|
+
// when simply updating URL query parameters.
|
|
148
|
+
return prevLocation.pathname !== location.pathname;
|
|
143
149
|
},
|
|
144
150
|
}),
|
|
145
151
|
);
|
|
@@ -151,23 +157,30 @@ describe('ScrollPositionRestoration', () => {
|
|
|
151
157
|
() => {
|
|
152
158
|
scrollTop(window, 5000);
|
|
153
159
|
delay(() => {
|
|
160
|
+
// Add URL query parameters to the current URL.
|
|
161
|
+
// This shouldn't result in a scroll position reset.
|
|
154
162
|
app.goTo('/detail?key=value');
|
|
155
163
|
});
|
|
156
164
|
},
|
|
157
165
|
() => {
|
|
166
|
+
// Check that the scroll position hasn't been reset.
|
|
167
|
+
//
|
|
158
168
|
// Here, it said "expected 4999.7998046875 to equal 5000".
|
|
159
169
|
// Using `.to.be.closeTo()` here instead of `.to.equal()` to work around this browser issue.
|
|
160
170
|
expect(scrollTop(window)).to.be.closeTo(5000, 0.5);
|
|
171
|
+
// Navigate to some other completely unrelated URL.
|
|
161
172
|
app.goTo('/');
|
|
162
173
|
},
|
|
163
174
|
() => {
|
|
175
|
+
// Check that the scroll position has been reset because it's now a completely
|
|
176
|
+
// different URL and not just the old one with new query parameters.
|
|
164
177
|
expect(scrollTop(window)).to.equal(0);
|
|
165
178
|
done();
|
|
166
179
|
},
|
|
167
180
|
]);
|
|
168
181
|
});
|
|
169
182
|
|
|
170
|
-
it('should
|
|
183
|
+
it('should stop saving scroll position when `disableSavingScrollPosition()` is called, and should resume saving scroll position when `enableSavingScrollPosition()` is called', (done) => {
|
|
171
184
|
const app = addScrollableContainerWithAnchors(createApp());
|
|
172
185
|
|
|
173
186
|
unlisten = runApp(app, [
|
|
@@ -205,27 +218,34 @@ describe('ScrollPositionRestoration', () => {
|
|
|
205
218
|
]);
|
|
206
219
|
});
|
|
207
220
|
|
|
208
|
-
it('should allow
|
|
221
|
+
it('should allow overriding the default source for reading a previously-saved scroll position', (done) => {
|
|
209
222
|
const app = addScrollableContainerWithAnchors(
|
|
210
223
|
createApp({
|
|
224
|
+
// Read a previously-saved scroll position not from the default "data storage"
|
|
225
|
+
// but from this "mock-up" which always returns the same scroll position.
|
|
211
226
|
getSavedPageScrollPositionOnLocationChange: () => [10, 20],
|
|
212
227
|
}),
|
|
213
228
|
);
|
|
214
229
|
|
|
215
230
|
unlisten = runApp(app, [
|
|
216
231
|
() => {
|
|
232
|
+
// Go to some random page.
|
|
217
233
|
app.goTo('/detail');
|
|
218
234
|
},
|
|
219
235
|
() => {
|
|
236
|
+
// Go to some random page again, for no reason.
|
|
220
237
|
app.goTo('/');
|
|
221
238
|
},
|
|
222
239
|
() => {
|
|
240
|
+
// Check that the "mock-up" scroll position has been restored.
|
|
241
|
+
//
|
|
223
242
|
// Here, it said "expected 9.966666221618652 to equal 10".
|
|
224
243
|
// Using `.to.be.closeTo()` here instead of `.to.equal()` to work around this browser issue.
|
|
225
244
|
expect(scrollLeft(window)).to.be.closeTo(10, 0.5);
|
|
226
245
|
// Here, it said "19.933332443237305 to equal 20".
|
|
227
246
|
// Using `.to.be.closeTo()` here instead of `.to.equal()` to work around this browser issue.
|
|
228
247
|
expect(scrollTop(window)).to.be.closeTo(20, 0.5);
|
|
248
|
+
// Test finished.
|
|
229
249
|
done();
|
|
230
250
|
},
|
|
231
251
|
]);
|
|
@@ -290,7 +310,7 @@ describe('ScrollPositionRestoration', () => {
|
|
|
290
310
|
it('should follow browser scroll behavior', (done) => {
|
|
291
311
|
const { container, ...app } = addScrollableContainer(
|
|
292
312
|
createApp({
|
|
293
|
-
|
|
313
|
+
shouldChangePageScrollPositionOnLocationChange: () => false,
|
|
294
314
|
}),
|
|
295
315
|
);
|
|
296
316
|
|
|
@@ -325,7 +345,7 @@ describe('ScrollPositionRestoration', () => {
|
|
|
325
345
|
const { container, ...app } =
|
|
326
346
|
withScrollableContainerAtIndexPageWithDisabledAutomaticScrollPositionRestoration(
|
|
327
347
|
createApp({
|
|
328
|
-
|
|
348
|
+
shouldChangePageScrollPositionOnLocationChange: () => false,
|
|
329
349
|
}),
|
|
330
350
|
);
|
|
331
351
|
|
|
@@ -359,7 +379,7 @@ describe('ScrollPositionRestoration', () => {
|
|
|
359
379
|
it('should save element scroll position on scroll event, i.e. before navigation is even attempted', (done) => {
|
|
360
380
|
const app1 = addScrollableContainer(
|
|
361
381
|
createApp({
|
|
362
|
-
|
|
382
|
+
shouldChangePageScrollPositionOnLocationChange: () => false,
|
|
363
383
|
}),
|
|
364
384
|
);
|
|
365
385
|
|
|
@@ -374,8 +394,9 @@ describe('ScrollPositionRestoration', () => {
|
|
|
374
394
|
const app2 = addScrollableContainer(
|
|
375
395
|
createApp({
|
|
376
396
|
// Restore the data of the session of `app1`.
|
|
397
|
+
// That data includes the scroll position.
|
|
377
398
|
sessionKey: app1.getSessionKey(),
|
|
378
|
-
|
|
399
|
+
shouldChangePageScrollPositionOnLocationChange: () => false,
|
|
379
400
|
}),
|
|
380
401
|
);
|
|
381
402
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import NavigationStack from '../../src/NavigationStack';
|
|
2
|
+
import WebBrowserEnvironment from '../../src/environment/WebBrowserEnvironment';
|
|
2
3
|
import ScrollPositionRestoration from '../../src/scroll-position/ScrollPositionRestoration';
|
|
3
|
-
import WebBrowserSession from '../../src/session/WebBrowserSession';
|
|
4
4
|
|
|
5
5
|
// Creates a website with `ScrollPositionRestoration`.
|
|
6
6
|
export default function createApp({
|
|
7
7
|
sessionKey,
|
|
8
|
-
|
|
8
|
+
shouldChangePageScrollPositionOnLocationChange,
|
|
9
9
|
getSavedPageScrollPositionOnLocationChange,
|
|
10
10
|
} = {}) {
|
|
11
11
|
let currentLocation = null;
|
|
@@ -56,17 +56,17 @@ export default function createApp({
|
|
|
56
56
|
throw new Error('Only one `listener` is allowed in tests');
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
navigationStack = new NavigationStack(WebBrowserEnvironment);
|
|
60
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
61
|
+
session = navigationStack._session;
|
|
60
62
|
// There's this one test that restores data of a session of a previous app
|
|
61
63
|
// and for that the new session just has to have the same key in order to read
|
|
62
64
|
// the previous app's session data from the environment storage.
|
|
63
65
|
if (sessionKey) {
|
|
64
66
|
session.key = sessionKey;
|
|
65
67
|
}
|
|
66
|
-
navigationStack = new NavigationStack(session);
|
|
67
68
|
scrollPositionRestoration = new ScrollPositionRestoration(session, {
|
|
68
|
-
|
|
69
|
-
shouldSetPageScrollPositionOnLocationChange,
|
|
69
|
+
shouldChangePageScrollPositionOnLocationChange,
|
|
70
70
|
_getSavedPageScrollPositionOnLocationChange:
|
|
71
71
|
getSavedPageScrollPositionOnLocationChange,
|
|
72
72
|
});
|
|
@@ -93,8 +93,8 @@ export default function createApp({
|
|
|
93
93
|
// Registers a scrollable container on a page.
|
|
94
94
|
function registerScrollableContainer(key, element, options) {
|
|
95
95
|
return scrollPositionRestoration.addScrollableContainer(key, element, {
|
|
96
|
-
|
|
97
|
-
options && options.
|
|
96
|
+
shouldChangeScrollPositionOnLocationChange:
|
|
97
|
+
options && options.shouldChangeScrollPositionOnLocationChange,
|
|
98
98
|
_getSavedScrollPositionOnLocationChange:
|
|
99
99
|
options && options.getSavedScrollPositionOnLocationChange,
|
|
100
100
|
});
|
|
@@ -18,9 +18,9 @@ export default function withScrollableContainerAtIndexPageWithDisabledAutomaticS
|
|
|
18
18
|
let unregisterScrollableContainer;
|
|
19
19
|
|
|
20
20
|
function listen(listener) {
|
|
21
|
-
function
|
|
22
|
-
location,
|
|
21
|
+
function shouldChangeScrollableContainerScrollPositionOnLocationChange(
|
|
23
22
|
prevLocation,
|
|
23
|
+
location,
|
|
24
24
|
) {
|
|
25
25
|
// Disable the automatic scroll position restoration on "back" navigation
|
|
26
26
|
// to check that it automatically restores scroll position when calling
|
|
@@ -37,8 +37,8 @@ export default function withScrollableContainerAtIndexPageWithDisabledAutomaticS
|
|
|
37
37
|
'container',
|
|
38
38
|
container,
|
|
39
39
|
{
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
shouldChangeScrollPositionOnLocationChange:
|
|
41
|
+
shouldChangeScrollableContainerScrollPositionOnLocationChange,
|
|
42
42
|
},
|
|
43
43
|
);
|
|
44
44
|
}
|