navigation-stack 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +603 -163
- package/data-storage/package.json +6 -0
- package/karma.conf.cjs +21 -4
- package/lib/cjs/NavigationStack.js +73 -0
- package/lib/cjs/data-storage/DataStorage.js +71 -0
- package/lib/cjs/data-storage/LocationDataStorage.js +29 -0
- package/lib/cjs/data-storage/index.js +9 -0
- package/lib/cjs/environment/InMemoryEnvironment.js +15 -0
- package/lib/cjs/environment/WebBrowserEnvironment.js +15 -0
- package/lib/cjs/environment/data-storage/InMemoryDataStorage.js +27 -0
- package/lib/cjs/environment/data-storage/WebBrowserDataStorage.js +21 -0
- package/lib/cjs/environment/scroll-position/InMemoryScrollPosition.js +44 -0
- package/lib/cjs/environment/scroll-position/WebBrowserScrollPosition.js +60 -0
- package/lib/cjs/getLocationFromInternalLocation.js +14 -0
- package/lib/cjs/index.js +20 -16
- package/lib/cjs/navigationBlockers.js +25 -23
- package/lib/cjs/{normalizeInputLocation.js → parseInputLocation.js} +25 -9
- package/lib/cjs/{ActionTypes.js → redux/ActionTypes.js} +1 -1
- package/lib/cjs/redux/ActionTypesInternal.js +8 -0
- package/lib/cjs/{Actions.js → redux/Actions.js} +5 -4
- package/lib/cjs/redux/createMiddlewares.js +60 -0
- package/lib/cjs/redux/index.js +13 -0
- package/lib/cjs/redux/internalLocationReducer.js +14 -0
- package/lib/cjs/redux/middleware/createAddInputLocationBasePathMiddleware.js +32 -0
- package/lib/cjs/redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.js +113 -0
- package/lib/cjs/redux/middleware/createProgrammaticNavigationBlockerMiddleware.js +94 -0
- package/lib/cjs/redux/middleware/createRemoveOutputLocationBasePathMiddleware.js +30 -0
- package/lib/cjs/redux/middleware/createUpdateInternalLocationMiddleware.js +73 -0
- package/lib/cjs/{middleware/navigationActionMiddleware.js → redux/middleware/navigationOperationMiddleware.js} +11 -8
- package/lib/cjs/{middleware/normalizeInputLocationMiddleware.js → redux/middleware/parseInputLocationMiddleware.js} +6 -4
- package/lib/cjs/redux/middleware/updateLocationMiddleware.js +34 -0
- package/lib/cjs/scroll-position/PageScrollPositionSetter.js +97 -0
- package/lib/cjs/scroll-position/ScrollPositionAutoSaver.js +130 -0
- package/lib/cjs/scroll-position/ScrollPositionRestoration.js +383 -0
- package/lib/cjs/scroll-position/ScrollPositionSaver.js +81 -0
- package/lib/cjs/scroll-position/ScrollPositionSetter.js +16 -0
- package/lib/cjs/scroll-position/constants.js +5 -0
- package/lib/cjs/scroll-position/index.js +7 -0
- package/lib/cjs/scroll-position/scheduleNextTick.js +11 -0
- package/lib/cjs/session/InMemorySession.js +22 -0
- package/lib/cjs/session/ServerSideRenderSession.js +17 -0
- package/lib/cjs/session/Session.js +196 -0
- package/lib/cjs/session/WebBrowserSession.js +20 -0
- package/lib/cjs/session/key/createSessionKey.js +23 -0
- package/lib/cjs/session/lifecycle/InMemorySessionLifecycle.js +19 -0
- package/lib/cjs/session/lifecycle/WebBrowserSessionLifecycle.js +128 -0
- package/lib/cjs/session/lifecycle/page-lifecycle/PageLifecycle.js +269 -0
- package/lib/cjs/session/lifecycle/page-lifecycle/PageLifecycleInstance.js +8 -0
- package/lib/cjs/session/lifecycle/page-lifecycle/supportsConstructableEventTarget.js +33 -0
- package/lib/cjs/session/navigation/InMemoryNavigation.js +104 -0
- package/lib/cjs/session/navigation/ServerSideNavigation.js +61 -0
- package/lib/cjs/session/navigation/WebBrowserNavigation.js +221 -0
- package/lib/cjs/session/navigation/error/NavigationOutOfBoundsError.js +12 -0
- package/lib/cjs/session/navigation/error/ServerSideNavigationError.js +21 -0
- package/lib/cjs/session/navigation/operation/operations.js +11 -0
- package/lib/cjs/session/subscription/Subscription.js +81 -0
- package/lib/data-storage/index.d.ts +35 -0
- package/lib/esm/NavigationStack.js +66 -0
- package/lib/esm/data-storage/DataStorage.js +65 -0
- package/lib/esm/data-storage/LocationDataStorage.js +22 -0
- package/lib/esm/data-storage/index.js +2 -0
- package/lib/esm/environment/InMemoryEnvironment.js +8 -0
- package/lib/esm/environment/WebBrowserEnvironment.js +8 -0
- package/lib/esm/environment/data-storage/InMemoryDataStorage.js +21 -0
- package/lib/esm/environment/data-storage/WebBrowserDataStorage.js +15 -0
- package/lib/esm/environment/scroll-position/InMemoryScrollPosition.js +38 -0
- package/lib/esm/environment/scroll-position/WebBrowserScrollPosition.js +54 -0
- package/lib/esm/getLocationFromInternalLocation.js +9 -0
- package/lib/esm/index.js +10 -8
- package/lib/esm/navigationBlockers.js +25 -23
- package/lib/esm/{normalizeInputLocation.js → parseInputLocation.js} +24 -8
- package/lib/esm/{ActionTypes.js → redux/ActionTypes.js} +1 -1
- package/lib/esm/redux/ActionTypesInternal.js +3 -0
- package/lib/esm/{Actions.js → redux/Actions.js} +5 -4
- package/lib/esm/redux/createMiddlewares.js +54 -0
- package/lib/esm/redux/index.js +4 -0
- package/lib/esm/redux/internalLocationReducer.js +8 -0
- package/lib/esm/redux/middleware/createAddInputLocationBasePathMiddleware.js +27 -0
- package/lib/esm/redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.js +108 -0
- package/lib/esm/redux/middleware/createProgrammaticNavigationBlockerMiddleware.js +88 -0
- package/lib/esm/redux/middleware/createRemoveOutputLocationBasePathMiddleware.js +25 -0
- package/lib/esm/redux/middleware/createUpdateInternalLocationMiddleware.js +68 -0
- package/lib/esm/{middleware/navigationActionMiddleware.js → redux/middleware/navigationOperationMiddleware.js} +10 -7
- package/lib/esm/{middleware/normalizeInputLocationMiddleware.js → redux/middleware/parseInputLocationMiddleware.js} +5 -3
- package/lib/esm/redux/middleware/updateLocationMiddleware.js +28 -0
- package/lib/esm/scroll-position/PageScrollPositionSetter.js +91 -0
- package/lib/esm/scroll-position/ScrollPositionAutoSaver.js +123 -0
- package/lib/esm/scroll-position/ScrollPositionRestoration.js +376 -0
- package/lib/esm/scroll-position/ScrollPositionSaver.js +74 -0
- package/lib/esm/scroll-position/ScrollPositionSetter.js +10 -0
- package/lib/esm/scroll-position/constants.js +1 -0
- package/lib/esm/scroll-position/index.js +1 -0
- package/lib/esm/scroll-position/scheduleNextTick.js +6 -0
- package/lib/esm/session/InMemorySession.js +15 -0
- package/lib/esm/session/ServerSideRenderSession.js +11 -0
- package/lib/esm/session/Session.js +189 -0
- package/lib/esm/session/WebBrowserSession.js +13 -0
- package/lib/esm/session/key/createSessionKey.js +18 -0
- package/lib/esm/session/lifecycle/InMemorySessionLifecycle.js +13 -0
- package/lib/esm/session/lifecycle/WebBrowserSessionLifecycle.js +120 -0
- package/lib/esm/session/lifecycle/page-lifecycle/PageLifecycle.js +263 -0
- package/lib/esm/session/lifecycle/page-lifecycle/PageLifecycleInstance.js +2 -0
- package/lib/esm/session/lifecycle/page-lifecycle/supportsConstructableEventTarget.js +30 -0
- package/lib/esm/session/navigation/InMemoryNavigation.js +97 -0
- package/lib/esm/session/navigation/ServerSideNavigation.js +54 -0
- package/lib/esm/session/navigation/WebBrowserNavigation.js +213 -0
- package/lib/esm/session/navigation/error/NavigationOutOfBoundsError.js +6 -0
- package/lib/esm/session/navigation/error/ServerSideNavigationError.js +14 -0
- package/lib/esm/session/navigation/operation/operations.js +6 -0
- package/lib/esm/session/subscription/Subscription.js +75 -0
- package/lib/index.d.ts +178 -157
- package/lib/redux/index.d.ts +90 -0
- package/lib/scroll-position/index.d.ts +107 -0
- package/package.json +9 -5
- package/redux/package.json +6 -0
- package/scroll-position/package.json +6 -0
- package/src/NavigationStack.js +84 -0
- package/src/data-storage/DataStorage.js +69 -0
- package/src/data-storage/LocationDataStorage.js +23 -0
- package/src/data-storage/index.js +2 -0
- package/src/environment/InMemoryEnvironment.js +9 -0
- package/src/environment/WebBrowserEnvironment.js +9 -0
- package/src/environment/data-storage/InMemoryDataStorage.js +23 -0
- package/src/environment/data-storage/WebBrowserDataStorage.js +17 -0
- package/src/environment/scroll-position/InMemoryScrollPosition.js +45 -0
- package/src/environment/scroll-position/WebBrowserScrollPosition.js +72 -0
- package/src/getLocationFromInternalLocation.js +7 -0
- package/src/index.js +10 -8
- package/src/navigationBlockers.js +28 -27
- package/src/{normalizeInputLocation.js → parseInputLocation.js} +23 -8
- package/src/{ActionTypes.js → redux/ActionTypes.js} +1 -1
- package/src/redux/ActionTypesInternal.js +3 -0
- package/src/{Actions.js → redux/Actions.js} +4 -3
- package/src/redux/createMiddlewares.js +65 -0
- package/src/redux/index.js +4 -0
- package/src/redux/internalLocationReducer.js +9 -0
- package/src/redux/middleware/createAddInputLocationBasePathMiddleware.js +27 -0
- package/src/redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.js +119 -0
- package/src/redux/middleware/createProgrammaticNavigationBlockerMiddleware.js +94 -0
- package/src/redux/middleware/createRemoveOutputLocationBasePathMiddleware.js +26 -0
- package/src/redux/middleware/createUpdateInternalLocationMiddleware.js +72 -0
- package/src/{middleware/navigationActionMiddleware.js → redux/middleware/navigationOperationMiddleware.js} +10 -3
- package/src/{middleware/normalizeInputLocationMiddleware.js → redux/middleware/parseInputLocationMiddleware.js} +5 -3
- package/src/redux/middleware/updateLocationMiddleware.js +28 -0
- package/src/scroll-position/PageScrollPositionSetter.js +110 -0
- package/src/scroll-position/ScrollPositionAutoSaver.js +151 -0
- package/src/scroll-position/ScrollPositionRestoration.js +506 -0
- package/src/scroll-position/ScrollPositionSaver.js +100 -0
- package/src/scroll-position/ScrollPositionSetter.js +16 -0
- package/src/scroll-position/constants.js +1 -0
- package/src/scroll-position/index.js +1 -0
- package/src/scroll-position/scheduleNextTick.js +6 -0
- package/src/session/InMemorySession.js +13 -0
- package/src/session/ServerSideRenderSession.js +9 -0
- package/src/session/Session.js +216 -0
- package/src/session/WebBrowserSession.js +13 -0
- package/src/session/key/createSessionKey.js +18 -0
- package/src/session/lifecycle/InMemorySessionLifecycle.js +13 -0
- package/src/session/lifecycle/WebBrowserSessionLifecycle.js +126 -0
- package/src/session/lifecycle/page-lifecycle/PageLifecycle.js +291 -0
- package/src/session/lifecycle/page-lifecycle/PageLifecycleInstance.js +3 -0
- package/src/session/lifecycle/page-lifecycle/supportsConstructableEventTarget.js +32 -0
- package/src/session/navigation/InMemoryNavigation.js +78 -0
- package/src/session/navigation/ServerSideNavigation.js +43 -0
- package/src/session/navigation/WebBrowserNavigation.js +224 -0
- package/src/session/navigation/error/NavigationOutOfBoundsError.js +7 -0
- package/src/session/navigation/error/ServerSideNavigationError.js +18 -0
- package/src/session/navigation/operation/operations.js +6 -0
- package/src/session/subscription/Subscription.js +76 -0
- package/test/NavigationStack.test.js +296 -0
- package/test/{LocationDataStorage.test.js → data-storage/LocationDataStorage.test.js} +3 -3
- package/test/data-storage/index.test.js +8 -0
- package/test/index.js +12 -0
- package/test/index.test.js +8 -7
- package/test/{helpers.js → middlewareTestUtil.js} +9 -12
- package/test/{normalizeInputLocation.test.js → parseInputLocationMiddleware.test.js} +9 -9
- package/test/{Action.test.js → redux/Action.test.js} +7 -6
- package/test/{ActionTypes.test.js → redux/ActionTypes.test.js} +2 -2
- package/test/redux/createMiddlewares.test.js +96 -0
- package/test/redux/index.test.js +10 -0
- package/test/{locationReducer.test.js → redux/locationReducer.test.js} +4 -7
- package/test/redux/middleware/createAddInputLocationBasePathMiddleware.test.js +40 -0
- package/test/redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.test.js +264 -0
- package/test/redux/middleware/createProgrammaticNavigationBlockerMiddleware.test.js +312 -0
- package/test/redux/middleware/createRemoveOutputLocationBasePathMiddleware.test.js +51 -0
- package/test/{middleware/navigationActionMiddleware.test.js → redux/middleware/navigationOperationMiddleware.test.js} +16 -12
- package/test/{middleware/normalizeInputLocationMiddleware.test.js → redux/middleware/parseInputLocationMiddleware.test.js} +4 -4
- package/test/scroll-position/ScrollPositionRestoration.test.js +418 -0
- package/test/scroll-position/addScrollableContainer.js +36 -0
- package/test/scroll-position/addScrollableContainerWithHyperlink.js +50 -0
- package/test/scroll-position/createApp.js +112 -0
- package/test/scroll-position/delay.js +9 -0
- package/test/scroll-position/mockPageLifecycle.js +17 -0
- package/test/scroll-position/runApp.js +24 -0
- package/test/scroll-position/withScrollableContainerAtIndexPage.js +62 -0
- package/test/session/InMemorySession.test.js +348 -0
- package/test/session/ServerSession.test.js +17 -9
- package/test/session/WebBrowserSession.test.js +265 -0
- package/test/testUtil.js +3 -0
- package/types/data-storage/index.d.ts +35 -0
- package/types/index.d.ts +178 -157
- package/types/redux/index.d.ts +90 -0
- package/types/scroll-position/index.d.ts +107 -0
- package/types/tsconfig.json +1 -1
- package/lib/cjs/LocationDataStorage.js +0 -60
- package/lib/cjs/addBeforeLocationChangeListener.js +0 -7
- package/lib/cjs/beforeLocationChangeListeners.js +0 -51
- package/lib/cjs/createMiddlewares.js +0 -47
- package/lib/cjs/middleware/createBasePathMiddleware.js +0 -24
- package/lib/cjs/middleware/createBeforeLocationChangeListenerMiddleware.js +0 -39
- package/lib/cjs/middleware/createLocationMiddleware.js +0 -56
- package/lib/cjs/middleware/createNavigationBlockerMiddleware.js +0 -161
- package/lib/cjs/middleware/createTransformLocationMiddleware.js +0 -38
- package/lib/cjs/onlyAllowedOnClientSide.js +0 -10
- package/lib/cjs/session/BrowserSession.js +0 -235
- package/lib/cjs/session/MemorySession.js +0 -223
- package/lib/cjs/session/ServerSession.js +0 -65
- package/lib/esm/LocationDataStorage.js +0 -53
- package/lib/esm/addBeforeLocationChangeListener.js +0 -2
- package/lib/esm/beforeLocationChangeListeners.js +0 -44
- package/lib/esm/createMiddlewares.js +0 -41
- package/lib/esm/middleware/createBasePathMiddleware.js +0 -19
- package/lib/esm/middleware/createBeforeLocationChangeListenerMiddleware.js +0 -34
- package/lib/esm/middleware/createLocationMiddleware.js +0 -50
- package/lib/esm/middleware/createNavigationBlockerMiddleware.js +0 -156
- package/lib/esm/middleware/createTransformLocationMiddleware.js +0 -33
- package/lib/esm/onlyAllowedOnClientSide.js +0 -5
- package/lib/esm/session/BrowserSession.js +0 -229
- package/lib/esm/session/MemorySession.js +0 -217
- package/lib/esm/session/ServerSession.js +0 -58
- package/src/LocationDataStorage.js +0 -59
- package/src/addBeforeLocationChangeListener.js +0 -2
- package/src/beforeLocationChangeListeners.js +0 -54
- package/src/createMiddlewares.js +0 -45
- package/src/middleware/createBasePathMiddleware.js +0 -20
- package/src/middleware/createBeforeLocationChangeListenerMiddleware.js +0 -40
- package/src/middleware/createLocationMiddleware.js +0 -55
- package/src/middleware/createNavigationBlockerMiddleware.js +0 -168
- package/src/middleware/createTransformLocationMiddleware.js +0 -29
- package/src/onlyAllowedOnClientSide.js +0 -5
- package/src/session/BrowserSession.js +0 -235
- package/src/session/MemorySession.js +0 -219
- package/src/session/ServerSession.js +0 -67
- package/test/createMiddlewares.test.js +0 -62
- package/test/middleware/createBasePathMiddleware.test.js +0 -67
- package/test/middleware/createBeforeLocationChangeListenerMiddleware.test.js +0 -141
- package/test/middleware/createNavigationBlockerMiddleware.test.js +0 -471
- package/test/middleware/createTransformLocationMiddleware.test.js +0 -44
- package/test/session/BrowserSession.test.js +0 -182
- package/test/session/MemorySession.test.js +0 -244
- /package/lib/cjs/{locationReducer.js → redux/locationReducer.js} +0 -0
- /package/lib/esm/{locationReducer.js → redux/locationReducer.js} +0 -0
- /package/src/{locationReducer.js → redux/locationReducer.js} +0 -0
package/types/tsconfig.json
CHANGED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.default = void 0;
|
|
5
|
-
var _getLocationUrl = _interopRequireDefault(require("./getLocationUrl"));
|
|
6
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
-
class LocationDataStorage {
|
|
8
|
-
constructor(environment, {
|
|
9
|
-
namespace
|
|
10
|
-
} = {}) {
|
|
11
|
-
this._environment = environment;
|
|
12
|
-
this._getFallbackLocationKey = _getLocationUrl.default;
|
|
13
|
-
this._stateKeyPrefix = namespace ? `${namespace}|` : '';
|
|
14
|
-
}
|
|
15
|
-
get(location, key) {
|
|
16
|
-
const stateKey = this._getStateKey(location, key);
|
|
17
|
-
try {
|
|
18
|
-
const value = this._environment.dataStorage.get(stateKey);
|
|
19
|
-
// === null is probably sufficient.
|
|
20
|
-
if (value === null) {
|
|
21
|
-
return undefined;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// We want to catch JSON parse errors in case someone separately threw
|
|
25
|
-
// junk into sessionStorage under our namespace.
|
|
26
|
-
return JSON.parse(value);
|
|
27
|
-
} catch (error) {
|
|
28
|
-
// Pretend that the entry doesn't exist.
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
set(location, key, value) {
|
|
33
|
-
const stateKey = this._getStateKey(location, key);
|
|
34
|
-
if (value === undefined) {
|
|
35
|
-
try {
|
|
36
|
-
this._environment.dataStorage.remove(stateKey);
|
|
37
|
-
} catch (error) {
|
|
38
|
-
// No need to handle errors here.
|
|
39
|
-
}
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Unlike with read, we want to fail on invalid values here, since the
|
|
44
|
-
// value here is provided by the caller of this method.
|
|
45
|
-
const valueString = JSON.stringify(value);
|
|
46
|
-
try {
|
|
47
|
-
this._environment.dataStorage.set(stateKey, valueString);
|
|
48
|
-
} catch (error) {
|
|
49
|
-
// No need to handle errors here either. If it didn't work, it didn't
|
|
50
|
-
// work. We make no guarantees about actually saving the value.
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
_getStateKey(location, key) {
|
|
54
|
-
const locationKey = location.key || this._getFallbackLocationKey(location);
|
|
55
|
-
const keyPrefix = `${this._stateKeyPrefix}${locationKey}`;
|
|
56
|
-
return `${keyPrefix}|${key}`;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
exports.default = LocationDataStorage;
|
|
60
|
-
module.exports = exports.default;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.default = void 0;
|
|
5
|
-
var _beforeLocationChangeListeners = require("./beforeLocationChangeListeners");
|
|
6
|
-
exports.default = _beforeLocationChangeListeners.addBeforeLocationChangeListener;
|
|
7
|
-
module.exports = exports.default;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.addBeforeLocationChangeListener = addBeforeLocationChangeListener;
|
|
5
|
-
exports.getBeforeLocationChangeListeners = getBeforeLocationChangeListeners;
|
|
6
|
-
exports.removeAllBeforeLocationChangeListeners = removeAllBeforeLocationChangeListeners;
|
|
7
|
-
exports.runBeforeLocationChangeListeners = runBeforeLocationChangeListeners;
|
|
8
|
-
/* eslint-disable no-underscore-dangle */
|
|
9
|
-
|
|
10
|
-
function getBeforeLocationChangeListeners(session) {
|
|
11
|
-
return session._beforeLocationChangeListenersList || [];
|
|
12
|
-
}
|
|
13
|
-
function addBeforeLocationChangeListenerToTheList(listener, session) {
|
|
14
|
-
if (!session._beforeLocationChangeListenersList) {
|
|
15
|
-
session._beforeLocationChangeListenersList = [];
|
|
16
|
-
}
|
|
17
|
-
session._beforeLocationChangeListenersList.push(listener);
|
|
18
|
-
}
|
|
19
|
-
function removeBeforeLocationChangeListenerFromTheList(listener, session) {
|
|
20
|
-
if (session._beforeLocationChangeListenersList) {
|
|
21
|
-
session._beforeLocationChangeListenersList = session._beforeLocationChangeListenersList.filter(_ => _ !== listener);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function removeAllBeforeLocationChangeListeners(session) {
|
|
25
|
-
session._beforeLocationChangeListenersList = [];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Runs the `listener` while ignoring any errors that might be thrown by it.
|
|
29
|
-
function runBeforeLocationChangeListener(listener, location) {
|
|
30
|
-
try {
|
|
31
|
-
listener(location);
|
|
32
|
-
} catch (error) {
|
|
33
|
-
// eslint-disable-next-line no-console
|
|
34
|
-
console.warn(`Ignoring before location change listener \`${listener.name}\` that failed with \`${error}\`.`);
|
|
35
|
-
// eslint-disable-next-line no-console
|
|
36
|
-
console.error(error);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Runs all listeners in order.
|
|
41
|
-
function runBeforeLocationChangeListeners(navigationListeners, toLocation) {
|
|
42
|
-
for (const listener of navigationListeners) {
|
|
43
|
-
runBeforeLocationChangeListener(listener, toLocation);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
function addBeforeLocationChangeListener(session, listener) {
|
|
47
|
-
addBeforeLocationChangeListenerToTheList(listener, session);
|
|
48
|
-
return () => {
|
|
49
|
-
removeBeforeLocationChangeListenerFromTheList(listener, session);
|
|
50
|
-
};
|
|
51
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.default = createMiddlewares;
|
|
5
|
-
var _createBasePathMiddleware = _interopRequireDefault(require("./middleware/createBasePathMiddleware"));
|
|
6
|
-
var _createBeforeLocationChangeListenerMiddleware = _interopRequireDefault(require("./middleware/createBeforeLocationChangeListenerMiddleware"));
|
|
7
|
-
var _createLocationMiddleware = _interopRequireDefault(require("./middleware/createLocationMiddleware"));
|
|
8
|
-
var _createNavigationBlockerMiddleware = _interopRequireDefault(require("./middleware/createNavigationBlockerMiddleware"));
|
|
9
|
-
var _navigationActionMiddleware = _interopRequireDefault(require("./middleware/navigationActionMiddleware"));
|
|
10
|
-
var _normalizeInputLocationMiddleware = _interopRequireDefault(require("./middleware/normalizeInputLocationMiddleware"));
|
|
11
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
-
function createMiddlewares(session, options) {
|
|
13
|
-
// Allows temporarily ignoring location update events.
|
|
14
|
-
let shouldIgnoreLocationSubscriptionEvents = false;
|
|
15
|
-
const ignoreLocationSubscriptionEvents = func => {
|
|
16
|
-
shouldIgnoreLocationSubscriptionEvents = true;
|
|
17
|
-
func();
|
|
18
|
-
shouldIgnoreLocationSubscriptionEvents = false;
|
|
19
|
-
};
|
|
20
|
-
return [
|
|
21
|
-
// Validates that the action "payload" (input location) is a proper `NormalizedInputLocation`.
|
|
22
|
-
_normalizeInputLocationMiddleware.default,
|
|
23
|
-
// Transforms a "PUSH" / "REPLACE" action into a "NAVIGATE" action.
|
|
24
|
-
_navigationActionMiddleware.default,
|
|
25
|
-
// If a website is hosted under a certain path (`basePath`)
|
|
26
|
-
// then this middleware will automatically strip that starting segment from the `pathname` of `location`s.
|
|
27
|
-
(0, _createBasePathMiddleware.default)(options && options.basePath),
|
|
28
|
-
// Allows blocking navigation.
|
|
29
|
-
// Handles `NAVIGATE` actions dispatched by the application itself.
|
|
30
|
-
(0, _createNavigationBlockerMiddleware.default)(session, {
|
|
31
|
-
ignoreLocationSubscriptionEvents
|
|
32
|
-
}),
|
|
33
|
-
// This "middleware" performs the actual navigation according to the `session` being used.
|
|
34
|
-
// For example, when `BrowserSession` is used, it calls methods of the `history` object.
|
|
35
|
-
(0, _createLocationMiddleware.default)(session, {
|
|
36
|
-
shouldIgnoreLocationSubscriptionEvents: () => shouldIgnoreLocationSubscriptionEvents
|
|
37
|
-
}),
|
|
38
|
-
// Allows blocking navigation.
|
|
39
|
-
// Handles location `UPDATE` actions dispatched in response to location update events.
|
|
40
|
-
(0, _createNavigationBlockerMiddleware.default)(session, {
|
|
41
|
-
ignoreLocationSubscriptionEvents
|
|
42
|
-
}),
|
|
43
|
-
// Allows subscribing to upcoming location changes
|
|
44
|
-
// before those changes are applied in the `location` object in the state.
|
|
45
|
-
(0, _createBeforeLocationChangeListenerMiddleware.default)(session)];
|
|
46
|
-
}
|
|
47
|
-
module.exports = exports.default;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.default = createBasePathMiddleware;
|
|
5
|
-
var _basePath = require("../basePath");
|
|
6
|
-
var _createTransformLocationMiddleware = _interopRequireDefault(require("./createTransformLocationMiddleware"));
|
|
7
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
-
// Creates a "middleware" that, when a website is hosted under a certain path (`basePath`),
|
|
9
|
-
// automatically strips that starting segment from the `pathname` of `location`s.
|
|
10
|
-
function createBasePathMiddleware(basePath) {
|
|
11
|
-
return (0, _createTransformLocationMiddleware.default)({
|
|
12
|
-
// Transforms input `Location`:
|
|
13
|
-
// prepends `basePath` to the URL.
|
|
14
|
-
transformInputLocation: location => {
|
|
15
|
-
return (0, _basePath.addBasePath)(location, basePath);
|
|
16
|
-
},
|
|
17
|
-
// Transforms subscription `Location` object:
|
|
18
|
-
// removes `basePath` from the URL.
|
|
19
|
-
transformSubscriptionLocation: location => {
|
|
20
|
-
return (0, _basePath.removeBasePath)(location, basePath);
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
module.exports = exports.default;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.default = createBeforeLocationChangeListenerMiddleware;
|
|
5
|
-
var _ActionTypes = _interopRequireDefault(require("../ActionTypes"));
|
|
6
|
-
var _beforeLocationChangeListeners = require("../beforeLocationChangeListeners");
|
|
7
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
-
// Creates a "middleware" that calls upcoming navigation listeners.
|
|
9
|
-
function createBeforeLocationChangeListenerMiddleware(session) {
|
|
10
|
-
return function navigationListenerMiddleware() {
|
|
11
|
-
return next => action => {
|
|
12
|
-
const {
|
|
13
|
-
type,
|
|
14
|
-
payload
|
|
15
|
-
} = action;
|
|
16
|
-
switch (type) {
|
|
17
|
-
// Trigger navigation listeners before the `location` has been updated in Redux state.
|
|
18
|
-
// It doesn't matter that the new location URL has already been updated in the web browser's
|
|
19
|
-
// address bar, or that the web browser's history has already switched to the new locaiton.
|
|
20
|
-
// From the application's point of view, all of that doesn't matter and even doesn't exist.
|
|
21
|
-
// All that exists from the application's point of view is the `location` object in the Redux state.
|
|
22
|
-
// Until the `location` object in the Redux state is updated, the old page is still rendered.
|
|
23
|
-
// The appliation is only concerned with the updates of the `location` object in the Redux state
|
|
24
|
-
// and completely ignores any updates to the URL in the web browser's address bar.
|
|
25
|
-
case _ActionTypes.default.UPDATE:
|
|
26
|
-
(0, _beforeLocationChangeListeners.runBeforeLocationChangeListeners)((0, _beforeLocationChangeListeners.getBeforeLocationChangeListeners)(session), payload);
|
|
27
|
-
return next(action);
|
|
28
|
-
|
|
29
|
-
// Remove any navigation listeners on `DISPOSE` event.
|
|
30
|
-
case _ActionTypes.default.DISPOSE:
|
|
31
|
-
(0, _beforeLocationChangeListeners.removeAllBeforeLocationChangeListeners)(session);
|
|
32
|
-
return next(action);
|
|
33
|
-
default:
|
|
34
|
-
return next(action);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
module.exports = exports.default;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.default = createLocationMiddleware;
|
|
5
|
-
var _ActionTypes = _interopRequireDefault(require("../ActionTypes"));
|
|
6
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
-
function updateLocation(location) {
|
|
8
|
-
return {
|
|
9
|
-
type: _ActionTypes.default.UPDATE,
|
|
10
|
-
payload: location
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Creates a "middleware" that performs the actual navigation according to the `session` being used.
|
|
15
|
-
// For example, when `BrowserSession` is used, it calls methods of the `window.history` object.
|
|
16
|
-
function createLocationMiddleware(session, {
|
|
17
|
-
shouldIgnoreLocationSubscriptionEvents
|
|
18
|
-
}) {
|
|
19
|
-
return function locationMiddleware() {
|
|
20
|
-
return next => {
|
|
21
|
-
// Whenever browser location changes,
|
|
22
|
-
// perform the same changes with the internal `location` object.
|
|
23
|
-
const unsubscribe = session.navigation.subscribe(location => {
|
|
24
|
-
if (!shouldIgnoreLocationSubscriptionEvents()) {
|
|
25
|
-
next(updateLocation(location));
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
return action => {
|
|
29
|
-
const {
|
|
30
|
-
type,
|
|
31
|
-
payload
|
|
32
|
-
} = action;
|
|
33
|
-
switch (type) {
|
|
34
|
-
case _ActionTypes.default.INIT:
|
|
35
|
-
return next(updateLocation(session.navigation.init()));
|
|
36
|
-
case _ActionTypes.default.NAVIGATE:
|
|
37
|
-
// `session.navigate()` doesn't trigger the `subscribe()` listener.
|
|
38
|
-
return next(updateLocation(session.navigation.navigate(payload)));
|
|
39
|
-
case _ActionTypes.default.SHIFT:
|
|
40
|
-
// `shift()` will trigger the `subscribe()` listener,
|
|
41
|
-
// which will call `updateLocation()`.
|
|
42
|
-
session.navigation.shift(payload);
|
|
43
|
-
// eslint-disable-next-line consistent-return
|
|
44
|
-
return;
|
|
45
|
-
case _ActionTypes.default.DISPOSE:
|
|
46
|
-
unsubscribe();
|
|
47
|
-
// eslint-disable-next-line consistent-return
|
|
48
|
-
return;
|
|
49
|
-
default:
|
|
50
|
-
return next(action);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
module.exports = exports.default;
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.default = createNavigationBlockerMiddleware;
|
|
5
|
-
var _ActionTypes = _interopRequireDefault(require("../ActionTypes"));
|
|
6
|
-
var _isPromise = _interopRequireDefault(require("../isPromise"));
|
|
7
|
-
var _navigationBlockers = require("../navigationBlockers");
|
|
8
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
-
// Creates a "middleware" that applies navigation blockers.
|
|
10
|
-
function createNavigationBlockerMiddleware(session, {
|
|
11
|
-
ignoreLocationSubscriptionEvents
|
|
12
|
-
}) {
|
|
13
|
-
function createNavigationBlockersEvaluationStatus() {
|
|
14
|
-
/* eslint-disable no-underscore-dangle */
|
|
15
|
-
if (session._navigationBlockersEvaluationStatus) {
|
|
16
|
-
session._navigationBlockersEvaluationStatus.cancelled = true;
|
|
17
|
-
}
|
|
18
|
-
session._navigationBlockersEvaluationStatus = {
|
|
19
|
-
cancelled: false
|
|
20
|
-
};
|
|
21
|
-
return session._navigationBlockersEvaluationStatus;
|
|
22
|
-
}
|
|
23
|
-
return function navigationBlockerMiddleware() {
|
|
24
|
-
return next => action => {
|
|
25
|
-
const {
|
|
26
|
-
type,
|
|
27
|
-
payload
|
|
28
|
-
} = action;
|
|
29
|
-
|
|
30
|
-
// Declaring `result` variable here fixes ESLint error:
|
|
31
|
-
// "Unexpected lexical declaration in case block".
|
|
32
|
-
let result;
|
|
33
|
-
switch (type) {
|
|
34
|
-
// Prevent or allow navigation that was initiated by the application
|
|
35
|
-
// by dispatching a `.push()` or `.replace()` action.
|
|
36
|
-
//
|
|
37
|
-
// It doesn't handle `.shift()` navigation actions because it doesn't yet know
|
|
38
|
-
// the `location` that it's gonna `shift` to. Instead, it waits for the web browser
|
|
39
|
-
// to "shift" to that `location` and then reads it and rewinds the "shift"
|
|
40
|
-
// if it should've been blocked. That is handled in the `case ActionTypes.UPDATE` block.
|
|
41
|
-
//
|
|
42
|
-
// This type of "shifting" and then rewinding the "shift" doesn't really matter to the application at all.
|
|
43
|
-
// From the application's point of view, all of that doesn't matter and even doesn't exist.
|
|
44
|
-
// All that exists from the application's point of view is the `location` object in the Redux state.
|
|
45
|
-
// Until the `location` object in the Redux state is updated, the old page is still rendered.
|
|
46
|
-
// The appliation is only concerned with the updates of the `location` object in the Redux state
|
|
47
|
-
// and completely ignores any updates to the URL in the web browser's address bar.
|
|
48
|
-
//
|
|
49
|
-
case _ActionTypes.default.NAVIGATE:
|
|
50
|
-
// `resultValue` variable name works around a stupid javascript error:
|
|
51
|
-
// "Cannot redeclare block-scoped variable 'result'".
|
|
52
|
-
result = (0, _navigationBlockers.runNavigationBlockers)((0, _navigationBlockers.getNavigationBlockers)(session), payload);
|
|
53
|
-
if ((0, _isPromise.default)(result)) {
|
|
54
|
-
const status = createNavigationBlockersEvaluationStatus();
|
|
55
|
-
// eslint-disable-next-line consistent-return
|
|
56
|
-
result.then(resultValue => {
|
|
57
|
-
if (!status.cancelled) {
|
|
58
|
-
if (!resultValue) {
|
|
59
|
-
return next(action);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
} else if (!result) {
|
|
64
|
-
return next(action);
|
|
65
|
-
}
|
|
66
|
-
// eslint-disable-next-line consistent-return
|
|
67
|
-
return;
|
|
68
|
-
|
|
69
|
-
// One can notice that this "middleware" handles both `NAVIGATE` and `UPDATE` Redux actions,
|
|
70
|
-
// even though a `NAVIGATE` action normally always causes a follow-up `UPDATE` Redux action.
|
|
71
|
-
// There's no contradiction here: if a navigation blocker should block a certain navigation,
|
|
72
|
-
// it will do that at the `NAVIGATION` stage and it won't get to the `UPDATE` stage, so it
|
|
73
|
-
// won't be called "second time" or something like that.
|
|
74
|
-
//
|
|
75
|
-
// One could ask then: Why handle `UPDATE` Redux action at all?
|
|
76
|
-
// The reason why it handles `UPDATE` Redux actions here is because
|
|
77
|
-
// `NAVIGATE` Redux actions are only emitted for programmatic "push" or "replace" navigation
|
|
78
|
-
// initiated by the application code, and there're other cases of navigation such as
|
|
79
|
-
// programmatic "shift" navigation or when the user manually clicks "Back" or "Forward" button
|
|
80
|
-
// in a web browser. Such "other" cases could only be handled by reacting to an `UPDATE` Redux action
|
|
81
|
-
// which is only emitted after the URL in the browser's address bar has changed.
|
|
82
|
-
//
|
|
83
|
-
// But there's no real drawback in reacting to an `UPDATE` Redux action "post factum" because
|
|
84
|
-
// from the application's point of view the address bar doesn't matter and even doesn't exist.
|
|
85
|
-
// All that exists from the application's point of view is the `location` object in the Redux state.
|
|
86
|
-
// Until the `location` object in the Redux state is updated, the old page is still rendered.
|
|
87
|
-
// The appliation is only concerned with the updates of the `location` object in the Redux state
|
|
88
|
-
// and completely ignores any updates to the URL in the web browser's address bar.
|
|
89
|
-
//
|
|
90
|
-
// So here, the "middleware" attempts to prevent or allow navigation that has already happened
|
|
91
|
-
// in the web browser's address bar but hasn't yet happened in Redux state.
|
|
92
|
-
// For example, it could be a user clicking a "Back"/"Forward" button in their web browser.
|
|
93
|
-
// If such navigation should've been blocked, it will simply not update the `locaiton` object in Redux state,
|
|
94
|
-
// and it will also "rewind" the change of the URL in the web browser's address bar so that it's consistent
|
|
95
|
-
// with the `location` in Redux state.
|
|
96
|
-
//
|
|
97
|
-
case _ActionTypes.default.UPDATE:
|
|
98
|
-
// If no navigation blockers to run, don't do anything.
|
|
99
|
-
if ((0, _navigationBlockers.getNavigationBlockers)(session).length === 0) {
|
|
100
|
-
return next(action);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// If it was the initial page load or a redirect,
|
|
104
|
-
// it's not really a navigation that could be rolled back.
|
|
105
|
-
if (payload.delta === 0) {
|
|
106
|
-
return next(action);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// It's not really possible for a location to not have a `delta` property in a web browser session.
|
|
110
|
-
// So this case is not something that's supposed to happen in real life.
|
|
111
|
-
// Rather, it's a guard against an unsupported or incorrect session implementation or something like that.
|
|
112
|
-
// If there's no `delta` property on the location, it means that the previous location can't be rewound to,
|
|
113
|
-
// so it can't really "prevent" the navigation that has just happened.
|
|
114
|
-
if (payload.delta === null) {
|
|
115
|
-
return next(action);
|
|
116
|
-
}
|
|
117
|
-
result = (0, _navigationBlockers.runNavigationBlockers)((0, _navigationBlockers.getNavigationBlockers)(session), payload);
|
|
118
|
-
if ((0, _isPromise.default)(result)) {
|
|
119
|
-
const status = createNavigationBlockersEvaluationStatus();
|
|
120
|
-
|
|
121
|
-
// While location blockers are running, rewind to the previous location.
|
|
122
|
-
ignoreLocationSubscriptionEvents(() => {
|
|
123
|
-
session.navigation.shift(-payload.delta);
|
|
124
|
-
});
|
|
125
|
-
result.then(promiseResult => {
|
|
126
|
-
if (promiseResult) {
|
|
127
|
-
// Navigation blocked.
|
|
128
|
-
// Already rewound to a previous location.
|
|
129
|
-
} else if (!status.cancelled) {
|
|
130
|
-
// Navigation not blocked.
|
|
131
|
-
// Rewind back to the new location.
|
|
132
|
-
ignoreLocationSubscriptionEvents(() => {
|
|
133
|
-
session.navigation.shift(payload.delta);
|
|
134
|
-
});
|
|
135
|
-
// Update the location.
|
|
136
|
-
next(action);
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
} else if (result) {
|
|
140
|
-
// Prevent the navigation: rewind to the previous location.
|
|
141
|
-
ignoreLocationSubscriptionEvents(() => {
|
|
142
|
-
session.navigation.shift(-payload.delta);
|
|
143
|
-
});
|
|
144
|
-
} else {
|
|
145
|
-
// Update the location.
|
|
146
|
-
return next(action);
|
|
147
|
-
}
|
|
148
|
-
// eslint-disable-next-line consistent-return
|
|
149
|
-
return;
|
|
150
|
-
|
|
151
|
-
// Remove any navigation blockers on `DISPOSE` event.
|
|
152
|
-
case _ActionTypes.default.DISPOSE:
|
|
153
|
-
(0, _navigationBlockers.removeAllNavigationBlockers)(session);
|
|
154
|
-
return next(action);
|
|
155
|
-
default:
|
|
156
|
-
return next(action);
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
module.exports = exports.default;
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.default = createTransformLocationMiddleware;
|
|
5
|
-
var _ActionTypes = _interopRequireDefault(require("../ActionTypes"));
|
|
6
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
-
// Creates a "middleware" that transforms action payload (location).
|
|
8
|
-
function createTransformLocationMiddleware({
|
|
9
|
-
transformInputLocation,
|
|
10
|
-
transformSubscriptionLocation
|
|
11
|
-
}) {
|
|
12
|
-
return function transformLocationMiddleware() {
|
|
13
|
-
return next => action => {
|
|
14
|
-
const {
|
|
15
|
-
type,
|
|
16
|
-
payload
|
|
17
|
-
} = action;
|
|
18
|
-
switch (type) {
|
|
19
|
-
// Transforms `NAVIGATE` action payload (`location`).
|
|
20
|
-
case _ActionTypes.default.NAVIGATE:
|
|
21
|
-
return next({
|
|
22
|
-
type,
|
|
23
|
-
payload: transformInputLocation(payload)
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
// Transforms `UPDATE` action payload (input `location`).
|
|
27
|
-
case _ActionTypes.default.UPDATE:
|
|
28
|
-
return next({
|
|
29
|
-
type,
|
|
30
|
-
payload: transformSubscriptionLocation(payload)
|
|
31
|
-
});
|
|
32
|
-
default:
|
|
33
|
-
return next(action);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
module.exports = exports.default;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.default = onlyAllowedOnClientSide;
|
|
5
|
-
function onlyAllowedOnClientSide() {
|
|
6
|
-
if (typeof window === 'undefined') {
|
|
7
|
-
throw new Error('This function can only be called on client side');
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
module.exports = exports.default;
|