1 | const React = require('react');
|
2 | const { StaticRouter } = require('react-router');
|
3 | const { renderToString, renderToStaticMarkup } = require('react-dom/server');
|
4 | const { renderRoutes, matchRoutes } = require('react-router-config');
|
5 |
|
6 | function isFunction(x) {
|
7 | return Object.prototype.toString.call(x) == '[object Function]';
|
8 | }
|
9 |
|
10 | function isString(input) {
|
11 | return (typeof input === "string") ? true : false;
|
12 | }
|
13 |
|
14 | function isObject(value) {
|
15 | if (Object.prototype.toString.call(value) !== '[object Object]') {
|
16 | return false
|
17 | } else {
|
18 | var prototype = Object.getPrototypeOf(value)
|
19 | return prototype === null || prototype === Object.prototype
|
20 | }
|
21 | }
|
22 |
|
23 | function isUndefined(x) {
|
24 | return !!(x === undefined);
|
25 | }
|
26 |
|
27 | function isNull(x) {
|
28 | return !!(x === null);
|
29 | }
|
30 |
|
31 | function isBoolean(value) {
|
32 | return !!(typeof value === 'boolean');
|
33 | }
|
34 |
|
35 | function isArray(o) {
|
36 | return !!o && typeof o === "object" && o.length !== undefined;
|
37 | }
|
38 |
|
39 | function isReactComponent(x) {
|
40 | return !!(x && objectHasValues(x) && ('$$typeof' in x) && (typeof x['$$typeof'] === 'symbol') && (x['$$typeof'].toString() === 'Symbol(react.element)'))
|
41 | }
|
42 |
|
43 | function objectHasValues(obj) {
|
44 | if (typeof obj === "object") {
|
45 | if (Object.getOwnPropertyNames(obj).length > 0) {
|
46 | return true;
|
47 | } else {
|
48 | return false;
|
49 | }
|
50 | } else if (typeof obj === 'undefined') {
|
51 | return false;
|
52 | }
|
53 | }
|
54 |
|
55 | function arrayHasValues(array) {
|
56 | if (array) {
|
57 | if (isArray(array)) {
|
58 | if (array.length) {
|
59 | return true
|
60 | } else {
|
61 | return false
|
62 | }
|
63 | } else {
|
64 | return false
|
65 | }
|
66 | } else {
|
67 | return false
|
68 | }
|
69 | }
|
70 |
|
71 | function avoidXSS(props) {
|
72 | return JSON.stringify(props).replace(/<\/script/g, '<\\/script').replace(/<!--/g, '<\\!--');
|
73 | }
|
74 |
|
75 | function resolveComponent(path) {
|
76 | let result;
|
77 | try {
|
78 | if (process.env.NODE_ENV !== "production") {
|
79 | delete require.cache[require.resolve(path)];
|
80 | }
|
81 | result = require(path).default;
|
82 | } catch (err) {
|
83 | result = false;
|
84 | } finally {
|
85 | return result;
|
86 | }
|
87 | }
|
88 |
|
89 | function renderComponent(location, component, props) {
|
90 | let Component;
|
91 |
|
92 | if (!component) {
|
93 | Component = React.createElement('div', null, null);
|
94 | if (process.env.NODE_ENV !== 'production') {
|
95 | console.info('The component you\'re trying to render seems to not exists.');
|
96 | }
|
97 | } else {
|
98 | Component = React.createElement(component, JSON.parse(avoidXSS(props.props)));
|
99 | }
|
100 |
|
101 | let context = {};
|
102 | let content = React.createElement(StaticRouter, { location, context }, Component);
|
103 |
|
104 | if (process.env.NODE_ENV === 'production') {
|
105 | return { html: renderToStaticMarkup(content), context: context };
|
106 | } else {
|
107 | return { html: renderToString(content), context: context };
|
108 | }
|
109 | }
|
110 |
|
111 | function getComponentByPathname(routes, path) {
|
112 | let route_ = null
|
113 |
|
114 | function get(_path, _routes) {
|
115 | _routes.some(route => {
|
116 | if ('path' in route && route.path === _path) {
|
117 | route_ = route
|
118 | return true
|
119 | } else {
|
120 | if ('routes' in route) {
|
121 | get(_path, route.routes)
|
122 | }
|
123 | return false
|
124 | }
|
125 | })
|
126 | }
|
127 |
|
128 | get(path, routes);
|
129 | return route_;
|
130 | }
|
131 |
|
132 | function getComponentFromRoutes(routes, url, props) {
|
133 | let extract = isBoolean(arguments[arguments.length -1]) ? arguments[arguments.length -1] : false;
|
134 | let output = { url, props, extract };
|
135 |
|
136 | if (arrayHasValues(routes)) {
|
137 | let branch = matchRoutes(routes, url);
|
138 | if (arrayHasValues(branch)) {
|
139 | if (extract) {
|
140 | if (objectHasValues(branch[0])) {
|
141 | if (objectHasValues(branch[0].route)) {
|
142 | if (objectHasValues(branch[0].route.component)) {
|
143 | if (isFunction(branch[0].route.component.default)) {
|
144 |
|
145 | output.Component = branch[0].route.component.default;
|
146 |
|
147 |
|
148 | if (objectHasValues(branch[1]) && objectHasValues(branch[1].match) && !branch[1].match.isExact) {
|
149 | let found = getComponentByPathname(routes, url);
|
150 | if (found && objectHasValues(found) && objectHasValues(found.component) && isFunction(found.component.default)) {
|
151 | output.Component = found.component.default;
|
152 | }
|
153 | }
|
154 | }
|
155 | } else if (isFunction(branch[0].route.component)) {
|
156 | output.Component = branch[0].route.component;
|
157 |
|
158 |
|
159 | if (objectHasValues(branch[1]) && objectHasValues(branch[1].match) && !branch[1].match.isExact) {
|
160 | let found = getComponentByPathname(routes, url);
|
161 | if (found && objectHasValues(found) && objectHasValues(found.component) && isFunction(found.component.default)) {
|
162 | output.Component = found.component.default;
|
163 | }
|
164 | }
|
165 | }
|
166 | }
|
167 | }
|
168 | } else {
|
169 | if (branch[0].route.component.default) {
|
170 | output.Component = branch[0].route.component.default;
|
171 | } else {
|
172 | output.Component = branch[0].route.component;
|
173 | }
|
174 | }
|
175 | } else {
|
176 | if (isArray(routes) && arrayHasValues(routes) && routes.length === 1) {
|
177 | if (isObject(routes[0]) && objectHasValues(routes[0])) {
|
178 | if (isFunction(routes[0].component)) {
|
179 | output.Component = routes[0].component
|
180 | }
|
181 | }
|
182 | }
|
183 | }
|
184 | }
|
185 |
|
186 | if (isBrowser()) {
|
187 | output.element = React.createElement(output.Component, JSON.parse(avoidXSS(props || {})));
|
188 | }
|
189 |
|
190 | return output;
|
191 | }
|
192 |
|
193 | function isBrowser() {
|
194 | return typeof window !== 'undefined';
|
195 | }
|
196 |
|
197 | function syncRouter(arrayRoutes, defaultComponent) {
|
198 | let properties = {};
|
199 | let component = null
|
200 |
|
201 | if (isBrowser) {
|
202 | let router = window.__INITIAL_STATE__ && window.__INITIAL_STATE__.reactRouter;
|
203 |
|
204 | if (router) {
|
205 | let { url, props, extract } = window.__INITIAL_STATE__;
|
206 |
|
207 |
|
208 | if (isObject(props)) {
|
209 | properties = props;
|
210 | }
|
211 |
|
212 |
|
213 | if (arrayRoutes && isArray(arrayRoutes) && arrayHasValues(arrayRoutes) && isString(url)) {
|
214 | let { Component } = getComponentFromRoutes(arrayRoutes, url, properties, extract);
|
215 | component = Component;
|
216 | }
|
217 | }
|
218 | }
|
219 |
|
220 | return {
|
221 | Component: component || defaultComponent || null,
|
222 | props: properties
|
223 | };
|
224 | }
|
225 |
|
226 | module.exports.isFunction = isFunction;
|
227 | module.exports.isString = isString;
|
228 | module.exports.isObject = isObject;
|
229 | module.exports.isUndefined = isUndefined;
|
230 | module.exports.isNull = isNull;
|
231 | module.exports.isBoolean = isBoolean;
|
232 | module.exports.isArray = isArray;
|
233 | module.exports.isReactComponent = isReactComponent;
|
234 | module.exports.arrayHasValues = arrayHasValues;
|
235 | module.exports.objectHasValues = objectHasValues;
|
236 | module.exports.avoidXSS = avoidXSS;
|
237 | module.exports.resolveComponent = resolveComponent;
|
238 | module.exports.renderComponent = renderComponent;
|
239 | module.exports.getComponentByPathname = getComponentByPathname;
|
240 | module.exports.getComponentFromRoutes = getComponentFromRoutes;
|
241 | module.exports.isBrowser = isBrowser;
|
242 | module.exports.syncRouter = syncRouter; |
\ | No newline at end of file |