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
|
@@ -2,86 +2,175 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.default = void 0;
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
5
|
+
var _basePath = require("./basePath");
|
|
6
|
+
var _LocationDataStorage = _interopRequireDefault(require("./data-storage/LocationDataStorage"));
|
|
7
|
+
var _getLocationFromInternalLocation = _interopRequireDefault(require("./getLocationFromInternalLocation"));
|
|
8
|
+
var _isPromise = _interopRequireDefault(require("./isPromise"));
|
|
9
|
+
var _navigationBlockers = require("./navigationBlockers");
|
|
10
|
+
var _navigationBlockersEvaluation = require("./navigationBlockersEvaluation");
|
|
11
|
+
var _parseInputLocation = _interopRequireDefault(require("./parseInputLocation"));
|
|
9
12
|
var _ScrollPositionRestoration = _interopRequireDefault(require("./scroll-position/ScrollPositionRestoration"));
|
|
10
|
-
|
|
13
|
+
var _Session = _interopRequireDefault(require("./session/Session"));
|
|
11
14
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
-
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
13
|
-
function getCreateMiddlewaresOptions(navigationStackOptions) {
|
|
14
|
-
if (!navigationStackOptions) {
|
|
15
|
-
return undefined;
|
|
16
|
-
}
|
|
17
|
-
// eslint-disable-next-line no-unused-vars
|
|
18
|
-
const restOptions = _objectWithoutPropertiesLoose(navigationStackOptions, _excluded);
|
|
19
|
-
return restOptions;
|
|
20
|
-
}
|
|
21
15
|
class NavigationStack {
|
|
22
|
-
constructor(
|
|
23
|
-
|
|
16
|
+
constructor(Environment, {
|
|
17
|
+
basePath,
|
|
18
|
+
manageScrollPosition,
|
|
19
|
+
scrollPositionSetter
|
|
20
|
+
} = {}) {
|
|
21
|
+
// Allows temporarily ignoring location update events.
|
|
22
|
+
this._doAndIgnoreLocationUpdates = func => {
|
|
23
|
+
this._ignoreLocationUpdates = true;
|
|
24
|
+
func();
|
|
25
|
+
this._ignoreLocationUpdates = false;
|
|
26
|
+
};
|
|
27
|
+
// Create a session.
|
|
28
|
+
this._session = new _Session.default(Environment);
|
|
29
|
+
|
|
30
|
+
// Base path, if used.
|
|
31
|
+
this._basePath = basePath;
|
|
32
|
+
|
|
33
|
+
// Create location data storage.
|
|
34
|
+
this.dataStorage = new _LocationDataStorage.default(this._session, {
|
|
35
|
+
namespace: 'navigation-stack'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Allows temporarily ignoring location update events when set to `true`.
|
|
39
|
+
this._ignoreLocationUpdates = false;
|
|
24
40
|
|
|
25
|
-
//
|
|
26
|
-
|
|
41
|
+
// Subscribe to location updates.
|
|
42
|
+
// * Ignores location updates if `_ignoreLocationUpdates` flag is temporarily set.
|
|
43
|
+
// * Runs navigation blockers to see if the location update should be reverted.
|
|
44
|
+
// * Updates `this._location` if the update wasn't ignored or blocked.
|
|
45
|
+
this._unsubscribe = this._session.subscribe(location => {
|
|
46
|
+
// If this location update shouldn't be temporarily ignored.
|
|
47
|
+
if (!this._ignoreLocationUpdates) {
|
|
48
|
+
// Remove `basePath` from `location`.
|
|
49
|
+
location = (0, _basePath.removeBasePath)(location, this._basePath);
|
|
50
|
+
|
|
51
|
+
// See if the location update should've been blocked.
|
|
52
|
+
// If it should've, it will automatically "rewind" it.
|
|
53
|
+
const result = (0, _navigationBlockersEvaluation.blockNonProgrammaticNavigationIfRequired)(location, this._session, this._doAndIgnoreLocationUpdates);
|
|
54
|
+
const onResult = blocked => {
|
|
55
|
+
if (!blocked) {
|
|
56
|
+
// Update `this._location`.
|
|
57
|
+
// Since it's gonna be returned from the public `this.current()` method,
|
|
58
|
+
// convert it from `LocationInternal` to `Location`.
|
|
59
|
+
this._location = (0, _getLocationFromInternalLocation.default)(location);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
if ((0, _isPromise.default)(result)) {
|
|
63
|
+
result.then(onResult);
|
|
64
|
+
} else {
|
|
65
|
+
onResult(result);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
27
69
|
|
|
28
70
|
// Create `ScrollPositionRestoration`.
|
|
29
|
-
if (
|
|
30
|
-
this._scrollPositionRestoration = new _ScrollPositionRestoration.default(
|
|
71
|
+
if (manageScrollPosition) {
|
|
72
|
+
this._scrollPositionRestoration = new _ScrollPositionRestoration.default(this._session,
|
|
73
|
+
// Custom `ScrollPositionSetter`.
|
|
74
|
+
{
|
|
75
|
+
scrollPositionSetter
|
|
76
|
+
});
|
|
31
77
|
}
|
|
32
78
|
}
|
|
79
|
+
|
|
80
|
+
// Subscribes to any changes of the current location.
|
|
81
|
+
// The first subscriber is always the `NavigationStack` itself
|
|
82
|
+
// because its listener is what drives the actual navigation.
|
|
83
|
+
// Any additional application-specific listeners could be added, if required.
|
|
84
|
+
subscribe(listener) {
|
|
85
|
+
// `NavigationStack.subscribe()` is simply a proxy to `Session.subscribe()`
|
|
86
|
+
// with the only convenience feature that it "normalizes" the `location` argument.
|
|
87
|
+
return this._session.subscribe(locationInternal => {
|
|
88
|
+
listener((0, _getLocationFromInternalLocation.default)(locationInternal));
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
addNavigationBlocker(blocker) {
|
|
92
|
+
return (0, _navigationBlockers.addNavigationBlocker)(this._session, blocker);
|
|
93
|
+
}
|
|
33
94
|
addScrollableContainer(scrollableContainerKey, scrollableContainer) {
|
|
34
95
|
if (!this._scrollPositionRestoration) {
|
|
35
|
-
throw new Error('`
|
|
96
|
+
throw new Error('`manageScrollPosition: true` option not passed');
|
|
36
97
|
}
|
|
37
98
|
return this._scrollPositionRestoration.addScrollableContainer(scrollableContainerKey, scrollableContainer);
|
|
38
99
|
}
|
|
39
|
-
subscribe(listener) {
|
|
40
|
-
// Subscribe to any potential Redux state changes.
|
|
41
|
-
return this._store.subscribe(() => {
|
|
42
|
-
// Initially, calls the listener when setting the initial location.
|
|
43
|
-
// After that, calls it on any location change.
|
|
44
|
-
const location = this.current();
|
|
45
|
-
if (!this._latestLocation || location !== this._latestLocation) {
|
|
46
|
-
this._latestLocation = location;
|
|
47
|
-
listener(location);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
100
|
init(initialLocation) {
|
|
52
|
-
if (this.
|
|
101
|
+
if (this._location) {
|
|
53
102
|
throw new Error('Already initialized');
|
|
54
103
|
}
|
|
55
|
-
this.
|
|
56
|
-
|
|
104
|
+
this._session.start(initialLocation && this._parseInputLocation(initialLocation));
|
|
105
|
+
if (this._scrollPositionRestoration) {
|
|
106
|
+
this._scrollPositionRestoration.start();
|
|
107
|
+
}
|
|
57
108
|
}
|
|
58
109
|
current() {
|
|
59
|
-
|
|
110
|
+
// TypeScript definition of the `.current()` method tells that it always returns
|
|
111
|
+
// some non-`undefined` location.
|
|
112
|
+
// But `this._location` is `undefined` until `.init(initialLocation?)` is called.
|
|
113
|
+
// To work around that limitation, it simply throws if `.current()` is called before `.init()`.
|
|
114
|
+
if (!this._location) {
|
|
115
|
+
throw new Error('Not initialized');
|
|
116
|
+
}
|
|
117
|
+
return this._location;
|
|
60
118
|
}
|
|
61
119
|
push(location) {
|
|
62
|
-
this.
|
|
120
|
+
this._navigate('push', location);
|
|
63
121
|
}
|
|
64
122
|
replace(location) {
|
|
65
|
-
this.
|
|
123
|
+
this._navigate('replace', location);
|
|
124
|
+
}
|
|
125
|
+
_navigate(operation, location) {
|
|
126
|
+
const toLocation = this._parseInputLocation(location);
|
|
127
|
+
const result = (0, _navigationBlockersEvaluation.blockProgrammaticNavigationIfRequired)(toLocation, this._session);
|
|
128
|
+
const onResult = blocked => {
|
|
129
|
+
if (!blocked) {
|
|
130
|
+
this._session.navigate(operation, toLocation);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
if ((0, _isPromise.default)(result)) {
|
|
134
|
+
result.then(onResult);
|
|
135
|
+
} else {
|
|
136
|
+
onResult(result);
|
|
137
|
+
}
|
|
66
138
|
}
|
|
67
139
|
shift(delta) {
|
|
68
|
-
this.
|
|
140
|
+
this._session.shift(delta);
|
|
69
141
|
}
|
|
70
142
|
stop() {
|
|
143
|
+
if (!this._unsubscribe) {
|
|
144
|
+
throw new Error('Already stopped');
|
|
145
|
+
}
|
|
146
|
+
this._unsubscribe();
|
|
147
|
+
this._unsubscribe = undefined;
|
|
148
|
+
|
|
149
|
+
// Even if it calls `unsubscribe()` function above, any other subscriptions
|
|
150
|
+
// would still stay. We're not talking about `navigationStack.subscribe()`
|
|
151
|
+
// subscriptions because those don't really matter in terms of cleaning them up:
|
|
152
|
+
// those're just Redux store subscriptions that don't have any side effects.
|
|
153
|
+
// Subscriptions we're talking here are `Session`'s own subscription
|
|
154
|
+
// via `session.subscribe()` and any hypothetical manual `session.subscribe()`
|
|
155
|
+
// calls that could be made by the application code for whatever purpose.
|
|
156
|
+
// Both of those should be cleared.
|
|
157
|
+
// To work around that, `.stop()` function removes all subscriptions.
|
|
158
|
+
this._session.stop();
|
|
159
|
+
(0, _navigationBlockers.removeAllNavigationBlockers)(this._session);
|
|
71
160
|
if (this._scrollPositionRestoration) {
|
|
72
161
|
this._scrollPositionRestoration.stop();
|
|
73
162
|
}
|
|
74
|
-
this._store.dispatch(_Actions.default.stop());
|
|
75
163
|
}
|
|
76
|
-
locationRendered() {
|
|
77
|
-
if (this._scrollPositionRestoration) {
|
|
78
|
-
|
|
79
|
-
if (!location) {
|
|
80
|
-
throw new Error('Not initialized');
|
|
81
|
-
}
|
|
82
|
-
return this._scrollPositionRestoration.locationRendered(location);
|
|
164
|
+
locationRendered(location) {
|
|
165
|
+
if (!this._scrollPositionRestoration) {
|
|
166
|
+
throw new Error('`manageScrollPosition: true` option not passed');
|
|
83
167
|
}
|
|
84
|
-
return
|
|
168
|
+
return this._scrollPositionRestoration.locationRendered(location);
|
|
169
|
+
}
|
|
170
|
+
_parseInputLocation(inputLocation) {
|
|
171
|
+
// Parse input location (string or incomplete object) to a proper `location` object.
|
|
172
|
+
// Add `basePath` to `location`.
|
|
173
|
+
return (0, _basePath.addBasePath)((0, _parseInputLocation.default)(inputLocation), this._basePath);
|
|
85
174
|
}
|
|
86
175
|
}
|
|
87
176
|
exports.default = NavigationStack;
|
|
@@ -10,6 +10,7 @@ class DataStorage {
|
|
|
10
10
|
throw new Error('`DataStorage` requires a `session.key`');
|
|
11
11
|
}
|
|
12
12
|
this._sessionKey = session.key;
|
|
13
|
+
this._log = session.environment.log;
|
|
13
14
|
this._dataStorage = session.environment.dataStorage;
|
|
14
15
|
this._namespace = namespace;
|
|
15
16
|
}
|
|
@@ -26,8 +27,8 @@ class DataStorage {
|
|
|
26
27
|
// junk into sessionStorage under our namespace.
|
|
27
28
|
return JSON.parse(value);
|
|
28
29
|
} catch (error) {
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
this._log.error('[navigation-stack] Could not read data from storage');
|
|
31
|
+
this._log.error(error);
|
|
31
32
|
|
|
32
33
|
// Pretend that the entry doesn't exist.
|
|
33
34
|
return undefined;
|
|
@@ -40,8 +41,8 @@ class DataStorage {
|
|
|
40
41
|
this._dataStorage.remove(storageKey);
|
|
41
42
|
} catch (error) {
|
|
42
43
|
// No need to handle errors here.
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
this._log.error('[navigation-stack] Could not delete data from storage');
|
|
45
|
+
this._log.error(error);
|
|
45
46
|
}
|
|
46
47
|
return;
|
|
47
48
|
}
|
|
@@ -54,8 +55,8 @@ class DataStorage {
|
|
|
54
55
|
} catch (error) {
|
|
55
56
|
// No need to handle errors here either. If it didn't work, it didn't
|
|
56
57
|
// work. We make no guarantees about actually saving the value.
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
this._log.error('[navigation-stack] Could not save data in storage');
|
|
59
|
+
this._log.error(error);
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -3,11 +3,17 @@
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.default = void 0;
|
|
5
5
|
var _InMemoryDataStorage = _interopRequireDefault(require("./data-storage/InMemoryDataStorage"));
|
|
6
|
+
var _InMemorySessionLifecycle = _interopRequireDefault(require("./lifecycle/InMemorySessionLifecycle"));
|
|
7
|
+
var _InMemoryLog = _interopRequireDefault(require("./log/InMemoryLog"));
|
|
8
|
+
var _InMemoryNavigation = _interopRequireDefault(require("./navigation/InMemoryNavigation"));
|
|
6
9
|
var _InMemoryScrollPosition = _interopRequireDefault(require("./scroll-position/InMemoryScrollPosition"));
|
|
7
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
11
|
class InMemoryEnvironment {
|
|
9
12
|
constructor() {
|
|
10
13
|
this.dataStorage = new _InMemoryDataStorage.default();
|
|
14
|
+
this.log = new _InMemoryLog.default();
|
|
15
|
+
this.lifecycle = new _InMemorySessionLifecycle.default();
|
|
16
|
+
this.navigation = new _InMemoryNavigation.default();
|
|
11
17
|
this.scrollPosition = new _InMemoryScrollPosition.default();
|
|
12
18
|
}
|
|
13
19
|
}
|
package/lib/cjs/{session/ServerSideRenderSession.js → environment/ServerSideRenderEnvironment.js}
RENAMED
|
@@ -2,16 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.default = void 0;
|
|
5
|
-
var
|
|
5
|
+
var _InMemoryEnvironment = _interopRequireDefault(require("./InMemoryEnvironment"));
|
|
6
6
|
var _ServerSideNavigation = _interopRequireDefault(require("./navigation/ServerSideNavigation"));
|
|
7
7
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
8
|
// `ServerSideRenderSession` is just a `InMemorySession` that specifically prohibits any navigation.
|
|
9
|
-
class
|
|
9
|
+
class ServerSideRenderEnvironment extends _InMemoryEnvironment.default {
|
|
10
10
|
constructor() {
|
|
11
|
-
super(
|
|
12
|
-
|
|
13
|
-
});
|
|
11
|
+
super();
|
|
12
|
+
this.navigation = new _ServerSideNavigation.default();
|
|
14
13
|
}
|
|
15
14
|
}
|
|
16
|
-
exports.default =
|
|
15
|
+
exports.default = ServerSideRenderEnvironment;
|
|
17
16
|
module.exports = exports.default;
|
|
@@ -3,12 +3,18 @@
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.default = void 0;
|
|
5
5
|
var _WebBrowserDataStorage = _interopRequireDefault(require("./data-storage/WebBrowserDataStorage"));
|
|
6
|
+
var _WebBrowserSessionLifecycle = _interopRequireDefault(require("./lifecycle/WebBrowserSessionLifecycle"));
|
|
7
|
+
var _WebBrowserLog = _interopRequireDefault(require("./log/WebBrowserLog"));
|
|
8
|
+
var _WebBrowserNavigation = _interopRequireDefault(require("./navigation/WebBrowserNavigation"));
|
|
6
9
|
var _WebBrowserScrollPosition = _interopRequireDefault(require("./scroll-position/WebBrowserScrollPosition"));
|
|
7
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
11
|
class WebBrowserEnvironment {
|
|
9
12
|
constructor() {
|
|
10
13
|
this.dataStorage = new _WebBrowserDataStorage.default();
|
|
11
14
|
this.scrollPosition = new _WebBrowserScrollPosition.default();
|
|
15
|
+
this.lifecycle = new _WebBrowserSessionLifecycle.default();
|
|
16
|
+
this.log = new _WebBrowserLog.default();
|
|
17
|
+
this.navigation = new _WebBrowserNavigation.default();
|
|
12
18
|
}
|
|
13
19
|
}
|
|
14
20
|
exports.default = WebBrowserEnvironment;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
const DEBUG_ENABLED = false;
|
|
6
|
+
class InMemoryLog {
|
|
7
|
+
debug(...args) {
|
|
8
|
+
if (DEBUG_ENABLED) {
|
|
9
|
+
// eslint-disable-next-line no-console
|
|
10
|
+
console.log(...args);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
warn(...args) {
|
|
14
|
+
// eslint-disable-next-line no-console
|
|
15
|
+
console.warn(...args);
|
|
16
|
+
}
|
|
17
|
+
error(...args) {
|
|
18
|
+
// eslint-disable-next-line no-console
|
|
19
|
+
console.error(...args);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.default = InMemoryLog;
|
|
23
|
+
module.exports = exports.default;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
class WebBrowserLog {
|
|
6
|
+
debug(...args) {
|
|
7
|
+
if (window.NAVIGATION_STACK_DEBUG_ENABLED) {
|
|
8
|
+
// eslint-disable-next-line no-console
|
|
9
|
+
console.log(...args);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
warn(...args) {
|
|
13
|
+
// eslint-disable-next-line no-console
|
|
14
|
+
console.warn(...args);
|
|
15
|
+
}
|
|
16
|
+
error(...args) {
|
|
17
|
+
// eslint-disable-next-line no-console
|
|
18
|
+
console.error(...args);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.default = WebBrowserLog;
|
|
22
|
+
module.exports = exports.default;
|
|
@@ -10,12 +10,23 @@ class InMemoryNavigation {
|
|
|
10
10
|
this._stack = [];
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
// Subscribes to any "asynchronous" changes of the current location,
|
|
14
|
+
// "asynchronous" changes being ones that happen out-of-sync with the code
|
|
15
|
+
// that might have potentially triggered those changes.
|
|
16
|
+
//
|
|
17
|
+
// For example, in a web browser, "Back"/"Forward" navigation happens out-of-sync
|
|
18
|
+
// with the code that calls `window.pushState()` or `window.replaceState()` function.
|
|
19
|
+
//
|
|
20
|
+
// Additionally, in a web browser, "Back"/"Forward" navigation could be triggered
|
|
21
|
+
// outside of the application code by user clicking those "Back"/"Forward" buttons manually
|
|
22
|
+
// in their web browser.
|
|
23
|
+
//
|
|
13
24
|
// eslint-disable-next-line no-unused-vars
|
|
14
|
-
|
|
15
|
-
// `InMemoryNavigation`
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
25
|
+
subscribeToAsyncrhonousLocationUpdates(listener) {
|
|
26
|
+
// `InMemoryNavigation` location changes are always "synchronous"
|
|
27
|
+
// with the code that initiated such changes, i.e. it always performs
|
|
28
|
+
// any navigation immediately at the time such navigation is triggered in code.
|
|
29
|
+
// Hence, this function doesn't have to "subscribe" to anything, so it's a "no op".
|
|
19
30
|
return () => {};
|
|
20
31
|
}
|
|
21
32
|
init(initialLocation, {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.default = void 0;
|
|
5
|
-
var
|
|
5
|
+
var _ServerSideRedirectError = _interopRequireDefault(require("./error/ServerSideRedirectError"));
|
|
6
6
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
7
|
/* eslint-disable no-underscore-dangle, max-classes-per-file */
|
|
8
8
|
|
|
@@ -21,12 +21,21 @@ class ServerSideNavigation {
|
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
// Subscribes to any "asynchronous" changes of the current location,
|
|
25
|
+
// "asynchronous" changes being ones that happen out-of-sync with the code
|
|
26
|
+
// that might have potentially triggered those changes.
|
|
27
|
+
//
|
|
28
|
+
// For example, in a web browser, "Back"/"Forward" navigation happens out-of-sync
|
|
29
|
+
// with the code that calls `window.pushState()` or `window.replaceState()` function.
|
|
30
|
+
//
|
|
31
|
+
// Additionally, in a web browser, "Back"/"Forward" navigation could be triggered
|
|
32
|
+
// outside of the application code by user clicking those "Back"/"Forward" buttons manually
|
|
33
|
+
// in their web browser.
|
|
34
|
+
//
|
|
24
35
|
// eslint-disable-next-line no-unused-vars
|
|
25
|
-
|
|
26
|
-
// `ServerSideNavigation`
|
|
27
|
-
//
|
|
28
|
-
// So no asynchronous listener would ever be called
|
|
29
|
-
// due to no asynchronous events being dispatched.
|
|
36
|
+
subscribeToAsyncrhonousLocationUpdates(listener) {
|
|
37
|
+
// `ServerSideNavigation` location changes are prohibited, so they couldn't happen.
|
|
38
|
+
// Hence, this function doesn't have to "subscribe" to anything, so it's a "no op".
|
|
30
39
|
return () => {};
|
|
31
40
|
}
|
|
32
41
|
|
|
@@ -37,7 +46,7 @@ class ServerSideNavigation {
|
|
|
37
46
|
index,
|
|
38
47
|
delta
|
|
39
48
|
}) {
|
|
40
|
-
throw new
|
|
49
|
+
throw new _ServerSideRedirectError.default(location);
|
|
41
50
|
}
|
|
42
51
|
|
|
43
52
|
// eslint-disable-next-line no-unused-vars
|
|
@@ -53,15 +53,28 @@ class WebBrowserNavigation {
|
|
|
53
53
|
this._currentLocationIndex = NO_LOCATION_INDEX;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
// Subscribes to changes
|
|
56
|
+
// Subscribes to any "asynchronous" changes of the current location,
|
|
57
|
+
// "asynchronous" changes being ones that happen out-of-sync with the code
|
|
58
|
+
// that might have potentially triggered those changes.
|
|
59
|
+
//
|
|
60
|
+
// For example, in a web browser, "Back"/"Forward" navigation happens out-of-sync
|
|
61
|
+
// with the code that calls `window.pushState()` or `window.replaceState()` function.
|
|
62
|
+
//
|
|
63
|
+
// Additionally, in a web browser, "Back"/"Forward" navigation could be triggered
|
|
64
|
+
// outside of the application code by user clicking those "Back"/"Forward" buttons manually
|
|
65
|
+
// in their web browser.
|
|
66
|
+
//
|
|
57
67
|
// Returns an `unsubscribe()` function which is "idempotent", i.e. it can be called multiple times.
|
|
58
|
-
|
|
68
|
+
//
|
|
69
|
+
subscribeToAsyncrhonousLocationUpdates(listener) {
|
|
59
70
|
const onPopState = () => {
|
|
60
71
|
// If "popstate" event is received before navigation is initialized,
|
|
61
|
-
// ignore such "popstate" event.
|
|
72
|
+
// ignore such "popstate" event. Such "ignore" behavior is logical from
|
|
73
|
+
// the application code's point of view: it doesn't expect any navigation events
|
|
74
|
+
// to be recorded before it has initialized the navigation.
|
|
62
75
|
// And besides, `this._currentLocationIndex` is not defined in such conditions.
|
|
63
76
|
if (this._currentLocationIndex === NO_LOCATION_INDEX) {
|
|
64
|
-
throw new Error('Received a "popstate" event before
|
|
77
|
+
throw new Error('Received a "popstate" event before finished initializing navigation');
|
|
65
78
|
}
|
|
66
79
|
const prevIndex = this._currentLocationIndex;
|
|
67
80
|
const {
|
|
@@ -92,6 +105,16 @@ class WebBrowserNavigation {
|
|
|
92
105
|
this._subscribed = false;
|
|
93
106
|
};
|
|
94
107
|
}
|
|
108
|
+
|
|
109
|
+
// When run in a web browser, it could not only "start" a new navigation session
|
|
110
|
+
// but also "resume" a previously-started navigation session. That could happen
|
|
111
|
+
// when the user refreshes a page in a web browser which still retains
|
|
112
|
+
// the previous navigation session's data but at the same time restarts
|
|
113
|
+
// the javascript code from scratch.
|
|
114
|
+
//
|
|
115
|
+
// So this `init()` method handles both cases: when there's previous navigation session's data
|
|
116
|
+
// that should be restored and when there's no previous navigation session's data.
|
|
117
|
+
//
|
|
95
118
|
init(initialLocation, {
|
|
96
119
|
operation,
|
|
97
120
|
key,
|
|
@@ -108,7 +131,8 @@ class WebBrowserNavigation {
|
|
|
108
131
|
// by calling `window.history.replaceState()` on page load.
|
|
109
132
|
// Otherwise, `window.history.state` would be `null` for the initial location
|
|
110
133
|
// and there'd be no place to store the additional properties of the initial location
|
|
111
|
-
// such as `location.key`.
|
|
134
|
+
// such as `location.key`. Without `location.key` always being present the initial location object,
|
|
135
|
+
// there'd be a bug of incorrect scroll position being set on the initial location URL in some scenarios:
|
|
112
136
|
// https://github.com/taion/scroll-behavior/issues/215
|
|
113
137
|
//
|
|
114
138
|
// If the user opens the initial page for the first time, `window.history.state` will be `null`.
|
|
@@ -122,7 +146,7 @@ class WebBrowserNavigation {
|
|
|
122
146
|
index
|
|
123
147
|
};
|
|
124
148
|
// Call `history.replaceState()`.
|
|
125
|
-
this.
|
|
149
|
+
this._navigateToLocationAndKeepItsAdditionalPropertiesInHistory(initialLocation, additionalProperties, delta);
|
|
126
150
|
}
|
|
127
151
|
this._currentLocationIndex = index;
|
|
128
152
|
|
|
@@ -142,7 +166,7 @@ class WebBrowserNavigation {
|
|
|
142
166
|
key,
|
|
143
167
|
index
|
|
144
168
|
};
|
|
145
|
-
this.
|
|
169
|
+
this._navigateToLocationAndKeepItsAdditionalPropertiesInHistory(location, additionalProperties, delta);
|
|
146
170
|
this._currentLocationIndex = index;
|
|
147
171
|
|
|
148
172
|
// Call the listeners.
|
|
@@ -204,7 +228,23 @@ class WebBrowserNavigation {
|
|
|
204
228
|
delta
|
|
205
229
|
};
|
|
206
230
|
}
|
|
207
|
-
|
|
231
|
+
|
|
232
|
+
// Stores "additional" properties associated with `location` in web browser's history storage.
|
|
233
|
+
// Web browser's history storage is not intended for large datasets and should only be used
|
|
234
|
+
// to store small bits of data.
|
|
235
|
+
//
|
|
236
|
+
// "Some browsers save state objects to the user's disk so they can be restored after the user restarts
|
|
237
|
+
// the browser, and impose a size limit on the serialized representation of a state object, and will throw
|
|
238
|
+
// an exception if you pass a state object whose serialized representation is larger than that size limit.
|
|
239
|
+
// So in cases where you want to ensure you have more space than what some browsers might impose,
|
|
240
|
+
// you're encouraged to use sessionStorage and/or localStorage."
|
|
241
|
+
//
|
|
242
|
+
// Source: https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
|
|
243
|
+
//
|
|
244
|
+
// To store large amounts of data, one could use `window.sessionStorage` instead.
|
|
245
|
+
// It is accessible via `DataStorage(session)` class.
|
|
246
|
+
//
|
|
247
|
+
_navigateToLocationAndKeepItsAdditionalPropertiesInHistory(location, additionalProperties, delta) {
|
|
208
248
|
const url = (0, _getLocationUrl.default)(location);
|
|
209
249
|
// `delta` property is not stored in `window.history.state`
|
|
210
250
|
// because it is supposed to be recalculated every time when reading from `window.history.state`.
|
|
@@ -6,7 +6,7 @@ var _getLocationUrl = _interopRequireDefault(require("../../../getLocationUrl"))
|
|
|
6
6
|
const _excluded = ["operation"];
|
|
7
7
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
8
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
9
|
-
class
|
|
9
|
+
class ServerSideRedirectError extends Error {
|
|
10
10
|
constructor(location) {
|
|
11
11
|
super(location ? `Navigate to ${(0, _getLocationUrl.default)(location)}` : 'Navigate to previous or next location');
|
|
12
12
|
if (location) {
|
|
@@ -17,5 +17,5 @@ class ServerSideNavigationError extends Error {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
exports.default =
|
|
20
|
+
exports.default = ServerSideRedirectError;
|
|
21
21
|
module.exports = exports.default;
|
|
@@ -49,9 +49,24 @@ class WebBrowserScrollPosition {
|
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
enableAutomaticScrollRestoration() {
|
|
52
|
+
// The default "auto" behavior seems to work in the following way:
|
|
53
|
+
//
|
|
54
|
+
// * It doesn't scroll to top on `window.history.pushState()` or `window.history.replaceState()`.
|
|
55
|
+
//
|
|
56
|
+
// * It does restore scroll position on "popstate" event
|
|
57
|
+
// (they say, in Firefox it happens before the event is dispatched,
|
|
58
|
+
// while in Chrome it happens after the event is dispatched)
|
|
59
|
+
//
|
|
60
|
+
// https://v5.reactrouter.com/web/guides/scroll-restoration
|
|
61
|
+
//
|
|
52
62
|
window.history.scrollRestoration = 'auto';
|
|
53
63
|
}
|
|
54
64
|
disableAutomaticScrollRestoration() {
|
|
65
|
+
// Setting `window.history.scrollRestoration` value updates it in the current history entry
|
|
66
|
+
// and any subsequent history entries.
|
|
67
|
+
// This means that it should be set at application initialization stage,
|
|
68
|
+
// that is before any navigation.
|
|
69
|
+
// https://majido.github.io/scroll-restoration-proposal/history-based-api.html
|
|
55
70
|
window.history.scrollRestoration = 'manual';
|
|
56
71
|
}
|
|
57
72
|
init() {}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = getLocationBaseFromLocation;
|
|
5
|
+
const _excluded = ["key", "index"];
|
|
6
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
7
|
+
// Converts `Location` object to a `LocationBase` object.
|
|
8
|
+
// It hides properties of location such as `key` or `index`.
|
|
9
|
+
function getLocationBaseFromLocation(location) {
|
|
10
|
+
// eslint-disable-next-line no-unused-vars
|
|
11
|
+
const locationBase = _objectWithoutPropertiesLoose(location, _excluded);
|
|
12
|
+
return locationBase;
|
|
13
|
+
}
|
|
14
|
+
module.exports = exports.default;
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.default = getLocationUrl;
|
|
5
|
-
var
|
|
5
|
+
var _stringifyQueryAsSearch = _interopRequireDefault(require("./stringifyQueryAsSearch"));
|
|
6
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
6
7
|
function getLocationUrl({
|
|
7
8
|
pathname,
|
|
8
9
|
search,
|
|
@@ -10,10 +11,7 @@ function getLocationUrl({
|
|
|
10
11
|
hash
|
|
11
12
|
}) {
|
|
12
13
|
if (!search && query) {
|
|
13
|
-
|
|
14
|
-
if (queryString) {
|
|
15
|
-
search = `?${queryString}`;
|
|
16
|
-
}
|
|
14
|
+
search = (0, _stringifyQueryAsSearch.default)(query);
|
|
17
15
|
}
|
|
18
16
|
return `${pathname}${search || ''}${hash || ''}`;
|
|
19
17
|
}
|