UNPKG

1.8 kB JavaScript View Raw
1/**
2 * react-router v8.3.1
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//#region lib/router/navigation.ts
12const DEFAULT_NAVIGATION_URL = new URL("http://localhost");
13function getNavigatorCurrentUrl(navigator) {
14 if (navigator.createURL) return navigator.createURL("/");
15 try {
16 return new URL(navigator.createHref("/"), DEFAULT_NAVIGATION_URL);
17 } catch {
18 return DEFAULT_NAVIGATION_URL;
19 }
20}
21function isSameOrigin(a, b) {
22 return a.origin === b.origin && (a.origin !== "null" || a.protocol === b.protocol && a.host === b.host);
23}
24function isExplicitUrl(destination, target) {
25 if (destination.startsWith("//")) return true;
26 let protocol = target.protocol.toLowerCase();
27 if (!destination.toLowerCase().startsWith(protocol)) return false;
28 return target.host === "" || destination.slice(protocol.length).startsWith("//");
29}
30function validateNavigationTarget(original, resolved, currentUrl, externalPolicy) {
31 let originalUrl = null;
32 try {
33 originalUrl = original == null ? null : new URL(original, currentUrl);
34 } catch {}
35 let resolvedUrl = new URL(resolved, currentUrl);
36 let originalIsExternal = originalUrl != null && !isSameOrigin(originalUrl, currentUrl);
37 let resolvedIsExternal = !isSameOrigin(resolvedUrl, currentUrl);
38 if (externalPolicy === "reject") {
39 if (originalIsExternal || resolvedIsExternal) throw new Error("External navigation is not allowed");
40 } else if (resolvedIsExternal) {
41 if (originalUrl == null || !isExplicitUrl(original, originalUrl) || !isSameOrigin(originalUrl, resolvedUrl)) throw new Error("External navigation is not allowed");
42 }
43}
44//#endregion
45export { getNavigatorCurrentUrl, validateNavigationTarget };