Projekt

Obecné

Profil

Stáhnout (2.78 KB) Statistiky
| Větev: | Revize:
1
import React from "react";
2
import PropTypes from "prop-types";
3
import { createLocation, createPath } from "history";
4
import invariant from "tiny-invariant";
5
import warning from "tiny-warning";
6

    
7
import Router from "./Router";
8

    
9
function addLeadingSlash(path) {
10
  return path.charAt(0) === "/" ? path : "/" + path;
11
}
12

    
13
function addBasename(basename, location) {
14
  if (!basename) return location;
15

    
16
  return {
17
    ...location,
18
    pathname: addLeadingSlash(basename) + location.pathname
19
  };
20
}
21

    
22
function stripBasename(basename, location) {
23
  if (!basename) return location;
24

    
25
  const base = addLeadingSlash(basename);
26

    
27
  if (location.pathname.indexOf(base) !== 0) return location;
28

    
29
  return {
30
    ...location,
31
    pathname: location.pathname.substr(base.length)
32
  };
33
}
34

    
35
function createURL(location) {
36
  return typeof location === "string" ? location : createPath(location);
37
}
38

    
39
function staticHandler(methodName) {
40
  return () => {
41
    invariant(false, "You cannot %s with <StaticRouter>", methodName);
42
  };
43
}
44

    
45
function noop() {}
46

    
47
/**
48
 * The public top-level API for a "static" <Router>, so-called because it
49
 * can't actually change the current location. Instead, it just records
50
 * location changes in a context object. Useful mainly in testing and
51
 * server-rendering scenarios.
52
 */
53
class StaticRouter extends React.Component {
54
  navigateTo(location, action) {
55
    const { basename = "", context = {} } = this.props;
56
    context.action = action;
57
    context.location = addBasename(basename, createLocation(location));
58
    context.url = createURL(context.location);
59
  }
60

    
61
  handlePush = location => this.navigateTo(location, "PUSH");
62
  handleReplace = location => this.navigateTo(location, "REPLACE");
63
  handleListen = () => noop;
64
  handleBlock = () => noop;
65

    
66
  render() {
67
    const { basename = "", context = {}, location = "/", ...rest } = this.props;
68

    
69
    const history = {
70
      createHref: path => addLeadingSlash(basename + createURL(path)),
71
      action: "POP",
72
      location: stripBasename(basename, createLocation(location)),
73
      push: this.handlePush,
74
      replace: this.handleReplace,
75
      go: staticHandler("go"),
76
      goBack: staticHandler("goBack"),
77
      goForward: staticHandler("goForward"),
78
      listen: this.handleListen,
79
      block: this.handleBlock
80
    };
81

    
82
    return <Router {...rest} history={history} staticContext={context} />;
83
  }
84
}
85

    
86
if (__DEV__) {
87
  StaticRouter.propTypes = {
88
    basename: PropTypes.string,
89
    context: PropTypes.object,
90
    location: PropTypes.oneOfType([PropTypes.string, PropTypes.object])
91
  };
92

    
93
  StaticRouter.prototype.componentDidMount = function() {
94
    warning(
95
      !this.props.history,
96
      "<StaticRouter> ignores the history prop. To use a custom history, " +
97
        "use `import { Router }` instead of `import { StaticRouter as Router }`."
98
    );
99
  };
100
}
101

    
102
export default StaticRouter;
(8-8/14)