@remix-run/router 1.0.3-pre.0 → 1.0.3-pre.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/history.ts CHANGED
@@ -125,6 +125,15 @@ export interface History {
125
125
  */
126
126
  createHref(to: To): string;
127
127
 
128
+ /**
129
+ * Encode a location the same way window.history would do (no-op for memory
130
+ * history) so we ensure our PUSH/REPLAC e navigations for data routers
131
+ * behave the same as POP
132
+ *
133
+ * @param location The incoming location from router.navigate()
134
+ */
135
+ encodeLocation(location: Location): Location;
136
+
128
137
  /**
129
138
  * Pushes a new location onto the history stack, increasing its length by one.
130
139
  * If there were any entries in the stack after the current one, they are
@@ -259,6 +268,9 @@ export function createMemoryHistory(
259
268
  createHref(to) {
260
269
  return typeof to === "string" ? to : createPath(to);
261
270
  },
271
+ encodeLocation(location) {
272
+ return location;
273
+ },
262
274
  push(to, state) {
263
275
  action = Action.Push;
264
276
  let nextLocation = createMemoryLocation(to, state);
@@ -527,6 +539,20 @@ export function parsePath(path: string): Partial<Path> {
527
539
  return parsedPath;
528
540
  }
529
541
 
542
+ export function createURL(location: Location | string): URL {
543
+ // window.location.origin is "null" (the literal string value) in Firefox
544
+ // under certain conditions, notably when serving from a local HTML file
545
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297
546
+ let base =
547
+ typeof window !== "undefined" &&
548
+ typeof window.location !== "undefined" &&
549
+ window.location.origin !== "null"
550
+ ? window.location.origin
551
+ : "unknown://unknown";
552
+ let href = typeof location === "string" ? location : createPath(location);
553
+ return new URL(href, base);
554
+ }
555
+
530
556
  export interface UrlHistory extends History {}
531
557
 
532
558
  export type UrlHistoryOptions = {
@@ -610,6 +636,16 @@ function getUrlBasedHistory(
610
636
  createHref(to) {
611
637
  return createHref(window, to);
612
638
  },
639
+ encodeLocation(location) {
640
+ // Encode a Location the same way window.location would
641
+ let url = createURL(createPath(location));
642
+ return {
643
+ ...location,
644
+ pathname: url.pathname,
645
+ search: url.search,
646
+ hash: url.hash,
647
+ };
648
+ },
613
649
  push,
614
650
  replace,
615
651
  go(n) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remix-run/router",
3
- "version": "1.0.3-pre.0",
3
+ "version": "1.0.3-pre.1",
4
4
  "description": "Nested/Data-driven/Framework-agnostic Routing",
5
5
  "keywords": [
6
6
  "remix",
package/router.ts CHANGED
@@ -1,8 +1,9 @@
1
- import type { History, Location, Path, To } from "./history";
1
+ import type { History, Location, To } from "./history";
2
2
  import {
3
3
  Action as HistoryAction,
4
4
  createLocation,
5
5
  createPath,
6
+ createURL,
6
7
  parsePath,
7
8
  } from "./history";
8
9
  import type {
@@ -769,13 +770,7 @@ export function createRouter(init: RouterInit): Router {
769
770
  // remains the same as POP and non-data-router usages. new URL() does all
770
771
  // the same encoding we'd get from a history.pushState/window.location read
771
772
  // without having to touch history
772
- let url = createURL(createPath(location));
773
- location = {
774
- ...location,
775
- pathname: url.pathname,
776
- search: url.search,
777
- hash: url.hash,
778
- };
773
+ location = init.history.encodeLocation(location);
779
774
 
780
775
  let historyAction =
781
776
  (opts && opts.replace) === true || submission != null
@@ -2038,14 +2033,13 @@ export function unstable_createStaticHandler(
2038
2033
  ): Promise<Omit<StaticHandlerContext, "location"> | Response> {
2039
2034
  let result: DataResult;
2040
2035
  if (!actionMatch.route.action) {
2041
- let href = createServerHref(new URL(request.url));
2042
2036
  if (isRouteRequest) {
2043
2037
  throw createRouterErrorResponse(null, {
2044
2038
  status: 405,
2045
2039
  statusText: "Method Not Allowed",
2046
2040
  });
2047
2041
  }
2048
- result = getMethodNotAllowedResult(href);
2042
+ result = getMethodNotAllowedResult(request.url);
2049
2043
  } else {
2050
2044
  result = await callLoaderOrAction(
2051
2045
  "action",
@@ -2288,7 +2282,7 @@ function normalizeNavigateOptions(
2288
2282
  path,
2289
2283
  submission: {
2290
2284
  formMethod: opts.formMethod,
2291
- formAction: createServerHref(parsePath(path)),
2285
+ formAction: stripHashFromPath(path),
2292
2286
  formEncType:
2293
2287
  (opts && opts.formEncType) || "application/x-www-form-urlencoded",
2294
2288
  formData: opts.formData,
@@ -2644,7 +2638,7 @@ function createRequest(
2644
2638
  signal: AbortSignal,
2645
2639
  submission?: Submission
2646
2640
  ): Request {
2647
- let url = createURL(location).toString();
2641
+ let url = createURL(stripHashFromPath(location)).toString();
2648
2642
  let init: RequestInit = { signal };
2649
2643
 
2650
2644
  if (submission) {
@@ -2894,7 +2888,7 @@ function getMethodNotAllowedMatches(routes: AgnosticDataRouteObject[]) {
2894
2888
  }
2895
2889
 
2896
2890
  function getMethodNotAllowedResult(path: Location | string): ErrorResult {
2897
- let href = typeof path === "string" ? path : createServerHref(path);
2891
+ let href = typeof path === "string" ? path : createPath(path);
2898
2892
  console.warn(
2899
2893
  "You're trying to submit to a route that does not have an action. To " +
2900
2894
  "fix this, please add an `action` function to the route for " +
@@ -2916,9 +2910,9 @@ function findRedirect(results: DataResult[]): RedirectResult | undefined {
2916
2910
  }
2917
2911
  }
2918
2912
 
2919
- // Create an href to represent a "server" URL without the hash
2920
- function createServerHref(location: Partial<Path> | Location | URL) {
2921
- return (location.pathname || "") + (location.search || "");
2913
+ function stripHashFromPath(path: To) {
2914
+ let parsedPath = typeof path === "string" ? parsePath(path) : path;
2915
+ return createPath({ ...parsedPath, hash: "" });
2922
2916
  }
2923
2917
 
2924
2918
  function isHashChangeOnly(a: Location, b: Location): boolean {
@@ -3058,14 +3052,4 @@ function getTargetMatch(
3058
3052
  let pathMatches = getPathContributingMatches(matches);
3059
3053
  return pathMatches[pathMatches.length - 1];
3060
3054
  }
3061
-
3062
- function createURL(location: Location | string): URL {
3063
- let base =
3064
- typeof window !== "undefined" && typeof window.location !== "undefined"
3065
- ? window.location.origin
3066
- : "unknown://unknown";
3067
- let href =
3068
- typeof location === "string" ? location : createServerHref(location);
3069
- return new URL(href, base);
3070
- }
3071
3055
  //#endregion
package/utils.ts CHANGED
@@ -331,9 +331,12 @@ export function matchRoutes<
331
331
  for (let i = 0; matches == null && i < branches.length; ++i) {
332
332
  matches = matchRouteBranch<string, RouteObjectType>(
333
333
  branches[i],
334
- // incoming pathnames are always encoded from either window.location or
335
- // from route.navigate, but we want to match against the unencoded paths
336
- // in the route definitions
334
+ // Incoming pathnames are generally encoded from either window.location
335
+ // or from router.navigate, but we want to match against the unencoded
336
+ // paths in the route definitions. Memory router locations won't be
337
+ // encoded here but there also shouldn't be anything to decode so this
338
+ // should be a safe operation. This avoids needing matchRoutes to be
339
+ // history-aware.
337
340
  safelyDecodeURI(pathname)
338
341
  );
339
342
  }