@remix-run/router 1.3.1 → 1.3.2-pre.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remix-run/router",
3
- "version": "1.3.1",
3
+ "version": "1.3.2-pre.0",
4
4
  "description": "Nested/Data-driven/Framework-agnostic Routing",
5
5
  "keywords": [
6
6
  "remix",
package/router.ts CHANGED
@@ -621,6 +621,8 @@ export const IDLE_BLOCKER: BlockerUnblocked = {
621
621
  location: undefined,
622
622
  };
623
623
 
624
+ const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
625
+
624
626
  const isBrowser =
625
627
  typeof window !== "undefined" &&
626
628
  typeof window.document !== "undefined" &&
@@ -754,10 +756,6 @@ export function createRouter(init: RouterInit): Router {
754
756
  // cancel active deferreds for eliminated routes.
755
757
  let activeDeferreds = new Map<string, DeferredData>();
756
758
 
757
- // We ony support a single active blocker at the moment since we don't have
758
- // any compelling use cases for multi-blocker yet
759
- let activeBlocker: string | null = null;
760
-
761
759
  // Store blocker functions in a separate Map outside of router state since
762
760
  // we don't need to update UI state if they change
763
761
  let blockerFunctions = new Map<string, BlockerFunction>();
@@ -782,7 +780,7 @@ export function createRouter(init: RouterInit): Router {
782
780
  }
783
781
 
784
782
  warning(
785
- activeBlocker != null && delta === null,
783
+ blockerFunctions.size === 0 || delta != null,
786
784
  "You are trying to use a blocker on a POP navigation to a location " +
787
785
  "that was not created by @remix-run/router. This will fail silently in " +
788
786
  "production. This can happen if you are navigating outside the router " +
@@ -1915,8 +1913,12 @@ export function createRouter(init: RouterInit): Router {
1915
1913
  "Expected a location on the redirect navigation"
1916
1914
  );
1917
1915
 
1918
- // Check if this an external redirect that goes to a new origin
1919
- if (isBrowser && typeof window?.location !== "undefined") {
1916
+ // Check if this an absolute external redirect that goes to a new origin
1917
+ if (
1918
+ ABSOLUTE_URL_REGEX.test(redirect.location) &&
1919
+ isBrowser &&
1920
+ typeof window?.location !== "undefined"
1921
+ ) {
1920
1922
  let newOrigin = init.history.createURL(redirect.location).origin;
1921
1923
  if (window.location.origin !== newOrigin) {
1922
1924
  if (replace) {
@@ -2123,12 +2125,6 @@ export function createRouter(init: RouterInit): Router {
2123
2125
 
2124
2126
  if (blockerFunctions.get(key) !== fn) {
2125
2127
  blockerFunctions.set(key, fn);
2126
- if (activeBlocker == null) {
2127
- // This is now the active blocker
2128
- activeBlocker = key;
2129
- } else if (key !== activeBlocker) {
2130
- warning(false, "A router only supports one blocker at a time");
2131
- }
2132
2128
  }
2133
2129
 
2134
2130
  return blocker;
@@ -2137,9 +2133,6 @@ export function createRouter(init: RouterInit): Router {
2137
2133
  function deleteBlocker(key: string) {
2138
2134
  state.blockers.delete(key);
2139
2135
  blockerFunctions.delete(key);
2140
- if (activeBlocker === key) {
2141
- activeBlocker = null;
2142
- }
2143
2136
  }
2144
2137
 
2145
2138
  // Utility function to update blockers, ensuring valid state transitions
@@ -2170,18 +2163,19 @@ export function createRouter(init: RouterInit): Router {
2170
2163
  nextLocation: Location;
2171
2164
  historyAction: HistoryAction;
2172
2165
  }): string | undefined {
2173
- if (activeBlocker == null) {
2166
+ if (blockerFunctions.size === 0) {
2174
2167
  return;
2175
2168
  }
2176
2169
 
2177
- // We only allow a single blocker at the moment. This will need to be
2178
- // updated if we enhance to support multiple blockers in the future
2179
- let blockerFunction = blockerFunctions.get(activeBlocker);
2180
- invariant(
2181
- blockerFunction,
2182
- "Could not find a function for the active blocker"
2183
- );
2184
- let blocker = state.blockers.get(activeBlocker);
2170
+ // We ony support a single active blocker at the moment since we don't have
2171
+ // any compelling use cases for multi-blocker yet
2172
+ if (blockerFunctions.size > 1) {
2173
+ warning(false, "A router only supports one blocker at a time");
2174
+ }
2175
+
2176
+ let entries = Array.from(blockerFunctions.entries());
2177
+ let [blockerKey, blockerFunction] = entries[entries.length - 1];
2178
+ let blocker = state.blockers.get(blockerKey);
2185
2179
 
2186
2180
  if (blocker && blocker.state === "proceeding") {
2187
2181
  // If the blocker is currently proceeding, we don't need to re-check
@@ -2192,7 +2186,7 @@ export function createRouter(init: RouterInit): Router {
2192
2186
  // At this point, we know we're unblocked/blocked so we need to check the
2193
2187
  // user-provided blocker function
2194
2188
  if (blockerFunction({ currentLocation, nextLocation, historyAction })) {
2195
- return activeBlocker;
2189
+ return blockerKey;
2196
2190
  }
2197
2191
  }
2198
2192
 
@@ -3093,10 +3087,8 @@ async function callLoaderOrAction(
3093
3087
  "Redirects returned/thrown from loaders/actions must have a Location header"
3094
3088
  );
3095
3089
 
3096
- let isAbsolute = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(location);
3097
-
3098
3090
  // Support relative routing in internal redirects
3099
- if (!isAbsolute) {
3091
+ if (!ABSOLUTE_URL_REGEX.test(location)) {
3100
3092
  let activeMatches = matches.slice(0, matches.indexOf(match) + 1);
3101
3093
  let routePathnames = getPathContributingMatches(activeMatches).map(
3102
3094
  (match) => match.pathnameBase