@remix-run/router 1.3.0-pre.0 → 1.3.0-pre.2
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 +12 -0
- package/dist/history.d.ts +4 -0
- package/dist/router.cjs.js +259 -33
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +49 -2
- package/dist/router.js +259 -34
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +259 -33
- package/dist/router.umd.js.map +1 -1
- package/dist/router.umd.min.js +2 -2
- package/dist/router.umd.min.js.map +1 -1
- package/history.ts +56 -12
- package/package.json +1 -1
- package/router.ts +271 -14
- package/utils.ts +1 -1
package/dist/router.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.3.0-pre.
|
|
2
|
+
* @remix-run/router v1.3.0-pre.2
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -139,7 +139,8 @@
|
|
|
139
139
|
if (v5Compat && listener) {
|
|
140
140
|
listener({
|
|
141
141
|
action,
|
|
142
|
-
location: nextLocation
|
|
142
|
+
location: nextLocation,
|
|
143
|
+
delta: 1
|
|
143
144
|
});
|
|
144
145
|
}
|
|
145
146
|
},
|
|
@@ -152,19 +153,23 @@
|
|
|
152
153
|
if (v5Compat && listener) {
|
|
153
154
|
listener({
|
|
154
155
|
action,
|
|
155
|
-
location: nextLocation
|
|
156
|
+
location: nextLocation,
|
|
157
|
+
delta: 0
|
|
156
158
|
});
|
|
157
159
|
}
|
|
158
160
|
},
|
|
159
161
|
|
|
160
162
|
go(delta) {
|
|
161
163
|
action = exports.Action.Pop;
|
|
162
|
-
|
|
164
|
+
let nextIndex = clampIndex(index + delta);
|
|
165
|
+
let nextLocation = entries[nextIndex];
|
|
166
|
+
index = nextIndex;
|
|
163
167
|
|
|
164
168
|
if (listener) {
|
|
165
169
|
listener({
|
|
166
170
|
action,
|
|
167
|
-
location:
|
|
171
|
+
location: nextLocation,
|
|
172
|
+
delta
|
|
168
173
|
});
|
|
169
174
|
}
|
|
170
175
|
},
|
|
@@ -323,10 +328,11 @@
|
|
|
323
328
|
*/
|
|
324
329
|
|
|
325
330
|
|
|
326
|
-
function getHistoryState(location) {
|
|
331
|
+
function getHistoryState(location, index) {
|
|
327
332
|
return {
|
|
328
333
|
usr: location.state,
|
|
329
|
-
key: location.key
|
|
334
|
+
key: location.key,
|
|
335
|
+
idx: index
|
|
330
336
|
};
|
|
331
337
|
}
|
|
332
338
|
/**
|
|
@@ -410,15 +416,45 @@
|
|
|
410
416
|
let globalHistory = window.history;
|
|
411
417
|
let action = exports.Action.Pop;
|
|
412
418
|
let listener = null;
|
|
419
|
+
let index = getIndex(); // Index should only be null when we initialize. If not, it's because the
|
|
420
|
+
// user called history.pushState or history.replaceState directly, in which
|
|
421
|
+
// case we should log a warning as it will result in bugs.
|
|
422
|
+
|
|
423
|
+
if (index == null) {
|
|
424
|
+
index = 0;
|
|
425
|
+
globalHistory.replaceState(_extends({}, globalHistory.state, {
|
|
426
|
+
idx: index
|
|
427
|
+
}), "");
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function getIndex() {
|
|
431
|
+
let state = globalHistory.state || {
|
|
432
|
+
idx: null
|
|
433
|
+
};
|
|
434
|
+
return state.idx;
|
|
435
|
+
}
|
|
413
436
|
|
|
414
437
|
function handlePop() {
|
|
415
|
-
|
|
438
|
+
let nextAction = exports.Action.Pop;
|
|
439
|
+
let nextIndex = getIndex();
|
|
416
440
|
|
|
417
|
-
if (
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
441
|
+
if (nextIndex != null) {
|
|
442
|
+
let delta = nextIndex - index;
|
|
443
|
+
action = nextAction;
|
|
444
|
+
index = nextIndex;
|
|
445
|
+
|
|
446
|
+
if (listener) {
|
|
447
|
+
listener({
|
|
448
|
+
action,
|
|
449
|
+
location: history.location,
|
|
450
|
+
delta
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
} else {
|
|
454
|
+
warning$1(false, // TODO: Write up a doc that explains our blocking strategy in detail
|
|
455
|
+
// and link to it here so people can understand better what is going on
|
|
456
|
+
// and how to avoid it.
|
|
457
|
+
"You are trying to block a POP navigation to a location that was not " + "created by @remix-run/router. The block will fail silently in " + "production, but in general you should do all navigation with the " + "router (instead of using window.history.pushState directly) " + "to avoid this situation.");
|
|
422
458
|
}
|
|
423
459
|
}
|
|
424
460
|
|
|
@@ -426,7 +462,8 @@
|
|
|
426
462
|
action = exports.Action.Push;
|
|
427
463
|
let location = createLocation(history.location, to, state);
|
|
428
464
|
if (validateLocation) validateLocation(location, to);
|
|
429
|
-
|
|
465
|
+
index = getIndex() + 1;
|
|
466
|
+
let historyState = getHistoryState(location, index);
|
|
430
467
|
let url = history.createHref(location); // try...catch because iOS limits us to 100 pushState calls :/
|
|
431
468
|
|
|
432
469
|
try {
|
|
@@ -440,7 +477,8 @@
|
|
|
440
477
|
if (v5Compat && listener) {
|
|
441
478
|
listener({
|
|
442
479
|
action,
|
|
443
|
-
location: history.location
|
|
480
|
+
location: history.location,
|
|
481
|
+
delta: 1
|
|
444
482
|
});
|
|
445
483
|
}
|
|
446
484
|
}
|
|
@@ -449,14 +487,16 @@
|
|
|
449
487
|
action = exports.Action.Replace;
|
|
450
488
|
let location = createLocation(history.location, to, state);
|
|
451
489
|
if (validateLocation) validateLocation(location, to);
|
|
452
|
-
|
|
490
|
+
index = getIndex();
|
|
491
|
+
let historyState = getHistoryState(location, index);
|
|
453
492
|
let url = history.createHref(location);
|
|
454
493
|
globalHistory.replaceState(historyState, "", url);
|
|
455
494
|
|
|
456
495
|
if (v5Compat && listener) {
|
|
457
496
|
listener({
|
|
458
497
|
action,
|
|
459
|
-
location: history.location
|
|
498
|
+
location: history.location,
|
|
499
|
+
delta: 0
|
|
460
500
|
});
|
|
461
501
|
}
|
|
462
502
|
}
|
|
@@ -992,7 +1032,7 @@
|
|
|
992
1032
|
if (typeof console !== "undefined") console.warn(message);
|
|
993
1033
|
|
|
994
1034
|
try {
|
|
995
|
-
// Welcome to debugging
|
|
1035
|
+
// Welcome to debugging @remix-run/router!
|
|
996
1036
|
//
|
|
997
1037
|
// This error is thrown as a convenience so you can more easily
|
|
998
1038
|
// find the source for a warning that appears in the console by
|
|
@@ -1435,6 +1475,12 @@
|
|
|
1435
1475
|
formEncType: undefined,
|
|
1436
1476
|
formData: undefined
|
|
1437
1477
|
};
|
|
1478
|
+
const IDLE_BLOCKER = {
|
|
1479
|
+
state: "unblocked",
|
|
1480
|
+
proceed: undefined,
|
|
1481
|
+
reset: undefined,
|
|
1482
|
+
location: undefined
|
|
1483
|
+
};
|
|
1438
1484
|
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
1439
1485
|
const isServer = !isBrowser; //#endregion
|
|
1440
1486
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -1499,7 +1545,8 @@
|
|
|
1499
1545
|
loaderData: init.hydrationData && init.hydrationData.loaderData || {},
|
|
1500
1546
|
actionData: init.hydrationData && init.hydrationData.actionData || null,
|
|
1501
1547
|
errors: init.hydrationData && init.hydrationData.errors || initialErrors,
|
|
1502
|
-
fetchers: new Map()
|
|
1548
|
+
fetchers: new Map(),
|
|
1549
|
+
blockers: new Map()
|
|
1503
1550
|
}; // -- Stateful internal variables to manage navigations --
|
|
1504
1551
|
// Current navigation in progress (to be committed in completeNavigation)
|
|
1505
1552
|
|
|
@@ -1541,7 +1588,16 @@
|
|
|
1541
1588
|
// promise resolves we update loaderData. If a new navigation starts we
|
|
1542
1589
|
// cancel active deferreds for eliminated routes.
|
|
1543
1590
|
|
|
1544
|
-
let activeDeferreds = new Map(); //
|
|
1591
|
+
let activeDeferreds = new Map(); // We ony support a single active blocker at the moment since we don't have
|
|
1592
|
+
// any compelling use cases for multi-blocker yet
|
|
1593
|
+
|
|
1594
|
+
let activeBlocker = null; // Store blocker functions in a separate Map outside of router state since
|
|
1595
|
+
// we don't need to update UI state if they change
|
|
1596
|
+
|
|
1597
|
+
let blockerFunctions = new Map(); // Flag to ignore the next history update, so we can revert the URL change on
|
|
1598
|
+
// a POP navigation that was blocked by the user without touching router state
|
|
1599
|
+
|
|
1600
|
+
let ignoreNextHistoryUpdate = false; // Initialize the router, all side effects should be kicked off from here.
|
|
1545
1601
|
// Implemented as a Fluent API for ease of:
|
|
1546
1602
|
// let router = createRouter(init).initialize();
|
|
1547
1603
|
|
|
@@ -1551,8 +1607,54 @@
|
|
|
1551
1607
|
unlistenHistory = init.history.listen(_ref => {
|
|
1552
1608
|
let {
|
|
1553
1609
|
action: historyAction,
|
|
1554
|
-
location
|
|
1610
|
+
location,
|
|
1611
|
+
delta
|
|
1555
1612
|
} = _ref;
|
|
1613
|
+
|
|
1614
|
+
// Ignore this event if it was just us resetting the URL from a
|
|
1615
|
+
// blocked POP navigation
|
|
1616
|
+
if (ignoreNextHistoryUpdate) {
|
|
1617
|
+
ignoreNextHistoryUpdate = false;
|
|
1618
|
+
return;
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
let blockerKey = shouldBlockNavigation({
|
|
1622
|
+
currentLocation: state.location,
|
|
1623
|
+
nextLocation: location,
|
|
1624
|
+
historyAction
|
|
1625
|
+
});
|
|
1626
|
+
|
|
1627
|
+
if (blockerKey) {
|
|
1628
|
+
// Restore the URL to match the current UI, but don't update router state
|
|
1629
|
+
ignoreNextHistoryUpdate = true;
|
|
1630
|
+
init.history.go(delta * -1); // Put the blocker into a blocked state
|
|
1631
|
+
|
|
1632
|
+
updateBlocker(blockerKey, {
|
|
1633
|
+
state: "blocked",
|
|
1634
|
+
location,
|
|
1635
|
+
|
|
1636
|
+
proceed() {
|
|
1637
|
+
updateBlocker(blockerKey, {
|
|
1638
|
+
state: "proceeding",
|
|
1639
|
+
proceed: undefined,
|
|
1640
|
+
reset: undefined,
|
|
1641
|
+
location
|
|
1642
|
+
}); // Re-do the same POP navigation we just blocked
|
|
1643
|
+
|
|
1644
|
+
init.history.go(delta);
|
|
1645
|
+
},
|
|
1646
|
+
|
|
1647
|
+
reset() {
|
|
1648
|
+
deleteBlocker(blockerKey);
|
|
1649
|
+
updateState({
|
|
1650
|
+
blockers: new Map(router.state.blockers)
|
|
1651
|
+
});
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
});
|
|
1655
|
+
return;
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1556
1658
|
return startNavigation(historyAction, location);
|
|
1557
1659
|
}); // Kick off initial data load if needed. Use Pop to avoid modifying history
|
|
1558
1660
|
|
|
@@ -1572,6 +1674,7 @@
|
|
|
1572
1674
|
subscribers.clear();
|
|
1573
1675
|
pendingNavigationController && pendingNavigationController.abort();
|
|
1574
1676
|
state.fetchers.forEach((_, key) => deleteFetcher(key));
|
|
1677
|
+
state.blockers.forEach((_, key) => deleteBlocker(key));
|
|
1575
1678
|
} // Subscribe to state updates for the router
|
|
1576
1679
|
|
|
1577
1680
|
|
|
@@ -1592,7 +1695,7 @@
|
|
|
1592
1695
|
|
|
1593
1696
|
|
|
1594
1697
|
function completeNavigation(location, newState) {
|
|
1595
|
-
var _location$state;
|
|
1698
|
+
var _location$state, _location$state2;
|
|
1596
1699
|
|
|
1597
1700
|
// Deduce if we're in a loading/actionReload state:
|
|
1598
1701
|
// - We have committed actionData in the store
|
|
@@ -1618,7 +1721,16 @@
|
|
|
1618
1721
|
} // Always preserve any existing loaderData from re-used routes
|
|
1619
1722
|
|
|
1620
1723
|
|
|
1621
|
-
let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData;
|
|
1724
|
+
let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData; // On a successful navigation we can assume we got through all blockers
|
|
1725
|
+
// so we can start fresh
|
|
1726
|
+
|
|
1727
|
+
for (let [key] of blockerFunctions) {
|
|
1728
|
+
deleteBlocker(key);
|
|
1729
|
+
} // Always respect the user flag. Otherwise don't reset on mutation
|
|
1730
|
+
// submission navigations unless they redirect
|
|
1731
|
+
|
|
1732
|
+
|
|
1733
|
+
let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true;
|
|
1622
1734
|
updateState(_extends({}, newState, {
|
|
1623
1735
|
// matches, errors, fetchers go through as-is
|
|
1624
1736
|
actionData,
|
|
@@ -1628,9 +1740,9 @@
|
|
|
1628
1740
|
initialized: true,
|
|
1629
1741
|
navigation: IDLE_NAVIGATION,
|
|
1630
1742
|
revalidation: "idle",
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1743
|
+
restoreScrollPosition: getSavedScrollPosition(location, newState.matches || state.matches),
|
|
1744
|
+
preventScrollReset,
|
|
1745
|
+
blockers: new Map(state.blockers)
|
|
1634
1746
|
}));
|
|
1635
1747
|
|
|
1636
1748
|
if (isUninterruptedRevalidation) ; else if (pendingAction === exports.Action.Pop) ; else if (pendingAction === exports.Action.Push) {
|
|
@@ -1661,13 +1773,14 @@
|
|
|
1661
1773
|
submission,
|
|
1662
1774
|
error
|
|
1663
1775
|
} = normalizeNavigateOptions(to, opts);
|
|
1664
|
-
let
|
|
1776
|
+
let currentLocation = state.location;
|
|
1777
|
+
let nextLocation = createLocation(state.location, path, opts && opts.state); // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded
|
|
1665
1778
|
// URL from window.location, so we need to encode it here so the behavior
|
|
1666
1779
|
// remains the same as POP and non-data-router usages. new URL() does all
|
|
1667
1780
|
// the same encoding we'd get from a history.pushState/window.location read
|
|
1668
1781
|
// without having to touch history
|
|
1669
1782
|
|
|
1670
|
-
|
|
1783
|
+
nextLocation = _extends({}, nextLocation, init.history.encodeLocation(nextLocation));
|
|
1671
1784
|
let userReplace = opts && opts.replace != null ? opts.replace : undefined;
|
|
1672
1785
|
let historyAction = exports.Action.Push;
|
|
1673
1786
|
|
|
@@ -1682,7 +1795,41 @@
|
|
|
1682
1795
|
}
|
|
1683
1796
|
|
|
1684
1797
|
let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined;
|
|
1685
|
-
|
|
1798
|
+
let blockerKey = shouldBlockNavigation({
|
|
1799
|
+
currentLocation,
|
|
1800
|
+
nextLocation,
|
|
1801
|
+
historyAction
|
|
1802
|
+
});
|
|
1803
|
+
|
|
1804
|
+
if (blockerKey) {
|
|
1805
|
+
// Put the blocker into a blocked state
|
|
1806
|
+
updateBlocker(blockerKey, {
|
|
1807
|
+
state: "blocked",
|
|
1808
|
+
location: nextLocation,
|
|
1809
|
+
|
|
1810
|
+
proceed() {
|
|
1811
|
+
updateBlocker(blockerKey, {
|
|
1812
|
+
state: "proceeding",
|
|
1813
|
+
proceed: undefined,
|
|
1814
|
+
reset: undefined,
|
|
1815
|
+
location: nextLocation
|
|
1816
|
+
}); // Send the same navigation through
|
|
1817
|
+
|
|
1818
|
+
navigate(to, opts);
|
|
1819
|
+
},
|
|
1820
|
+
|
|
1821
|
+
reset() {
|
|
1822
|
+
deleteBlocker(blockerKey);
|
|
1823
|
+
updateState({
|
|
1824
|
+
blockers: new Map(state.blockers)
|
|
1825
|
+
});
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
});
|
|
1829
|
+
return;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
return await startNavigation(historyAction, nextLocation, {
|
|
1686
1833
|
submission,
|
|
1687
1834
|
// Send through the formData serialization error if we have one so we can
|
|
1688
1835
|
// render at the right error boundary after we match routes
|
|
@@ -2454,7 +2601,9 @@
|
|
|
2454
2601
|
await startNavigation(redirectHistoryAction, redirectLocation, {
|
|
2455
2602
|
submission: _extends({}, submission, {
|
|
2456
2603
|
formAction: redirect.location
|
|
2457
|
-
})
|
|
2604
|
+
}),
|
|
2605
|
+
// Preserve this flag across redirects
|
|
2606
|
+
preventScrollReset: pendingPreventScrollReset
|
|
2458
2607
|
});
|
|
2459
2608
|
} else {
|
|
2460
2609
|
// Otherwise, we kick off a new loading navigation, preserving the
|
|
@@ -2467,7 +2616,9 @@
|
|
|
2467
2616
|
formAction: submission ? submission.formAction : undefined,
|
|
2468
2617
|
formEncType: submission ? submission.formEncType : undefined,
|
|
2469
2618
|
formData: submission ? submission.formData : undefined
|
|
2470
|
-
}
|
|
2619
|
+
},
|
|
2620
|
+
// Preserve this flag across redirects
|
|
2621
|
+
preventScrollReset: pendingPreventScrollReset
|
|
2471
2622
|
});
|
|
2472
2623
|
}
|
|
2473
2624
|
}
|
|
@@ -2586,6 +2737,78 @@
|
|
|
2586
2737
|
return yeetedKeys.length > 0;
|
|
2587
2738
|
}
|
|
2588
2739
|
|
|
2740
|
+
function getBlocker(key, fn) {
|
|
2741
|
+
let blocker = state.blockers.get(key) || IDLE_BLOCKER;
|
|
2742
|
+
|
|
2743
|
+
if (blockerFunctions.get(key) !== fn) {
|
|
2744
|
+
blockerFunctions.set(key, fn);
|
|
2745
|
+
|
|
2746
|
+
if (activeBlocker == null) {
|
|
2747
|
+
// This is now the active blocker
|
|
2748
|
+
activeBlocker = key;
|
|
2749
|
+
} else if (key !== activeBlocker) {
|
|
2750
|
+
warning(false, "A router only supports one blocker at a time");
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
|
|
2754
|
+
return blocker;
|
|
2755
|
+
}
|
|
2756
|
+
|
|
2757
|
+
function deleteBlocker(key) {
|
|
2758
|
+
state.blockers.delete(key);
|
|
2759
|
+
blockerFunctions.delete(key);
|
|
2760
|
+
|
|
2761
|
+
if (activeBlocker === key) {
|
|
2762
|
+
activeBlocker = null;
|
|
2763
|
+
}
|
|
2764
|
+
} // Utility function to update blockers, ensuring valid state transitions
|
|
2765
|
+
|
|
2766
|
+
|
|
2767
|
+
function updateBlocker(key, newBlocker) {
|
|
2768
|
+
let blocker = state.blockers.get(key) || IDLE_BLOCKER; // Poor mans state machine :)
|
|
2769
|
+
// https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM
|
|
2770
|
+
|
|
2771
|
+
invariant(blocker.state === "unblocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "proceeding" || blocker.state === "blocked" && newBlocker.state === "unblocked" || blocker.state === "proceeding" && newBlocker.state === "unblocked", "Invalid blocker state transition: " + blocker.state + " -> " + newBlocker.state);
|
|
2772
|
+
state.blockers.set(key, newBlocker);
|
|
2773
|
+
updateState({
|
|
2774
|
+
blockers: new Map(state.blockers)
|
|
2775
|
+
});
|
|
2776
|
+
}
|
|
2777
|
+
|
|
2778
|
+
function shouldBlockNavigation(_ref10) {
|
|
2779
|
+
let {
|
|
2780
|
+
currentLocation,
|
|
2781
|
+
nextLocation,
|
|
2782
|
+
historyAction
|
|
2783
|
+
} = _ref10;
|
|
2784
|
+
|
|
2785
|
+
if (activeBlocker == null) {
|
|
2786
|
+
return;
|
|
2787
|
+
} // We only allow a single blocker at the moment. This will need to be
|
|
2788
|
+
// updated if we enhance to support multiple blockers in the future
|
|
2789
|
+
|
|
2790
|
+
|
|
2791
|
+
let blockerFunction = blockerFunctions.get(activeBlocker);
|
|
2792
|
+
invariant(blockerFunction, "Could not find a function for the active blocker");
|
|
2793
|
+
let blocker = state.blockers.get(activeBlocker);
|
|
2794
|
+
|
|
2795
|
+
if (blocker && blocker.state === "proceeding") {
|
|
2796
|
+
// If the blocker is currently proceeding, we don't need to re-check
|
|
2797
|
+
// it and can let this navigation continue
|
|
2798
|
+
return;
|
|
2799
|
+
} // At this point, we know we're unblocked/blocked so we need to check the
|
|
2800
|
+
// user-provided blocker function
|
|
2801
|
+
|
|
2802
|
+
|
|
2803
|
+
if (blockerFunction({
|
|
2804
|
+
currentLocation,
|
|
2805
|
+
nextLocation,
|
|
2806
|
+
historyAction
|
|
2807
|
+
})) {
|
|
2808
|
+
return activeBlocker;
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
|
|
2589
2812
|
function cancelActiveDeferreds(predicate) {
|
|
2590
2813
|
let cancelledRouteIds = [];
|
|
2591
2814
|
activeDeferreds.forEach((dfd, routeId) => {
|
|
@@ -2678,6 +2901,8 @@
|
|
|
2678
2901
|
getFetcher,
|
|
2679
2902
|
deleteFetcher,
|
|
2680
2903
|
dispose,
|
|
2904
|
+
getBlocker,
|
|
2905
|
+
deleteBlocker,
|
|
2681
2906
|
_internalFetchControllers: fetchControllers,
|
|
2682
2907
|
_internalActiveDeferreds: activeDeferreds
|
|
2683
2908
|
};
|
|
@@ -3198,8 +3423,8 @@
|
|
|
3198
3423
|
cancelledDeferredRoutes.some(id => id === match.route.id) || shouldRevalidateLoader(history, state.location, state.matches[index], submission, location, match, isRevalidationRequired, actionResult))); // Pick fetcher.loads that need to be revalidated
|
|
3199
3424
|
|
|
3200
3425
|
let revalidatingFetchers = [];
|
|
3201
|
-
fetchLoadMatches && fetchLoadMatches.forEach((
|
|
3202
|
-
let [href, match, fetchMatches] =
|
|
3426
|
+
fetchLoadMatches && fetchLoadMatches.forEach((_ref11, key) => {
|
|
3427
|
+
let [href, match, fetchMatches] = _ref11;
|
|
3203
3428
|
|
|
3204
3429
|
// This fetcher was cancelled from a prior action submission - force reload
|
|
3205
3430
|
if (cancelledFetcherLoads.includes(key)) {
|
|
@@ -3801,6 +4026,7 @@
|
|
|
3801
4026
|
|
|
3802
4027
|
exports.AbortedDeferredError = AbortedDeferredError;
|
|
3803
4028
|
exports.ErrorResponse = ErrorResponse;
|
|
4029
|
+
exports.IDLE_BLOCKER = IDLE_BLOCKER;
|
|
3804
4030
|
exports.IDLE_FETCHER = IDLE_FETCHER;
|
|
3805
4031
|
exports.IDLE_NAVIGATION = IDLE_NAVIGATION;
|
|
3806
4032
|
exports.UNSAFE_DEFERRED_SYMBOL = UNSAFE_DEFERRED_SYMBOL;
|