From 5ff29852df0730adc5c3c361ad5da6240c307e14 Mon Sep 17 00:00:00 2001 From: Ryan Florence Date: Mon, 25 Aug 2014 21:36:42 -0600 Subject: [PATCH] release v0.5.3 --- CHANGELOG.md | 16 + bower.json | 2 +- dist/react-router.js | 2152 +++++++++++++++++++++++--------------- dist/react-router.min.js | 4 +- package.json | 4 +- 5 files changed, 1334 insertions(+), 844 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ca12a793d..f1fef33da8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +v0.5.3 - Tue, 26 Aug 2014 03:36:42 GMT +-------------------------------------- + +- [273625a](../../commit/273625a) [fixed] Active state on s with key prop +- [283d3f6](../../commit/283d3f6) [added] RouteStore#registerChildren +- [a030648](../../commit/a030648) [changed] Relaxed MemoryStore invariant +- [e028768](../../commit/e028768) [added] component +- [6878120](../../commit/6878120) [added] onAbortedTransition, onActiveStateChange, onTransitionError Routes props +- [58073ca](../../commit/58073ca) [changed] Transition#cancelReason => abortReason +- [6d1ae95](../../commit/6d1ae95) [fixed] sibling array route configs +- [0e7a182](../../commit/0e7a182) [added] pluggable history implementations closes #166 +- [ca96f86](../../commit/ca96f86) [fixed] typo in Link +- [f3dc513](../../commit/f3dc513) [added] onClick handler to +- [b9f92f9](../../commit/b9f92f9) [changed] updated rf-changelog + + v0.5.2 - Thu, 07 Aug 2014 18:25:47 GMT -------------------------------------- diff --git a/bower.json b/bower.json index 0f0e831eb3..a317f9f123 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "react-router", - "version": "0.5.2", + "version": "0.5.3", "homepage": "https://github.com/rackt/react-router", "authors": [ "Ryan Florence", diff --git a/dist/react-router.js b/dist/react-router.js index 4df07e1ee5..5b0b7567dc 100644 --- a/dist/react-router.js +++ b/dist/react-router.js @@ -1,27 +1,31 @@ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.ReactRouter=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o component is a special kind of that + * renders when its parent matches but none of its siblings do. + * Only one such route may be used at any given level in the + * route hierarchy. + */ +function DefaultRoute(props) { + return Route( + merge(props, { + name: null, + path: null + }) + ); +} + +module.exports = DefaultRoute; + +},{"./Route":14,"react/lib/merge":57}],12:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var ActiveState = _dereq_('../mixins/ActiveState'); var withoutProperties = _dereq_('../helpers/withoutProperties'); var transitionTo = _dereq_('../helpers/transitionTo'); +var hasOwnProperty = _dereq_('../helpers/hasOwnProperty'); var makeHref = _dereq_('../helpers/makeHref'); -var hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty); + +function isLeftClickEvent(event) { + return event.button === 0; +} + +function isModifiedEvent(event) { + return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); +} + /** * A map of component props that are reserved for use by the * router and/or React. All other props are used as params that are @@ -48,6 +82,7 @@ var hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty); */ var RESERVED_PROPS = { to: true, + key: true, className: true, activeClassName: true, query: true, @@ -89,7 +124,8 @@ var Link = React.createClass({ propTypes: { to: React.PropTypes.string.isRequired, activeClassName: React.PropTypes.string.isRequired, - query: React.PropTypes.object + query: React.PropTypes.object, + onClick: React.PropTypes.func }, getDefaultProps: function () { @@ -146,12 +182,22 @@ var Link = React.createClass({ }, handleClick: function (event) { - if (isModifiedEvent(event) || !isLeftClick(event)) + var allowTransition = true; + var ret; + + if (this.props.onClick) + ret = this.props.onClick(event); + + if (isModifiedEvent(event) || !isLeftClickEvent(event)) return; + if (ret === false || event.defaultPrevented === true) + allowTransition = false; + event.preventDefault(); - transitionTo(this.props.to, this.getParams(), this.props.query); + if (allowTransition) + transitionTo(this.props.to, this.getParams(), this.props.query); }, render: function () { @@ -163,9 +209,8 @@ var Link = React.createClass({ // pull in props without overriding for (var propName in this.props) { - if (hasOwn(this.props, propName) && hasOwn(props, propName) === false) { + if (hasOwnProperty(this.props, propName) && hasOwnProperty(props, propName) === false) props[propName] = this.props[propName]; - } } return React.DOM.a(props, this.props.children); @@ -173,44 +218,41 @@ var Link = React.createClass({ }); -function isLeftClick(event) { - return event.button === 0; -} - -function isModifiedEvent(event) { - return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); -} - module.exports = Link; -},{"../helpers/makeHref":17,"../helpers/transitionTo":22,"../helpers/withoutProperties":23,"../mixins/ActiveState":24}],11:[function(_dereq_,module,exports){ +},{"../helpers/hasOwnProperty":22,"../helpers/makeHref":23,"../helpers/transitionTo":28,"../helpers/withoutProperties":29,"../mixins/ActiveState":33}],13:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var Route = _dereq_('./Route'); -function Redirect(props) { - return Route({ - path: props.from, - handler: createRedirectClass(props.to) - }); -} - -function createRedirectClass(to) { +function createRedirectHandler(to) { return React.createClass({ statics: { - willTransitionTo: function(transition, params, query) { + willTransitionTo: function (transition, params, query) { transition.redirect(to, params, query); } }, - render: function() { + render: function () { return null; } }); } +/** + * A component is a special kind of that always + * redirects when it matches. + */ +function Redirect(props) { + return Route({ + name: props.name, + path: props.from || props.path, + handler: createRedirectHandler(props.to) + }); +} + module.exports = Redirect; -},{"./Route":12}],12:[function(_dereq_,module,exports){ +},{"./Route":14}],14:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var withoutProperties = _dereq_('../helpers/withoutProperties'); @@ -222,6 +264,8 @@ var withoutProperties = _dereq_('../helpers/withoutProperties'); var RESERVED_PROPS = { handler: true, path: true, + defaultRoute: true, + paramNames: true, children: true // ReactChildren }; @@ -275,6 +319,7 @@ var RESERVED_PROPS = { * }); */ var Route = React.createClass({ + displayName: 'Route', statics: { @@ -285,49 +330,93 @@ var Route = React.createClass({ }, - getDefaultProps: function() { - return { - preserveScrollPosition: false - }; - }, - propTypes: { + preserveScrollPosition: React.PropTypes.bool.isRequired, handler: React.PropTypes.any.isRequired, path: React.PropTypes.string, - name: React.PropTypes.string, - preserveScrollPosition: React.PropTypes.bool + name: React.PropTypes.string + }, + + getDefaultProps: function () { + return { + preserveScrollPosition: false + }; }, render: function () { throw new Error( 'The component should not be rendered directly. You may be ' + - 'missing a wrapper around your list of routes.'); + 'missing a wrapper around your list of routes.' + ); } }); module.exports = Route; -},{"../helpers/withoutProperties":23}],13:[function(_dereq_,module,exports){ +},{"../helpers/withoutProperties":29}],15:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var warning = _dereq_('react/lib/warning'); -var ExecutionEnvironment = _dereq_('react/lib/ExecutionEnvironment'); -var mergeProperties = _dereq_('../helpers/mergeProperties'); +var copyProperties = _dereq_('react/lib/copyProperties'); +var Promise = _dereq_('es6-promise').Promise; +var Route = _dereq_('../components/Route'); var goBack = _dereq_('../helpers/goBack'); var replaceWith = _dereq_('../helpers/replaceWith'); -var transitionTo = _dereq_('../helpers/transitionTo'); -var Route = _dereq_('../components/Route'); var Path = _dereq_('../helpers/Path'); +var Redirect = _dereq_('../helpers/Redirect'); +var Transition = _dereq_('../helpers/Transition'); +var HashLocation = _dereq_('../locations/HashLocation'); +var HistoryLocation = _dereq_('../locations/HistoryLocation'); +var RefreshLocation = _dereq_('../locations/RefreshLocation'); var ActiveStore = _dereq_('../stores/ActiveStore'); +var PathStore = _dereq_('../stores/PathStore'); var RouteStore = _dereq_('../stores/RouteStore'); -var URLStore = _dereq_('../stores/URLStore'); -var Promise = _dereq_('es6-promise').Promise; /** * The ref name that can be used to reference the active route component. */ var REF_NAME = '__activeRoute__'; +/** + * A hash of { name, location } pairs of all locations. + */ +var NAMED_LOCATIONS = { + hash: HashLocation, + history: HistoryLocation, + refresh: RefreshLocation, + disabled: RefreshLocation // TODO: Remove +}; + +/** + * The default handler for aborted transitions. Redirects replace + * the current URL and all others roll it back. + */ +function defaultAbortedTransitionHandler(transition) { + var reason = transition.abortReason; + + if (reason instanceof Redirect) { + replaceWith(reason.to, reason.params, reason.query); + } else { + goBack(); + } +} + +/** + * The default handler for active state updates. + */ +function defaultActiveStateChangeHandler(state) { + ActiveStore.updateState(state); +} + +/** + * The default handler for errors that were thrown asynchronously + * while transitioning. The default behavior is to re-throw the + * error so that it isn't silently swallowed. + */ +function defaultTransitionErrorHandler(error) { + throw error; // This error probably originated in a transition hook. +} + /** * The component configures the route hierarchy and renders the * route matching the current location when rendered into a document. @@ -335,71 +424,63 @@ var REF_NAME = '__activeRoute__'; * See the component for more details. */ var Routes = React.createClass({ - displayName: 'Routes', - statics: { - - /** - * Handles errors that were thrown asynchronously. By default, the - * error is re-thrown so we don't swallow them silently. - */ - handleAsyncError: function (error, route) { - throw error; // This error probably originated in a transition hook. - }, - - /** - * Handles cancelled transitions. By default, redirects replace the - * current URL and aborts roll it back. - */ - handleCancelledTransition: function (transition, routes) { - var reason = transition.cancelReason; - - if (reason instanceof Redirect) { - replaceWith(reason.to, reason.params, reason.query); - } else if (reason instanceof Abort) { - goBack(); - } - } - - }, + displayName: 'Routes', propTypes: { - location: React.PropTypes.oneOf([ 'hash', 'history' ]).isRequired, - preserveScrollPosition: React.PropTypes.bool + onAbortedTransition: React.PropTypes.func.isRequired, + onActiveStateChange: React.PropTypes.func.isRequired, + onTransitionError: React.PropTypes.func.isRequired, + preserveScrollPosition: React.PropTypes.bool, + location: function (props, propName, componentName) { + var location = props[propName]; + + if (typeof location === 'string' && !(location in NAMED_LOCATIONS)) + return new Error('Unknown location "' + location + '", see ' + componentName); + } }, getDefaultProps: function () { return { - location: 'hash', - preserveScrollPosition: false + onAbortedTransition: defaultAbortedTransitionHandler, + onActiveStateChange: defaultActiveStateChangeHandler, + onTransitionError: defaultTransitionErrorHandler, + preserveScrollPosition: false, + location: HashLocation }; }, getInitialState: function () { - return {}; + return { + routes: RouteStore.registerChildren(this.props.children, this) + }; }, - componentWillMount: function () { - React.Children.forEach(this.props.children, function (child) { - RouteStore.registerRoute(child); - }); - if (!URLStore.isSetup() && ExecutionEnvironment.canUseDOM) - URLStore.setup(this.props.location); + getLocation: function () { + var location = this.props.location; + + if (typeof location === 'string') + return NAMED_LOCATIONS[location]; + + return location; + }, - URLStore.addChangeListener(this.handleRouteChange); + componentWillMount: function () { + PathStore.setup(this.getLocation()); + PathStore.addChangeListener(this.handlePathChange); }, componentDidMount: function () { - this.dispatch(URLStore.getCurrentPath()); + this.handlePathChange(); }, componentWillUnmount: function () { - URLStore.removeChangeListener(this.handleRouteChange); + PathStore.removeChangeListener(this.handlePathChange); }, - handleRouteChange: function () { - this.dispatch(URLStore.getCurrentPath()); + handlePathChange: function () { + this.dispatch(PathStore.getCurrentPath()); }, /** @@ -420,15 +501,7 @@ var Routes = React.createClass({ * { route: , params: { id: '123' } } ] */ match: function (path) { - var rootRoutes = this.props.children; - if (!Array.isArray(rootRoutes)) { - rootRoutes = [rootRoutes]; - } - var matches = null; - for (var i = 0; matches == null && i < rootRoutes.length; i++) { - matches = findMatches(Path.withoutQuery(path), rootRoutes[i]); - } - return matches; + return findMatches(Path.withoutQuery(path), this.state.routes, this.props.defaultRoute); }, /** @@ -459,11 +532,18 @@ var Routes = React.createClass({ var transition = new Transition(path); var routes = this; - var promise = syncWithTransition(routes, transition).then(function (newState) { - if (transition.isCancelled) { - Routes.handleCancelledTransition(transition, routes); - } else if (newState) { - ActiveStore.updateState(newState); + var promise = runTransitionHooks(routes, transition).then(function (nextState) { + if (transition.isAborted) { + routes.props.onAbortedTransition(transition); + } else if (nextState) { + routes.setState(nextState); + routes.props.onActiveStateChange(nextState); + + // TODO: add functional test + var rootMatch = getRootMatch(nextState.matches); + + if (rootMatch) + maybeScrollWindow(routes, rootMatch.route); } return transition; @@ -473,7 +553,7 @@ var Routes = React.createClass({ promise = promise.then(undefined, function (error) { // Use setTimeout to break the promise chain. setTimeout(function () { - Routes.handleAsyncError(error, routes); + routes.props.onTransitionError(error); }); }); } @@ -496,71 +576,42 @@ var Routes = React.createClass({ }); -function Transition(path) { - this.path = path; - this.cancelReason = null; - this.isCancelled = false; -} - -mergeProperties(Transition.prototype, { - - abort: function () { - this.cancelReason = new Abort(); - this.isCancelled = true; - }, - - redirect: function (to, params, query) { - this.cancelReason = new Redirect(to, params, query); - this.isCancelled = true; - }, - - retry: function () { - transitionTo(this.path); - } +function findMatches(path, routes, defaultRoute) { + var matches = null, route, params; -}); + for (var i = 0, len = routes.length; i < len; ++i) { + route = routes[i]; -function Abort() {} + // Check the subtree first to find the most deeply-nested match. + matches = findMatches(path, route.props.children, route.props.defaultRoute); -function Redirect(to, params, query) { - this.to = to; - this.params = params; - this.query = query; -} + if (matches != null) { + var rootParams = getRootMatch(matches).params; + + params = route.props.paramNames.reduce(function (params, paramName) { + params[paramName] = rootParams[paramName]; + return params; + }, {}); -function findMatches(path, route) { - var children = route.props.children, matches; - var params; + matches.unshift(makeMatch(route, params)); - // Check the subtree first to find the most deeply-nested match. - if (Array.isArray(children)) { - for (var i = 0, len = children.length; matches == null && i < len; ++i) { - matches = findMatches(path, children[i]); + return matches; } - } else if (children) { - matches = findMatches(path, children); - } - - if (matches) { - var rootParams = getRootMatch(matches).params; - params = {}; - - Path.extractParamNames(route.props.path).forEach(function (paramName) { - params[paramName] = rootParams[paramName]; - }); - matches.unshift(makeMatch(route, params)); + // No routes in the subtree matched, so check this route. + params = Path.extractParams(route.props.path, path); - return matches; + if (params) + return [ makeMatch(route, params) ]; } - // No routes in the subtree matched, so check this route. - params = Path.extractParams(route.props.path, path); + // No routes matched, so try the default route if there is one. + params = defaultRoute && Path.extractParams(defaultRoute.props.path, path); if (params) - return [ makeMatch(route, params) ]; + return [ makeMatch(defaultRoute, params) ]; - return null; + return matches; } function makeMatch(route, params) { @@ -599,7 +650,7 @@ function updateMatchComponents(matches, refs) { * if they all pass successfully. Returns a promise that resolves to the new * state if it needs to be updated, or undefined if not. */ -function syncWithTransition(routes, transition) { +function runTransitionHooks(routes, transition) { if (routes.state.path === transition.path) return Promise.resolve(); // Nothing to do! @@ -631,18 +682,19 @@ function syncWithTransition(routes, transition) { toMatches = nextMatches; } - return checkTransitionFromHooks(fromMatches, transition).then(function () { - if (transition.isCancelled) + return runTransitionFromHooks(fromMatches, transition).then(function () { + if (transition.isAborted) return; // No need to continue. - return checkTransitionToHooks(toMatches, transition).then(function () { - if (transition.isCancelled) + return runTransitionToHooks(toMatches, transition).then(function () { + if (transition.isAborted) return; // No need to continue. var rootMatch = getRootMatch(nextMatches); var params = (rootMatch && rootMatch.params) || {}; var query = Path.extractQuery(transition.path) || {}; - var state = { + + return { path: transition.path, matches: nextMatches, activeParams: params, @@ -651,12 +703,6 @@ function syncWithTransition(routes, transition) { return match.route; }) }; - - // TODO: add functional test - maybeScrollWindow(routes, toMatches[toMatches.length - 1]); - routes.setState(state); - - return state; }); }); } @@ -667,14 +713,14 @@ function syncWithTransition(routes, transition) { * the route's handler, so that the deepest nested handlers are called first. * Returns a promise that resolves after the last handler. */ -function checkTransitionFromHooks(matches, transition) { +function runTransitionFromHooks(matches, transition) { var promise = Promise.resolve(); reversedArray(matches).forEach(function (match) { promise = promise.then(function () { var handler = match.route.props.handler; - if (!transition.isCancelled && handler.willTransitionFrom) + if (!transition.isAborted && handler.willTransitionFrom) return handler.willTransitionFrom(transition, match.component); }); }); @@ -687,14 +733,14 @@ function checkTransitionFromHooks(matches, transition) { * with the transition object and any params that apply to that handler. Returns * a promise that resolves after the last handler. */ -function checkTransitionToHooks(matches, transition) { +function runTransitionToHooks(matches, transition) { var promise = Promise.resolve(); - matches.forEach(function (match, index) { + matches.forEach(function (match) { promise = promise.then(function () { var handler = match.route.props.handler; - if (!transition.isCancelled && handler.willTransitionTo) + if (!transition.isAborted && handler.willTransitionTo) return handler.willTransitionTo(transition, match.params); }); }); @@ -736,7 +782,7 @@ function computeHandlerProps(matches, query) { if (arguments.length > 2 && typeof arguments[2] !== 'undefined') throw new Error('Passing children to a route handler is not supported'); - return route.props.handler(mergeProperties(props, addedProps)); + return route.props.handler(copyProperties(props, addedProps)); }.bind(this, props); }); @@ -751,11 +797,8 @@ function reversedArray(array) { return array.slice(0).reverse(); } -function maybeScrollWindow(routes, match) { - if (routes.props.preserveScrollPosition) - return; - - if (!match || match.route.props.preserveScrollPosition) +function maybeScrollWindow(routes, rootRoute) { + if (routes.props.preserveScrollPosition || rootRoute.props.preserveScrollPosition) return; window.scrollTo(0, 0); @@ -763,10 +806,10 @@ function maybeScrollWindow(routes, match) { module.exports = Routes; -},{"../components/Route":12,"../helpers/Path":14,"../helpers/goBack":16,"../helpers/mergeProperties":19,"../helpers/replaceWith":20,"../helpers/transitionTo":22,"../stores/ActiveStore":26,"../stores/RouteStore":27,"../stores/URLStore":28,"es6-promise":32,"react/lib/ExecutionEnvironment":57,"react/lib/warning":61}],14:[function(_dereq_,module,exports){ +},{"../components/Route":14,"../helpers/Path":16,"../helpers/Redirect":17,"../helpers/Transition":18,"../helpers/goBack":21,"../helpers/replaceWith":25,"../locations/HashLocation":30,"../locations/HistoryLocation":31,"../locations/RefreshLocation":32,"../stores/ActiveStore":35,"../stores/PathStore":36,"../stores/RouteStore":37,"es6-promise":42,"react/lib/copyProperties":53,"react/lib/warning":61}],16:[function(_dereq_,module,exports){ var invariant = _dereq_('react/lib/invariant'); +var copyProperties = _dereq_('react/lib/copyProperties'); var qs = _dereq_('querystring'); -var mergeProperties = _dereq_('./mergeProperties'); var URL = _dereq_('./URL'); var paramMatcher = /((?::[a-z_$][a-z0-9_$]*)|\*)/ig; @@ -891,7 +934,7 @@ var Path = { var existingQuery = Path.extractQuery(path); if (existingQuery) - query = query ? mergeProperties(existingQuery, query) : existingQuery; + query = query ? copyProperties(existingQuery, query) : existingQuery; var queryString = query && qs.stringify(query); @@ -912,7 +955,55 @@ var Path = { module.exports = Path; -},{"./URL":15,"./mergeProperties":19,"querystring":31,"react/lib/invariant":60}],15:[function(_dereq_,module,exports){ +},{"./URL":19,"querystring":41,"react/lib/copyProperties":53,"react/lib/invariant":55}],17:[function(_dereq_,module,exports){ +/** + * Encapsulates a redirect to the given route. + */ +function Redirect(to, params, query) { + this.to = to; + this.params = params; + this.query = query; +} + +module.exports = Redirect; + +},{}],18:[function(_dereq_,module,exports){ +var mixInto = _dereq_('react/lib/mixInto'); +var transitionTo = _dereq_('./transitionTo'); +var Redirect = _dereq_('./Redirect'); + +/** + * Encapsulates a transition to a given path. + * + * The willTransitionTo and willTransitionFrom handlers receive + * an instance of this class as their first argument. + */ +function Transition(path) { + this.path = path; + this.abortReason = null; + this.isAborted = false; +} + +mixInto(Transition, { + + abort: function (reason) { + this.abortReason = reason; + this.isAborted = true; + }, + + redirect: function (to, params, query) { + this.abort(new Redirect(to, params, query)); + }, + + retry: function () { + transitionTo(this.path); + } + +}); + +module.exports = Transition; + +},{"./Redirect":17,"./transitionTo":28,"react/lib/mixInto":60}],19:[function(_dereq_,module,exports){ var urlEncodedSpaceRE = /\+/g; var encodedSpaceRE = /%20/g; @@ -936,27 +1027,45 @@ var URL = { module.exports = URL; -},{}],16:[function(_dereq_,module,exports){ -var URLStore = _dereq_('../stores/URLStore'); +},{}],20:[function(_dereq_,module,exports){ +/** + * Returns the current URL path from `window.location`, including query string + */ +function getWindowPath() { + return window.location.pathname + window.location.search; +} + +module.exports = getWindowPath; + +},{}],21:[function(_dereq_,module,exports){ +var PathStore = _dereq_('../stores/PathStore'); + +/** + * Transitions to the previous URL. + */ function goBack() { - URLStore.back(); + PathStore.pop(); } module.exports = goBack; -},{"../stores/URLStore":28}],17:[function(_dereq_,module,exports){ -var URLStore = _dereq_('../stores/URLStore'); +},{"../stores/PathStore":36}],22:[function(_dereq_,module,exports){ +module.exports = Function.prototype.call.bind(Object.prototype.hasOwnProperty); + +},{}],23:[function(_dereq_,module,exports){ +var HashLocation = _dereq_('../locations/HashLocation'); +var PathStore = _dereq_('../stores/PathStore'); var makePath = _dereq_('./makePath'); /** * Returns a string that may safely be used as the href of a * link to the route with the given name. */ -function makeHref(routeName, params, query) { - var path = makePath(routeName, params, query); +function makeHref(to, params, query) { + var path = makePath(to, params, query); - if (URLStore.getLocation() === 'hash') + if (PathStore.getLocation() === HashLocation) return '#' + path; return path; @@ -964,7 +1073,7 @@ function makeHref(routeName, params, query) { module.exports = makeHref; -},{"../stores/URLStore":28,"./makePath":18}],18:[function(_dereq_,module,exports){ +},{"../locations/HashLocation":30,"../stores/PathStore":36,"./makePath":24}],24:[function(_dereq_,module,exports){ var invariant = _dereq_('react/lib/invariant'); var RouteStore = _dereq_('../stores/RouteStore'); var Path = _dereq_('./Path'); @@ -994,20 +1103,8 @@ function makePath(to, params, query) { module.exports = makePath; -},{"../stores/RouteStore":27,"./Path":14,"react/lib/invariant":60}],19:[function(_dereq_,module,exports){ -function mergeProperties(object, properties) { - for (var property in properties) { - if (properties.hasOwnProperty(property)) - object[property] = properties[property]; - } - - return object; -} - -module.exports = mergeProperties; - -},{}],20:[function(_dereq_,module,exports){ -var URLStore = _dereq_('../stores/URLStore'); +},{"../stores/RouteStore":37,"./Path":16,"react/lib/invariant":55}],25:[function(_dereq_,module,exports){ +var PathStore = _dereq_('../stores/PathStore'); var makePath = _dereq_('./makePath'); /** @@ -1015,12 +1112,12 @@ var makePath = _dereq_('./makePath'); * the current URL in the history stack. */ function replaceWith(to, params, query) { - URLStore.replace(makePath(to, params, query)); + PathStore.replace(makePath(to, params, query)); } module.exports = replaceWith; -},{"../stores/URLStore":28,"./makePath":18}],21:[function(_dereq_,module,exports){ +},{"../stores/PathStore":36,"./makePath":24}],26:[function(_dereq_,module,exports){ var Promise = _dereq_('es6-promise').Promise; /** @@ -1047,8 +1144,26 @@ function resolveAsyncState(asyncState, setState) { module.exports = resolveAsyncState; -},{"es6-promise":32}],22:[function(_dereq_,module,exports){ -var URLStore = _dereq_('../stores/URLStore'); +},{"es6-promise":42}],27:[function(_dereq_,module,exports){ +function supportsHistory() { + /*! taken from modernizr + * https://github.com/Modernizr/Modernizr/blob/master/LICENSE + * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js + */ + var ua = navigator.userAgent; + if ((ua.indexOf('Android 2.') !== -1 || + (ua.indexOf('Android 4.0') !== -1)) && + ua.indexOf('Mobile Safari') !== -1 && + ua.indexOf('Chrome') === -1) { + return false; + } + return (window.history && 'pushState' in window.history); +} + +module.exports = supportsHistory; + +},{}],28:[function(_dereq_,module,exports){ +var PathStore = _dereq_('../stores/PathStore'); var makePath = _dereq_('./makePath'); /** @@ -1056,12 +1171,12 @@ var makePath = _dereq_('./makePath'); * a new URL onto the history stack. */ function transitionTo(to, params, query) { - URLStore.push(makePath(to, params, query)); + PathStore.push(makePath(to, params, query)); } module.exports = transitionTo; -},{"../stores/URLStore":28,"./makePath":18}],23:[function(_dereq_,module,exports){ +},{"../stores/PathStore":36,"./makePath":24}],29:[function(_dereq_,module,exports){ function withoutProperties(object, properties) { var result = {}; @@ -1075,53 +1190,216 @@ function withoutProperties(object, properties) { module.exports = withoutProperties; -},{}],24:[function(_dereq_,module,exports){ -var ActiveStore = _dereq_('../stores/ActiveStore'); +},{}],30:[function(_dereq_,module,exports){ +var invariant = _dereq_('react/lib/invariant'); +var ExecutionEnvironment = _dereq_('react/lib/ExecutionEnvironment'); +var getWindowPath = _dereq_('../helpers/getWindowPath'); + +var _onChange; /** - * A mixin for components that need to know about the routes, params, - * and query that are currently active. Components that use it get two - * things: - * - * 1. An `isActive` static method they can use to check if a route, - * params, and query are active. - * 2. An `updateActiveState` instance method that is called when the - * active state changes. - * - * Example: - * - * var Tab = React.createClass({ - * - * mixins: [ Router.ActiveState ], - * - * getInitialState: function () { - * return { - * isActive: false - * }; - * }, - * - * updateActiveState: function () { - * this.setState({ - * isActive: Tab.isActive(routeName, params, query) - * }) - * } - * - * }); + * A Location that uses `window.location.hash`. */ -var ActiveState = { +var HashLocation = { - statics: { + setup: function (onChange) { + invariant( + ExecutionEnvironment.canUseDOM, + 'You cannot use HashLocation in an environment with no DOM' + ); - /** - * Returns true if the route with the given name, URL parameters, and query - * are all currently active. - */ - isActive: ActiveStore.isActive + _onChange = onChange; + // Make sure the hash is at least / to begin with. + if (window.location.hash === '') + window.location.replace(getWindowPath() + '#/'); + + if (window.addEventListener) { + window.addEventListener('hashchange', _onChange, false); + } else { + window.attachEvent('onhashchange', _onChange); + } }, - componentWillMount: function () { - ActiveStore.addChangeListener(this.handleActiveStateChange); + teardown: function () { + if (window.removeEventListener) { + window.removeEventListener('hashchange', _onChange, false); + } else { + window.detachEvent('onhashchange', _onChange); + } + }, + + push: function (path) { + window.location.hash = path; + }, + + replace: function (path) { + window.location.replace(getWindowPath() + '#' + path); + }, + + pop: function () { + window.history.back(); + }, + + getCurrentPath: function () { + return window.location.hash.substr(1); + }, + + toString: function () { + return ''; + } + +}; + +module.exports = HashLocation; + +},{"../helpers/getWindowPath":20,"react/lib/ExecutionEnvironment":52,"react/lib/invariant":55}],31:[function(_dereq_,module,exports){ +var invariant = _dereq_('react/lib/invariant'); +var ExecutionEnvironment = _dereq_('react/lib/ExecutionEnvironment'); +var getWindowPath = _dereq_('../helpers/getWindowPath'); + +var _onChange; + +/** + * A Location that uses HTML5 history. + */ +var HistoryLocation = { + + setup: function (onChange) { + invariant( + ExecutionEnvironment.canUseDOM, + 'You cannot use HistoryLocation in an environment with no DOM' + ); + + _onChange = onChange; + + if (window.addEventListener) { + window.addEventListener('popstate', _onChange, false); + } else { + window.attachEvent('popstate', _onChange); + } + }, + + teardown: function () { + if (window.removeEventListener) { + window.removeEventListener('popstate', _onChange, false); + } else { + window.detachEvent('popstate', _onChange); + } + }, + + push: function (path) { + window.history.pushState({ path: path }, '', path); + _onChange(); + }, + + replace: function (path) { + window.history.replaceState({ path: path }, '', path); + _onChange(); + }, + + pop: function () { + window.history.back(); + }, + + getCurrentPath: getWindowPath, + + toString: function () { + return ''; + } + +}; + +module.exports = HistoryLocation; + +},{"../helpers/getWindowPath":20,"react/lib/ExecutionEnvironment":52,"react/lib/invariant":55}],32:[function(_dereq_,module,exports){ +var invariant = _dereq_('react/lib/invariant'); +var ExecutionEnvironment = _dereq_('react/lib/ExecutionEnvironment'); +var getWindowPath = _dereq_('../helpers/getWindowPath'); + +/** + * A Location that uses full page refreshes. This is used as + * the fallback for HistoryLocation in browsers that do not + * support the HTML5 history API. + */ +var RefreshLocation = { + + setup: function () { + invariant( + ExecutionEnvironment.canUseDOM, + 'You cannot use RefreshLocation in an environment with no DOM' + ); + }, + + push: function (path) { + window.location = path; + }, + + replace: function (path) { + window.location.replace(path); + }, + + pop: function () { + window.history.back(); + }, + + getCurrentPath: getWindowPath, + + toString: function () { + return ''; + } + +}; + +module.exports = RefreshLocation; + +},{"../helpers/getWindowPath":20,"react/lib/ExecutionEnvironment":52,"react/lib/invariant":55}],33:[function(_dereq_,module,exports){ +var ActiveStore = _dereq_('../stores/ActiveStore'); + +/** + * A mixin for components that need to know about the routes, params, + * and query that are currently active. Components that use it get two + * things: + * + * 1. An `isActive` static method they can use to check if a route, + * params, and query are active. + * 2. An `updateActiveState` instance method that is called when the + * active state changes. + * + * Example: + * + * var Tab = React.createClass({ + * + * mixins: [ Router.ActiveState ], + * + * getInitialState: function () { + * return { + * isActive: false + * }; + * }, + * + * updateActiveState: function () { + * this.setState({ + * isActive: Tab.isActive(routeName, params, query) + * }) + * } + * + * }); + */ +var ActiveState = { + + statics: { + + /** + * Returns true if the route with the given name, URL parameters, and query + * are all currently active. + */ + isActive: ActiveStore.isActive + + }, + + componentWillMount: function () { + ActiveStore.addChangeListener(this.handleActiveStateChange); }, componentDidMount: function () { @@ -1142,7 +1420,7 @@ var ActiveState = { module.exports = ActiveState; -},{"../stores/ActiveStore":26}],25:[function(_dereq_,module,exports){ +},{"../stores/ActiveStore":35}],34:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var resolveAsyncState = _dereq_('../helpers/resolveAsyncState'); @@ -1239,7 +1517,7 @@ var AsyncState = { }, componentDidMount: function () { - if (this.props.initialAsyncState || !this.constructor.getInitialAsyncState) + if (this.props.initialAsyncState || typeof this.constructor.getInitialAsyncState !== 'function') return; resolveAsyncState( @@ -1252,7 +1530,18 @@ var AsyncState = { module.exports = AsyncState; -},{"../helpers/resolveAsyncState":21}],26:[function(_dereq_,module,exports){ +},{"../helpers/resolveAsyncState":26}],35:[function(_dereq_,module,exports){ +var EventEmitter = _dereq_('events').EventEmitter; + +var CHANGE_EVENT = 'change'; +var _events = new EventEmitter; + +_events.setMaxListeners(0); + +function notifyChange() { + _events.emit(CHANGE_EVENT); +} + var _activeRoutes = []; var _activeParams = {}; var _activeQuery = {}; @@ -1281,13 +1570,6 @@ function queryIsActive(query) { return true; } -var EventEmitter = _dereq_('event-emitter'); -var _events = EventEmitter(); - -function notifyChange() { - _events.emit('change'); -} - /** * The ActiveStore keeps track of which routes, URL and query parameters are * currently active on a page. s subscribe to the ActiveStore to know @@ -1295,18 +1577,12 @@ function notifyChange() { */ var ActiveStore = { - /** - * Adds a listener that will be called when this store changes. - */ addChangeListener: function (listener) { - _events.on('change', listener); + _events.on(CHANGE_EVENT, listener); }, - /** - * Removes the given change listener. - */ removeChangeListener: function (listener) { - _events.off('change', listener); + _events.removeListener(CHANGE_EVENT, listener); }, /** @@ -1340,7 +1616,94 @@ var ActiveStore = { module.exports = ActiveStore; -},{"event-emitter":42}],27:[function(_dereq_,module,exports){ +},{"events":38}],36:[function(_dereq_,module,exports){ +var warning = _dereq_('react/lib/warning'); +var EventEmitter = _dereq_('events').EventEmitter; +var supportsHistory = _dereq_('../helpers/supportsHistory'); +var HistoryLocation = _dereq_('../locations/HistoryLocation'); +var RefreshLocation = _dereq_('../locations/RefreshLocation'); + +var CHANGE_EVENT = 'change'; +var _events = new EventEmitter; + +function notifyChange() { + _events.emit(CHANGE_EVENT); +} + +var _location; + +/** + * The PathStore keeps track of the current URL path and manages + * the location strategy that is used to update the URL. + */ +var PathStore = { + + addChangeListener: function (listener) { + _events.on(CHANGE_EVENT, listener); + }, + + removeChangeListener: function (listener) { + _events.removeListener(CHANGE_EVENT, listener); + + // Automatically teardown when the last listener is removed. + if (EventEmitter.listenerCount(_events, CHANGE_EVENT) === 0) + PathStore.teardown(); + }, + + setup: function (location) { + // When using HistoryLocation, automatically fallback + // to RefreshLocation in browsers that do not support + // the HTML5 history API. + if (location === HistoryLocation && !supportsHistory()) + location = RefreshLocation; + + if (_location == null) { + _location = location; + + if (_location && typeof _location.setup === 'function') + _location.setup(notifyChange); + } else { + warning( + _location === location, + 'Cannot use location %s, already using %s', location, _location + ); + } + }, + + teardown: function () { + if (_location && typeof _location.teardown === 'function') + _location.teardown(); + + _location = null; + }, + + getLocation: function () { + return _location; + }, + + push: function (path) { + if (_location.getCurrentPath() !== path) + _location.push(path); + }, + + replace: function (path) { + if (_location.getCurrentPath() !== path) + _location.replace(path); + }, + + pop: function () { + _location.pop(); + }, + + getCurrentPath: function () { + return _location.getCurrentPath(); + } + +}; + +module.exports = PathStore; + +},{"../helpers/supportsHistory":27,"../locations/HistoryLocation":31,"../locations/RefreshLocation":32,"events":38,"react/lib/warning":61}],37:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var invariant = _dereq_('react/lib/invariant'); var warning = _dereq_('react/lib/warning'); @@ -1369,63 +1732,95 @@ var RouteStore = { * from the store. */ unregisterRoute: function (route) { - if (route.props.name) - delete _namedRoutes[route.props.name]; + var props = route.props; - React.Children.forEach(route.props.children, function (child) { - RouteStore.unregisterRoute(child); - }); + if (props.name) + delete _namedRoutes[props.name]; + + React.Children.forEach(props.children, RouteStore.unregisterRoute); }, /** * Registers a and all of its children with the store. Also, * does some normalization and validation on route props. */ - registerRoute: function (route, _parentRoute) { - // Make sure the 's path begins with a slash. Default to its name. - // We can't do this in getDefaultProps because it may not be called on - // s that are never actually mounted. - if (route.props.path || route.props.name) { - route.props.path = Path.normalize(route.props.path || route.props.name); - } else { - route.props.path = '/'; - } + registerRoute: function (route, parentRoute) { + // Note: parentRoute may be a _or_ a . + var props = route.props; - // Make sure the has a valid React component for a handler. invariant( - React.isValidClass(route.props.handler), - 'The handler for Route "' + (route.props.name || route.props.path) + '" ' + - 'must be a valid React component' + React.isValidClass(props.handler), + 'The handler for the "%s" route must be a valid React class', + props.name || props.path ); - // Make sure the has all params that its parent needs. - if (_parentRoute) { - var paramNames = Path.extractParamNames(route.props.path); + // Default routes have no name, path, or children. + var isDefault = !(props.path || props.name || props.children); + + if (props.path || props.name) { + props.path = Path.normalize(props.path || props.name); + } else if (parentRoute && parentRoute.props.path) { + props.path = parentRoute.props.path; + } else { + props.path = '/'; + } + + props.paramNames = Path.extractParamNames(props.path); - Path.extractParamNames(_parentRoute.props.path).forEach(function (paramName) { + // Make sure the route's path has all params its parent needs. + if (parentRoute && Array.isArray(parentRoute.props.paramNames)) { + parentRoute.props.paramNames.forEach(function (paramName) { invariant( - paramNames.indexOf(paramName) !== -1, - 'The nested route path "' + route.props.path + '" is missing the "' + paramName + '" ' + - 'parameter of its parent path "' + _parentRoute.props.path + '"' + props.paramNames.indexOf(paramName) !== -1, + 'The nested route path "%s" is missing the "%s" parameter of its parent path "%s"', + props.path, paramName, parentRoute.props.path ); }); } - // Make sure the can be looked up by s. - if (route.props.name) { - var existingRoute = _namedRoutes[route.props.name]; + // Make sure the route can be looked up by s. + if (props.name) { + var existingRoute = _namedRoutes[props.name]; invariant( !existingRoute || route === existingRoute, - 'You cannot use the name "' + route.props.name + '" for more than one route' + 'You cannot use the name "%s" for more than one route', + props.name + ); + + _namedRoutes[props.name] = route; + } + + if (parentRoute && isDefault) { + invariant( + parentRoute.props.defaultRoute == null, + 'You may not have more than one per ' ); - _namedRoutes[route.props.name] = route; + parentRoute.props.defaultRoute = route; + + return null; } - React.Children.forEach(route.props.children, function (child) { - RouteStore.registerRoute(child, route); + // Make sure children is an array. + props.children = RouteStore.registerChildren(props.children, route); + + return route; + }, + + /** + * Registers many children routes at once, always returning an array. + */ + registerChildren: function (children, parentRoute) { + var routes = []; + + React.Children.forEach(children, function (child) { + // Exclude s. + if (child = RouteStore.registerRoute(child, parentRoute)) + routes.push(child); }); + + return routes; }, /** @@ -1439,225 +1834,312 @@ var RouteStore = { module.exports = RouteStore; -},{"../helpers/Path":14,"react/lib/invariant":60,"react/lib/warning":61}],28:[function(_dereq_,module,exports){ -var ExecutionEnvironment = _dereq_('react/lib/ExecutionEnvironment'); -var invariant = _dereq_('react/lib/invariant'); -var warning = _dereq_('react/lib/warning'); - -var _location; -var _currentPath = '/'; -var _lastPath = null; - -function getWindowChangeEvent(location) { - if (location === 'history') - return 'popstate'; +},{"../helpers/Path":16,"react/lib/invariant":55,"react/lib/warning":61}],38:[function(_dereq_,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - return window.addEventListener ? 'hashchange' : 'onhashchange'; +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; } +module.exports = EventEmitter; -function getWindowPath() { - return window.location.pathname + window.location.search; -} +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; -var EventEmitter = _dereq_('event-emitter'); -var _events = EventEmitter(); +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; -function notifyChange() { - _events.emit('change'); -} +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; -/** - * The URLStore keeps track of the current URL. In DOM environments, it may be - * attached to window.location to automatically sync with the URL in a browser's - * location bar. s subscribe to the URLStore to know when the URL changes. - */ -var URLStore = { +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; - /** - * Adds a listener that will be called when this store changes. - */ - addChangeListener: function (listener) { - _events.on('change', listener); - }, +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; - /** - * Removes the given change listener. - */ - removeChangeListener: function (listener) { - _events.off('change', listener); - }, + if (!this._events) + this._events = {}; - /** - * Returns the type of navigation that is currently being used. - */ - getLocation: function () { - return _location || 'hash'; - }, - - /** - * Returns the value of the current URL path. - */ - getCurrentPath: function () { - if (_location === 'history' || _location === 'disabledHistory') - return getWindowPath(); + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + throw TypeError('Uncaught, unspecified "error" event.'); + } + return false; + } + } - if (_location === 'hash') - return window.location.hash.substr(1); + handler = this._events[type]; - return _currentPath; - }, + if (isUndefined(handler)) + return false; - /** - * Pushes the given path onto the browser navigation stack. - */ - push: function (path) { - if (path === this.getCurrentPath()) - return; + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } - if (_location === 'disabledHistory') - return window.location = path; + return true; +}; - if (_location === 'history') { - window.history.pushState({ path: path }, '', path); - notifyChange(); - } else if (_location === 'hash') { - window.location.hash = path; +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; } else { - _lastPath = _currentPath; - _currentPath = path; - notifyChange(); + m = EventEmitter.defaultMaxListeners; } - }, - /** - * Replaces the current URL path with the given path without adding an entry - * to the browser's history. - */ - replace: function (path) { - if (_location === 'disabledHistory') { - window.location.replace(path); - } else if (_location === 'history') { - window.history.replaceState({ path: path }, '', path); - notifyChange(); - } else if (_location === 'hash') { - window.location.replace(getWindowPath() + '#' + path); - } else { - _currentPath = path; - notifyChange(); + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } } - }, + } - /** - * Reverts the URL to whatever it was before the last update. - */ - back: function () { - if (_location != null) { - window.history.back(); - } else { - invariant( - _lastPath, - 'You cannot make the URL store go back more than once when it does not use the DOM' - ); + return this; +}; - _currentPath = _lastPath; - _lastPath = null; - notifyChange(); - } - }, +EventEmitter.prototype.on = EventEmitter.prototype.addListener; - /** - * Returns true if the URL store has already been setup. - */ - isSetup: function () { - return _location != null; - }, +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - /** - * Sets up the URL store to get the value of the current path from window.location - * as it changes. The location argument may be either "hash" or "history". - */ - setup: function (location) { - invariant( - ExecutionEnvironment.canUseDOM, - 'You cannot setup the URL store in an environment with no DOM' - ); + var fired = false; - if (_location != null) { - warning( - _location === location, - 'The URL store was already setup using ' + _location + ' location. ' + - 'You cannot use ' + location + ' location on the same page' - ); + function g() { + this.removeListener(type, g); - return; // Don't setup twice. + if (!fired) { + fired = true; + listener.apply(this, arguments); } + } - if (location === 'history' && !supportsHistory()) { - _location = 'disabledHistory'; - return; - } + g.listener = listener; + this.on(type, g); - var changeEvent = getWindowChangeEvent(location); + return this; +}; - invariant( - changeEvent || location === 'disabledHistory', - 'The URL store location "' + location + '" is not valid. ' + - 'It must be either "hash" or "history"' - ); +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; - _location = location; + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - if (location === 'hash' && window.location.hash === '') - URLStore.replace('/'); + if (!this._events || !this._events[type]) + return this; - if (window.addEventListener) { - window.addEventListener(changeEvent, notifyChange, false); - } else { - window.attachEvent(changeEvent, notifyChange); - } + list = this._events[type]; + length = list.length; + position = -1; - notifyChange(); - }, + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); - /** - * Stops listening for changes to window.location. - */ - teardown: function () { - if (_location == null) - return; + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } - var changeEvent = getWindowChangeEvent(_location); + if (position < 0) + return this; - if (window.removeEventListener) { - window.removeEventListener(changeEvent, notifyChange, false); + if (list.length === 1) { + list.length = 0; + delete this._events[type]; } else { - window.detachEvent(changeEvent, notifyChange); + list.splice(position, 1); } - _location = null; - _currentPath = '/'; + if (this._events.removeListener) + this.emit('removeListener', type, listener); } + return this; }; -function supportsHistory() { - /*! taken from modernizr - * https://github.com/Modernizr/Modernizr/blob/master/LICENSE - * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js - */ - var ua = navigator.userAgent; - if ((ua.indexOf('Android 2.') !== -1 || - (ua.indexOf('Android 4.0') !== -1)) && - ua.indexOf('Mobile Safari') !== -1 && - ua.indexOf('Chrome') === -1) { - return false; +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; } - return (window.history && 'pushState' in window.history); + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; } -module.exports = URLStore; +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} -},{"event-emitter":42,"react/lib/ExecutionEnvironment":57,"react/lib/invariant":60,"react/lib/warning":61}],29:[function(_dereq_,module,exports){ +},{}],39:[function(_dereq_,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -1743,7 +2225,7 @@ var isArray = Array.isArray || function (xs) { return Object.prototype.toString.call(xs) === '[object Array]'; }; -},{}],30:[function(_dereq_,module,exports){ +},{}],40:[function(_dereq_,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -1830,19 +2312,19 @@ var objectKeys = Object.keys || function (obj) { return res; }; -},{}],31:[function(_dereq_,module,exports){ +},{}],41:[function(_dereq_,module,exports){ 'use strict'; exports.decode = exports.parse = _dereq_('./decode'); exports.encode = exports.stringify = _dereq_('./encode'); -},{"./decode":29,"./encode":30}],32:[function(_dereq_,module,exports){ +},{"./decode":39,"./encode":40}],42:[function(_dereq_,module,exports){ "use strict"; var Promise = _dereq_("./promise/promise").Promise; var polyfill = _dereq_("./promise/polyfill").polyfill; exports.Promise = Promise; exports.polyfill = polyfill; -},{"./promise/polyfill":36,"./promise/promise":37}],33:[function(_dereq_,module,exports){ +},{"./promise/polyfill":46,"./promise/promise":47}],43:[function(_dereq_,module,exports){ "use strict"; /* global toString */ @@ -1936,7 +2418,7 @@ function all(promises) { } exports.all = all; -},{"./utils":41}],34:[function(_dereq_,module,exports){ +},{"./utils":51}],44:[function(_dereq_,module,exports){ "use strict"; var browserGlobal = (typeof window !== 'undefined') ? window : {}; var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; @@ -1998,7 +2480,7 @@ function asap(callback, arg) { } exports.asap = asap; -},{}],35:[function(_dereq_,module,exports){ +},{}],45:[function(_dereq_,module,exports){ "use strict"; var config = { instrument: false @@ -2014,7 +2496,7 @@ function configure(name, value) { exports.config = config; exports.configure = configure; -},{}],36:[function(_dereq_,module,exports){ +},{}],46:[function(_dereq_,module,exports){ "use strict"; /*global self*/ var RSVPPromise = _dereq_("./promise").Promise; @@ -2053,7 +2535,7 @@ function polyfill() { } exports.polyfill = polyfill; -},{"./promise":37,"./utils":41}],37:[function(_dereq_,module,exports){ +},{"./promise":47,"./utils":51}],47:[function(_dereq_,module,exports){ "use strict"; var config = _dereq_("./config").config; var configure = _dereq_("./config").configure; @@ -2265,7 +2747,7 @@ function publishRejection(promise) { } exports.Promise = Promise; -},{"./all":33,"./asap":34,"./config":35,"./race":38,"./reject":39,"./resolve":40,"./utils":41}],38:[function(_dereq_,module,exports){ +},{"./all":43,"./asap":44,"./config":45,"./race":48,"./reject":49,"./resolve":50,"./utils":51}],48:[function(_dereq_,module,exports){ "use strict"; /* global toString */ var isArray = _dereq_("./utils").isArray; @@ -2355,7 +2837,7 @@ function race(promises) { } exports.race = race; -},{"./utils":41}],39:[function(_dereq_,module,exports){ +},{"./utils":51}],49:[function(_dereq_,module,exports){ "use strict"; /** `RSVP.reject` returns a promise that will become rejected with the passed @@ -2403,7 +2885,7 @@ function reject(reason) { } exports.reject = reject; -},{}],40:[function(_dereq_,module,exports){ +},{}],50:[function(_dereq_,module,exports){ "use strict"; function resolve(value) { /*jshint validthis:true */ @@ -2419,7 +2901,7 @@ function resolve(value) { } exports.resolve = resolve; -},{}],41:[function(_dereq_,module,exports){ +},{}],51:[function(_dereq_,module,exports){ "use strict"; function objectOrFunction(x) { return isFunction(x) || (typeof x === "object" && x !== null); @@ -2442,347 +2924,7 @@ exports.objectOrFunction = objectOrFunction; exports.isFunction = isFunction; exports.isArray = isArray; exports.now = now; -},{}],42:[function(_dereq_,module,exports){ -'use strict'; - -var d = _dereq_('d') - , callable = _dereq_('es5-ext/object/valid-callable') - - , apply = Function.prototype.apply, call = Function.prototype.call - , create = Object.create, defineProperty = Object.defineProperty - , defineProperties = Object.defineProperties - , hasOwnProperty = Object.prototype.hasOwnProperty - , descriptor = { configurable: true, enumerable: false, writable: true } - - , on, once, off, emit, methods, descriptors, base; - -on = function (type, listener) { - var data; - - callable(listener); - - if (!hasOwnProperty.call(this, '__ee__')) { - data = descriptor.value = create(null); - defineProperty(this, '__ee__', descriptor); - descriptor.value = null; - } else { - data = this.__ee__; - } - if (!data[type]) data[type] = listener; - else if (typeof data[type] === 'object') data[type].push(listener); - else data[type] = [data[type], listener]; - - return this; -}; - -once = function (type, listener) { - var once, self; - - callable(listener); - self = this; - on.call(this, type, once = function () { - off.call(self, type, once); - apply.call(listener, this, arguments); - }); - - once.__eeOnceListener__ = listener; - return this; -}; - -off = function (type, listener) { - var data, listeners, candidate, i; - - callable(listener); - - if (!hasOwnProperty.call(this, '__ee__')) return this; - data = this.__ee__; - if (!data[type]) return this; - listeners = data[type]; - - if (typeof listeners === 'object') { - for (i = 0; (candidate = listeners[i]); ++i) { - if ((candidate === listener) || - (candidate.__eeOnceListener__ === listener)) { - if (listeners.length === 2) data[type] = listeners[i ? 0 : 1]; - else listeners.splice(i, 1); - } - } - } else { - if ((listeners === listener) || - (listeners.__eeOnceListener__ === listener)) { - delete data[type]; - } - } - - return this; -}; - -emit = function (type) { - var i, l, listener, listeners, args; - - if (!hasOwnProperty.call(this, '__ee__')) return; - listeners = this.__ee__[type]; - if (!listeners) return; - - if (typeof listeners === 'object') { - l = arguments.length; - args = new Array(l - 1); - for (i = 1; i < l; ++i) args[i - 1] = arguments[i]; - - listeners = listeners.slice(); - for (i = 0; (listener = listeners[i]); ++i) { - apply.call(listener, this, args); - } - } else { - switch (arguments.length) { - case 1: - call.call(listeners, this); - break; - case 2: - call.call(listeners, this, arguments[1]); - break; - case 3: - call.call(listeners, this, arguments[1], arguments[2]); - break; - default: - l = arguments.length; - args = new Array(l - 1); - for (i = 1; i < l; ++i) { - args[i - 1] = arguments[i]; - } - apply.call(listeners, this, args); - } - } -}; - -methods = { - on: on, - once: once, - off: off, - emit: emit -}; - -descriptors = { - on: d(on), - once: d(once), - off: d(off), - emit: d(emit) -}; - -base = defineProperties({}, descriptors); - -module.exports = exports = function (o) { - return (o == null) ? create(base) : defineProperties(Object(o), descriptors); -}; -exports.methods = methods; - -},{"d":43,"es5-ext/object/valid-callable":52}],43:[function(_dereq_,module,exports){ -'use strict'; - -var assign = _dereq_('es5-ext/object/assign') - , normalizeOpts = _dereq_('es5-ext/object/normalize-options') - , isCallable = _dereq_('es5-ext/object/is-callable') - , contains = _dereq_('es5-ext/string/#/contains') - - , d; - -d = module.exports = function (dscr, value/*, options*/) { - var c, e, w, options, desc; - if ((arguments.length < 2) || (typeof dscr !== 'string')) { - options = value; - value = dscr; - dscr = null; - } else { - options = arguments[2]; - } - if (dscr == null) { - c = w = true; - e = false; - } else { - c = contains.call(dscr, 'c'); - e = contains.call(dscr, 'e'); - w = contains.call(dscr, 'w'); - } - - desc = { value: value, configurable: c, enumerable: e, writable: w }; - return !options ? desc : assign(normalizeOpts(options), desc); -}; - -d.gs = function (dscr, get, set/*, options*/) { - var c, e, options, desc; - if (typeof dscr !== 'string') { - options = set; - set = get; - get = dscr; - dscr = null; - } else { - options = arguments[3]; - } - if (get == null) { - get = undefined; - } else if (!isCallable(get)) { - options = get; - get = set = undefined; - } else if (set == null) { - set = undefined; - } else if (!isCallable(set)) { - options = set; - set = undefined; - } - if (dscr == null) { - c = true; - e = false; - } else { - c = contains.call(dscr, 'c'); - e = contains.call(dscr, 'e'); - } - - desc = { get: get, set: set, configurable: c, enumerable: e }; - return !options ? desc : assign(normalizeOpts(options), desc); -}; - -},{"es5-ext/object/assign":44,"es5-ext/object/is-callable":47,"es5-ext/object/normalize-options":51,"es5-ext/string/#/contains":54}],44:[function(_dereq_,module,exports){ -'use strict'; - -module.exports = _dereq_('./is-implemented')() - ? Object.assign - : _dereq_('./shim'); - -},{"./is-implemented":45,"./shim":46}],45:[function(_dereq_,module,exports){ -'use strict'; - -module.exports = function () { - var assign = Object.assign, obj; - if (typeof assign !== 'function') return false; - obj = { foo: 'raz' }; - assign(obj, { bar: 'dwa' }, { trzy: 'trzy' }); - return (obj.foo + obj.bar + obj.trzy) === 'razdwatrzy'; -}; - -},{}],46:[function(_dereq_,module,exports){ -'use strict'; - -var keys = _dereq_('../keys') - , value = _dereq_('../valid-value') - - , max = Math.max; - -module.exports = function (dest, src/*, …srcn*/) { - var error, i, l = max(arguments.length, 2), assign; - dest = Object(value(dest)); - assign = function (key) { - try { dest[key] = src[key]; } catch (e) { - if (!error) error = e; - } - }; - for (i = 1; i < l; ++i) { - src = arguments[i]; - keys(src).forEach(assign); - } - if (error !== undefined) throw error; - return dest; -}; - -},{"../keys":48,"../valid-value":53}],47:[function(_dereq_,module,exports){ -// Deprecated - -'use strict'; - -module.exports = function (obj) { return typeof obj === 'function'; }; - -},{}],48:[function(_dereq_,module,exports){ -'use strict'; - -module.exports = _dereq_('./is-implemented')() - ? Object.keys - : _dereq_('./shim'); - -},{"./is-implemented":49,"./shim":50}],49:[function(_dereq_,module,exports){ -'use strict'; - -module.exports = function () { - try { - Object.keys('primitive'); - return true; - } catch (e) { return false; } -}; - -},{}],50:[function(_dereq_,module,exports){ -'use strict'; - -var keys = Object.keys; - -module.exports = function (object) { - return keys(object == null ? object : Object(object)); -}; - -},{}],51:[function(_dereq_,module,exports){ -'use strict'; - -var assign = _dereq_('./assign') - - , forEach = Array.prototype.forEach - , create = Object.create, getPrototypeOf = Object.getPrototypeOf - - , process; - -process = function (src, obj) { - var proto = getPrototypeOf(src); - return assign(proto ? process(proto, obj) : obj, src); -}; - -module.exports = function (options/*, …options*/) { - var result = create(null); - forEach.call(arguments, function (options) { - if (options == null) return; - process(Object(options), result); - }); - return result; -}; - -},{"./assign":44}],52:[function(_dereq_,module,exports){ -'use strict'; - -module.exports = function (fn) { - if (typeof fn !== 'function') throw new TypeError(fn + " is not a function"); - return fn; -}; - -},{}],53:[function(_dereq_,module,exports){ -'use strict'; - -module.exports = function (value) { - if (value == null) throw new TypeError("Cannot use null or undefined"); - return value; -}; - -},{}],54:[function(_dereq_,module,exports){ -'use strict'; - -module.exports = _dereq_('./is-implemented')() - ? String.prototype.contains - : _dereq_('./shim'); - -},{"./is-implemented":55,"./shim":56}],55:[function(_dereq_,module,exports){ -'use strict'; - -var str = 'razdwatrzy'; - -module.exports = function () { - if (typeof str.contains !== 'function') return false; - return ((str.contains('dwa') === true) && (str.contains('foo') === false)); -}; - -},{}],56:[function(_dereq_,module,exports){ -'use strict'; - -var indexOf = String.prototype.indexOf; - -module.exports = function (searchString/*, position*/) { - return indexOf.call(this, searchString, arguments[1]) > -1; -}; - -},{}],57:[function(_dereq_,module,exports){ +},{}],52:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * @@ -2834,7 +2976,7 @@ var ExecutionEnvironment = { module.exports = ExecutionEnvironment; -},{}],58:[function(_dereq_,module,exports){ +},{}],53:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * @@ -2890,7 +3032,7 @@ function copyProperties(obj, a, b, c, d, e, f) { module.exports = copyProperties; -},{}],59:[function(_dereq_,module,exports){ +},{}],54:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * @@ -2935,7 +3077,7 @@ copyProperties(emptyFunction, { module.exports = emptyFunction; -},{"./copyProperties":58}],60:[function(_dereq_,module,exports){ +},{"./copyProperties":53}],55:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * @@ -2997,6 +3139,338 @@ var invariant = function(condition, format, a, b, c, d, e, f) { module.exports = invariant; +},{}],56:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2014 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @providesModule keyMirror + * @typechecks static-only + */ + +"use strict"; + +var invariant = _dereq_("./invariant"); + +/** + * Constructs an enumeration with keys equal to their value. + * + * For example: + * + * var COLORS = keyMirror({blue: null, red: null}); + * var myColor = COLORS.blue; + * var isColorValid = !!COLORS[myColor]; + * + * The last line could not be performed if the values of the generated enum were + * not equal to their keys. + * + * Input: {key1: val1, key2: val2} + * Output: {key1: key1, key2: key2} + * + * @param {object} obj + * @return {object} + */ +var keyMirror = function(obj) { + var ret = {}; + var key; + ("production" !== "production" ? invariant( + obj instanceof Object && !Array.isArray(obj), + 'keyMirror(...): Argument must be an object.' + ) : invariant(obj instanceof Object && !Array.isArray(obj))); + for (key in obj) { + if (!obj.hasOwnProperty(key)) { + continue; + } + ret[key] = key; + } + return ret; +}; + +module.exports = keyMirror; + +},{"./invariant":55}],57:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2014 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @providesModule merge + */ + +"use strict"; + +var mergeInto = _dereq_("./mergeInto"); + +/** + * Shallow merges two structures into a return value, without mutating either. + * + * @param {?object} one Optional object with properties to merge from. + * @param {?object} two Optional object with properties to merge from. + * @return {object} The shallow extension of one by two. + */ +var merge = function(one, two) { + var result = {}; + mergeInto(result, one); + mergeInto(result, two); + return result; +}; + +module.exports = merge; + +},{"./mergeInto":59}],58:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2014 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @providesModule mergeHelpers + * + * requiresPolyfills: Array.isArray + */ + +"use strict"; + +var invariant = _dereq_("./invariant"); +var keyMirror = _dereq_("./keyMirror"); + +/** + * Maximum number of levels to traverse. Will catch circular structures. + * @const + */ +var MAX_MERGE_DEPTH = 36; + +/** + * We won't worry about edge cases like new String('x') or new Boolean(true). + * Functions are considered terminals, and arrays are not. + * @param {*} o The item/object/value to test. + * @return {boolean} true iff the argument is a terminal. + */ +var isTerminal = function(o) { + return typeof o !== 'object' || o === null; +}; + +var mergeHelpers = { + + MAX_MERGE_DEPTH: MAX_MERGE_DEPTH, + + isTerminal: isTerminal, + + /** + * Converts null/undefined values into empty object. + * + * @param {?Object=} arg Argument to be normalized (nullable optional) + * @return {!Object} + */ + normalizeMergeArg: function(arg) { + return arg === undefined || arg === null ? {} : arg; + }, + + /** + * If merging Arrays, a merge strategy *must* be supplied. If not, it is + * likely the caller's fault. If this function is ever called with anything + * but `one` and `two` being `Array`s, it is the fault of the merge utilities. + * + * @param {*} one Array to merge into. + * @param {*} two Array to merge from. + */ + checkMergeArrayArgs: function(one, two) { + ("production" !== "production" ? invariant( + Array.isArray(one) && Array.isArray(two), + 'Tried to merge arrays, instead got %s and %s.', + one, + two + ) : invariant(Array.isArray(one) && Array.isArray(two))); + }, + + /** + * @param {*} one Object to merge into. + * @param {*} two Object to merge from. + */ + checkMergeObjectArgs: function(one, two) { + mergeHelpers.checkMergeObjectArg(one); + mergeHelpers.checkMergeObjectArg(two); + }, + + /** + * @param {*} arg + */ + checkMergeObjectArg: function(arg) { + ("production" !== "production" ? invariant( + !isTerminal(arg) && !Array.isArray(arg), + 'Tried to merge an object, instead got %s.', + arg + ) : invariant(!isTerminal(arg) && !Array.isArray(arg))); + }, + + /** + * @param {*} arg + */ + checkMergeIntoObjectArg: function(arg) { + ("production" !== "production" ? invariant( + (!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg), + 'Tried to merge into an object, instead got %s.', + arg + ) : invariant((!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg))); + }, + + /** + * Checks that a merge was not given a circular object or an object that had + * too great of depth. + * + * @param {number} Level of recursion to validate against maximum. + */ + checkMergeLevel: function(level) { + ("production" !== "production" ? invariant( + level < MAX_MERGE_DEPTH, + 'Maximum deep merge depth exceeded. You may be attempting to merge ' + + 'circular structures in an unsupported way.' + ) : invariant(level < MAX_MERGE_DEPTH)); + }, + + /** + * Checks that the supplied merge strategy is valid. + * + * @param {string} Array merge strategy. + */ + checkArrayStrategy: function(strategy) { + ("production" !== "production" ? invariant( + strategy === undefined || strategy in mergeHelpers.ArrayStrategies, + 'You must provide an array strategy to deep merge functions to ' + + 'instruct the deep merge how to resolve merging two arrays.' + ) : invariant(strategy === undefined || strategy in mergeHelpers.ArrayStrategies)); + }, + + /** + * Set of possible behaviors of merge algorithms when encountering two Arrays + * that must be merged together. + * - `clobber`: The left `Array` is ignored. + * - `indexByIndex`: The result is achieved by recursively deep merging at + * each index. (not yet supported.) + */ + ArrayStrategies: keyMirror({ + Clobber: true, + IndexByIndex: true + }) + +}; + +module.exports = mergeHelpers; + +},{"./invariant":55,"./keyMirror":56}],59:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2014 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @providesModule mergeInto + * @typechecks static-only + */ + +"use strict"; + +var mergeHelpers = _dereq_("./mergeHelpers"); + +var checkMergeObjectArg = mergeHelpers.checkMergeObjectArg; +var checkMergeIntoObjectArg = mergeHelpers.checkMergeIntoObjectArg; + +/** + * Shallow merges two structures by mutating the first parameter. + * + * @param {object|function} one Object to be merged into. + * @param {?object} two Optional object with properties to merge from. + */ +function mergeInto(one, two) { + checkMergeIntoObjectArg(one); + if (two != null) { + checkMergeObjectArg(two); + for (var key in two) { + if (!two.hasOwnProperty(key)) { + continue; + } + one[key] = two[key]; + } + } +} + +module.exports = mergeInto; + +},{"./mergeHelpers":58}],60:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2014 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @providesModule mixInto + */ + +"use strict"; + +/** + * Simply copies properties to the prototype. + */ +var mixInto = function(constructor, methodBag) { + var methodName; + for (methodName in methodBag) { + if (!methodBag.hasOwnProperty(methodName)) { + continue; + } + constructor.prototype[methodName] = methodBag[methodName]; + } +}; + +module.exports = mixInto; + },{}],61:[function(_dereq_,module,exports){ /** * Copyright 2014 Facebook, Inc. @@ -3047,12 +3521,12 @@ if ("production" !== "production") { module.exports = warning; -},{"./emptyFunction":59}],62:[function(_dereq_,module,exports){ +},{"./emptyFunction":54}],62:[function(_dereq_,module,exports){ module.exports = _dereq_('./modules/helpers/replaceWith'); -},{"./modules/helpers/replaceWith":20}],63:[function(_dereq_,module,exports){ +},{"./modules/helpers/replaceWith":25}],63:[function(_dereq_,module,exports){ module.exports = _dereq_('./modules/helpers/transitionTo'); -},{"./modules/helpers/transitionTo":22}]},{},[8]) -(8) +},{"./modules/helpers/transitionTo":28}]},{},[9]) +(9) }); \ No newline at end of file diff --git a/dist/react-router.min.js b/dist/react-router.min.js index 86b29b4456..c1ef9c2ade 100644 --- a/dist/react-router.min.js +++ b/dist/react-router.min.js @@ -1,2 +1,2 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.ReactRouter=e()}}(function(){return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o component should not be rendered directly. You may be missing a wrapper around your list of routes.")}});module.exports=Route},{"../helpers/withoutProperties":23}],13:[function(_dereq_,module){function Transition(path){this.path=path,this.cancelReason=null,this.isCancelled=!1}function Abort(){}function Redirect(to,params,query){this.to=to,this.params=params,this.query=query}function findMatches(path,route){var matches,params,children=route.props.children;if(Array.isArray(children))for(var i=0,len=children.length;null==matches&&len>i;++i)matches=findMatches(path,children[i]);else children&&(matches=findMatches(path,children));if(matches){var rootParams=getRootMatch(matches).params;return params={},Path.extractParamNames(route.props.path).forEach(function(paramName){params[paramName]=rootParams[paramName]}),matches.unshift(makeMatch(route,params)),matches}return params=Path.extractParams(route.props.path,path),params?[makeMatch(route,params)]:null}function makeMatch(route,params){return{route:route,params:params}}function hasMatch(matches,match){return matches.some(function(m){if(m.route!==match.route)return!1;for(var property in m.params)if(m.params[property]!==match.params[property])return!1;return!0})}function getRootMatch(matches){return matches[matches.length-1]}function updateMatchComponents(matches,refs){for(var component,i=0;component=refs[REF_NAME];)matches[i++].component=component,refs=component.refs}function syncWithTransition(routes,transition){if(routes.state.path===transition.path)return Promise.resolve();var currentMatches=routes.state.matches,nextMatches=routes.match(transition.path);warning(nextMatches,'No route matches path "'+transition.path+'". Make sure you have somewhere in your routes'),nextMatches||(nextMatches=[]);var fromMatches,toMatches;return currentMatches?(updateMatchComponents(currentMatches,routes.refs),fromMatches=currentMatches.filter(function(match){return!hasMatch(nextMatches,match)}),toMatches=nextMatches.filter(function(match){return!hasMatch(currentMatches,match)})):(fromMatches=[],toMatches=nextMatches),checkTransitionFromHooks(fromMatches,transition).then(function(){return transition.isCancelled?void 0:checkTransitionToHooks(toMatches,transition).then(function(){if(!transition.isCancelled){var rootMatch=getRootMatch(nextMatches),params=rootMatch&&rootMatch.params||{},query=Path.extractQuery(transition.path)||{},state={path:transition.path,matches:nextMatches,activeParams:params,activeQuery:query,activeRoutes:nextMatches.map(function(match){return match.route})};return maybeScrollWindow(routes,toMatches[toMatches.length-1]),routes.setState(state),state}})})}function checkTransitionFromHooks(matches,transition){var promise=Promise.resolve();return reversedArray(matches).forEach(function(match){promise=promise.then(function(){var handler=match.route.props.handler;return!transition.isCancelled&&handler.willTransitionFrom?handler.willTransitionFrom(transition,match.component):void 0})}),promise}function checkTransitionToHooks(matches,transition){var promise=Promise.resolve();return matches.forEach(function(match){promise=promise.then(function(){var handler=match.route.props.handler;return!transition.isCancelled&&handler.willTransitionTo?handler.willTransitionTo(transition,match.params):void 0})}),promise}function computeHandlerProps(matches,query){var childHandler,props={ref:null,key:null,params:null,query:null,activeRouteHandler:returnNull};return reversedArray(matches).forEach(function(match){var route=match.route;props=Route.getUnreservedProps(route.props),props.ref=REF_NAME,props.key=Path.injectParams(route.props.path,match.params),props.params=match.params,props.query=query,props.activeRouteHandler=childHandler?childHandler:returnNull,childHandler=function(props,addedProps){if(arguments.length>2&&"undefined"!=typeof arguments[2])throw new Error("Passing children to a route handler is not supported");return route.props.handler(mergeProperties(props,addedProps))}.bind(this,props)}),props}function returnNull(){return null}function reversedArray(array){return array.slice(0).reverse()}function maybeScrollWindow(routes,match){routes.props.preserveScrollPosition||match&&!match.route.props.preserveScrollPosition&&window.scrollTo(0,0)}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,warning=_dereq_("react/lib/warning"),ExecutionEnvironment=_dereq_("react/lib/ExecutionEnvironment"),mergeProperties=_dereq_("../helpers/mergeProperties"),goBack=_dereq_("../helpers/goBack"),replaceWith=_dereq_("../helpers/replaceWith"),transitionTo=_dereq_("../helpers/transitionTo"),Route=_dereq_("../components/Route"),Path=_dereq_("../helpers/Path"),ActiveStore=_dereq_("../stores/ActiveStore"),RouteStore=_dereq_("../stores/RouteStore"),URLStore=_dereq_("../stores/URLStore"),Promise=_dereq_("es6-promise").Promise,REF_NAME="__activeRoute__",Routes=React.createClass({displayName:"Routes",statics:{handleAsyncError:function(error){throw error},handleCancelledTransition:function(transition){var reason=transition.cancelReason;reason instanceof Redirect?replaceWith(reason.to,reason.params,reason.query):reason instanceof Abort&&goBack()}},propTypes:{location:React.PropTypes.oneOf(["hash","history"]).isRequired,preserveScrollPosition:React.PropTypes.bool},getDefaultProps:function(){return{location:"hash",preserveScrollPosition:!1}},getInitialState:function(){return{}},componentWillMount:function(){React.Children.forEach(this.props.children,function(child){RouteStore.registerRoute(child)}),!URLStore.isSetup()&&ExecutionEnvironment.canUseDOM&&URLStore.setup(this.props.location),URLStore.addChangeListener(this.handleRouteChange)},componentDidMount:function(){this.dispatch(URLStore.getCurrentPath())},componentWillUnmount:function(){URLStore.removeChangeListener(this.handleRouteChange)},handleRouteChange:function(){this.dispatch(URLStore.getCurrentPath())},match:function(path){var rootRoutes=this.props.children;Array.isArray(rootRoutes)||(rootRoutes=[rootRoutes]);for(var matches=null,i=0;null==matches&&i defined somewhere in your routes'),path=route.props.path}return Path.withQuery(Path.injectParams(path,params),query)}var invariant=_dereq_("react/lib/invariant"),RouteStore=_dereq_("../stores/RouteStore"),Path=_dereq_("./Path");module.exports=makePath},{"../stores/RouteStore":27,"./Path":14,"react/lib/invariant":60}],19:[function(_dereq_,module){function mergeProperties(object,properties){for(var property in properties)properties.hasOwnProperty(property)&&(object[property]=properties[property]);return object}module.exports=mergeProperties},{}],20:[function(_dereq_,module){function replaceWith(to,params,query){URLStore.replace(makePath(to,params,query))}var URLStore=_dereq_("../stores/URLStore"),makePath=_dereq_("./makePath");module.exports=replaceWith},{"../stores/URLStore":28,"./makePath":18}],21:[function(_dereq_,module){function resolveAsyncState(asyncState,setState){if(null==asyncState)return Promise.resolve();var keys=Object.keys(asyncState);return Promise.all(keys.map(function(key){return Promise.resolve(asyncState[key]).then(function(value){var newState={};newState[key]=value,setState(newState)})}))}var Promise=_dereq_("es6-promise").Promise;module.exports=resolveAsyncState},{"es6-promise":32}],22:[function(_dereq_,module){function transitionTo(to,params,query){URLStore.push(makePath(to,params,query))}var URLStore=_dereq_("../stores/URLStore"),makePath=_dereq_("./makePath");module.exports=transitionTo},{"../stores/URLStore":28,"./makePath":18}],23:[function(_dereq_,module){function withoutProperties(object,properties){var result={};for(var property in object)object.hasOwnProperty(property)&&!properties[property]&&(result[property]=object[property]);return result}module.exports=withoutProperties},{}],24:[function(_dereq_,module){var ActiveStore=_dereq_("../stores/ActiveStore"),ActiveState={statics:{isActive:ActiveStore.isActive},componentWillMount:function(){ActiveStore.addChangeListener(this.handleActiveStateChange)},componentDidMount:function(){this.updateActiveState&&this.updateActiveState()},componentWillUnmount:function(){ActiveStore.removeChangeListener(this.handleActiveStateChange)},handleActiveStateChange:function(){this.isMounted()&&this.updateActiveState&&this.updateActiveState()}};module.exports=ActiveState},{"../stores/ActiveStore":26}],25:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,resolveAsyncState=_dereq_("../helpers/resolveAsyncState"),AsyncState={propTypes:{initialAsyncState:React.PropTypes.object},getInitialState:function(){return this.props.initialAsyncState||null},updateAsyncState:function(state){this.isMounted()&&this.setState(state)},componentDidMount:function(){!this.props.initialAsyncState&&this.constructor.getInitialAsyncState&&resolveAsyncState(this.constructor.getInitialAsyncState(this.props.params,this.props.query,this.updateAsyncState),this.updateAsyncState)}};module.exports=AsyncState},{"../helpers/resolveAsyncState":21}],26:[function(_dereq_,module){function routeIsActive(routeName){return _activeRoutes.some(function(route){return route.props.name===routeName})}function paramsAreActive(params){for(var property in params)if(_activeParams[property]!==String(params[property]))return!1;return!0}function queryIsActive(query){for(var property in query)if(_activeQuery[property]!==String(query[property]))return!1;return!0}function notifyChange(){_events.emit("change")}var _activeRoutes=[],_activeParams={},_activeQuery={},EventEmitter=_dereq_("event-emitter"),_events=EventEmitter(),ActiveStore={addChangeListener:function(listener){_events.on("change",listener)},removeChangeListener:function(listener){_events.off("change",listener)},updateState:function(state){state=state||{},_activeRoutes=state.activeRoutes||[],_activeParams=state.activeParams||{},_activeQuery=state.activeQuery||{},notifyChange()},isActive:function(routeName,params,query){var isActive=routeIsActive(routeName)&¶msAreActive(params);return query?isActive&&queryIsActive(query):isActive}};module.exports=ActiveStore},{"event-emitter":42}],27:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,invariant=_dereq_("react/lib/invariant"),Path=(_dereq_("react/lib/warning"),_dereq_("../helpers/Path")),_namedRoutes={},RouteStore={unregisterAllRoutes:function(){_namedRoutes={}},unregisterRoute:function(route){route.props.name&&delete _namedRoutes[route.props.name],React.Children.forEach(route.props.children,function(child){RouteStore.unregisterRoute(child)})},registerRoute:function(route,_parentRoute){if(route.props.path=route.props.path||route.props.name?Path.normalize(route.props.path||route.props.name):"/",invariant(React.isValidClass(route.props.handler),'The handler for Route "'+(route.props.name||route.props.path)+'" must be a valid React component'),_parentRoute){var paramNames=Path.extractParamNames(route.props.path);Path.extractParamNames(_parentRoute.props.path).forEach(function(paramName){invariant(-1!==paramNames.indexOf(paramName),'The nested route path "'+route.props.path+'" is missing the "'+paramName+'" parameter of its parent path "'+_parentRoute.props.path+'"')})}if(route.props.name){var existingRoute=_namedRoutes[route.props.name];invariant(!existingRoute||route===existingRoute,'You cannot use the name "'+route.props.name+'" for more than one route'),_namedRoutes[route.props.name]=route}React.Children.forEach(route.props.children,function(child){RouteStore.registerRoute(child,route)})},getRouteByName:function(routeName){return _namedRoutes[routeName]||null}};module.exports=RouteStore},{"../helpers/Path":14,"react/lib/invariant":60,"react/lib/warning":61}],28:[function(_dereq_,module){function getWindowChangeEvent(location){return"history"===location?"popstate":window.addEventListener?"hashchange":"onhashchange"}function getWindowPath(){return window.location.pathname+window.location.search}function notifyChange(){_events.emit("change")}function supportsHistory(){var ua=navigator.userAgent;return-1===ua.indexOf("Android 2.")&&-1===ua.indexOf("Android 4.0")||-1===ua.indexOf("Mobile Safari")||-1!==ua.indexOf("Chrome")?window.history&&"pushState"in window.history:!1}var _location,ExecutionEnvironment=_dereq_("react/lib/ExecutionEnvironment"),invariant=_dereq_("react/lib/invariant"),warning=_dereq_("react/lib/warning"),_currentPath="/",_lastPath=null,EventEmitter=_dereq_("event-emitter"),_events=EventEmitter(),URLStore={addChangeListener:function(listener){_events.on("change",listener)},removeChangeListener:function(listener){_events.off("change",listener)},getLocation:function(){return _location||"hash"},getCurrentPath:function(){return"history"===_location||"disabledHistory"===_location?getWindowPath():"hash"===_location?window.location.hash.substr(1):_currentPath},push:function(path){return path!==this.getCurrentPath()?"disabledHistory"===_location?window.location=path:void("history"===_location?(window.history.pushState({path:path},"",path),notifyChange()):"hash"===_location?window.location.hash=path:(_lastPath=_currentPath,_currentPath=path,notifyChange())):void 0},replace:function(path){"disabledHistory"===_location?window.location.replace(path):"history"===_location?(window.history.replaceState({path:path},"",path),notifyChange()):"hash"===_location?window.location.replace(getWindowPath()+"#"+path):(_currentPath=path,notifyChange())},back:function(){null!=_location?window.history.back():(invariant(_lastPath,"You cannot make the URL store go back more than once when it does not use the DOM"),_currentPath=_lastPath,_lastPath=null,notifyChange())},isSetup:function(){return null!=_location},setup:function(location){if(invariant(ExecutionEnvironment.canUseDOM,"You cannot setup the URL store in an environment with no DOM"),null!=_location)return void warning(_location===location,"The URL store was already setup using "+_location+" location. You cannot use "+location+" location on the same page");if("history"===location&&!supportsHistory())return void(_location="disabledHistory");var changeEvent=getWindowChangeEvent(location);invariant(changeEvent||"disabledHistory"===location,'The URL store location "'+location+'" is not valid. It must be either "hash" or "history"'),_location=location,"hash"===location&&""===window.location.hash&&URLStore.replace("/"),window.addEventListener?window.addEventListener(changeEvent,notifyChange,!1):window.attachEvent(changeEvent,notifyChange),notifyChange()},teardown:function(){if(null!=_location){var changeEvent=getWindowChangeEvent(_location);window.removeEventListener?window.removeEventListener(changeEvent,notifyChange,!1):window.detachEvent(changeEvent,notifyChange),_location=null,_currentPath="/"}}};module.exports=URLStore},{"event-emitter":42,"react/lib/ExecutionEnvironment":57,"react/lib/invariant":60,"react/lib/warning":61}],29:[function(_dereq_,module){"use strict";function hasOwnProperty(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop)}module.exports=function(qs,sep,eq,options){sep=sep||"&",eq=eq||"=";var obj={};if("string"!=typeof qs||0===qs.length)return obj;var regexp=/\+/g;qs=qs.split(sep);var maxKeys=1e3;options&&"number"==typeof options.maxKeys&&(maxKeys=options.maxKeys);var len=qs.length;maxKeys>0&&len>maxKeys&&(len=maxKeys);for(var i=0;len>i;++i){var kstr,vstr,k,v,x=qs[i].replace(regexp,"%20"),idx=x.indexOf(eq);idx>=0?(kstr=x.substr(0,idx),vstr=x.substr(idx+1)):(kstr=x,vstr=""),k=decodeURIComponent(kstr),v=decodeURIComponent(vstr),hasOwnProperty(obj,k)?isArray(obj[k])?obj[k].push(v):obj[k]=[obj[k],v]:obj[k]=v}return obj};var isArray=Array.isArray||function(xs){return"[object Array]"===Object.prototype.toString.call(xs)}},{}],30:[function(_dereq_,module){"use strict";function map(xs,f){if(xs.map)return xs.map(f);for(var res=[],i=0;ii;++i)args[i-1]=arguments[i];for(listeners=listeners.slice(),i=0;listener=listeners[i];++i)apply.call(listener,this,args)}else switch(arguments.length){case 1:call.call(listeners,this);break;case 2:call.call(listeners,this,arguments[1]);break;case 3:call.call(listeners,this,arguments[1],arguments[2]);break;default:for(l=arguments.length,args=new Array(l-1),i=1;l>i;++i)args[i-1]=arguments[i];apply.call(listeners,this,args)}},methods={on:on,once:once,off:off,emit:emit},descriptors={on:d(on),once:d(once),off:d(off),emit:d(emit)},base=defineProperties({},descriptors),module.exports=exports=function(o){return null==o?create(base):defineProperties(Object(o),descriptors)},exports.methods=methods},{d:43,"es5-ext/object/valid-callable":52}],43:[function(_dereq_,module){"use strict";var d,assign=_dereq_("es5-ext/object/assign"),normalizeOpts=_dereq_("es5-ext/object/normalize-options"),isCallable=_dereq_("es5-ext/object/is-callable"),contains=_dereq_("es5-ext/string/#/contains");d=module.exports=function(dscr,value){var c,e,w,options,desc;return arguments.length<2||"string"!=typeof dscr?(options=value,value=dscr,dscr=null):options=arguments[2],null==dscr?(c=w=!0,e=!1):(c=contains.call(dscr,"c"),e=contains.call(dscr,"e"),w=contains.call(dscr,"w")),desc={value:value,configurable:c,enumerable:e,writable:w},options?assign(normalizeOpts(options),desc):desc},d.gs=function(dscr,get,set){var c,e,options,desc;return"string"!=typeof dscr?(options=set,set=get,get=dscr,dscr=null):options=arguments[3],null==get?get=void 0:isCallable(get)?null==set?set=void 0:isCallable(set)||(options=set,set=void 0):(options=get,get=set=void 0),null==dscr?(c=!0,e=!1):(c=contains.call(dscr,"c"),e=contains.call(dscr,"e")),desc={get:get,set:set,configurable:c,enumerable:e},options?assign(normalizeOpts(options),desc):desc}},{"es5-ext/object/assign":44,"es5-ext/object/is-callable":47,"es5-ext/object/normalize-options":51,"es5-ext/string/#/contains":54}],44:[function(_dereq_,module){"use strict";module.exports=_dereq_("./is-implemented")()?Object.assign:_dereq_("./shim")},{"./is-implemented":45,"./shim":46}],45:[function(_dereq_,module){"use strict";module.exports=function(){var obj,assign=Object.assign;return"function"!=typeof assign?!1:(obj={foo:"raz"},assign(obj,{bar:"dwa"},{trzy:"trzy"}),obj.foo+obj.bar+obj.trzy==="razdwatrzy")}},{}],46:[function(_dereq_,module){"use strict";var keys=_dereq_("../keys"),value=_dereq_("../valid-value"),max=Math.max;module.exports=function(dest,src){var error,i,assign,l=max(arguments.length,2);for(dest=Object(value(dest)),assign=function(key){try{dest[key]=src[key]}catch(e){error||(error=e)}},i=1;l>i;++i)src=arguments[i],keys(src).forEach(assign);if(void 0!==error)throw error;return dest}},{"../keys":48,"../valid-value":53}],47:[function(_dereq_,module){"use strict";module.exports=function(obj){return"function"==typeof obj}},{}],48:[function(_dereq_,module){"use strict";module.exports=_dereq_("./is-implemented")()?Object.keys:_dereq_("./shim")},{"./is-implemented":49,"./shim":50}],49:[function(_dereq_,module){"use strict";module.exports=function(){try{return Object.keys("primitive"),!0}catch(e){return!1}}},{}],50:[function(_dereq_,module){"use strict";var keys=Object.keys;module.exports=function(object){return keys(null==object?object:Object(object))}},{}],51:[function(_dereq_,module){"use strict";var process,assign=_dereq_("./assign"),forEach=Array.prototype.forEach,create=Object.create,getPrototypeOf=Object.getPrototypeOf;process=function(src,obj){var proto=getPrototypeOf(src);return assign(proto?process(proto,obj):obj,src)},module.exports=function(){var result=create(null);return forEach.call(arguments,function(options){null!=options&&process(Object(options),result)}),result}},{"./assign":44}],52:[function(_dereq_,module){"use strict";module.exports=function(fn){if("function"!=typeof fn)throw new TypeError(fn+" is not a function");return fn}},{}],53:[function(_dereq_,module){"use strict";module.exports=function(value){if(null==value)throw new TypeError("Cannot use null or undefined");return value}},{}],54:[function(_dereq_,module){"use strict";module.exports=_dereq_("./is-implemented")()?String.prototype.contains:_dereq_("./shim")},{"./is-implemented":55,"./shim":56}],55:[function(_dereq_,module){"use strict";var str="razdwatrzy";module.exports=function(){return"function"!=typeof str.contains?!1:str.contains("dwa")===!0&&str.contains("foo")===!1}},{}],56:[function(_dereq_,module){"use strict";var indexOf=String.prototype.indexOf;module.exports=function(searchString){return indexOf.call(this,searchString,arguments[1])>-1}},{}],57:[function(_dereq_,module){"use strict";var canUseDOM=!("undefined"==typeof window||!window.document||!window.document.createElement),ExecutionEnvironment={canUseDOM:canUseDOM,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:canUseDOM&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:canUseDOM&&!!window.screen,isInWorker:!canUseDOM};module.exports=ExecutionEnvironment},{}],58:[function(_dereq_,module){function copyProperties(obj,a,b,c,d,e,f){obj=obj||{};for(var v,args=[a,b,c,d,e],ii=0;args[ii];){v=args[ii++];for(var k in v)obj[k]=v[k];v.hasOwnProperty&&v.hasOwnProperty("toString")&&"undefined"!=typeof v.toString&&obj.toString!==v.toString&&(obj.toString=v.toString)}return obj}module.exports=copyProperties},{}],59:[function(_dereq_,module){function makeEmptyFunction(arg){return function(){return arg}}function emptyFunction(){}var copyProperties=_dereq_("./copyProperties");copyProperties(emptyFunction,{thatReturns:makeEmptyFunction,thatReturnsFalse:makeEmptyFunction(!1),thatReturnsTrue:makeEmptyFunction(!0),thatReturnsNull:makeEmptyFunction(null),thatReturnsThis:function(){return this},thatReturnsArgument:function(arg){return arg}}),module.exports=emptyFunction},{"./copyProperties":58}],60:[function(_dereq_,module){"use strict";var invariant=function(condition,format,a,b,c,d,e,f){if(!condition){var error;if(void 0===format)error=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var args=[a,b,c,d,e,f],argIndex=0;error=new Error("Invariant Violation: "+format.replace(/%s/g,function(){return args[argIndex++]}))}throw error.framesToPop=1,error}};module.exports=invariant},{}],61:[function(_dereq_,module){"use strict";var emptyFunction=_dereq_("./emptyFunction"),warning=emptyFunction;module.exports=warning},{"./emptyFunction":59}],62:[function(_dereq_,module){module.exports=_dereq_("./modules/helpers/replaceWith")},{"./modules/helpers/replaceWith":20}],63:[function(_dereq_,module){module.exports=_dereq_("./modules/helpers/transitionTo")},{"./modules/helpers/transitionTo":22}]},{},[8])(8)}); \ No newline at end of file +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.ReactRouter=e()}}(function(){return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o component should not be rendered directly. You may be missing a wrapper around your list of routes.")}});module.exports=Route},{"../helpers/withoutProperties":29}],15:[function(_dereq_,module){function defaultAbortedTransitionHandler(transition){var reason=transition.abortReason;reason instanceof Redirect?replaceWith(reason.to,reason.params,reason.query):goBack()}function defaultActiveStateChangeHandler(state){ActiveStore.updateState(state)}function defaultTransitionErrorHandler(error){throw error}function findMatches(path,routes,defaultRoute){for(var route,params,matches=null,i=0,len=routes.length;len>i;++i){if(route=routes[i],matches=findMatches(path,route.props.children,route.props.defaultRoute),null!=matches){var rootParams=getRootMatch(matches).params;return params=route.props.paramNames.reduce(function(params,paramName){return params[paramName]=rootParams[paramName],params},{}),matches.unshift(makeMatch(route,params)),matches}if(params=Path.extractParams(route.props.path,path))return[makeMatch(route,params)]}return params=defaultRoute&&Path.extractParams(defaultRoute.props.path,path),params?[makeMatch(defaultRoute,params)]:matches}function makeMatch(route,params){return{route:route,params:params}}function hasMatch(matches,match){return matches.some(function(m){if(m.route!==match.route)return!1;for(var property in m.params)if(m.params[property]!==match.params[property])return!1;return!0})}function getRootMatch(matches){return matches[matches.length-1]}function updateMatchComponents(matches,refs){for(var component,i=0;component=refs[REF_NAME];)matches[i++].component=component,refs=component.refs}function runTransitionHooks(routes,transition){if(routes.state.path===transition.path)return Promise.resolve();var currentMatches=routes.state.matches,nextMatches=routes.match(transition.path);warning(nextMatches,'No route matches path "'+transition.path+'". Make sure you have somewhere in your routes'),nextMatches||(nextMatches=[]);var fromMatches,toMatches;return currentMatches?(updateMatchComponents(currentMatches,routes.refs),fromMatches=currentMatches.filter(function(match){return!hasMatch(nextMatches,match)}),toMatches=nextMatches.filter(function(match){return!hasMatch(currentMatches,match)})):(fromMatches=[],toMatches=nextMatches),runTransitionFromHooks(fromMatches,transition).then(function(){return transition.isAborted?void 0:runTransitionToHooks(toMatches,transition).then(function(){if(!transition.isAborted){var rootMatch=getRootMatch(nextMatches),params=rootMatch&&rootMatch.params||{},query=Path.extractQuery(transition.path)||{};return{path:transition.path,matches:nextMatches,activeParams:params,activeQuery:query,activeRoutes:nextMatches.map(function(match){return match.route})}}})})}function runTransitionFromHooks(matches,transition){var promise=Promise.resolve();return reversedArray(matches).forEach(function(match){promise=promise.then(function(){var handler=match.route.props.handler;return!transition.isAborted&&handler.willTransitionFrom?handler.willTransitionFrom(transition,match.component):void 0})}),promise}function runTransitionToHooks(matches,transition){var promise=Promise.resolve();return matches.forEach(function(match){promise=promise.then(function(){var handler=match.route.props.handler;return!transition.isAborted&&handler.willTransitionTo?handler.willTransitionTo(transition,match.params):void 0})}),promise}function computeHandlerProps(matches,query){var childHandler,props={ref:null,key:null,params:null,query:null,activeRouteHandler:returnNull};return reversedArray(matches).forEach(function(match){var route=match.route;props=Route.getUnreservedProps(route.props),props.ref=REF_NAME,props.key=Path.injectParams(route.props.path,match.params),props.params=match.params,props.query=query,props.activeRouteHandler=childHandler?childHandler:returnNull,childHandler=function(props,addedProps){if(arguments.length>2&&"undefined"!=typeof arguments[2])throw new Error("Passing children to a route handler is not supported");return route.props.handler(copyProperties(props,addedProps))}.bind(this,props)}),props}function returnNull(){return null}function reversedArray(array){return array.slice(0).reverse()}function maybeScrollWindow(routes,rootRoute){routes.props.preserveScrollPosition||rootRoute.props.preserveScrollPosition||window.scrollTo(0,0)}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,warning=_dereq_("react/lib/warning"),copyProperties=_dereq_("react/lib/copyProperties"),Promise=_dereq_("es6-promise").Promise,Route=_dereq_("../components/Route"),goBack=_dereq_("../helpers/goBack"),replaceWith=_dereq_("../helpers/replaceWith"),Path=_dereq_("../helpers/Path"),Redirect=_dereq_("../helpers/Redirect"),Transition=_dereq_("../helpers/Transition"),HashLocation=_dereq_("../locations/HashLocation"),HistoryLocation=_dereq_("../locations/HistoryLocation"),RefreshLocation=_dereq_("../locations/RefreshLocation"),ActiveStore=_dereq_("../stores/ActiveStore"),PathStore=_dereq_("../stores/PathStore"),RouteStore=_dereq_("../stores/RouteStore"),REF_NAME="__activeRoute__",NAMED_LOCATIONS={hash:HashLocation,history:HistoryLocation,refresh:RefreshLocation,disabled:RefreshLocation},Routes=React.createClass({displayName:"Routes",propTypes:{onAbortedTransition:React.PropTypes.func.isRequired,onActiveStateChange:React.PropTypes.func.isRequired,onTransitionError:React.PropTypes.func.isRequired,preserveScrollPosition:React.PropTypes.bool,location:function(props,propName,componentName){var location=props[propName];return"string"!=typeof location||location in NAMED_LOCATIONS?void 0:new Error('Unknown location "'+location+'", see '+componentName)}},getDefaultProps:function(){return{onAbortedTransition:defaultAbortedTransitionHandler,onActiveStateChange:defaultActiveStateChangeHandler,onTransitionError:defaultTransitionErrorHandler,preserveScrollPosition:!1,location:HashLocation}},getInitialState:function(){return{routes:RouteStore.registerChildren(this.props.children,this)}},getLocation:function(){var location=this.props.location;return"string"==typeof location?NAMED_LOCATIONS[location]:location},componentWillMount:function(){PathStore.setup(this.getLocation()),PathStore.addChangeListener(this.handlePathChange)},componentDidMount:function(){this.handlePathChange()},componentWillUnmount:function(){PathStore.removeChangeListener(this.handlePathChange)},handlePathChange:function(){this.dispatch(PathStore.getCurrentPath())},match:function(path){return findMatches(Path.withoutQuery(path),this.state.routes,this.props.defaultRoute)},dispatch:function(path,returnRejectedPromise){var transition=new Transition(path),routes=this,promise=runTransitionHooks(routes,transition).then(function(nextState){if(transition.isAborted)routes.props.onAbortedTransition(transition);else if(nextState){routes.setState(nextState),routes.props.onActiveStateChange(nextState);var rootMatch=getRootMatch(nextState.matches);rootMatch&&maybeScrollWindow(routes,rootMatch.route)}return transition});return returnRejectedPromise||(promise=promise.then(void 0,function(error){setTimeout(function(){routes.props.onTransitionError(error)})})),promise},render:function(){if(!this.state.path)return null;var matches=this.state.matches;return matches.length?matches[0].route.props.handler(computeHandlerProps(matches,this.state.activeQuery)):null}});module.exports=Routes},{"../components/Route":14,"../helpers/Path":16,"../helpers/Redirect":17,"../helpers/Transition":18,"../helpers/goBack":21,"../helpers/replaceWith":25,"../locations/HashLocation":30,"../locations/HistoryLocation":31,"../locations/RefreshLocation":32,"../stores/ActiveStore":35,"../stores/PathStore":36,"../stores/RouteStore":37,"es6-promise":42,"react/lib/copyProperties":53,"react/lib/warning":61}],16:[function(_dereq_,module){function getParamName(pathSegment){return"*"===pathSegment?"splat":pathSegment.substr(1)}function compilePattern(pattern){if(_compiledPatterns[pattern])return _compiledPatterns[pattern];var compiled=_compiledPatterns[pattern]={},paramNames=compiled.paramNames=[],source=pattern.replace(paramMatcher,function(match,pathSegment){return paramNames.push(getParamName(pathSegment)),"*"===pathSegment?"(.*?)":"([^/?#]+)"});return compiled.matcher=new RegExp("^"+source+"$","i"),compiled}function isDynamicPattern(pattern){return-1!==pattern.indexOf(":")||-1!==pattern.indexOf("*")}var invariant=_dereq_("react/lib/invariant"),copyProperties=_dereq_("react/lib/copyProperties"),qs=_dereq_("querystring"),URL=_dereq_("./URL"),paramMatcher=/((?::[a-z_$][a-z0-9_$]*)|\*)/gi,queryMatcher=/\?(.+)/,_compiledPatterns={},Path={extractParams:function(pattern,path){if(!pattern)return null;if(!isDynamicPattern(pattern))return pattern===URL.decode(path)?{}:null;var compiled=compilePattern(pattern),match=URL.decode(path).match(compiled.matcher);if(!match)return null;var params={};return compiled.paramNames.forEach(function(paramName,index){params[paramName]=match[index+1]}),params},extractParamNames:function(pattern){return pattern?compilePattern(pattern).paramNames:[]},injectParams:function(pattern,params){return pattern?isDynamicPattern(pattern)?(params=params||{},pattern.replace(paramMatcher,function(match,pathSegment){var paramName=getParamName(pathSegment);return invariant(null!=params[paramName],'Missing "'+paramName+'" parameter for path "'+pattern+'"'),String(params[paramName]).split("/").map(URL.encode).join("/")})):pattern:null},extractQuery:function(path){var match=path.match(queryMatcher);return match&&qs.parse(match[1])},withoutQuery:function(path){return path.replace(queryMatcher,"")},withQuery:function(path,query){var existingQuery=Path.extractQuery(path);existingQuery&&(query=query?copyProperties(existingQuery,query):existingQuery);var queryString=query&&qs.stringify(query);return queryString?Path.withoutQuery(path)+"?"+queryString:path},normalize:function(path){return path.replace(/^\/*/,"/")}};module.exports=Path},{"./URL":19,querystring:41,"react/lib/copyProperties":53,"react/lib/invariant":55}],17:[function(_dereq_,module){function Redirect(to,params,query){this.to=to,this.params=params,this.query=query}module.exports=Redirect},{}],18:[function(_dereq_,module){function Transition(path){this.path=path,this.abortReason=null,this.isAborted=!1}var mixInto=_dereq_("react/lib/mixInto"),transitionTo=_dereq_("./transitionTo"),Redirect=_dereq_("./Redirect");mixInto(Transition,{abort:function(reason){this.abortReason=reason,this.isAborted=!0},redirect:function(to,params,query){this.abort(new Redirect(to,params,query))},retry:function(){transitionTo(this.path)}}),module.exports=Transition},{"./Redirect":17,"./transitionTo":28,"react/lib/mixInto":60}],19:[function(_dereq_,module){var urlEncodedSpaceRE=/\+/g,encodedSpaceRE=/%20/g,URL={decode:function(str){return str=str.replace(urlEncodedSpaceRE," "),decodeURIComponent(str)},encode:function(str){return str=encodeURIComponent(str),str.replace(encodedSpaceRE,"+")}};module.exports=URL},{}],20:[function(_dereq_,module){function getWindowPath(){return window.location.pathname+window.location.search}module.exports=getWindowPath},{}],21:[function(_dereq_,module){function goBack(){PathStore.pop()}var PathStore=_dereq_("../stores/PathStore");module.exports=goBack},{"../stores/PathStore":36}],22:[function(_dereq_,module){module.exports=Function.prototype.call.bind(Object.prototype.hasOwnProperty)},{}],23:[function(_dereq_,module){function makeHref(to,params,query){var path=makePath(to,params,query);return PathStore.getLocation()===HashLocation?"#"+path:path}var HashLocation=_dereq_("../locations/HashLocation"),PathStore=_dereq_("../stores/PathStore"),makePath=_dereq_("./makePath");module.exports=makeHref},{"../locations/HashLocation":30,"../stores/PathStore":36,"./makePath":24}],24:[function(_dereq_,module){function makePath(to,params,query){var path;if("/"===to.charAt(0))path=Path.normalize(to);else{var route=RouteStore.getRouteByName(to);invariant(route,'Unable to find a route named "'+to+'". Make sure you have a defined somewhere in your routes'),path=route.props.path}return Path.withQuery(Path.injectParams(path,params),query)}var invariant=_dereq_("react/lib/invariant"),RouteStore=_dereq_("../stores/RouteStore"),Path=_dereq_("./Path");module.exports=makePath},{"../stores/RouteStore":37,"./Path":16,"react/lib/invariant":55}],25:[function(_dereq_,module){function replaceWith(to,params,query){PathStore.replace(makePath(to,params,query))}var PathStore=_dereq_("../stores/PathStore"),makePath=_dereq_("./makePath");module.exports=replaceWith},{"../stores/PathStore":36,"./makePath":24}],26:[function(_dereq_,module){function resolveAsyncState(asyncState,setState){if(null==asyncState)return Promise.resolve();var keys=Object.keys(asyncState);return Promise.all(keys.map(function(key){return Promise.resolve(asyncState[key]).then(function(value){var newState={};newState[key]=value,setState(newState)})}))}var Promise=_dereq_("es6-promise").Promise;module.exports=resolveAsyncState},{"es6-promise":42}],27:[function(_dereq_,module){function supportsHistory(){var ua=navigator.userAgent;return-1===ua.indexOf("Android 2.")&&-1===ua.indexOf("Android 4.0")||-1===ua.indexOf("Mobile Safari")||-1!==ua.indexOf("Chrome")?window.history&&"pushState"in window.history:!1}module.exports=supportsHistory},{}],28:[function(_dereq_,module){function transitionTo(to,params,query){PathStore.push(makePath(to,params,query))}var PathStore=_dereq_("../stores/PathStore"),makePath=_dereq_("./makePath");module.exports=transitionTo},{"../stores/PathStore":36,"./makePath":24}],29:[function(_dereq_,module){function withoutProperties(object,properties){var result={};for(var property in object)object.hasOwnProperty(property)&&!properties[property]&&(result[property]=object[property]);return result}module.exports=withoutProperties},{}],30:[function(_dereq_,module){var _onChange,invariant=_dereq_("react/lib/invariant"),ExecutionEnvironment=_dereq_("react/lib/ExecutionEnvironment"),getWindowPath=_dereq_("../helpers/getWindowPath"),HashLocation={setup:function(onChange){invariant(ExecutionEnvironment.canUseDOM,"You cannot use HashLocation in an environment with no DOM"),_onChange=onChange,""===window.location.hash&&window.location.replace(getWindowPath()+"#/"),window.addEventListener?window.addEventListener("hashchange",_onChange,!1):window.attachEvent("onhashchange",_onChange)},teardown:function(){window.removeEventListener?window.removeEventListener("hashchange",_onChange,!1):window.detachEvent("onhashchange",_onChange)},push:function(path){window.location.hash=path},replace:function(path){window.location.replace(getWindowPath()+"#"+path)},pop:function(){window.history.back()},getCurrentPath:function(){return window.location.hash.substr(1)},toString:function(){return""}};module.exports=HashLocation},{"../helpers/getWindowPath":20,"react/lib/ExecutionEnvironment":52,"react/lib/invariant":55}],31:[function(_dereq_,module){var _onChange,invariant=_dereq_("react/lib/invariant"),ExecutionEnvironment=_dereq_("react/lib/ExecutionEnvironment"),getWindowPath=_dereq_("../helpers/getWindowPath"),HistoryLocation={setup:function(onChange){invariant(ExecutionEnvironment.canUseDOM,"You cannot use HistoryLocation in an environment with no DOM"),_onChange=onChange,window.addEventListener?window.addEventListener("popstate",_onChange,!1):window.attachEvent("popstate",_onChange)},teardown:function(){window.removeEventListener?window.removeEventListener("popstate",_onChange,!1):window.detachEvent("popstate",_onChange)},push:function(path){window.history.pushState({path:path},"",path),_onChange()},replace:function(path){window.history.replaceState({path:path},"",path),_onChange()},pop:function(){window.history.back()},getCurrentPath:getWindowPath,toString:function(){return""}};module.exports=HistoryLocation},{"../helpers/getWindowPath":20,"react/lib/ExecutionEnvironment":52,"react/lib/invariant":55}],32:[function(_dereq_,module){var invariant=_dereq_("react/lib/invariant"),ExecutionEnvironment=_dereq_("react/lib/ExecutionEnvironment"),getWindowPath=_dereq_("../helpers/getWindowPath"),RefreshLocation={setup:function(){invariant(ExecutionEnvironment.canUseDOM,"You cannot use RefreshLocation in an environment with no DOM")},push:function(path){window.location=path},replace:function(path){window.location.replace(path)},pop:function(){window.history.back()},getCurrentPath:getWindowPath,toString:function(){return""}};module.exports=RefreshLocation},{"../helpers/getWindowPath":20,"react/lib/ExecutionEnvironment":52,"react/lib/invariant":55}],33:[function(_dereq_,module){var ActiveStore=_dereq_("../stores/ActiveStore"),ActiveState={statics:{isActive:ActiveStore.isActive},componentWillMount:function(){ActiveStore.addChangeListener(this.handleActiveStateChange)},componentDidMount:function(){this.updateActiveState&&this.updateActiveState()},componentWillUnmount:function(){ActiveStore.removeChangeListener(this.handleActiveStateChange)},handleActiveStateChange:function(){this.isMounted()&&this.updateActiveState&&this.updateActiveState()}};module.exports=ActiveState},{"../stores/ActiveStore":35}],34:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,resolveAsyncState=_dereq_("../helpers/resolveAsyncState"),AsyncState={propTypes:{initialAsyncState:React.PropTypes.object},getInitialState:function(){return this.props.initialAsyncState||null},updateAsyncState:function(state){this.isMounted()&&this.setState(state)},componentDidMount:function(){this.props.initialAsyncState||"function"!=typeof this.constructor.getInitialAsyncState||resolveAsyncState(this.constructor.getInitialAsyncState(this.props.params,this.props.query,this.updateAsyncState),this.updateAsyncState)}};module.exports=AsyncState},{"../helpers/resolveAsyncState":26}],35:[function(_dereq_,module){function notifyChange(){_events.emit(CHANGE_EVENT)}function routeIsActive(routeName){return _activeRoutes.some(function(route){return route.props.name===routeName})}function paramsAreActive(params){for(var property in params)if(_activeParams[property]!==String(params[property]))return!1;return!0}function queryIsActive(query){for(var property in query)if(_activeQuery[property]!==String(query[property]))return!1;return!0}var EventEmitter=_dereq_("events").EventEmitter,CHANGE_EVENT="change",_events=new EventEmitter;_events.setMaxListeners(0);var _activeRoutes=[],_activeParams={},_activeQuery={},ActiveStore={addChangeListener:function(listener){_events.on(CHANGE_EVENT,listener)},removeChangeListener:function(listener){_events.removeListener(CHANGE_EVENT,listener)},updateState:function(state){state=state||{},_activeRoutes=state.activeRoutes||[],_activeParams=state.activeParams||{},_activeQuery=state.activeQuery||{},notifyChange()},isActive:function(routeName,params,query){var isActive=routeIsActive(routeName)&¶msAreActive(params);return query?isActive&&queryIsActive(query):isActive}};module.exports=ActiveStore},{events:38}],36:[function(_dereq_,module){function notifyChange(){_events.emit(CHANGE_EVENT)}var _location,warning=_dereq_("react/lib/warning"),EventEmitter=_dereq_("events").EventEmitter,supportsHistory=_dereq_("../helpers/supportsHistory"),HistoryLocation=_dereq_("../locations/HistoryLocation"),RefreshLocation=_dereq_("../locations/RefreshLocation"),CHANGE_EVENT="change",_events=new EventEmitter,PathStore={addChangeListener:function(listener){_events.on(CHANGE_EVENT,listener)},removeChangeListener:function(listener){_events.removeListener(CHANGE_EVENT,listener),0===EventEmitter.listenerCount(_events,CHANGE_EVENT)&&PathStore.teardown()},setup:function(location){location!==HistoryLocation||supportsHistory()||(location=RefreshLocation),null==_location?(_location=location,_location&&"function"==typeof _location.setup&&_location.setup(notifyChange)):warning(_location===location,"Cannot use location %s, already using %s",location,_location)},teardown:function(){_location&&"function"==typeof _location.teardown&&_location.teardown(),_location=null},getLocation:function(){return _location},push:function(path){_location.getCurrentPath()!==path&&_location.push(path)},replace:function(path){_location.getCurrentPath()!==path&&_location.replace(path)},pop:function(){_location.pop()},getCurrentPath:function(){return _location.getCurrentPath()}};module.exports=PathStore},{"../helpers/supportsHistory":27,"../locations/HistoryLocation":31,"../locations/RefreshLocation":32,events:38,"react/lib/warning":61}],37:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,invariant=_dereq_("react/lib/invariant"),Path=(_dereq_("react/lib/warning"),_dereq_("../helpers/Path")),_namedRoutes={},RouteStore={unregisterAllRoutes:function(){_namedRoutes={}},unregisterRoute:function(route){var props=route.props;props.name&&delete _namedRoutes[props.name],React.Children.forEach(props.children,RouteStore.unregisterRoute)},registerRoute:function(route,parentRoute){var props=route.props;invariant(React.isValidClass(props.handler),'The handler for the "%s" route must be a valid React class',props.name||props.path);var isDefault=!(props.path||props.name||props.children);if(props.path=props.path||props.name?Path.normalize(props.path||props.name):parentRoute&&parentRoute.props.path?parentRoute.props.path:"/",props.paramNames=Path.extractParamNames(props.path),parentRoute&&Array.isArray(parentRoute.props.paramNames)&&parentRoute.props.paramNames.forEach(function(paramName){invariant(-1!==props.paramNames.indexOf(paramName),'The nested route path "%s" is missing the "%s" parameter of its parent path "%s"',props.path,paramName,parentRoute.props.path)}),props.name){var existingRoute=_namedRoutes[props.name];invariant(!existingRoute||route===existingRoute,'You cannot use the name "%s" for more than one route',props.name),_namedRoutes[props.name]=route}return parentRoute&&isDefault?(invariant(null==parentRoute.props.defaultRoute,"You may not have more than one per "),parentRoute.props.defaultRoute=route,null):(props.children=RouteStore.registerChildren(props.children,route),route)},registerChildren:function(children,parentRoute){var routes=[];return React.Children.forEach(children,function(child){(child=RouteStore.registerRoute(child,parentRoute))&&routes.push(child)}),routes},getRouteByName:function(routeName){return _namedRoutes[routeName]||null}};module.exports=RouteStore},{"../helpers/Path":16,"react/lib/invariant":55,"react/lib/warning":61}],38:[function(_dereq_,module){function EventEmitter(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function isFunction(arg){return"function"==typeof arg}function isNumber(arg){return"number"==typeof arg}function isObject(arg){return"object"==typeof arg&&null!==arg}function isUndefined(arg){return void 0===arg}module.exports=EventEmitter,EventEmitter.EventEmitter=EventEmitter,EventEmitter.prototype._events=void 0,EventEmitter.prototype._maxListeners=void 0,EventEmitter.defaultMaxListeners=10,EventEmitter.prototype.setMaxListeners=function(n){if(!isNumber(n)||0>n||isNaN(n))throw TypeError("n must be a positive number");return this._maxListeners=n,this},EventEmitter.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(this._events||(this._events={}),"error"===type&&(!this._events.error||isObject(this._events.error)&&!this._events.error.length))throw er=arguments[1],er instanceof Error?er:TypeError('Uncaught, unspecified "error" event.');if(handler=this._events[type],isUndefined(handler))return!1;if(isFunction(handler))switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:for(len=arguments.length,args=new Array(len-1),i=1;len>i;i++)args[i-1]=arguments[i];handler.apply(this,args)}else if(isObject(handler)){for(len=arguments.length,args=new Array(len-1),i=1;len>i;i++)args[i-1]=arguments[i];for(listeners=handler.slice(),len=listeners.length,i=0;len>i;i++)listeners[i].apply(this,args)}return!0},EventEmitter.prototype.addListener=function(type,listener){var m;if(!isFunction(listener))throw TypeError("listener must be a function");if(this._events||(this._events={}),this._events.newListener&&this.emit("newListener",type,isFunction(listener.listener)?listener.listener:listener),this._events[type]?isObject(this._events[type])?this._events[type].push(listener):this._events[type]=[this._events[type],listener]:this._events[type]=listener,isObject(this._events[type])&&!this._events[type].warned){var m;m=isUndefined(this._maxListeners)?EventEmitter.defaultMaxListeners:this._maxListeners,m&&m>0&&this._events[type].length>m&&(this._events[type].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[type].length),"function"==typeof console.trace&&console.trace())}return this},EventEmitter.prototype.on=EventEmitter.prototype.addListener,EventEmitter.prototype.once=function(type,listener){function g(){this.removeListener(type,g),fired||(fired=!0,listener.apply(this,arguments))}if(!isFunction(listener))throw TypeError("listener must be a function");var fired=!1;return g.listener=listener,this.on(type,g),this},EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;if(list=this._events[type],length=list.length,position=-1,list===listener||isFunction(list.listener)&&list.listener===listener)delete this._events[type],this._events.removeListener&&this.emit("removeListener",type,listener); +else if(isObject(list)){for(i=length;i-->0;)if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}if(0>position)return this;1===list.length?(list.length=0,delete this._events[type]):list.splice(position,1),this._events.removeListener&&this.emit("removeListener",type,listener)}return this},EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[type]&&delete this._events[type],this;if(0===arguments.length){for(key in this._events)"removeListener"!==key&&this.removeAllListeners(key);return this.removeAllListeners("removeListener"),this._events={},this}if(listeners=this._events[type],isFunction(listeners))this.removeListener(type,listeners);else for(;listeners.length;)this.removeListener(type,listeners[listeners.length-1]);return delete this._events[type],this},EventEmitter.prototype.listeners=function(type){var ret;return ret=this._events&&this._events[type]?isFunction(this._events[type])?[this._events[type]]:this._events[type].slice():[]},EventEmitter.listenerCount=function(emitter,type){var ret;return ret=emitter._events&&emitter._events[type]?isFunction(emitter._events[type])?1:emitter._events[type].length:0}},{}],39:[function(_dereq_,module){"use strict";function hasOwnProperty(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop)}module.exports=function(qs,sep,eq,options){sep=sep||"&",eq=eq||"=";var obj={};if("string"!=typeof qs||0===qs.length)return obj;var regexp=/\+/g;qs=qs.split(sep);var maxKeys=1e3;options&&"number"==typeof options.maxKeys&&(maxKeys=options.maxKeys);var len=qs.length;maxKeys>0&&len>maxKeys&&(len=maxKeys);for(var i=0;len>i;++i){var kstr,vstr,k,v,x=qs[i].replace(regexp,"%20"),idx=x.indexOf(eq);idx>=0?(kstr=x.substr(0,idx),vstr=x.substr(idx+1)):(kstr=x,vstr=""),k=decodeURIComponent(kstr),v=decodeURIComponent(vstr),hasOwnProperty(obj,k)?isArray(obj[k])?obj[k].push(v):obj[k]=[obj[k],v]:obj[k]=v}return obj};var isArray=Array.isArray||function(xs){return"[object Array]"===Object.prototype.toString.call(xs)}},{}],40:[function(_dereq_,module){"use strict";function map(xs,f){if(xs.map)return xs.map(f);for(var res=[],i=0;ilevel)},checkArrayStrategy:function(strategy){invariant(void 0===strategy||strategy in mergeHelpers.ArrayStrategies)},ArrayStrategies:keyMirror({Clobber:!0,IndexByIndex:!0})};module.exports=mergeHelpers},{"./invariant":55,"./keyMirror":56}],59:[function(_dereq_,module){"use strict";function mergeInto(one,two){if(checkMergeIntoObjectArg(one),null!=two){checkMergeObjectArg(two);for(var key in two)two.hasOwnProperty(key)&&(one[key]=two[key])}}var mergeHelpers=_dereq_("./mergeHelpers"),checkMergeObjectArg=mergeHelpers.checkMergeObjectArg,checkMergeIntoObjectArg=mergeHelpers.checkMergeIntoObjectArg;module.exports=mergeInto},{"./mergeHelpers":58}],60:[function(_dereq_,module){"use strict";var mixInto=function(constructor,methodBag){var methodName;for(methodName in methodBag)methodBag.hasOwnProperty(methodName)&&(constructor.prototype[methodName]=methodBag[methodName])};module.exports=mixInto},{}],61:[function(_dereq_,module){"use strict";var emptyFunction=_dereq_("./emptyFunction"),warning=emptyFunction;module.exports=warning},{"./emptyFunction":54}],62:[function(_dereq_,module){module.exports=_dereq_("./modules/helpers/replaceWith")},{"./modules/helpers/replaceWith":25}],63:[function(_dereq_,module){module.exports=_dereq_("./modules/helpers/transitionTo")},{"./modules/helpers/transitionTo":28}]},{},[9])(9)}); \ No newline at end of file diff --git a/package.json b/package.json index ba7872cce6..5bf3467ee4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-router", - "version": "0.5.2", + "version": "0.5.3", "description": "A complete routing library for React.js", "tags": [ "react", @@ -54,4 +54,4 @@ "browserify-shim": { "react": "global:React" } -} +} \ No newline at end of file