react-router 6.2.2 → 6.4.0-pre.10

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.
@@ -1,1020 +0,0 @@
1
- /**
2
- * React Router v6.2.2
3
- *
4
- * Copyright (c) Remix Software Inc.
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE.md file in the root directory of this source tree.
8
- *
9
- * @license MIT
10
- */
11
- (function (global, factory) {
12
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('history')) :
13
- typeof define === 'function' && define.amd ? define(['exports', 'react', 'history'], factory) :
14
- (global = global || self, factory(global.ReactRouter = {}, global.React, global.HistoryLibrary));
15
- }(this, (function (exports, React, history) { 'use strict';
16
-
17
- function invariant(cond, message) {
18
- if (!cond) throw new Error(message);
19
- }
20
-
21
- function warning(cond, message) {
22
- if (!cond) {
23
- // eslint-disable-next-line no-console
24
- if (typeof console !== "undefined") console.warn(message);
25
-
26
- try {
27
- // Welcome to debugging React Router!
28
- //
29
- // This error is thrown as a convenience so you can more easily
30
- // find the source for a warning that appears in the console by
31
- // enabling "pause on exceptions" in your JavaScript debugger.
32
- throw new Error(message); // eslint-disable-next-line no-empty
33
- } catch (e) {}
34
- }
35
- }
36
-
37
- const alreadyWarned = {};
38
-
39
- function warningOnce(key, cond, message) {
40
- if (!cond && !alreadyWarned[key]) {
41
- alreadyWarned[key] = true;
42
- warning(false, message) ;
43
- }
44
- } ///////////////////////////////////////////////////////////////////////////////
45
- // CONTEXT
46
- ///////////////////////////////////////////////////////////////////////////////
47
-
48
- /**
49
- * A Navigator is a "location changer"; it's how you get to different locations.
50
- *
51
- * Every history instance conforms to the Navigator interface, but the
52
- * distinction is useful primarily when it comes to the low-level <Router> API
53
- * where both the location and a navigator must be provided separately in order
54
- * to avoid "tearing" that may occur in a suspense-enabled app if the action
55
- * and/or location were to be read directly from the history instance.
56
- */
57
-
58
-
59
- const NavigationContext = /*#__PURE__*/React.createContext(null);
60
-
61
- {
62
- NavigationContext.displayName = "Navigation";
63
- }
64
-
65
- const LocationContext = /*#__PURE__*/React.createContext(null);
66
-
67
- {
68
- LocationContext.displayName = "Location";
69
- }
70
-
71
- const RouteContext = /*#__PURE__*/React.createContext({
72
- outlet: null,
73
- matches: []
74
- });
75
-
76
- {
77
- RouteContext.displayName = "Route";
78
- } ///////////////////////////////////////////////////////////////////////////////
79
- // COMPONENTS
80
- ///////////////////////////////////////////////////////////////////////////////
81
-
82
-
83
- /**
84
- * A <Router> that stores all entries in memory.
85
- *
86
- * @see https://reactrouter.com/docs/en/v6/api#memoryrouter
87
- */
88
- function MemoryRouter(_ref) {
89
- let {
90
- basename,
91
- children,
92
- initialEntries,
93
- initialIndex
94
- } = _ref;
95
- let historyRef = React.useRef();
96
-
97
- if (historyRef.current == null) {
98
- historyRef.current = history.createMemoryHistory({
99
- initialEntries,
100
- initialIndex
101
- });
102
- }
103
-
104
- let history$1 = historyRef.current;
105
- let [state, setState] = React.useState({
106
- action: history$1.action,
107
- location: history$1.location
108
- });
109
- React.useLayoutEffect(() => history$1.listen(setState), [history$1]);
110
- return /*#__PURE__*/React.createElement(Router, {
111
- basename: basename,
112
- children: children,
113
- location: state.location,
114
- navigationType: state.action,
115
- navigator: history$1
116
- });
117
- }
118
-
119
- /**
120
- * Changes the current location.
121
- *
122
- * Note: This API is mostly useful in React.Component subclasses that are not
123
- * able to use hooks. In functional components, we recommend you use the
124
- * `useNavigate` hook instead.
125
- *
126
- * @see https://reactrouter.com/docs/en/v6/api#navigate
127
- */
128
- function Navigate(_ref2) {
129
- let {
130
- to,
131
- replace,
132
- state
133
- } = _ref2;
134
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of
135
- // the router loaded. We can help them understand how to avoid that.
136
- "<Navigate> may be used only in the context of a <Router> component.") : void 0;
137
- warning(!React.useContext(NavigationContext).static, "<Navigate> must not be used on the initial render in a <StaticRouter>. " + "This is a no-op, but you should modify your code so the <Navigate> is " + "only ever rendered in response to some user interaction or state change.") ;
138
- let navigate = useNavigate();
139
- React.useEffect(() => {
140
- navigate(to, {
141
- replace,
142
- state
143
- });
144
- });
145
- return null;
146
- }
147
-
148
- /**
149
- * Renders the child route's element, if there is one.
150
- *
151
- * @see https://reactrouter.com/docs/en/v6/api#outlet
152
- */
153
- function Outlet(props) {
154
- return useOutlet(props.context);
155
- }
156
-
157
- /**
158
- * Declares an element that should be rendered at a certain URL path.
159
- *
160
- * @see https://reactrouter.com/docs/en/v6/api#route
161
- */
162
- function Route(_props) {
163
- invariant(false, "A <Route> is only ever to be used as the child of <Routes> element, " + "never rendered directly. Please wrap your <Route> in a <Routes>.") ;
164
- }
165
-
166
- /**
167
- * Provides location context for the rest of the app.
168
- *
169
- * Note: You usually won't render a <Router> directly. Instead, you'll render a
170
- * router that is more specific to your environment such as a <BrowserRouter>
171
- * in web browsers or a <StaticRouter> for server rendering.
172
- *
173
- * @see https://reactrouter.com/docs/en/v6/api#router
174
- */
175
- function Router(_ref3) {
176
- let {
177
- basename: basenameProp = "/",
178
- children = null,
179
- location: locationProp,
180
- navigationType = history.Action.Pop,
181
- navigator,
182
- static: staticProp = false
183
- } = _ref3;
184
- !!useInRouterContext() ? invariant(false, "You cannot render a <Router> inside another <Router>." + " You should never have more than one in your app.") : void 0;
185
- let basename = normalizePathname(basenameProp);
186
- let navigationContext = React.useMemo(() => ({
187
- basename,
188
- navigator,
189
- static: staticProp
190
- }), [basename, navigator, staticProp]);
191
-
192
- if (typeof locationProp === "string") {
193
- locationProp = history.parsePath(locationProp);
194
- }
195
-
196
- let {
197
- pathname = "/",
198
- search = "",
199
- hash = "",
200
- state = null,
201
- key = "default"
202
- } = locationProp;
203
- let location = React.useMemo(() => {
204
- let trailingPathname = stripBasename(pathname, basename);
205
-
206
- if (trailingPathname == null) {
207
- return null;
208
- }
209
-
210
- return {
211
- pathname: trailingPathname,
212
- search,
213
- hash,
214
- state,
215
- key
216
- };
217
- }, [basename, pathname, search, hash, state, key]);
218
- warning(location != null, "<Router basename=\"" + basename + "\"> is not able to match the URL " + ("\"" + pathname + search + hash + "\" because it does not start with the ") + "basename, so the <Router> won't render anything.") ;
219
-
220
- if (location == null) {
221
- return null;
222
- }
223
-
224
- return /*#__PURE__*/React.createElement(NavigationContext.Provider, {
225
- value: navigationContext
226
- }, /*#__PURE__*/React.createElement(LocationContext.Provider, {
227
- children: children,
228
- value: {
229
- location,
230
- navigationType
231
- }
232
- }));
233
- }
234
-
235
- /**
236
- * A container for a nested tree of <Route> elements that renders the branch
237
- * that best matches the current location.
238
- *
239
- * @see https://reactrouter.com/docs/en/v6/api#routes
240
- */
241
- function Routes(_ref4) {
242
- let {
243
- children,
244
- location
245
- } = _ref4;
246
- return useRoutes(createRoutesFromChildren(children), location);
247
- } ///////////////////////////////////////////////////////////////////////////////
248
- // HOOKS
249
- ///////////////////////////////////////////////////////////////////////////////
250
-
251
- /**
252
- * Returns the full href for the given "to" value. This is useful for building
253
- * custom links that are also accessible and preserve right-click behavior.
254
- *
255
- * @see https://reactrouter.com/docs/en/v6/api#usehref
256
- */
257
-
258
- function useHref(to) {
259
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
260
- // router loaded. We can help them understand how to avoid that.
261
- "useHref() may be used only in the context of a <Router> component.") : void 0;
262
- let {
263
- basename,
264
- navigator
265
- } = React.useContext(NavigationContext);
266
- let {
267
- hash,
268
- pathname,
269
- search
270
- } = useResolvedPath(to);
271
- let joinedPathname = pathname;
272
-
273
- if (basename !== "/") {
274
- let toPathname = getToPathname(to);
275
- let endsWithSlash = toPathname != null && toPathname.endsWith("/");
276
- joinedPathname = pathname === "/" ? basename + (endsWithSlash ? "/" : "") : joinPaths([basename, pathname]);
277
- }
278
-
279
- return navigator.createHref({
280
- pathname: joinedPathname,
281
- search,
282
- hash
283
- });
284
- }
285
- /**
286
- * Returns true if this component is a descendant of a <Router>.
287
- *
288
- * @see https://reactrouter.com/docs/en/v6/api#useinroutercontext
289
- */
290
-
291
- function useInRouterContext() {
292
- return React.useContext(LocationContext) != null;
293
- }
294
- /**
295
- * Returns the current location object, which represents the current URL in web
296
- * browsers.
297
- *
298
- * Note: If you're using this it may mean you're doing some of your own
299
- * "routing" in your app, and we'd like to know what your use case is. We may
300
- * be able to provide something higher-level to better suit your needs.
301
- *
302
- * @see https://reactrouter.com/docs/en/v6/api#uselocation
303
- */
304
-
305
- function useLocation() {
306
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
307
- // router loaded. We can help them understand how to avoid that.
308
- "useLocation() may be used only in the context of a <Router> component.") : void 0;
309
- return React.useContext(LocationContext).location;
310
- }
311
-
312
- /**
313
- * Returns the current navigation action which describes how the router came to
314
- * the current location, either by a pop, push, or replace on the history stack.
315
- *
316
- * @see https://reactrouter.com/docs/en/v6/api#usenavigationtype
317
- */
318
- function useNavigationType() {
319
- return React.useContext(LocationContext).navigationType;
320
- }
321
- /**
322
- * Returns true if the URL for the given "to" value matches the current URL.
323
- * This is useful for components that need to know "active" state, e.g.
324
- * <NavLink>.
325
- *
326
- * @see https://reactrouter.com/docs/en/v6/api#usematch
327
- */
328
-
329
- function useMatch(pattern) {
330
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
331
- // router loaded. We can help them understand how to avoid that.
332
- "useMatch() may be used only in the context of a <Router> component.") : void 0;
333
- let {
334
- pathname
335
- } = useLocation();
336
- return React.useMemo(() => matchPath(pattern, pathname), [pathname, pattern]);
337
- }
338
- /**
339
- * The interface for the navigate() function returned from useNavigate().
340
- */
341
-
342
- /**
343
- * Returns an imperative method for changing the location. Used by <Link>s, but
344
- * may also be used by other elements to change the location.
345
- *
346
- * @see https://reactrouter.com/docs/en/v6/api#usenavigate
347
- */
348
- function useNavigate() {
349
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
350
- // router loaded. We can help them understand how to avoid that.
351
- "useNavigate() may be used only in the context of a <Router> component.") : void 0;
352
- let {
353
- basename,
354
- navigator
355
- } = React.useContext(NavigationContext);
356
- let {
357
- matches
358
- } = React.useContext(RouteContext);
359
- let {
360
- pathname: locationPathname
361
- } = useLocation();
362
- let routePathnamesJson = JSON.stringify(matches.map(match => match.pathnameBase));
363
- let activeRef = React.useRef(false);
364
- React.useEffect(() => {
365
- activeRef.current = true;
366
- });
367
- let navigate = React.useCallback(function (to, options) {
368
- if (options === void 0) {
369
- options = {};
370
- }
371
-
372
- warning(activeRef.current, "You should call navigate() in a React.useEffect(), not when " + "your component is first rendered.") ;
373
- if (!activeRef.current) return;
374
-
375
- if (typeof to === "number") {
376
- navigator.go(to);
377
- return;
378
- }
379
-
380
- let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname);
381
-
382
- if (basename !== "/") {
383
- path.pathname = joinPaths([basename, path.pathname]);
384
- }
385
-
386
- (!!options.replace ? navigator.replace : navigator.push)(path, options.state);
387
- }, [basename, navigator, routePathnamesJson, locationPathname]);
388
- return navigate;
389
- }
390
- const OutletContext = /*#__PURE__*/React.createContext(null);
391
- /**
392
- * Returns the context (if provided) for the child route at this level of the route
393
- * hierarchy.
394
- * @see https://reactrouter.com/docs/en/v6/api#useoutletcontext
395
- */
396
-
397
- function useOutletContext() {
398
- return React.useContext(OutletContext);
399
- }
400
- /**
401
- * Returns the element for the child route at this level of the route
402
- * hierarchy. Used internally by <Outlet> to render child routes.
403
- *
404
- * @see https://reactrouter.com/docs/en/v6/api#useoutlet
405
- */
406
-
407
- function useOutlet(context) {
408
- let outlet = React.useContext(RouteContext).outlet;
409
-
410
- if (outlet) {
411
- return /*#__PURE__*/React.createElement(OutletContext.Provider, {
412
- value: context
413
- }, outlet);
414
- }
415
-
416
- return outlet;
417
- }
418
- /**
419
- * Returns an object of key/value pairs of the dynamic params from the current
420
- * URL that were matched by the route path.
421
- *
422
- * @see https://reactrouter.com/docs/en/v6/api#useparams
423
- */
424
-
425
- function useParams() {
426
- let {
427
- matches
428
- } = React.useContext(RouteContext);
429
- let routeMatch = matches[matches.length - 1];
430
- return routeMatch ? routeMatch.params : {};
431
- }
432
- /**
433
- * Resolves the pathname of the given `to` value against the current location.
434
- *
435
- * @see https://reactrouter.com/docs/en/v6/api#useresolvedpath
436
- */
437
-
438
- function useResolvedPath(to) {
439
- let {
440
- matches
441
- } = React.useContext(RouteContext);
442
- let {
443
- pathname: locationPathname
444
- } = useLocation();
445
- let routePathnamesJson = JSON.stringify(matches.map(match => match.pathnameBase));
446
- return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname), [to, routePathnamesJson, locationPathname]);
447
- }
448
- /**
449
- * Returns the element of the route that matched the current location, prepared
450
- * with the correct context to render the remainder of the route tree. Route
451
- * elements in the tree must render an <Outlet> to render their child route's
452
- * element.
453
- *
454
- * @see https://reactrouter.com/docs/en/v6/api#useroutes
455
- */
456
-
457
- function useRoutes(routes, locationArg) {
458
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
459
- // router loaded. We can help them understand how to avoid that.
460
- "useRoutes() may be used only in the context of a <Router> component.") : void 0;
461
- let {
462
- matches: parentMatches
463
- } = React.useContext(RouteContext);
464
- let routeMatch = parentMatches[parentMatches.length - 1];
465
- let parentParams = routeMatch ? routeMatch.params : {};
466
- let parentPathname = routeMatch ? routeMatch.pathname : "/";
467
- let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/";
468
- let parentRoute = routeMatch && routeMatch.route;
469
-
470
- {
471
- // You won't get a warning about 2 different <Routes> under a <Route>
472
- // without a trailing *, but this is a best-effort warning anyway since we
473
- // cannot even give the warning unless they land at the parent route.
474
- //
475
- // Example:
476
- //
477
- // <Routes>
478
- // {/* This route path MUST end with /* because otherwise
479
- // it will never match /blog/post/123 */}
480
- // <Route path="blog" element={<Blog />} />
481
- // <Route path="blog/feed" element={<BlogFeed />} />
482
- // </Routes>
483
- //
484
- // function Blog() {
485
- // return (
486
- // <Routes>
487
- // <Route path="post/:id" element={<Post />} />
488
- // </Routes>
489
- // );
490
- // }
491
- let parentPath = parentRoute && parentRoute.path || "";
492
- warningOnce(parentPathname, !parentRoute || parentPath.endsWith("*"), "You rendered descendant <Routes> (or called `useRoutes()`) at " + ("\"" + parentPathname + "\" (under <Route path=\"" + parentPath + "\">) but the ") + "parent route path has no trailing \"*\". This means if you navigate " + "deeper, the parent won't match anymore and therefore the child " + "routes will never render.\n\n" + ("Please change the parent <Route path=\"" + parentPath + "\"> to <Route ") + ("path=\"" + (parentPath === "/" ? "*" : parentPath + "/*") + "\">."));
493
- }
494
-
495
- let locationFromContext = useLocation();
496
- let location;
497
-
498
- if (locationArg) {
499
- var _parsedLocationArg$pa;
500
-
501
- let parsedLocationArg = typeof locationArg === "string" ? history.parsePath(locationArg) : locationArg;
502
- !(parentPathnameBase === "/" || ((_parsedLocationArg$pa = parsedLocationArg.pathname) == null ? void 0 : _parsedLocationArg$pa.startsWith(parentPathnameBase))) ? invariant(false, "When overriding the location using `<Routes location>` or `useRoutes(routes, location)`, " + "the location pathname must begin with the portion of the URL pathname that was " + ("matched by all parent routes. The current pathname base is \"" + parentPathnameBase + "\" ") + ("but pathname \"" + parsedLocationArg.pathname + "\" was given in the `location` prop.")) : void 0;
503
- location = parsedLocationArg;
504
- } else {
505
- location = locationFromContext;
506
- }
507
-
508
- let pathname = location.pathname || "/";
509
- let remainingPathname = parentPathnameBase === "/" ? pathname : pathname.slice(parentPathnameBase.length) || "/";
510
- let matches = matchRoutes(routes, {
511
- pathname: remainingPathname
512
- });
513
-
514
- {
515
- warning(parentRoute || matches != null, "No routes matched location \"" + location.pathname + location.search + location.hash + "\" ") ;
516
- warning(matches == null || matches[matches.length - 1].route.element !== undefined, "Matched leaf route at location \"" + location.pathname + location.search + location.hash + "\" does not have an element. " + "This means it will render an <Outlet /> with a null value by default resulting in an \"empty\" page.") ;
517
- }
518
-
519
- return _renderMatches(matches && matches.map(match => Object.assign({}, match, {
520
- params: Object.assign({}, parentParams, match.params),
521
- pathname: joinPaths([parentPathnameBase, match.pathname]),
522
- pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([parentPathnameBase, match.pathnameBase])
523
- })), parentMatches);
524
- } ///////////////////////////////////////////////////////////////////////////////
525
- // UTILS
526
- ///////////////////////////////////////////////////////////////////////////////
527
-
528
- /**
529
- * Creates a route config from a React "children" object, which is usually
530
- * either a `<Route>` element or an array of them. Used internally by
531
- * `<Routes>` to create a route config from its children.
532
- *
533
- * @see https://reactrouter.com/docs/en/v6/api#createroutesfromchildren
534
- */
535
-
536
- function createRoutesFromChildren(children) {
537
- let routes = [];
538
- React.Children.forEach(children, element => {
539
- if (! /*#__PURE__*/React.isValidElement(element)) {
540
- // Ignore non-elements. This allows people to more easily inline
541
- // conditionals in their route config.
542
- return;
543
- }
544
-
545
- if (element.type === React.Fragment) {
546
- // Transparently support React.Fragment and its children.
547
- routes.push.apply(routes, createRoutesFromChildren(element.props.children));
548
- return;
549
- }
550
-
551
- !(element.type === Route) ? invariant(false, "[" + (typeof element.type === "string" ? element.type : element.type.name) + "] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>") : void 0;
552
- let route = {
553
- caseSensitive: element.props.caseSensitive,
554
- element: element.props.element,
555
- index: element.props.index,
556
- path: element.props.path
557
- };
558
-
559
- if (element.props.children) {
560
- route.children = createRoutesFromChildren(element.props.children);
561
- }
562
-
563
- routes.push(route);
564
- });
565
- return routes;
566
- }
567
- /**
568
- * The parameters that were parsed from the URL path.
569
- */
570
-
571
- /**
572
- * Returns a path with params interpolated.
573
- *
574
- * @see https://reactrouter.com/docs/en/v6/api#generatepath
575
- */
576
- function generatePath(path, params) {
577
- if (params === void 0) {
578
- params = {};
579
- }
580
-
581
- return path.replace(/:(\w+)/g, (_, key) => {
582
- !(params[key] != null) ? invariant(false, "Missing \":" + key + "\" param") : void 0;
583
- return params[key];
584
- }).replace(/\/*\*$/, _ => params["*"] == null ? "" : params["*"].replace(/^\/*/, "/"));
585
- }
586
- /**
587
- * A RouteMatch contains info about how a route matched a URL.
588
- */
589
-
590
- /**
591
- * Matches the given routes to a location and returns the match data.
592
- *
593
- * @see https://reactrouter.com/docs/en/v6/api#matchroutes
594
- */
595
- function matchRoutes(routes, locationArg, basename) {
596
- if (basename === void 0) {
597
- basename = "/";
598
- }
599
-
600
- let location = typeof locationArg === "string" ? history.parsePath(locationArg) : locationArg;
601
- let pathname = stripBasename(location.pathname || "/", basename);
602
-
603
- if (pathname == null) {
604
- return null;
605
- }
606
-
607
- let branches = flattenRoutes(routes);
608
- rankRouteBranches(branches);
609
- let matches = null;
610
-
611
- for (let i = 0; matches == null && i < branches.length; ++i) {
612
- matches = matchRouteBranch(branches[i], pathname);
613
- }
614
-
615
- return matches;
616
- }
617
-
618
- function flattenRoutes(routes, branches, parentsMeta, parentPath) {
619
- if (branches === void 0) {
620
- branches = [];
621
- }
622
-
623
- if (parentsMeta === void 0) {
624
- parentsMeta = [];
625
- }
626
-
627
- if (parentPath === void 0) {
628
- parentPath = "";
629
- }
630
-
631
- routes.forEach((route, index) => {
632
- let meta = {
633
- relativePath: route.path || "",
634
- caseSensitive: route.caseSensitive === true,
635
- childrenIndex: index,
636
- route
637
- };
638
-
639
- if (meta.relativePath.startsWith("/")) {
640
- !meta.relativePath.startsWith(parentPath) ? invariant(false, "Absolute route path \"" + meta.relativePath + "\" nested under path " + ("\"" + parentPath + "\" is not valid. An absolute child route path ") + "must start with the combined path of all its parent routes.") : void 0;
641
- meta.relativePath = meta.relativePath.slice(parentPath.length);
642
- }
643
-
644
- let path = joinPaths([parentPath, meta.relativePath]);
645
- let routesMeta = parentsMeta.concat(meta); // Add the children before adding this route to the array so we traverse the
646
- // route tree depth-first and child routes appear before their parents in
647
- // the "flattened" version.
648
-
649
- if (route.children && route.children.length > 0) {
650
- !(route.index !== true) ? invariant(false, "Index routes must not have child routes. Please remove " + ("all child routes from route path \"" + path + "\".")) : void 0;
651
- flattenRoutes(route.children, branches, routesMeta, path);
652
- } // Routes without a path shouldn't ever match by themselves unless they are
653
- // index routes, so don't add them to the list of possible branches.
654
-
655
-
656
- if (route.path == null && !route.index) {
657
- return;
658
- }
659
-
660
- branches.push({
661
- path,
662
- score: computeScore(path, route.index),
663
- routesMeta
664
- });
665
- });
666
- return branches;
667
- }
668
-
669
- function rankRouteBranches(branches) {
670
- branches.sort((a, b) => a.score !== b.score ? b.score - a.score // Higher score first
671
- : compareIndexes(a.routesMeta.map(meta => meta.childrenIndex), b.routesMeta.map(meta => meta.childrenIndex)));
672
- }
673
-
674
- const paramRe = /^:\w+$/;
675
- const dynamicSegmentValue = 3;
676
- const indexRouteValue = 2;
677
- const emptySegmentValue = 1;
678
- const staticSegmentValue = 10;
679
- const splatPenalty = -2;
680
-
681
- const isSplat = s => s === "*";
682
-
683
- function computeScore(path, index) {
684
- let segments = path.split("/");
685
- let initialScore = segments.length;
686
-
687
- if (segments.some(isSplat)) {
688
- initialScore += splatPenalty;
689
- }
690
-
691
- if (index) {
692
- initialScore += indexRouteValue;
693
- }
694
-
695
- return segments.filter(s => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore);
696
- }
697
-
698
- function compareIndexes(a, b) {
699
- let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);
700
- return siblings ? // If two routes are siblings, we should try to match the earlier sibling
701
- // first. This allows people to have fine-grained control over the matching
702
- // behavior by simply putting routes with identical paths in the order they
703
- // want them tried.
704
- a[a.length - 1] - b[b.length - 1] : // Otherwise, it doesn't really make sense to rank non-siblings by index,
705
- // so they sort equally.
706
- 0;
707
- }
708
-
709
- function matchRouteBranch(branch, pathname) {
710
- let {
711
- routesMeta
712
- } = branch;
713
- let matchedParams = {};
714
- let matchedPathname = "/";
715
- let matches = [];
716
-
717
- for (let i = 0; i < routesMeta.length; ++i) {
718
- let meta = routesMeta[i];
719
- let end = i === routesMeta.length - 1;
720
- let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
721
- let match = matchPath({
722
- path: meta.relativePath,
723
- caseSensitive: meta.caseSensitive,
724
- end
725
- }, remainingPathname);
726
- if (!match) return null;
727
- Object.assign(matchedParams, match.params);
728
- let route = meta.route;
729
- matches.push({
730
- params: matchedParams,
731
- pathname: joinPaths([matchedPathname, match.pathname]),
732
- pathnameBase: normalizePathname(joinPaths([matchedPathname, match.pathnameBase])),
733
- route
734
- });
735
-
736
- if (match.pathnameBase !== "/") {
737
- matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
738
- }
739
- }
740
-
741
- return matches;
742
- }
743
- /**
744
- * Renders the result of `matchRoutes()` into a React element.
745
- */
746
-
747
-
748
- function renderMatches(matches) {
749
- return _renderMatches(matches);
750
- }
751
-
752
- function _renderMatches(matches, parentMatches) {
753
- if (parentMatches === void 0) {
754
- parentMatches = [];
755
- }
756
-
757
- if (matches == null) return null;
758
- return matches.reduceRight((outlet, match, index) => {
759
- return /*#__PURE__*/React.createElement(RouteContext.Provider, {
760
- children: match.route.element !== undefined ? match.route.element : outlet,
761
- value: {
762
- outlet,
763
- matches: parentMatches.concat(matches.slice(0, index + 1))
764
- }
765
- });
766
- }, null);
767
- }
768
- /**
769
- * A PathPattern is used to match on some portion of a URL pathname.
770
- */
771
-
772
-
773
- /**
774
- * Performs pattern matching on a URL pathname and returns information about
775
- * the match.
776
- *
777
- * @see https://reactrouter.com/docs/en/v6/api#matchpath
778
- */
779
- function matchPath(pattern, pathname) {
780
- if (typeof pattern === "string") {
781
- pattern = {
782
- path: pattern,
783
- caseSensitive: false,
784
- end: true
785
- };
786
- }
787
-
788
- let [matcher, paramNames] = compilePath(pattern.path, pattern.caseSensitive, pattern.end);
789
- let match = pathname.match(matcher);
790
- if (!match) return null;
791
- let matchedPathname = match[0];
792
- let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
793
- let captureGroups = match.slice(1);
794
- let params = paramNames.reduce((memo, paramName, index) => {
795
- // We need to compute the pathnameBase here using the raw splat value
796
- // instead of using params["*"] later because it will be decoded then
797
- if (paramName === "*") {
798
- let splatValue = captureGroups[index] || "";
799
- pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
800
- }
801
-
802
- memo[paramName] = safelyDecodeURIComponent(captureGroups[index] || "", paramName);
803
- return memo;
804
- }, {});
805
- return {
806
- params,
807
- pathname: matchedPathname,
808
- pathnameBase,
809
- pattern
810
- };
811
- }
812
-
813
- function compilePath(path, caseSensitive, end) {
814
- if (caseSensitive === void 0) {
815
- caseSensitive = false;
816
- }
817
-
818
- if (end === void 0) {
819
- end = true;
820
- }
821
-
822
- warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\".")) ;
823
- let paramNames = [];
824
- let regexpSource = "^" + path.replace(/\/*\*?$/, "") // Ignore trailing / and /*, we'll handle it below
825
- .replace(/^\/*/, "/") // Make sure it has a leading /
826
- .replace(/[\\.*+^$?{}|()[\]]/g, "\\$&") // Escape special regex chars
827
- .replace(/:(\w+)/g, (_, paramName) => {
828
- paramNames.push(paramName);
829
- return "([^\\/]+)";
830
- });
831
-
832
- if (path.endsWith("*")) {
833
- paramNames.push("*");
834
- regexpSource += path === "*" || path === "/*" ? "(.*)$" // Already matched the initial /, just match the rest
835
- : "(?:\\/(.+)|\\/*)$"; // Don't include the / in params["*"]
836
- } else {
837
- regexpSource += end ? "\\/*$" // When matching to the end, ignore trailing slashes
838
- : // Otherwise, match a word boundary or a proceeding /. The word boundary restricts
839
- // parent routes to matching only their own words and nothing more, e.g. parent
840
- // route "/home" should not match "/home2".
841
- // Additionally, allow paths starting with `.`, `-`, `~`, and url-encoded entities,
842
- // but do not consume the character in the matched path so they can match against
843
- // nested paths.
844
- "(?:(?=[.~-]|%[0-9A-F]{2})|\\b|\\/|$)";
845
- }
846
-
847
- let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i");
848
- return [matcher, paramNames];
849
- }
850
-
851
- function safelyDecodeURIComponent(value, paramName) {
852
- try {
853
- return decodeURIComponent(value);
854
- } catch (error) {
855
- warning(false, "The value for the URL param \"" + paramName + "\" will not be decoded because" + (" the string \"" + value + "\" is a malformed URL segment. This is probably") + (" due to a bad percent encoding (" + error + ").")) ;
856
- return value;
857
- }
858
- }
859
- /**
860
- * Returns a resolved path object relative to the given pathname.
861
- *
862
- * @see https://reactrouter.com/docs/en/v6/api#resolvepath
863
- */
864
-
865
-
866
- function resolvePath(to, fromPathname) {
867
- if (fromPathname === void 0) {
868
- fromPathname = "/";
869
- }
870
-
871
- let {
872
- pathname: toPathname,
873
- search = "",
874
- hash = ""
875
- } = typeof to === "string" ? history.parsePath(to) : to;
876
- let pathname = toPathname ? toPathname.startsWith("/") ? toPathname : resolvePathname(toPathname, fromPathname) : fromPathname;
877
- return {
878
- pathname,
879
- search: normalizeSearch(search),
880
- hash: normalizeHash(hash)
881
- };
882
- }
883
-
884
- function resolvePathname(relativePath, fromPathname) {
885
- let segments = fromPathname.replace(/\/+$/, "").split("/");
886
- let relativeSegments = relativePath.split("/");
887
- relativeSegments.forEach(segment => {
888
- if (segment === "..") {
889
- // Keep the root "" segment so the pathname starts at /
890
- if (segments.length > 1) segments.pop();
891
- } else if (segment !== ".") {
892
- segments.push(segment);
893
- }
894
- });
895
- return segments.length > 1 ? segments.join("/") : "/";
896
- }
897
-
898
- function resolveTo(toArg, routePathnames, locationPathname) {
899
- let to = typeof toArg === "string" ? history.parsePath(toArg) : toArg;
900
- let toPathname = toArg === "" || to.pathname === "" ? "/" : to.pathname; // If a pathname is explicitly provided in `to`, it should be relative to the
901
- // route context. This is explained in `Note on `<Link to>` values` in our
902
- // migration guide from v5 as a means of disambiguation between `to` values
903
- // that begin with `/` and those that do not. However, this is problematic for
904
- // `to` values that do not provide a pathname. `to` can simply be a search or
905
- // hash string, in which case we should assume that the navigation is relative
906
- // to the current location's pathname and *not* the route pathname.
907
-
908
- let from;
909
-
910
- if (toPathname == null) {
911
- from = locationPathname;
912
- } else {
913
- let routePathnameIndex = routePathnames.length - 1;
914
-
915
- if (toPathname.startsWith("..")) {
916
- let toSegments = toPathname.split("/"); // Each leading .. segment means "go up one route" instead of "go up one
917
- // URL segment". This is a key difference from how <a href> works and a
918
- // major reason we call this a "to" value instead of a "href".
919
-
920
- while (toSegments[0] === "..") {
921
- toSegments.shift();
922
- routePathnameIndex -= 1;
923
- }
924
-
925
- to.pathname = toSegments.join("/");
926
- } // If there are more ".." segments than parent routes, resolve relative to
927
- // the root / URL.
928
-
929
-
930
- from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
931
- }
932
-
933
- let path = resolvePath(to, from); // Ensure the pathname has a trailing slash if the original to value had one.
934
-
935
- if (toPathname && toPathname !== "/" && toPathname.endsWith("/") && !path.pathname.endsWith("/")) {
936
- path.pathname += "/";
937
- }
938
-
939
- return path;
940
- }
941
-
942
- function getToPathname(to) {
943
- // Empty strings should be treated the same as / paths
944
- return to === "" || to.pathname === "" ? "/" : typeof to === "string" ? history.parsePath(to).pathname : to.pathname;
945
- }
946
-
947
- function stripBasename(pathname, basename) {
948
- if (basename === "/") return pathname;
949
-
950
- if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
951
- return null;
952
- }
953
-
954
- let nextChar = pathname.charAt(basename.length);
955
-
956
- if (nextChar && nextChar !== "/") {
957
- // pathname does not start with basename/
958
- return null;
959
- }
960
-
961
- return pathname.slice(basename.length) || "/";
962
- }
963
-
964
- const joinPaths = paths => paths.join("/").replace(/\/\/+/g, "/");
965
-
966
- const normalizePathname = pathname => pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
967
-
968
- const normalizeSearch = search => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
969
-
970
- const normalizeHash = hash => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash; ///////////////////////////////////////////////////////////////////////////////
971
-
972
- Object.defineProperty(exports, 'NavigationType', {
973
- enumerable: true,
974
- get: function () {
975
- return history.Action;
976
- }
977
- });
978
- Object.defineProperty(exports, 'createPath', {
979
- enumerable: true,
980
- get: function () {
981
- return history.createPath;
982
- }
983
- });
984
- Object.defineProperty(exports, 'parsePath', {
985
- enumerable: true,
986
- get: function () {
987
- return history.parsePath;
988
- }
989
- });
990
- exports.MemoryRouter = MemoryRouter;
991
- exports.Navigate = Navigate;
992
- exports.Outlet = Outlet;
993
- exports.Route = Route;
994
- exports.Router = Router;
995
- exports.Routes = Routes;
996
- exports.UNSAFE_LocationContext = LocationContext;
997
- exports.UNSAFE_NavigationContext = NavigationContext;
998
- exports.UNSAFE_RouteContext = RouteContext;
999
- exports.createRoutesFromChildren = createRoutesFromChildren;
1000
- exports.generatePath = generatePath;
1001
- exports.matchPath = matchPath;
1002
- exports.matchRoutes = matchRoutes;
1003
- exports.renderMatches = renderMatches;
1004
- exports.resolvePath = resolvePath;
1005
- exports.useHref = useHref;
1006
- exports.useInRouterContext = useInRouterContext;
1007
- exports.useLocation = useLocation;
1008
- exports.useMatch = useMatch;
1009
- exports.useNavigate = useNavigate;
1010
- exports.useNavigationType = useNavigationType;
1011
- exports.useOutlet = useOutlet;
1012
- exports.useOutletContext = useOutletContext;
1013
- exports.useParams = useParams;
1014
- exports.useResolvedPath = useResolvedPath;
1015
- exports.useRoutes = useRoutes;
1016
-
1017
- Object.defineProperty(exports, '__esModule', { value: true });
1018
-
1019
- })));
1020
- //# sourceMappingURL=react-router.development.js.map