UNPKG

4.5 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5require('./chunk/constants.js');
6require('./chunk/utils.js');
7var core = require('./core.js');
8
9/**
10 * @return {string} pathname
11 */
12function getPathname() {
13 return location.pathname;
14}
15/**
16 * Dispatch history a new pathname
17 * @type {Redirect}
18 */
19function redirect(pathname) {
20 if (pathname == getPathname()) return;
21 history.pushState({}, "history", pathname);
22 window.dispatchEvent(new PopStateEvent("popstate"));
23}
24
25function subscribe(handler) {
26 window.addEventListener("popstate", handler);
27 return () => window.removeEventListener("popstate", handler);
28}
29
30const FOLDERS = /([^\/]+)/g;
31const FOLDER = "[^\\/]";
32const SPLIT = "(?:\\/){0,1}";
33const PARAM = /^(:)(\w+)(\?|(\.){3}){0,1}/;
34const PARAMS_EMPTY = {};
35const MEMO = {};
36
37function format(path) {
38 return path.replace(/(\/){2,}/g, "/").replace(/([^\/]+)\/$/, "$1");
39}
40
41function join(a, b) {
42 let split = "/";
43 return format((a || split) + split + (b || split));
44}
45
46function parse(string) {
47 let folders = string.match(FOLDERS) || [""];
48 let params = [];
49 let regexp = new RegExp(
50 "^" +
51 folders
52 .map(folder => {
53 let [string, param, field, type] =
54 folder.match(PARAM) || [];
55 if (param) {
56 params.push(field);
57 if (type === "...") {
58 return `(.*)`;
59 } else if (type === "?") {
60 return `${SPLIT}(${FOLDER}*)`;
61 } else {
62 return `\\/(${FOLDER}+)`;
63 }
64 } else {
65 return `\\/(?:${folder
66 .replace(/(\.|\-)/g, "\\$1")
67 .replace(/\*/g, FOLDER + "+")
68 .replace(/\((?!\?\:)/g, "(?:")})`;
69 }
70 })
71 .join("") +
72 "$",
73 "i"
74 );
75
76 return { regexp, params, logs: {} };
77}
78/**
79 * permite comparar un patron de captura vs un ruta de entrada
80 * @param {string} path - ruta de patron de captura
81 * @param {string} value - ruta de comparacion a patron
82 * @return {array} - [ inRoute:boolean, params:object ];
83 */
84function match(path, value) {
85 path = format(path);
86 value = format(value);
87 if (!MEMO[path]) {
88 MEMO[path] = parse(path);
89 }
90 let { regexp, params, logs } = MEMO[path];
91 if (logs[value]) {
92 return logs[value];
93 }
94 let vs = value.match(regexp);
95 return (logs[value] = [
96 vs ? true : false,
97 vs
98 ? vs.slice(1).reduce((next, value, index) => {
99 next[params[index] || index] = value;
100 return next;
101 }, {})
102 : PARAMS_EMPTY
103 ]);
104}
105
106function useHistory() {
107 let pathname = getPathname();
108 let [state, setState] = core.useState({ pathname });
109
110 core.useEffect(() => {
111 function handler() {
112 let pathname = getPathname();
113 setState(state =>
114 state.pathname != pathname ? { pathname } : state
115 );
116 }
117 return subscribe(handler);
118 }, []);
119 return [pathname, redirect];
120}
121
122function useMatchRoute(path) {
123 return match(path, getPathname());
124}
125
126function useRoute(path, parentPath) {
127 useHistory();
128 return useMatchRoute(join(parentPath, path));
129}
130
131function useRedirect(path, parentPath) {
132 return core.useCallback(
133 replacePath =>
134 redirect(
135 join(
136 parentPath,
137 typeof replacePath == "string" ? replacePath : path
138 )
139 ),
140 [path, parentPath]
141 );
142}
143
144function useRouter(cases, parentPath) {
145 let def = "default";
146 let [pathname] = useHistory();
147 for (let key in cases) {
148 if (key != def) {
149 let [status, params] = match(join(parentPath, key), pathname);
150 if (status) return cases[key](params);
151 }
152 }
153 return cases[def]();
154}
155
156exports.useHistory = useHistory;
157exports.useMatchRoute = useMatchRoute;
158exports.useRedirect = useRedirect;
159exports.useRoute = useRoute;
160exports.useRouter = useRouter;
161//# sourceMappingURL=use-router.js.map