react-router
Advanced tools
Comparing version 0.5.3 to 0.6.0
@@ -0,8 +1,24 @@ | ||
v0.6.0 - Fri, 29 Aug 2014 20:58:36 GMT | ||
-------------------------------------- | ||
- [2a75f3e](../../commit/2a75f3e) [added] query argument to willTransitionTo | ||
- [b7e21bb](../../commit/b7e21bb) [fixed] Window scrolling | ||
- [5864531](../../commit/5864531) [changed] Default <Redirect from> to * | ||
- [1064881](../../commit/1064881) [changed] paths to inherit parents | ||
- [79caf99](../../commit/79caf99) [added] <DefaultRoute name> | ||
- [25adcab](../../commit/25adcab) [fixed] Using HashLocation without a preceeding / | ||
- [a63c940](../../commit/a63c940) [added] <NotFoundRoute> | ||
- [d5bd656](../../commit/d5bd656) [changed] path matching algorithm | ||
- [6526e70](../../commit/6526e70) [removed] location="disabled" | ||
- [8d2f3ed](../../commit/8d2f3ed) [changed] `<Link/>`s to take params property | ||
- [2a85b74](../../commit/2a85b74) [changed] handler keys to be optional | ||
v0.5.3 - Tue, 26 Aug 2014 03:36:42 GMT | ||
-------------------------------------- | ||
- [273625a](../../commit/273625a) [fixed] Active state on <Link>s with key prop | ||
- [273625a](../../commit/273625a) [fixed] Active state on `<Link>`s with key prop | ||
- [283d3f6](../../commit/283d3f6) [added] RouteStore#registerChildren | ||
- [a030648](../../commit/a030648) [changed] Relaxed MemoryStore invariant | ||
- [e028768](../../commit/e028768) [added] <DefaultRoute> component | ||
- [e028768](../../commit/e028768) [added] `<DefaultRoute>` component | ||
- [6878120](../../commit/6878120) [added] onAbortedTransition, onActiveStateChange, onTransitionError Routes props | ||
@@ -13,3 +29,3 @@ - [58073ca](../../commit/58073ca) [changed] Transition#cancelReason => abortReason | ||
- [ca96f86](../../commit/ca96f86) [fixed] typo in Link | ||
- [f3dc513](../../commit/f3dc513) [added] onClick handler to <Link /> | ||
- [f3dc513](../../commit/f3dc513) [added] onClick handler to `<Link />` | ||
- [b9f92f9](../../commit/b9f92f9) [changed] updated rf-changelog | ||
@@ -16,0 +32,0 @@ |
@@ -1,2 +0,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<r.length;o++)s(r[o]);return s}({1:[function(_dereq_,module){module.exports=_dereq_("./modules/mixins/ActiveState")},{"./modules/mixins/ActiveState":33}],2:[function(_dereq_,module){module.exports=_dereq_("./modules/mixins/AsyncState")},{"./modules/mixins/AsyncState":34}],3:[function(_dereq_,module){module.exports=_dereq_("./modules/components/DefaultRoute")},{"./modules/components/DefaultRoute":11}],4:[function(_dereq_,module){module.exports=_dereq_("./modules/components/Link")},{"./modules/components/Link":12}],5:[function(_dereq_,module){module.exports=_dereq_("./modules/components/Redirect")},{"./modules/components/Redirect":13}],6:[function(_dereq_,module){module.exports=_dereq_("./modules/components/Route")},{"./modules/components/Route":14}],7:[function(_dereq_,module){module.exports=_dereq_("./modules/components/Routes")},{"./modules/components/Routes":15}],8:[function(_dereq_,module){module.exports=_dereq_("./modules/helpers/goBack")},{"./modules/helpers/goBack":21}],9:[function(_dereq_,module,exports){exports.ActiveState=_dereq_("./ActiveState"),exports.AsyncState=_dereq_("./AsyncState"),exports.DefaultRoute=_dereq_("./DefaultRoute"),exports.Link=_dereq_("./Link"),exports.Redirect=_dereq_("./Redirect"),exports.Route=_dereq_("./Route"),exports.Routes=_dereq_("./Routes"),exports.goBack=_dereq_("./goBack"),exports.replaceWith=_dereq_("./replaceWith"),exports.transitionTo=_dereq_("./transitionTo"),exports.makeHref=_dereq_("./makeHref")},{"./ActiveState":1,"./AsyncState":2,"./DefaultRoute":3,"./Link":4,"./Redirect":5,"./Route":6,"./Routes":7,"./goBack":8,"./makeHref":10,"./replaceWith":62,"./transitionTo":63}],10:[function(_dereq_,module){module.exports=_dereq_("./modules/helpers/makeHref")},{"./modules/helpers/makeHref":23}],11:[function(_dereq_,module){function DefaultRoute(props){return Route(merge(props,{name:null,path:null}))}var merge=_dereq_("react/lib/merge"),Route=_dereq_("./Route");module.exports=DefaultRoute},{"./Route":14,"react/lib/merge":57}],12:[function(_dereq_,module){function isLeftClickEvent(event){return 0===event.button}function isModifiedEvent(event){return!!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,ActiveState=_dereq_("../mixins/ActiveState"),withoutProperties=_dereq_("../helpers/withoutProperties"),transitionTo=_dereq_("../helpers/transitionTo"),hasOwnProperty=_dereq_("../helpers/hasOwnProperty"),makeHref=_dereq_("../helpers/makeHref"),RESERVED_PROPS={to:!0,key:!0,className:!0,activeClassName:!0,query:!0,children:!0},Link=React.createClass({displayName:"Link",mixins:[ActiveState],statics:{getUnreservedProps:function(props){return withoutProperties(props,RESERVED_PROPS)}},propTypes:{to:React.PropTypes.string.isRequired,activeClassName:React.PropTypes.string.isRequired,query:React.PropTypes.object,onClick:React.PropTypes.func},getDefaultProps:function(){return{activeClassName:"active"}},getInitialState:function(){return{isActive:!1}},getParams:function(){return Link.getUnreservedProps(this.props)},getHref:function(){return makeHref(this.props.to,this.getParams(),this.props.query)},getClassName:function(){var className=this.props.className||"";return this.state.isActive?className+" "+this.props.activeClassName:className},componentWillReceiveProps:function(nextProps){var params=Link.getUnreservedProps(nextProps);this.setState({isActive:Link.isActive(nextProps.to,params,nextProps.query)})},updateActiveState:function(){this.setState({isActive:Link.isActive(this.props.to,this.getParams(),this.props.query)})},handleClick:function(event){var ret,allowTransition=!0;this.props.onClick&&(ret=this.props.onClick(event)),!isModifiedEvent(event)&&isLeftClickEvent(event)&&((ret===!1||event.defaultPrevented===!0)&&(allowTransition=!1),event.preventDefault(),allowTransition&&transitionTo(this.props.to,this.getParams(),this.props.query))},render:function(){var props={href:this.getHref(),className:this.getClassName(),onClick:this.handleClick};for(var propName in this.props)hasOwnProperty(this.props,propName)&&hasOwnProperty(props,propName)===!1&&(props[propName]=this.props[propName]);return React.DOM.a(props,this.props.children)}});module.exports=Link},{"../helpers/hasOwnProperty":22,"../helpers/makeHref":23,"../helpers/transitionTo":28,"../helpers/withoutProperties":29,"../mixins/ActiveState":33}],13:[function(_dereq_,module){function createRedirectHandler(to){return React.createClass({statics:{willTransitionTo:function(transition,params,query){transition.redirect(to,params,query)}},render:function(){return null}})}function Redirect(props){return Route({name:props.name,path:props.from||props.path,handler:createRedirectHandler(props.to)})}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,Route=_dereq_("./Route");module.exports=Redirect},{"./Route":14}],14:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,withoutProperties=_dereq_("../helpers/withoutProperties"),RESERVED_PROPS={handler:!0,path:!0,defaultRoute:!0,paramNames:!0,children:!0},Route=React.createClass({displayName:"Route",statics:{getUnreservedProps:function(props){return withoutProperties(props,RESERVED_PROPS)}},propTypes:{preserveScrollPosition:React.PropTypes.bool.isRequired,handler:React.PropTypes.any.isRequired,path:React.PropTypes.string,name:React.PropTypes.string},getDefaultProps:function(){return{preserveScrollPosition:!1}},render:function(){throw new Error("The <Route> component should not be rendered directly. You may be missing a <Routes> 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 <Route path="'+transition.path+'"> 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 <Route name="'+to+'"> 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"<HashLocation>"}};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"<HistoryLocation>"}};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"<RefreshLocation>"}};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 <DefaultRoute> per <Route>"),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;i<xs.length;i++)res.push(f(xs[i],i));return res}var stringifyPrimitive=function(v){switch(typeof v){case"string":return v;case"boolean":return v?"true":"false";case"number":return isFinite(v)?v:"";default:return""}};module.exports=function(obj,sep,eq,name){return sep=sep||"&",eq=eq||"=",null===obj&&(obj=void 0),"object"==typeof obj?map(objectKeys(obj),function(k){var ks=encodeURIComponent(stringifyPrimitive(k))+eq;return isArray(obj[k])?map(obj[k],function(v){return ks+encodeURIComponent(stringifyPrimitive(v))}).join(sep):ks+encodeURIComponent(stringifyPrimitive(obj[k]))}).join(sep):name?encodeURIComponent(stringifyPrimitive(name))+eq+encodeURIComponent(stringifyPrimitive(obj)):""};var isArray=Array.isArray||function(xs){return"[object Array]"===Object.prototype.toString.call(xs)},objectKeys=Object.keys||function(obj){var res=[];for(var key in obj)Object.prototype.hasOwnProperty.call(obj,key)&&res.push(key);return res}},{}],41:[function(_dereq_,module,exports){"use strict";exports.decode=exports.parse=_dereq_("./decode"),exports.encode=exports.stringify=_dereq_("./encode")},{"./decode":39,"./encode":40}],42:[function(_dereq_,module,exports){"use strict";var Promise=_dereq_("./promise/promise").Promise,polyfill=_dereq_("./promise/polyfill").polyfill;exports.Promise=Promise,exports.polyfill=polyfill},{"./promise/polyfill":46,"./promise/promise":47}],43:[function(_dereq_,module,exports){"use strict";function all(promises){var Promise=this;if(!isArray(promises))throw new TypeError("You must pass an array to all.");return new Promise(function(resolve,reject){function resolver(index){return function(value){resolveAll(index,value)}}function resolveAll(index,value){results[index]=value,0===--remaining&&resolve(results)}var promise,results=[],remaining=promises.length;0===remaining&&resolve([]);for(var i=0;i<promises.length;i++)promise=promises[i],promise&&isFunction(promise.then)?promise.then(resolver(i),reject):resolveAll(i,promise)})}var isArray=_dereq_("./utils").isArray,isFunction=_dereq_("./utils").isFunction;exports.all=all},{"./utils":51}],44:[function(_dereq_,module,exports){"use strict";function useNextTick(){return function(){process.nextTick(flush)}}function useMutationObserver(){var iterations=0,observer=new BrowserMutationObserver(flush),node=document.createTextNode("");return observer.observe(node,{characterData:!0}),function(){node.data=iterations=++iterations%2}}function useSetTimeout(){return function(){local.setTimeout(flush,1)}}function flush(){for(var i=0;i<queue.length;i++){var tuple=queue[i],callback=tuple[0],arg=tuple[1];callback(arg)}queue=[]}function asap(callback,arg){var length=queue.push([callback,arg]);1===length&&scheduleFlush()}var scheduleFlush,browserGlobal="undefined"!=typeof window?window:{},BrowserMutationObserver=browserGlobal.MutationObserver||browserGlobal.WebKitMutationObserver,local="undefined"!=typeof global?global:void 0===this?window:this,queue=[];scheduleFlush="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?useNextTick():BrowserMutationObserver?useMutationObserver():useSetTimeout(),exports.asap=asap},{}],45:[function(_dereq_,module,exports){"use strict";function configure(name,value){return 2!==arguments.length?config[name]:void(config[name]=value)}var config={instrument:!1};exports.config=config,exports.configure=configure},{}],46:[function(_dereq_,module,exports){"use strict";function polyfill(){var local;local="undefined"!=typeof global?global:"undefined"!=typeof window&&window.document?window:self;var es6PromiseSupport="Promise"in local&&"resolve"in local.Promise&&"reject"in local.Promise&&"all"in local.Promise&&"race"in local.Promise&&function(){var resolve;return new local.Promise(function(r){resolve=r}),isFunction(resolve)}();es6PromiseSupport||(local.Promise=RSVPPromise)}var RSVPPromise=_dereq_("./promise").Promise,isFunction=_dereq_("./utils").isFunction;exports.polyfill=polyfill},{"./promise":47,"./utils":51}],47:[function(_dereq_,module,exports){"use strict";function Promise(resolver){if(!isFunction(resolver))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof Promise))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],invokeResolver(resolver,this)}function invokeResolver(resolver,promise){function resolvePromise(value){resolve(promise,value)}function rejectPromise(reason){reject(promise,reason)}try{resolver(resolvePromise,rejectPromise)}catch(e){rejectPromise(e)}}function invokeCallback(settled,promise,callback,detail){var value,error,succeeded,failed,hasCallback=isFunction(callback);if(hasCallback)try{value=callback(detail),succeeded=!0}catch(e){failed=!0,error=e}else value=detail,succeeded=!0;handleThenable(promise,value)||(hasCallback&&succeeded?resolve(promise,value):failed?reject(promise,error):settled===FULFILLED?resolve(promise,value):settled===REJECTED&&reject(promise,value))}function subscribe(parent,child,onFulfillment,onRejection){var subscribers=parent._subscribers,length=subscribers.length;subscribers[length]=child,subscribers[length+FULFILLED]=onFulfillment,subscribers[length+REJECTED]=onRejection}function publish(promise,settled){for(var child,callback,subscribers=promise._subscribers,detail=promise._detail,i=0;i<subscribers.length;i+=3)child=subscribers[i],callback=subscribers[i+settled],invokeCallback(settled,child,callback,detail);promise._subscribers=null}function handleThenable(promise,value){var resolved,then=null;try{if(promise===value)throw new TypeError("A promises callback cannot return that same promise.");if(objectOrFunction(value)&&(then=value.then,isFunction(then)))return then.call(value,function(val){return resolved?!0:(resolved=!0,void(value!==val?resolve(promise,val):fulfill(promise,val)))},function(val){return resolved?!0:(resolved=!0,void reject(promise,val))}),!0}catch(error){return resolved?!0:(reject(promise,error),!0)}return!1}function resolve(promise,value){promise===value?fulfill(promise,value):handleThenable(promise,value)||fulfill(promise,value)}function fulfill(promise,value){promise._state===PENDING&&(promise._state=SEALED,promise._detail=value,config.async(publishFulfillment,promise))}function reject(promise,reason){promise._state===PENDING&&(promise._state=SEALED,promise._detail=reason,config.async(publishRejection,promise))}function publishFulfillment(promise){publish(promise,promise._state=FULFILLED)}function publishRejection(promise){publish(promise,promise._state=REJECTED)}var config=_dereq_("./config").config,objectOrFunction=(_dereq_("./config").configure,_dereq_("./utils").objectOrFunction),isFunction=_dereq_("./utils").isFunction,all=(_dereq_("./utils").now,_dereq_("./all").all),race=_dereq_("./race").race,staticResolve=_dereq_("./resolve").resolve,staticReject=_dereq_("./reject").reject,asap=_dereq_("./asap").asap;config.async=asap;var PENDING=void 0,SEALED=0,FULFILLED=1,REJECTED=2;Promise.prototype={constructor:Promise,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(onFulfillment,onRejection){var promise=this,thenPromise=new this.constructor(function(){});if(this._state){var callbacks=arguments;config.async(function(){invokeCallback(promise._state,thenPromise,callbacks[promise._state-1],promise._detail)})}else subscribe(this,thenPromise,onFulfillment,onRejection);return thenPromise},"catch":function(onRejection){return this.then(null,onRejection)}},Promise.all=all,Promise.race=race,Promise.resolve=staticResolve,Promise.reject=staticReject,exports.Promise=Promise},{"./all":43,"./asap":44,"./config":45,"./race":48,"./reject":49,"./resolve":50,"./utils":51}],48:[function(_dereq_,module,exports){"use strict";function race(promises){var Promise=this;if(!isArray(promises))throw new TypeError("You must pass an array to race.");return new Promise(function(resolve,reject){for(var promise,i=0;i<promises.length;i++)promise=promises[i],promise&&"function"==typeof promise.then?promise.then(resolve,reject):resolve(promise)})}var isArray=_dereq_("./utils").isArray;exports.race=race},{"./utils":51}],49:[function(_dereq_,module,exports){"use strict";function reject(reason){var Promise=this;return new Promise(function(resolve,reject){reject(reason)})}exports.reject=reject},{}],50:[function(_dereq_,module,exports){"use strict";function resolve(value){if(value&&"object"==typeof value&&value.constructor===this)return value;var Promise=this;return new Promise(function(resolve){resolve(value)})}exports.resolve=resolve},{}],51:[function(_dereq_,module,exports){"use strict";function objectOrFunction(x){return isFunction(x)||"object"==typeof x&&null!==x}function isFunction(x){return"function"==typeof x}function isArray(x){return"[object Array]"===Object.prototype.toString.call(x)}var now=Date.now||function(){return(new Date).getTime()};exports.objectOrFunction=objectOrFunction,exports.isFunction=isFunction,exports.isArray=isArray,exports.now=now},{}],52:[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},{}],53:[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},{}],54:[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":53}],55:[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},{}],56:[function(_dereq_,module){"use strict";var invariant=_dereq_("./invariant"),keyMirror=function(obj){var key,ret={};invariant(obj instanceof Object&&!Array.isArray(obj));for(key in obj)obj.hasOwnProperty(key)&&(ret[key]=key);return ret};module.exports=keyMirror},{"./invariant":55}],57:[function(_dereq_,module){"use strict";var mergeInto=_dereq_("./mergeInto"),merge=function(one,two){var result={};return mergeInto(result,one),mergeInto(result,two),result};module.exports=merge},{"./mergeInto":59}],58:[function(_dereq_,module){"use strict";var invariant=_dereq_("./invariant"),keyMirror=_dereq_("./keyMirror"),MAX_MERGE_DEPTH=36,isTerminal=function(o){return"object"!=typeof o||null===o},mergeHelpers={MAX_MERGE_DEPTH:MAX_MERGE_DEPTH,isTerminal:isTerminal,normalizeMergeArg:function(arg){return void 0===arg||null===arg?{}:arg},checkMergeArrayArgs:function(one,two){invariant(Array.isArray(one)&&Array.isArray(two))},checkMergeObjectArgs:function(one,two){mergeHelpers.checkMergeObjectArg(one),mergeHelpers.checkMergeObjectArg(two)},checkMergeObjectArg:function(arg){invariant(!isTerminal(arg)&&!Array.isArray(arg))},checkMergeIntoObjectArg:function(arg){invariant(!(isTerminal(arg)&&"function"!=typeof arg||Array.isArray(arg)))},checkMergeLevel:function(level){invariant(MAX_MERGE_DEPTH>level)},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)}); | ||
!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<r.length;o++)s(r[o]);return s}({1:[function(_dereq_,module){module.exports=_dereq_("./modules/mixins/ActiveState")},{"./modules/mixins/ActiveState":33}],2:[function(_dereq_,module){module.exports=_dereq_("./modules/mixins/AsyncState")},{"./modules/mixins/AsyncState":34}],3:[function(_dereq_,module){module.exports=_dereq_("./modules/components/DefaultRoute")},{"./modules/components/DefaultRoute":13}],4:[function(_dereq_,module){module.exports=_dereq_("./modules/components/Link")},{"./modules/components/Link":14}],5:[function(_dereq_,module){module.exports=_dereq_("./modules/components/NotFoundRoute")},{"./modules/components/NotFoundRoute":15}],6:[function(_dereq_,module){module.exports=_dereq_("./modules/components/Redirect")},{"./modules/components/Redirect":16}],7:[function(_dereq_,module){module.exports=_dereq_("./modules/components/Route")},{"./modules/components/Route":17}],8:[function(_dereq_,module){module.exports=_dereq_("./modules/components/Routes")},{"./modules/components/Routes":18}],9:[function(_dereq_,module){module.exports=_dereq_("./modules/actions/LocationActions").goBack},{"./modules/actions/LocationActions":12}],10:[function(_dereq_,module,exports){exports.ActiveState=_dereq_("./ActiveState"),exports.AsyncState=_dereq_("./AsyncState"),exports.DefaultRoute=_dereq_("./DefaultRoute"),exports.Link=_dereq_("./Link"),exports.NotFoundRoute=_dereq_("./NotFoundRoute"),exports.Redirect=_dereq_("./Redirect"),exports.Route=_dereq_("./Route"),exports.Routes=_dereq_("./Routes"),exports.goBack=_dereq_("./goBack"),exports.makeHref=_dereq_("./makeHref"),exports.replaceWith=_dereq_("./replaceWith"),exports.transitionTo=_dereq_("./transitionTo")},{"./ActiveState":1,"./AsyncState":2,"./DefaultRoute":3,"./Link":4,"./NotFoundRoute":5,"./Redirect":6,"./Route":7,"./Routes":8,"./goBack":9,"./makeHref":11,"./replaceWith":67,"./transitionTo":68}],11:[function(_dereq_,module){module.exports=_dereq_("./modules/helpers/makeHref")},{"./modules/helpers/makeHref":25}],12:[function(_dereq_,module){var LocationDispatcher=_dereq_("../dispatchers/LocationDispatcher"),makePath=_dereq_("../helpers/makePath"),LocationActions={PUSH:"push",REPLACE:"replace",POP:"pop",UPDATE_SCROLL:"update-scroll",transitionTo:function(to,params,query){LocationDispatcher.handleViewAction({type:LocationActions.PUSH,path:makePath(to,params,query)})},replaceWith:function(to,params,query){LocationDispatcher.handleViewAction({type:LocationActions.REPLACE,path:makePath(to,params,query)})},goBack:function(){LocationDispatcher.handleViewAction({type:LocationActions.POP})},updateScroll:function(){LocationDispatcher.handleViewAction({type:LocationActions.UPDATE_SCROLL})}};module.exports=LocationActions},{"../dispatchers/LocationDispatcher":19,"../helpers/makePath":26}],13:[function(_dereq_,module){function DefaultRoute(props){return Route(merge(props,{path:null,isDefault:!0}))}var merge=_dereq_("react/lib/merge"),Route=_dereq_("./Route");module.exports=DefaultRoute},{"./Route":17,"react/lib/merge":62}],14:[function(_dereq_,module){function isLeftClickEvent(event){return 0===event.button}function isModifiedEvent(event){return!!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,ActiveState=_dereq_("../mixins/ActiveState"),transitionTo=_dereq_("../actions/LocationActions").transitionTo,withoutProperties=_dereq_("../helpers/withoutProperties"),hasOwnProperty=_dereq_("../helpers/hasOwnProperty"),makeHref=_dereq_("../helpers/makeHref"),warning=_dereq_("react/lib/warning"),RESERVED_PROPS={to:!0,key:!0,className:!0,activeClassName:!0,query:!0,onClick:!0,children:!0},Link=React.createClass({displayName:"Link",mixins:[ActiveState],statics:{getUnreservedProps:function(props){return warning(!1,"Passing props for params on <Link>s is deprecated, please use the `params` property."),withoutProperties(props,RESERVED_PROPS)},getParams:function(props){return props.params||Link.getUnreservedProps(props)}},propTypes:{to:React.PropTypes.string.isRequired,activeClassName:React.PropTypes.string.isRequired,params:React.PropTypes.object,query:React.PropTypes.object,onClick:React.PropTypes.func},getDefaultProps:function(){return{activeClassName:"active"}},getInitialState:function(){return{isActive:!1}},getHref:function(){return makeHref(this.props.to,Link.getParams(this.props),this.props.query)},getClassName:function(){var className=this.props.className||"";return this.state.isActive?className+" "+this.props.activeClassName:className},componentWillReceiveProps:function(nextProps){var params=Link.getParams(nextProps);this.setState({isActive:Link.isActive(nextProps.to,params,nextProps.query)})},updateActiveState:function(){this.setState({isActive:Link.isActive(this.props.to,Link.getParams(this.props),this.props.query)})},handleClick:function(event){var ret,allowTransition=!0;this.props.onClick&&(ret=this.props.onClick(event)),!isModifiedEvent(event)&&isLeftClickEvent(event)&&((ret===!1||event.defaultPrevented===!0)&&(allowTransition=!1),event.preventDefault(),allowTransition&&transitionTo(this.props.to,Link.getParams(this.props),this.props.query))},render:function(){var props={href:this.getHref(),className:this.getClassName(),onClick:this.handleClick};for(var propName in this.props)hasOwnProperty(this.props,propName)&&hasOwnProperty(props,propName)===!1&&(props[propName]=this.props[propName]);return React.DOM.a(props,this.props.children)}});module.exports=Link},{"../actions/LocationActions":12,"../helpers/hasOwnProperty":24,"../helpers/makeHref":25,"../helpers/withoutProperties":29,"../mixins/ActiveState":33,"react/lib/warning":66}],15:[function(_dereq_,module){function NotFoundRoute(props){return Route(merge(props,{path:null,catchAll:!0}))}var merge=_dereq_("react/lib/merge"),Route=_dereq_("./Route");module.exports=NotFoundRoute},{"./Route":17,"react/lib/merge":62}],16:[function(_dereq_,module){function createRedirectHandler(to){return React.createClass({statics:{willTransitionTo:function(transition,params,query){transition.redirect(to,params,query)}},render:function(){return null}})}function Redirect(props){return Route({name:props.name,path:props.from||props.path||"*",handler:createRedirectHandler(props.to)})}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,Route=_dereq_("./Route");module.exports=Redirect},{"./Route":17}],17:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,withoutProperties=_dereq_("../helpers/withoutProperties"),RESERVED_PROPS={handler:!0,path:!0,defaultRoute:!0,paramNames:!0,children:!0},Route=React.createClass({displayName:"Route",statics:{getUnreservedProps:function(props){return withoutProperties(props,RESERVED_PROPS)}},propTypes:{preserveScrollPosition:React.PropTypes.bool.isRequired,handler:React.PropTypes.any.isRequired,path:React.PropTypes.string,name:React.PropTypes.string},getDefaultProps:function(){return{preserveScrollPosition:!1}},render:function(){throw new Error("The <Route> component should not be rendered directly. You may be missing a <Routes> wrapper around your list of routes.")}});module.exports=Route},{"../helpers/withoutProperties":29}],18:[function(_dereq_,module){function defaultAbortedTransitionHandler(transition){var reason=transition.abortReason;reason instanceof Redirect?LocationActions.replaceWith(reason.to,reason.params,reason.query):LocationActions.goBack()}function defaultActiveStateChangeHandler(state){ActiveStore.updateState(state)}function defaultTransitionErrorHandler(error){throw error}function maybeUpdateScroll(routes,rootRoute){routes.props.preserveScrollPosition||rootRoute.props.preserveScrollPosition||LocationActions.updateScroll()}function findMatches(path,routes,defaultRoute,notFoundRoute){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,route.props.notFoundRoute),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 defaultRoute&&(params=Path.extractParams(defaultRoute.props.path,path))?[makeMatch(defaultRoute,params)]:notFoundRoute&&(params=Path.extractParams(notFoundRoute.props.path,path))?[makeMatch(notFoundRoute,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 <Route path="'+transition.path+'"> somewhere in your routes'),nextMatches||(nextMatches=[]);var fromMatches,toMatches;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);var query=Path.extractQuery(transition.path)||{};return runTransitionFromHooks(fromMatches,transition).then(function(){return transition.isAborted?void 0:runTransitionToHooks(toMatches,transition,query).then(function(){if(!transition.isAborted){var rootMatch=getRootMatch(nextMatches),params=rootMatch&&rootMatch.params||{};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,query){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,query):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.params=match.params,props.query=query,route.props.addHandlerKey&&(props.key=Path.injectParams(route.props.path,match.params)),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()}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,LocationActions=_dereq_("../actions/LocationActions"),Route=_dereq_("../components/Route"),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},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,this.props.notFoundRoute)},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&&maybeUpdateScroll(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},{"../actions/LocationActions":12,"../components/Route":17,"../helpers/Path":20,"../helpers/Redirect":21,"../helpers/Transition":22,"../locations/HashLocation":30,"../locations/HistoryLocation":31,"../locations/RefreshLocation":32,"../stores/ActiveStore":35,"../stores/PathStore":36,"../stores/RouteStore":37,"es6-promise":38,"react/lib/copyProperties":58,"react/lib/warning":66}],19:[function(_dereq_,module){var copyProperties=_dereq_("react/lib/copyProperties"),Dispatcher=_dereq_("flux").Dispatcher,LocationDispatcher=copyProperties(new Dispatcher,{handleViewAction:function(action){this.dispatch({source:"VIEW_ACTION",action:action})}});module.exports=LocationDispatcher},{flux:49,"react/lib/copyProperties":58}],20:[function(_dereq_,module){function encodeURL(url){return encodeURIComponent(url).replace(/%20/g,"+")}function decodeURL(url){return decodeURIComponent(url.replace(/\+/g," "))}function encodeURLPath(path){return String(path).split("/").map(encodeURL).join("/")}function compilePattern(pattern){if(!(pattern in _compiledPatterns)){var paramNames=[],source=pattern.replace(paramMatcher,function(match,paramName){return paramName?(paramNames.push(paramName),"([^./?#]+)"):"*"===match?(paramNames.push("splat"),"(.*?)"):"\\"+match});_compiledPatterns[pattern]={matcher:new RegExp("^"+source+"$","i"),paramNames:paramNames}}return _compiledPatterns[pattern]}var invariant=_dereq_("react/lib/invariant"),merge=_dereq_("qs/lib/utils").merge,qs=_dereq_("qs"),paramMatcher=/:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g,queryMatcher=/\?(.+)/,_compiledPatterns={},Path={extractParamNames:function(pattern){return compilePattern(pattern).paramNames},extractParams:function(pattern,path){var object=compilePattern(pattern),match=decodeURL(path).match(object.matcher);if(!match)return null;var params={};return object.paramNames.forEach(function(paramName,index){params[paramName]=match[index+1]}),params},injectParams:function(pattern,params){params=params||{};var splatIndex=0;return pattern.replace(paramMatcher,function(match,paramName){paramName=paramName||"splat",invariant(null!=params[paramName],'Missing "'+paramName+'" parameter for path "'+pattern+'"');var segment;return"splat"===paramName&&Array.isArray(params[paramName])?(segment=params[paramName][splatIndex++],invariant(null!=segment,"Missing splat # "+splatIndex+' for path "'+pattern+'"')):segment=params[paramName],encodeURLPath(segment)})},extractQuery:function(path){var match=decodeURL(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?merge(existingQuery,query):existingQuery);var queryString=query&&qs.stringify(query);return queryString?Path.withoutQuery(path)+"?"+queryString:path},isAbsolute:function(path){return"/"===path.charAt(0)},normalize:function(path){return path.replace(/^\/*/,"/")},join:function(a,b){return a.replace(/\/*$/,"/")+b}};module.exports=Path},{qs:52,"qs/lib/utils":56,"react/lib/invariant":60}],21:[function(_dereq_,module){function Redirect(to,params,query){this.to=to,this.params=params,this.query=query}module.exports=Redirect},{}],22:[function(_dereq_,module){function Transition(path){this.path=path,this.abortReason=null,this.isAborted=!1}var mixInto=_dereq_("react/lib/mixInto"),transitionTo=_dereq_("../actions/LocationActions").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},{"../actions/LocationActions":12,"./Redirect":21,"react/lib/mixInto":65}],23:[function(_dereq_,module){function getWindowPath(){return window.location.pathname+window.location.search}module.exports=getWindowPath},{}],24:[function(_dereq_,module){module.exports=Function.prototype.call.bind(Object.prototype.hasOwnProperty)},{}],25:[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":26}],26:[function(_dereq_,module){function makePath(to,params,query){var path;if(Path.isAbsolute(to))path=Path.normalize(to);else{var route=RouteStore.getRouteByName(to);invariant(route,'Unable to find a route named "'+to+'". Make sure you have a <Route name="'+to+'"> 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":20,"react/lib/invariant":60}],27:[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":38}],28:[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},{}],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){function getHashPath(){return window.location.hash.substr(1)}function ensureSlash(){var path=getHashPath();return"/"===path.charAt(0)?!0:(HashLocation.replace("/"+path),!1)}function handleHashChange(){ensureSlash()&&_onChange()}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,ensureSlash(),window.addEventListener?window.addEventListener("hashchange",handleHashChange,!1):window.attachEvent("onhashchange",handleHashChange)},teardown:function(){window.removeEventListener?window.removeEventListener("hashchange",handleHashChange,!1):window.detachEvent("onhashchange",handleHashChange)},push:function(path){window.location.hash=path},replace:function(path){window.location.replace(getWindowPath()+"#"+path)},pop:function(){window.history.back()},getCurrentPath:getHashPath,toString:function(){return"<HashLocation>"}};module.exports=HashLocation},{"../helpers/getWindowPath":23,"react/lib/ExecutionEnvironment":57,"react/lib/invariant":60}],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"<HistoryLocation>"}};module.exports=HistoryLocation},{"../helpers/getWindowPath":23,"react/lib/ExecutionEnvironment":57,"react/lib/invariant":60}],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"<RefreshLocation>"}};module.exports=RefreshLocation},{"../helpers/getWindowPath":23,"react/lib/ExecutionEnvironment":57,"react/lib/invariant":60}],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()&&"function"==typeof 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":27}],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:48}],36:[function(_dereq_,module){function notifyChange(){_events.emit(CHANGE_EVENT)}function recordScrollPosition(path){_scrollPositions[path]={x:window.scrollX,y:window.scrollY}}function updateScrollPosition(path){var p=PathStore.getScrollPosition(path);window.scrollTo(p.x,p.y)}var _location,warning=_dereq_("react/lib/warning"),EventEmitter=_dereq_("events").EventEmitter,LocationActions=_dereq_("../actions/LocationActions"),LocationDispatcher=_dereq_("../dispatchers/LocationDispatcher"),supportsHistory=_dereq_("../helpers/supportsHistory"),HistoryLocation=_dereq_("../locations/HistoryLocation"),RefreshLocation=_dereq_("../locations/RefreshLocation"),CHANGE_EVENT="change",_events=new EventEmitter,_scrollPositions={},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},getCurrentPath:function(){return _location.getCurrentPath()},getScrollPosition:function(path){return _scrollPositions[path]||{x:0,y:0}},dispatchToken:LocationDispatcher.register(function(payload){var action=payload.action,currentPath=_location.getCurrentPath();switch(action.type){case LocationActions.PUSH:currentPath!==action.path&&(recordScrollPosition(currentPath),_location.push(action.path));break;case LocationActions.REPLACE:currentPath!==action.path&&(recordScrollPosition(currentPath),_location.replace(action.path));break;case LocationActions.POP:recordScrollPosition(currentPath),_location.pop();break;case LocationActions.UPDATE_SCROLL:updateScrollPosition(currentPath)}})};module.exports=PathStore},{"../actions/LocationActions":12,"../dispatchers/LocationDispatcher":19,"../helpers/supportsHistory":28,"../locations/HistoryLocation":31,"../locations/RefreshLocation":32,events:48,"react/lib/warning":66}],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 parentPath=parentRoute&&parentRoute.props.path||"/";if(!props.path&&!props.name||props.isDefault||props.catchAll)props.path=parentPath,props.catchAll&&(props.path+="*");else{var path=props.path||props.name;Path.isAbsolute(path)||(path=Path.join(parentPath,path)),props.path=Path.normalize(path)}if(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 props.catchAll?(invariant(parentRoute,"<NotFoundRoute> must have a parent <Route>"),invariant(null==parentRoute.props.notFoundRoute,"You may not have more than one <NotFoundRoute> per <Route>"),parentRoute.props.notFoundRoute=route,null):props.isDefault?(invariant(parentRoute,"<DefaultRoute> must have a parent <Route>"),invariant(null==parentRoute.props.defaultRoute,"You may not have more than one <DefaultRoute> per <Route>"),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":20,"react/lib/invariant":60,"react/lib/warning":66}],38:[function(_dereq_,module,exports){"use strict";var Promise=_dereq_("./promise/promise").Promise,polyfill=_dereq_("./promise/polyfill").polyfill;exports.Promise=Promise,exports.polyfill=polyfill},{"./promise/polyfill":42,"./promise/promise":43}],39:[function(_dereq_,module,exports){"use strict";function all(promises){var Promise=this;if(!isArray(promises))throw new TypeError("You must pass an array to all.");return new Promise(function(resolve,reject){function resolver(index){return function(value){resolveAll(index,value) | ||
}}function resolveAll(index,value){results[index]=value,0===--remaining&&resolve(results)}var promise,results=[],remaining=promises.length;0===remaining&&resolve([]);for(var i=0;i<promises.length;i++)promise=promises[i],promise&&isFunction(promise.then)?promise.then(resolver(i),reject):resolveAll(i,promise)})}var isArray=_dereq_("./utils").isArray,isFunction=_dereq_("./utils").isFunction;exports.all=all},{"./utils":47}],40:[function(_dereq_,module,exports){"use strict";function useNextTick(){return function(){process.nextTick(flush)}}function useMutationObserver(){var iterations=0,observer=new BrowserMutationObserver(flush),node=document.createTextNode("");return observer.observe(node,{characterData:!0}),function(){node.data=iterations=++iterations%2}}function useSetTimeout(){return function(){local.setTimeout(flush,1)}}function flush(){for(var i=0;i<queue.length;i++){var tuple=queue[i],callback=tuple[0],arg=tuple[1];callback(arg)}queue=[]}function asap(callback,arg){var length=queue.push([callback,arg]);1===length&&scheduleFlush()}var scheduleFlush,browserGlobal="undefined"!=typeof window?window:{},BrowserMutationObserver=browserGlobal.MutationObserver||browserGlobal.WebKitMutationObserver,local="undefined"!=typeof global?global:void 0===this?window:this,queue=[];scheduleFlush="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?useNextTick():BrowserMutationObserver?useMutationObserver():useSetTimeout(),exports.asap=asap},{}],41:[function(_dereq_,module,exports){"use strict";function configure(name,value){return 2!==arguments.length?config[name]:void(config[name]=value)}var config={instrument:!1};exports.config=config,exports.configure=configure},{}],42:[function(_dereq_,module,exports){"use strict";function polyfill(){var local;local="undefined"!=typeof global?global:"undefined"!=typeof window&&window.document?window:self;var es6PromiseSupport="Promise"in local&&"resolve"in local.Promise&&"reject"in local.Promise&&"all"in local.Promise&&"race"in local.Promise&&function(){var resolve;return new local.Promise(function(r){resolve=r}),isFunction(resolve)}();es6PromiseSupport||(local.Promise=RSVPPromise)}var RSVPPromise=_dereq_("./promise").Promise,isFunction=_dereq_("./utils").isFunction;exports.polyfill=polyfill},{"./promise":43,"./utils":47}],43:[function(_dereq_,module,exports){"use strict";function Promise(resolver){if(!isFunction(resolver))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof Promise))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],invokeResolver(resolver,this)}function invokeResolver(resolver,promise){function resolvePromise(value){resolve(promise,value)}function rejectPromise(reason){reject(promise,reason)}try{resolver(resolvePromise,rejectPromise)}catch(e){rejectPromise(e)}}function invokeCallback(settled,promise,callback,detail){var value,error,succeeded,failed,hasCallback=isFunction(callback);if(hasCallback)try{value=callback(detail),succeeded=!0}catch(e){failed=!0,error=e}else value=detail,succeeded=!0;handleThenable(promise,value)||(hasCallback&&succeeded?resolve(promise,value):failed?reject(promise,error):settled===FULFILLED?resolve(promise,value):settled===REJECTED&&reject(promise,value))}function subscribe(parent,child,onFulfillment,onRejection){var subscribers=parent._subscribers,length=subscribers.length;subscribers[length]=child,subscribers[length+FULFILLED]=onFulfillment,subscribers[length+REJECTED]=onRejection}function publish(promise,settled){for(var child,callback,subscribers=promise._subscribers,detail=promise._detail,i=0;i<subscribers.length;i+=3)child=subscribers[i],callback=subscribers[i+settled],invokeCallback(settled,child,callback,detail);promise._subscribers=null}function handleThenable(promise,value){var resolved,then=null;try{if(promise===value)throw new TypeError("A promises callback cannot return that same promise.");if(objectOrFunction(value)&&(then=value.then,isFunction(then)))return then.call(value,function(val){return resolved?!0:(resolved=!0,void(value!==val?resolve(promise,val):fulfill(promise,val)))},function(val){return resolved?!0:(resolved=!0,void reject(promise,val))}),!0}catch(error){return resolved?!0:(reject(promise,error),!0)}return!1}function resolve(promise,value){promise===value?fulfill(promise,value):handleThenable(promise,value)||fulfill(promise,value)}function fulfill(promise,value){promise._state===PENDING&&(promise._state=SEALED,promise._detail=value,config.async(publishFulfillment,promise))}function reject(promise,reason){promise._state===PENDING&&(promise._state=SEALED,promise._detail=reason,config.async(publishRejection,promise))}function publishFulfillment(promise){publish(promise,promise._state=FULFILLED)}function publishRejection(promise){publish(promise,promise._state=REJECTED)}var config=_dereq_("./config").config,objectOrFunction=(_dereq_("./config").configure,_dereq_("./utils").objectOrFunction),isFunction=_dereq_("./utils").isFunction,all=(_dereq_("./utils").now,_dereq_("./all").all),race=_dereq_("./race").race,staticResolve=_dereq_("./resolve").resolve,staticReject=_dereq_("./reject").reject,asap=_dereq_("./asap").asap;config.async=asap;var PENDING=void 0,SEALED=0,FULFILLED=1,REJECTED=2;Promise.prototype={constructor:Promise,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(onFulfillment,onRejection){var promise=this,thenPromise=new this.constructor(function(){});if(this._state){var callbacks=arguments;config.async(function(){invokeCallback(promise._state,thenPromise,callbacks[promise._state-1],promise._detail)})}else subscribe(this,thenPromise,onFulfillment,onRejection);return thenPromise},"catch":function(onRejection){return this.then(null,onRejection)}},Promise.all=all,Promise.race=race,Promise.resolve=staticResolve,Promise.reject=staticReject,exports.Promise=Promise},{"./all":39,"./asap":40,"./config":41,"./race":44,"./reject":45,"./resolve":46,"./utils":47}],44:[function(_dereq_,module,exports){"use strict";function race(promises){var Promise=this;if(!isArray(promises))throw new TypeError("You must pass an array to race.");return new Promise(function(resolve,reject){for(var promise,i=0;i<promises.length;i++)promise=promises[i],promise&&"function"==typeof promise.then?promise.then(resolve,reject):resolve(promise)})}var isArray=_dereq_("./utils").isArray;exports.race=race},{"./utils":47}],45:[function(_dereq_,module,exports){"use strict";function reject(reason){var Promise=this;return new Promise(function(resolve,reject){reject(reason)})}exports.reject=reject},{}],46:[function(_dereq_,module,exports){"use strict";function resolve(value){if(value&&"object"==typeof value&&value.constructor===this)return value;var Promise=this;return new Promise(function(resolve){resolve(value)})}exports.resolve=resolve},{}],47:[function(_dereq_,module,exports){"use strict";function objectOrFunction(x){return isFunction(x)||"object"==typeof x&&null!==x}function isFunction(x){return"function"==typeof x}function isArray(x){return"[object Array]"===Object.prototype.toString.call(x)}var now=Date.now||function(){return(new Date).getTime()};exports.objectOrFunction=objectOrFunction,exports.isFunction=isFunction,exports.isArray=isArray,exports.now=now},{}],48:[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}},{}],49:[function(_dereq_,module){module.exports.Dispatcher=_dereq_("./lib/Dispatcher")},{"./lib/Dispatcher":50}],50:[function(_dereq_,module){function Dispatcher(){"use strict";this.$Dispatcher_callbacks={},this.$Dispatcher_isPending={},this.$Dispatcher_isHandled={},this.$Dispatcher_isDispatching=!1,this.$Dispatcher_pendingPayload=null}var invariant=_dereq_("./invariant"),_lastID=1,_prefix="ID_";Dispatcher.prototype.register=function(callback){"use strict";var id=_prefix+_lastID++;return this.$Dispatcher_callbacks[id]=callback,id},Dispatcher.prototype.unregister=function(id){"use strict";invariant(this.$Dispatcher_callbacks[id],"Dispatcher.unregister(...): `%s` does not map to a registered callback.",id),delete this.$Dispatcher_callbacks[id]},Dispatcher.prototype.waitFor=function(ids){"use strict";invariant(this.$Dispatcher_isDispatching,"Dispatcher.waitFor(...): Must be invoked while dispatching.");for(var ii=0;ii<ids.length;ii++){var id=ids[ii];this.$Dispatcher_isPending[id]?invariant(this.$Dispatcher_isHandled[id],"Dispatcher.waitFor(...): Circular dependency detected while waiting for `%s`.",id):(invariant(this.$Dispatcher_callbacks[id],"Dispatcher.waitFor(...): `%s` does not map to a registered callback.",id),this.$Dispatcher_invokeCallback(id))}},Dispatcher.prototype.dispatch=function(payload){"use strict";invariant(!this.$Dispatcher_isDispatching,"Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch."),this.$Dispatcher_startDispatching(payload);try{for(var id in this.$Dispatcher_callbacks)this.$Dispatcher_isPending[id]||this.$Dispatcher_invokeCallback(id)}finally{this.$Dispatcher_stopDispatching()}},Dispatcher.prototype.isDispatching=function(){"use strict";return this.$Dispatcher_isDispatching},Dispatcher.prototype.$Dispatcher_invokeCallback=function(id){"use strict";this.$Dispatcher_isPending[id]=!0,this.$Dispatcher_callbacks[id](this.$Dispatcher_pendingPayload),this.$Dispatcher_isHandled[id]=!0},Dispatcher.prototype.$Dispatcher_startDispatching=function(payload){"use strict";for(var id in this.$Dispatcher_callbacks)this.$Dispatcher_isPending[id]=!1,this.$Dispatcher_isHandled[id]=!1;this.$Dispatcher_pendingPayload=payload,this.$Dispatcher_isDispatching=!0},Dispatcher.prototype.$Dispatcher_stopDispatching=function(){"use strict";this.$Dispatcher_pendingPayload=null,this.$Dispatcher_isDispatching=!1},module.exports=Dispatcher},{"./invariant":51}],51:[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},{}],52:[function(_dereq_,module){module.exports=_dereq_("./lib")},{"./lib":53}],53:[function(_dereq_,module){var Stringify=_dereq_("./stringify"),Parse=_dereq_("./parse");module.exports={stringify:Stringify,parse:Parse}},{"./parse":54,"./stringify":55}],54:[function(_dereq_,module){var Utils=_dereq_("./utils"),internals={delimiter:"&",depth:5,arrayLimit:20,parametersLimit:1e3};internals.parseValues=function(str,delimiter){delimiter="string"==typeof delimiter?delimiter:internals.delimiter;for(var obj={},parts=str.split(delimiter,internals.parametersLimit),i=0,il=parts.length;il>i;++i){var part=parts[i],pos=-1===part.indexOf("]=")?part.indexOf("="):part.indexOf("]=")+1;if(-1===pos)obj[Utils.decode(part)]="";else{var key=Utils.decode(part.slice(0,pos)),val=Utils.decode(part.slice(pos+1));obj[key]=obj[key]?[].concat(obj[key]).concat(val):val}}return obj},internals.parseObject=function(chain,val){if(!chain.length)return val;var root=chain.shift(),obj={};if("[]"===root)obj=[],obj=obj.concat(internals.parseObject(chain,val));else{var cleanRoot="["===root[0]&&"]"===root[root.length-1]?root.slice(1,root.length-1):root,index=parseInt(cleanRoot,10);!isNaN(index)&&root!==cleanRoot&&index<=internals.arrayLimit?(obj=[],obj[index]=internals.parseObject(chain,val)):obj[cleanRoot]=internals.parseObject(chain,val)}return obj},internals.parseKeys=function(key,val,depth){if(key){var parent=/^([^\[\]]*)/,child=/(\[[^\[\]]*\])/g,segment=parent.exec(key);if(!Object.prototype.hasOwnProperty(segment[1])){var keys=[];segment[1]&&keys.push(segment[1]);for(var i=0;null!==(segment=child.exec(key))&&depth>i;)++i,Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g,""))||keys.push(segment[1]);return segment&&keys.push("["+key.slice(segment.index)+"]"),internals.parseObject(keys,val)}}},module.exports=function(str,depth,delimiter){if(""===str||null===str||"undefined"==typeof str)return{};"number"!=typeof depth&&(delimiter=depth,depth=internals.depth);var tempObj="string"==typeof str?internals.parseValues(str,delimiter):Utils.clone(str),obj={};for(var key in tempObj)if(tempObj.hasOwnProperty(key)){var newObj=internals.parseKeys(key,tempObj[key],depth);obj=Utils.merge(obj,newObj)}return Utils.compact(obj)}},{"./utils":56}],55:[function(_dereq_,module){var internals={delimiter:"&"};internals.stringify=function(obj,prefix){if(Buffer.isBuffer(obj)?obj=obj.toString():obj instanceof Date?obj=obj.toISOString():null===obj&&(obj=""),"string"==typeof obj||"number"==typeof obj||"boolean"==typeof obj)return[encodeURIComponent(prefix)+"="+encodeURIComponent(obj)];var values=[];for(var key in obj)obj.hasOwnProperty(key)&&(values=values.concat(internals.stringify(obj[key],prefix+"["+key+"]")));return values},module.exports=function(obj,delimiter){delimiter="undefined"==typeof delimiter?internals.delimiter:delimiter;var keys=[];for(var key in obj)obj.hasOwnProperty(key)&&(keys=keys.concat(internals.stringify(obj[key],key)));return keys.join(delimiter)}},{}],56:[function(_dereq_,module,exports){exports.arrayToObject=function(source){for(var obj={},i=0,il=source.length;il>i;++i)"undefined"!=typeof source[i]&&(obj[i]=source[i]);return obj},exports.clone=function(source){if("object"!=typeof source||null===source)return source;if(Buffer.isBuffer(source))return source.toString();var obj=Array.isArray(source)?[]:{};for(var i in source)source.hasOwnProperty(i)&&(obj[i]=exports.clone(source[i]));return obj},exports.merge=function(target,source){if(!source)return target;var obj=exports.clone(target);if(Array.isArray(source)){for(var i=0,il=source.length;il>i;++i)"undefined"!=typeof source[i]&&(obj[i]="object"==typeof obj[i]?exports.merge(obj[i],source[i]):source[i]);return obj}Array.isArray(obj)&&(obj=exports.arrayToObject(obj));for(var keys=Object.keys(source),k=0,kl=keys.length;kl>k;++k){var key=keys[k],value=source[key];obj[key]=value&&"object"==typeof value?obj[key]?exports.merge(obj[key],value):exports.clone(value):value}return obj},exports.decode=function(str){try{return decodeURIComponent(str.replace(/\+/g," "))}catch(e){return str}},exports.compact=function(obj){if("object"!=typeof obj||null===obj)return obj;var compacted={};for(var key in obj)if(obj.hasOwnProperty(key))if(Array.isArray(obj[key])){compacted[key]=[];for(var i=0,l=obj[key].length;l>i;i++)"undefined"!=typeof obj[key][i]&&compacted[key].push(obj[key][i])}else compacted[key]=exports.compact(obj[key]);return compacted}},{}],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 invariant=_dereq_("./invariant"),keyMirror=function(obj){var key,ret={};invariant(obj instanceof Object&&!Array.isArray(obj));for(key in obj)obj.hasOwnProperty(key)&&(ret[key]=key);return ret};module.exports=keyMirror},{"./invariant":60}],62:[function(_dereq_,module){"use strict";var mergeInto=_dereq_("./mergeInto"),merge=function(one,two){var result={};return mergeInto(result,one),mergeInto(result,two),result};module.exports=merge},{"./mergeInto":64}],63:[function(_dereq_,module){"use strict";var invariant=_dereq_("./invariant"),keyMirror=_dereq_("./keyMirror"),MAX_MERGE_DEPTH=36,isTerminal=function(o){return"object"!=typeof o||null===o},mergeHelpers={MAX_MERGE_DEPTH:MAX_MERGE_DEPTH,isTerminal:isTerminal,normalizeMergeArg:function(arg){return void 0===arg||null===arg?{}:arg},checkMergeArrayArgs:function(one,two){invariant(Array.isArray(one)&&Array.isArray(two))},checkMergeObjectArgs:function(one,two){mergeHelpers.checkMergeObjectArg(one),mergeHelpers.checkMergeObjectArg(two)},checkMergeObjectArg:function(arg){invariant(!isTerminal(arg)&&!Array.isArray(arg))},checkMergeIntoObjectArg:function(arg){invariant(!(isTerminal(arg)&&"function"!=typeof arg||Array.isArray(arg)))},checkMergeLevel:function(level){invariant(MAX_MERGE_DEPTH>level)},checkArrayStrategy:function(strategy){invariant(void 0===strategy||strategy in mergeHelpers.ArrayStrategies)},ArrayStrategies:keyMirror({Clobber:!0,IndexByIndex:!0})};module.exports=mergeHelpers},{"./invariant":60,"./keyMirror":61}],64:[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":63}],65:[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},{}],66:[function(_dereq_,module){"use strict";var emptyFunction=_dereq_("./emptyFunction"),warning=emptyFunction;module.exports=warning},{"./emptyFunction":59}],67:[function(_dereq_,module){module.exports=_dereq_("./modules/actions/LocationActions").replaceWith},{"./modules/actions/LocationActions":12}],68:[function(_dereq_,module){module.exports=_dereq_("./modules/actions/LocationActions").transitionTo},{"./modules/actions/LocationActions":12}]},{},[10])(10)}); |
@@ -13,12 +13,4 @@ API: `DefaultRoute` (component) | ||
### `handler` | ||
See [Route::props][routeProps] | ||
The component to be rendered when the route is active. | ||
### `preserveScrollPosition` | ||
If `true`, the router will not scroll the window up when the route is | ||
transitioned to. Defaults to `false`. Ignored if the parent `<Routes/>` | ||
has been set to `true`. | ||
Example | ||
@@ -64,1 +56,2 @@ ------- | ||
[routeProps]:/docs/api/components/Route.md#props |
@@ -15,2 +15,19 @@ API: `Link` (component) | ||
### `params` | ||
Object, the parameters to fill in the dynamic segments of your route. | ||
#### Example | ||
```js | ||
// given a route config like this | ||
<Route name="user" path="/user/:userId"/> | ||
// create a link with this | ||
<Link to="user" params={{userId: "123"}}/> | ||
// though, if your user properties match up to the dynamic segements: | ||
<Link to="user" params={user}/> | ||
``` | ||
### `query` | ||
@@ -21,7 +38,2 @@ | ||
### `[param]` | ||
Any dynamic segments the route defines (like `:userId`) are passed by | ||
name through the link's properties to the resulting url. | ||
### `activeClassName` | ||
@@ -49,3 +61,3 @@ | ||
```xml | ||
<Link to="user" userId={user.id} query={{foo: bar}}>{user.name}</Link> | ||
<Link to="user" params={{userId: user.id}} query={{foo: bar}}>{user.name}</Link> | ||
<!-- becomes one of these depending on your router and if the route is | ||
@@ -60,4 +72,4 @@ active --> | ||
<!-- change the activeClassName --> | ||
<Link activeClassName="current" to="user" userId={user.id}>{user.name}</Link> | ||
<Link activeClassName="current" to="user" params={{userId: user.id}}>{user.name}</Link> | ||
``` | ||
@@ -11,3 +11,4 @@ API: `Redirect` (component) | ||
The path you want to redirect from, including dynamic segments. | ||
The path you want to redirect from, including dynamic segments. Defaults | ||
to `*` so you can redirect anything not found to somewhere else. | ||
@@ -30,5 +31,16 @@ ### `to` | ||
<Route name="about-user" path="about/:userId" handler={UserProfile}/> | ||
<Route name="course" path="course/:courseId"> | ||
<Route name="course-dashboard" path="dashboard" handler={Dashboard}/> | ||
<Route name="course-assignments" path="assignments" handler={Assignments}/> | ||
<!-- | ||
anything like `/course/123/invalid` redirects to | ||
`/course/123/dashboard` | ||
--> | ||
<Redirect to="course-dashboard" /> | ||
</Route> | ||
</Route> | ||
<!-- `/get-in-touch` -> `/contact` --> | ||
<Redirect from="get-in-touch" to="contact" /> | ||
<!-- `/profile/123` -> `/about/123` --> | ||
<Redirect from="profile/:userId" to="about-user" /> | ||
@@ -35,0 +47,0 @@ </Routes> |
@@ -16,8 +16,8 @@ API: `Route` (component) | ||
The path used in the URL, supporting dynamic segments. If left | ||
undefined, the path will be defined by the `name`, and if there is no | ||
name, will default to `/`. This path is always absolute from the URL | ||
"root", even if the leading slash is left off. Nested routes do not | ||
inherit the path of their parent. | ||
The path used in the URL. If left undefined, the path will be defined by | ||
the `name`, and if there is no name, will default to `/`. | ||
Please refer to the [Path Matching Guide][path-matching] to learn more | ||
about supported path matching syntax. | ||
### `handler` | ||
@@ -27,2 +27,22 @@ | ||
### `addHandlerKey` | ||
Defaults to `false`. | ||
If you have dynamic segments in your URL, a transition from `/users/123` | ||
to `/users/456` does not call `getInitialState`, `componentWillMount` or | ||
`componentWillUnmount`. If you are using those lifecycle hooks to fetch | ||
data and set state, you will also need to implement | ||
`componentWillReceiveProps` on your handler, just like any other | ||
component with changing props. This way, you can leverage the | ||
performance of the React DOM diff algorithm. Look at the `Contact` | ||
handler in the `master-detail` example. | ||
If you'd rather be lazy, set this to `true` and the router will add a | ||
key to your route, causing all new DOM to be built, and then the life | ||
cycle hooks will all be called. | ||
You will want this to be `true` if you're doing animations with React's | ||
TransitionGroup component. | ||
### `preserveScrollPosition` | ||
@@ -87,1 +107,2 @@ | ||
[path-matching]:/docs/guides/path-matching.md |
@@ -64,3 +64,3 @@ API: `RouteHandler` (component) | ||
### `willTransitionTo(transition, params)` | ||
### `willTransitionTo(transition, params, query)` | ||
@@ -67,0 +67,0 @@ Called when a route is about to render, giving you the opportunity to |
@@ -9,2 +9,3 @@ React Router API | ||
- [`Link`](/docs/api/components/Link.md) | ||
- [`NotFoundRoute`](/docs/api/components/NotFoundRoute.md) | ||
- [`Redirect`](/docs/api/components/Redirect.md) | ||
@@ -11,0 +12,0 @@ - [`Route`](/docs/api/components/Route.md) |
@@ -151,4 +151,4 @@ React Router Guide | ||
<Route name="app" path="/" handler={App}> | ||
<Route name="inbox" path="/inbox" handler={Inbox}/> | ||
<Route name="calendar" path="/calendar" handler={Calendar}/> | ||
<Route name="inbox" handler={Inbox}/> | ||
<Route name="calendar" handler={Calendar}/> | ||
<DefaultRoute handler={Dashboard}/> | ||
@@ -232,10 +232,10 @@ </Route> | ||
<Routes location="history"> | ||
<Route path="/" handler={App}> | ||
<Route handler={App}> | ||
<Route name="inbox" path="/inbox" handler={Inbox}> | ||
<Route name="message" path="/inbox/:messageId" handler={Message}/> | ||
<Route name="inbox" handler={Inbox}> | ||
<Route name="message" path=":messageId" handler={Message}/> | ||
<DefaultRoute handler={InboxStats}/> | ||
</Route> | ||
<Route name="calendar" path="/calendar" handler={Calendar}/> | ||
<Route name="calendar" handler={Calendar}/> | ||
<DefaultRoute handler={Dashboard}/> | ||
@@ -256,9 +256,2 @@ | ||
**Note**: the paths are not inherited from parent to child. This gives | ||
you the flexibility to have any url you need. Were the paths to be | ||
inherited, you'd be forced to couple your urls to your route hierarchy. | ||
For example, we may want `/inbox` and `/messages/123` instead of `/inbox` | ||
and `/inbox/123`. We can just change the path on the `message` route and | ||
still get view nesting even though the urls are not nested. | ||
Dynamic Segments | ||
@@ -274,3 +267,3 @@ ---------------- | ||
```xml | ||
<Route name="message" path="/inbox/:messageId" handler={Message}/> | ||
<Route name="message" path=":messageId" handler={Message}/> | ||
``` | ||
@@ -290,3 +283,3 @@ | ||
Assuming the user navigates to `/inbox/123`, `this.props.messageId` is | ||
Assuming the user navigates to `/inbox/123`, `this.props.params.messageId` is | ||
going to be `'123'`. Check out the [AsyncState][AsyncState] mixin to see | ||
@@ -297,5 +290,32 @@ how you can turn this parameter into state on your component. Or for a | ||
Links | ||
----- | ||
Important Note About Dynamic Segments | ||
------------------------------------- | ||
If you have dynamic segments in your URL, a transition from `/users/123` | ||
to `/users/456` does not call `getInitialState`, `componentWillMount` or | ||
`componentWillUnmount`. If you are using those lifecycle hooks to fetch | ||
data and set state, you will also need to implement | ||
`componentWillReceiveProps` on your handler, just like any other | ||
component whose props are changing. This way you can leverage the | ||
performance of the React DOM diff algorithm. Look at the `Contact` | ||
handler in the `master-detail` example. | ||
If you'd rather be lazy, you can use the `addHandlerKey` option and set | ||
it to `true` on your route to opt-out of the performance. See also | ||
[Route][Route]. | ||
Scrolling | ||
--------- | ||
By default, the router will manage the scroll position between route | ||
transitions. When a user clicks "back" or "forward", it will restore | ||
their scroll position. If they visit a new route, it will automatically | ||
scroll the window to the top. You can opt out of this with the | ||
`preserverScrollPosition` option on [Routes][Routes] or [Route][Route]. | ||
Bells and Whistles | ||
------------------ | ||
### `<Link/>` | ||
The `<Link/>` component allows you to conveniently navigate users around | ||
@@ -307,2 +327,42 @@ the application with accessible anchor tags that don't break normal link | ||
### `<NotFoundRoute/>` | ||
At any level of your UI nesting, you can render a handler if the url | ||
beyond what was matched isn't recognized. | ||
```xml | ||
<Routes location="history"> | ||
<Route path="/" handler={App}> | ||
<Route name="inbox" path="/inbox" handler={Inbox}> | ||
<!-- | ||
will render inside the `Inbox` UI for any paths not recognized | ||
after the parent route's path `/inbox/*` | ||
--> | ||
<NotFoundRoute handler={InboxNotFound} | ||
<Route name="message" path="/inbox/:messageId" handler={Message}/> | ||
<DefaultRoute handler={InboxStats}/> | ||
</Route> | ||
<Route name="calendar" path="/calendar" handler={Calendar}/> | ||
<DefaultRoute handler={Dashboard}/> | ||
</Route> | ||
<!-- will catch any route that isn't recognized at all --> | ||
<NotFoundRoute handler={NotFound} | ||
</Routes> | ||
``` | ||
### `<Redirect/>` | ||
URLs in an app change, so we made it easy to not break the old ones. | ||
```xml | ||
<Route name="message" path="/inbox/:messageId" handler={Message} /> | ||
<Redirect path="/messages/:messageId" to="message" /> | ||
``` | ||
Path Matching | ||
------------- | ||
There's a lot more to be said about path matching, check out the [Path | ||
Matching Guide][path-matching]. | ||
API Documentation | ||
@@ -316,3 +376,6 @@ ----------------- | ||
[AsyncState]:../api/mixins/AsyncState.md | ||
[Route]:../api/components/Route.md | ||
[Routes]:../api/components/Routes.md | ||
[API]:../api/ | ||
[path-matching]:./path-matching.md | ||
@@ -1,1 +0,1 @@ | ||
module.exports = require('./modules/helpers/goBack'); | ||
module.exports = require('./modules/actions/LocationActions').goBack; |
@@ -5,2 +5,3 @@ exports.ActiveState = require('./ActiveState'); | ||
exports.Link = require('./Link'); | ||
exports.NotFoundRoute = require('./NotFoundRoute'); | ||
exports.Redirect = require('./Redirect'); | ||
@@ -10,4 +11,4 @@ exports.Route = require('./Route'); | ||
exports.goBack = require('./goBack'); | ||
exports.makeHref = require('./makeHref'); | ||
exports.replaceWith = require('./replaceWith'); | ||
exports.transitionTo = require('./transitionTo'); | ||
exports.makeHref = require('./makeHref'); |
@@ -13,4 +13,4 @@ var merge = require('react/lib/merge'); | ||
merge(props, { | ||
name: null, | ||
path: null | ||
path: null, | ||
isDefault: true | ||
}) | ||
@@ -17,0 +17,0 @@ ); |
var React = require('react'); | ||
var ActiveState = require('../mixins/ActiveState'); | ||
var transitionTo = require('../actions/LocationActions').transitionTo; | ||
var withoutProperties = require('../helpers/withoutProperties'); | ||
var transitionTo = require('../helpers/transitionTo'); | ||
var hasOwnProperty = require('../helpers/hasOwnProperty'); | ||
var makeHref = require('../helpers/makeHref'); | ||
var warning = require('react/lib/warning'); | ||
@@ -17,3 +18,3 @@ function isLeftClickEvent(event) { | ||
/** | ||
* A map of <Link> component props that are reserved for use by the | ||
* DEPRECATED: A map of <Link> component props that are reserved for use by the | ||
* router and/or React. All other props are used as params that are | ||
@@ -28,2 +29,3 @@ * interpolated into the link's path. | ||
query: true, | ||
onClick:true, | ||
children: true // ReactChildren | ||
@@ -43,3 +45,3 @@ }; | ||
* | ||
* <Link to="showPost" postId="123"/> | ||
* <Link to="showPost" params={{postId: "123"}} /> | ||
* | ||
@@ -49,3 +51,3 @@ * In addition to params, links may pass along query string parameters | ||
* | ||
* <Link to="showPost" postId="123" query={{show:true}}/> | ||
* <Link to="showPost" params={{postId: "123"}} query={{show:true}}/> | ||
*/ | ||
@@ -60,4 +62,17 @@ var Link = React.createClass({ | ||
// TODO: Deprecate passing props as params in v1.0 | ||
getUnreservedProps: function (props) { | ||
warning( | ||
false, | ||
'Passing props for params on <Link>s is deprecated, '+ | ||
'please use the `params` property.' | ||
); | ||
return withoutProperties(props, RESERVED_PROPS); | ||
}, | ||
/** | ||
* Returns a hash of URL parameters to use in this <Link>'s path. | ||
*/ | ||
getParams: function (props) { | ||
return props.params || Link.getUnreservedProps(props); | ||
} | ||
@@ -70,2 +85,3 @@ | ||
activeClassName: React.PropTypes.string.isRequired, | ||
params: React.PropTypes.object, | ||
query: React.PropTypes.object, | ||
@@ -88,13 +104,6 @@ onClick: React.PropTypes.func | ||
/** | ||
* Returns a hash of URL parameters to use in this <Link>'s path. | ||
*/ | ||
getParams: function () { | ||
return Link.getUnreservedProps(this.props); | ||
}, | ||
/** | ||
* Returns the value of the "href" attribute to use on the DOM element. | ||
*/ | ||
getHref: function () { | ||
return makeHref(this.props.to, this.getParams(), this.props.query); | ||
return makeHref(this.props.to, Link.getParams(this.props), this.props.query); | ||
}, | ||
@@ -116,3 +125,3 @@ | ||
componentWillReceiveProps: function (nextProps) { | ||
var params = Link.getUnreservedProps(nextProps); | ||
var params = Link.getParams(nextProps); | ||
@@ -126,3 +135,3 @@ this.setState({ | ||
this.setState({ | ||
isActive: Link.isActive(this.props.to, this.getParams(), this.props.query) | ||
isActive: Link.isActive(this.props.to, Link.getParams(this.props), this.props.query) | ||
}); | ||
@@ -147,3 +156,3 @@ }, | ||
if (allowTransition) | ||
transitionTo(this.props.to, this.getParams(), this.props.query); | ||
transitionTo(this.props.to, Link.getParams(this.props), this.props.query); | ||
}, | ||
@@ -150,0 +159,0 @@ |
@@ -20,3 +20,3 @@ var React = require('react'); | ||
* A <Redirect> component is a special kind of <Route> that always | ||
* redirects when it matches. | ||
* redirects to another route when it matches. | ||
*/ | ||
@@ -26,3 +26,3 @@ function Redirect(props) { | ||
name: props.name, | ||
path: props.from || props.path, | ||
path: props.from || props.path || '*', | ||
handler: createRedirectHandler(props.to) | ||
@@ -29,0 +29,0 @@ }); |
@@ -5,5 +5,4 @@ var React = require('react'); | ||
var Promise = require('es6-promise').Promise; | ||
var LocationActions = require('../actions/LocationActions'); | ||
var Route = require('../components/Route'); | ||
var goBack = require('../helpers/goBack'); | ||
var replaceWith = require('../helpers/replaceWith'); | ||
var Path = require('../helpers/Path'); | ||
@@ -30,4 +29,3 @@ var Redirect = require('../helpers/Redirect'); | ||
history: HistoryLocation, | ||
refresh: RefreshLocation, | ||
disabled: RefreshLocation // TODO: Remove | ||
refresh: RefreshLocation | ||
}; | ||
@@ -43,5 +41,5 @@ | ||
if (reason instanceof Redirect) { | ||
replaceWith(reason.to, reason.params, reason.query); | ||
LocationActions.replaceWith(reason.to, reason.params, reason.query); | ||
} else { | ||
goBack(); | ||
LocationActions.goBack(); | ||
} | ||
@@ -66,2 +64,7 @@ } | ||
function maybeUpdateScroll(routes, rootRoute) { | ||
if (!routes.props.preserveScrollPosition && !rootRoute.props.preserveScrollPosition) | ||
LocationActions.updateScroll(); | ||
} | ||
/** | ||
@@ -106,3 +109,2 @@ * The <Routes> component configures the route hierarchy and renders the | ||
getLocation: function () { | ||
@@ -152,3 +154,3 @@ var location = this.props.location; | ||
match: function (path) { | ||
return findMatches(Path.withoutQuery(path), this.state.routes, this.props.defaultRoute); | ||
return findMatches(Path.withoutQuery(path), this.state.routes, this.props.defaultRoute, this.props.notFoundRoute); | ||
}, | ||
@@ -195,3 +197,3 @@ | ||
if (rootMatch) | ||
maybeScrollWindow(routes, rootMatch.route); | ||
maybeUpdateScroll(routes, rootMatch.route); | ||
} | ||
@@ -229,3 +231,3 @@ | ||
function findMatches(path, routes, defaultRoute) { | ||
function findMatches(path, routes, defaultRoute, notFoundRoute) { | ||
var matches = null, route, params; | ||
@@ -237,3 +239,3 @@ | ||
// Check the subtree first to find the most deeply-nested match. | ||
matches = findMatches(path, route.props.children, route.props.defaultRoute); | ||
matches = findMatches(path, route.props.children, route.props.defaultRoute, route.props.notFoundRoute); | ||
@@ -261,7 +263,9 @@ if (matches != null) { | ||
// No routes matched, so try the default route if there is one. | ||
params = defaultRoute && Path.extractParams(defaultRoute.props.path, path); | ||
if (params) | ||
if (defaultRoute && (params = Path.extractParams(defaultRoute.props.path, path))) | ||
return [ makeMatch(defaultRoute, params) ]; | ||
// Last attempt: does the "not found" route match? | ||
if (notFoundRoute && (params = Path.extractParams(notFoundRoute.props.path, path))) | ||
return [ makeMatch(notFoundRoute, params) ]; | ||
return matches; | ||
@@ -338,2 +342,4 @@ } | ||
var query = Path.extractQuery(transition.path) || {}; | ||
return runTransitionFromHooks(fromMatches, transition).then(function () { | ||
@@ -343,3 +349,3 @@ if (transition.isAborted) | ||
return runTransitionToHooks(toMatches, transition).then(function () { | ||
return runTransitionToHooks(toMatches, transition, query).then(function () { | ||
if (transition.isAborted) | ||
@@ -350,3 +356,2 @@ return; // No need to continue. | ||
var params = (rootMatch && rootMatch.params) || {}; | ||
var query = Path.extractQuery(transition.path) || {}; | ||
@@ -392,3 +397,3 @@ return { | ||
*/ | ||
function runTransitionToHooks(matches, transition) { | ||
function runTransitionToHooks(matches, transition, query) { | ||
var promise = Promise.resolve(); | ||
@@ -401,3 +406,3 @@ | ||
if (!transition.isAborted && handler.willTransitionTo) | ||
return handler.willTransitionTo(transition, match.params); | ||
return handler.willTransitionTo(transition, match.params, query); | ||
}); | ||
@@ -429,6 +434,8 @@ }); | ||
props.ref = REF_NAME; | ||
props.key = Path.injectParams(route.props.path, match.params); | ||
props.params = match.params; | ||
props.query = query; | ||
if (route.props.addHandlerKey) | ||
props.key = Path.injectParams(route.props.path, match.params); | ||
if (childHandler) { | ||
@@ -459,9 +466,2 @@ props.activeRouteHandler = childHandler; | ||
function maybeScrollWindow(routes, rootRoute) { | ||
if (routes.props.preserveScrollPosition || rootRoute.props.preserveScrollPosition) | ||
return; | ||
window.scrollTo(0, 0); | ||
} | ||
module.exports = Routes; |
@@ -11,4 +11,4 @@ var invariant = require('react/lib/invariant'); | ||
var path; | ||
if (to.charAt(0) === '/') { | ||
path = Path.normalize(to); // Absolute path. | ||
if (Path.isAbsolute(to)) { | ||
path = Path.normalize(to); | ||
} else { | ||
@@ -15,0 +15,0 @@ var route = RouteStore.getRouteByName(to); |
var invariant = require('react/lib/invariant'); | ||
var copyProperties = require('react/lib/copyProperties'); | ||
var qs = require('querystring'); | ||
var URL = require('./URL'); | ||
var merge = require('qs/lib/utils').merge; | ||
var qs = require('qs'); | ||
var paramMatcher = /((?::[a-z_$][a-z0-9_$]*)|\*)/ig; | ||
var queryMatcher = /\?(.+)/; | ||
function encodeURL(url) { | ||
return encodeURIComponent(url).replace(/%20/g, '+'); | ||
} | ||
function getParamName(pathSegment) { | ||
return pathSegment === '*' ? 'splat' : pathSegment.substr(1); | ||
function decodeURL(url) { | ||
return decodeURIComponent(url.replace(/\+/g, ' ')); | ||
} | ||
function encodeURLPath(path) { | ||
return String(path).split('/').map(encodeURL).join('/'); | ||
} | ||
var paramMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g; | ||
var queryMatcher = /\?(.+)/; | ||
var _compiledPatterns = {}; | ||
function compilePattern(pattern) { | ||
if (_compiledPatterns[pattern]) | ||
return _compiledPatterns[pattern]; | ||
if (!(pattern in _compiledPatterns)) { | ||
var paramNames = []; | ||
var source = pattern.replace(paramMatcher, function (match, paramName) { | ||
if (paramName) { | ||
paramNames.push(paramName); | ||
return '([^./?#]+)'; | ||
} else if (match === '*') { | ||
paramNames.push('splat'); | ||
return '(.*?)'; | ||
} else { | ||
return '\\' + match; | ||
} | ||
}); | ||
var compiled = _compiledPatterns[pattern] = {}; | ||
var paramNames = compiled.paramNames = []; | ||
_compiledPatterns[pattern] = { | ||
matcher: new RegExp('^' + source + '$', 'i'), | ||
paramNames: paramNames | ||
}; | ||
} | ||
var source = pattern.replace(paramMatcher, function (match, pathSegment) { | ||
paramNames.push(getParamName(pathSegment)); | ||
return pathSegment === '*' ? '(.*?)' : '([^/?#]+)'; | ||
}); | ||
compiled.matcher = new RegExp('^' + source + '$', 'i'); | ||
return compiled; | ||
return _compiledPatterns[pattern]; | ||
} | ||
function isDynamicPattern(pattern) { | ||
return pattern.indexOf(':') !== -1 || pattern.indexOf('*') !== -1; | ||
} | ||
var Path = { | ||
/** | ||
* Returns an array of the names of all parameters in the given pattern. | ||
*/ | ||
extractParamNames: function (pattern) { | ||
return compilePattern(pattern).paramNames; | ||
}, | ||
/** | ||
* Extracts the portions of the given URL path that match the given pattern | ||
@@ -44,15 +61,5 @@ * and returns an object of param name => value pairs. Returns null if the | ||
extractParams: function (pattern, path) { | ||
if (!pattern) | ||
return null; | ||
var object = compilePattern(pattern); | ||
var match = decodeURL(path).match(object.matcher); | ||
if (!isDynamicPattern(pattern)) { | ||
if (pattern === URL.decode(path)) | ||
return {}; // No dynamic segments, but the paths match. | ||
return null; | ||
} | ||
var compiled = compilePattern(pattern); | ||
var match = URL.decode(path).match(compiled.matcher); | ||
if (!match) | ||
@@ -63,3 +70,3 @@ return null; | ||
compiled.paramNames.forEach(function (paramName, index) { | ||
object.paramNames.forEach(function (paramName, index) { | ||
params[paramName] = match[index + 1]; | ||
@@ -72,11 +79,2 @@ }); | ||
/** | ||
* Returns an array of the names of all parameters in the given pattern. | ||
*/ | ||
extractParamNames: function (pattern) { | ||
if (!pattern) | ||
return []; | ||
return compilePattern(pattern).paramNames; | ||
}, | ||
/** | ||
* Returns a version of the given route path with params interpolated. Throws | ||
@@ -86,13 +84,9 @@ * if there is a dynamic segment of the route path for which there is no param. | ||
injectParams: function (pattern, params) { | ||
if (!pattern) | ||
return null; | ||
params = params || {}; | ||
if (!isDynamicPattern(pattern)) | ||
return pattern; | ||
var splatIndex = 0; | ||
params = params || {}; | ||
return pattern.replace(paramMatcher, function (match, paramName) { | ||
paramName = paramName || 'splat'; | ||
return pattern.replace(paramMatcher, function (match, pathSegment) { | ||
var paramName = getParamName(pathSegment); | ||
invariant( | ||
@@ -103,4 +97,15 @@ params[paramName] != null, | ||
// Preserve forward slashes. | ||
return String(params[paramName]).split('/').map(URL.encode).join('/'); | ||
var segment; | ||
if (paramName === 'splat' && Array.isArray(params[paramName])) { | ||
segment = params[paramName][splatIndex++]; | ||
invariant( | ||
segment != null, | ||
'Missing splat # ' + splatIndex + ' for path "' + pattern + '"' | ||
); | ||
} else { | ||
segment = params[paramName]; | ||
} | ||
return encodeURLPath(segment); | ||
}); | ||
@@ -110,7 +115,7 @@ }, | ||
/** | ||
* Returns an object that is the result of parsing any query string contained in | ||
* the given path, null if the path contains no query string. | ||
* Returns an object that is the result of parsing any query string contained | ||
* in the given path, null if the path contains no query string. | ||
*/ | ||
extractQuery: function (path) { | ||
var match = path.match(queryMatcher); | ||
var match = decodeURL(path).match(queryMatcher); | ||
return match && qs.parse(match[1]); | ||
@@ -127,4 +132,4 @@ }, | ||
/** | ||
* Returns a version of the given path with the parameters in the given query | ||
* added to the query string. | ||
* Returns a version of the given path with the parameters in the given | ||
* query merged into the query string. | ||
*/ | ||
@@ -135,3 +140,3 @@ withQuery: function (path, query) { | ||
if (existingQuery) | ||
query = query ? copyProperties(existingQuery, query) : existingQuery; | ||
query = query ? merge(existingQuery, query) : existingQuery; | ||
@@ -147,6 +152,20 @@ var queryString = query && qs.stringify(query); | ||
/** | ||
* Returns true if the given path is absolute. | ||
*/ | ||
isAbsolute: function (path) { | ||
return path.charAt(0) === '/'; | ||
}, | ||
/** | ||
* Returns a normalized version of the given path. | ||
*/ | ||
normalize: function (path) { | ||
normalize: function (path, parentRoute) { | ||
return path.replace(/^\/*/, '/'); | ||
}, | ||
/** | ||
* Joins two URL paths together. | ||
*/ | ||
join: function (a, b) { | ||
return a.replace(/\/*$/, '/') + b; | ||
} | ||
@@ -153,0 +172,0 @@ |
var mixInto = require('react/lib/mixInto'); | ||
var transitionTo = require('./transitionTo'); | ||
var transitionTo = require('../actions/LocationActions').transitionTo; | ||
var Redirect = require('./Redirect'); | ||
@@ -4,0 +4,0 @@ |
@@ -5,4 +5,24 @@ var invariant = require('react/lib/invariant'); | ||
function getHashPath() { | ||
return window.location.hash.substr(1); | ||
} | ||
function ensureSlash() { | ||
var path = getHashPath(); | ||
if (path.charAt(0) === '/') | ||
return true; | ||
HashLocation.replace('/' + path); | ||
return false; | ||
} | ||
var _onChange; | ||
function handleHashChange() { | ||
if (ensureSlash()) | ||
_onChange(); | ||
} | ||
/** | ||
@@ -21,10 +41,8 @@ * A Location that uses `window.location.hash`. | ||
// Make sure the hash is at least / to begin with. | ||
if (window.location.hash === '') | ||
window.location.replace(getWindowPath() + '#/'); | ||
ensureSlash(); | ||
if (window.addEventListener) { | ||
window.addEventListener('hashchange', _onChange, false); | ||
window.addEventListener('hashchange', handleHashChange, false); | ||
} else { | ||
window.attachEvent('onhashchange', _onChange); | ||
window.attachEvent('onhashchange', handleHashChange); | ||
} | ||
@@ -35,5 +53,5 @@ }, | ||
if (window.removeEventListener) { | ||
window.removeEventListener('hashchange', _onChange, false); | ||
window.removeEventListener('hashchange', handleHashChange, false); | ||
} else { | ||
window.detachEvent('onhashchange', _onChange); | ||
window.detachEvent('onhashchange', handleHashChange); | ||
} | ||
@@ -54,5 +72,3 @@ }, | ||
getCurrentPath: function () { | ||
return window.location.hash.substr(1); | ||
}, | ||
getCurrentPath: getHashPath, | ||
@@ -59,0 +75,0 @@ toString: function () { |
@@ -59,3 +59,3 @@ var ActiveStore = require('../stores/ActiveStore'); | ||
handleActiveStateChange: function () { | ||
if (this.isMounted() && this.updateActiveState) | ||
if (this.isMounted() && typeof this.updateActiveState === 'function') | ||
this.updateActiveState(); | ||
@@ -62,0 +62,0 @@ } |
var warning = require('react/lib/warning'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var LocationActions = require('../actions/LocationActions'); | ||
var LocationDispatcher = require('../dispatchers/LocationDispatcher'); | ||
var supportsHistory = require('../helpers/supportsHistory'); | ||
@@ -14,2 +16,16 @@ var HistoryLocation = require('../locations/HistoryLocation'); | ||
var _scrollPositions = {}; | ||
function recordScrollPosition(path) { | ||
_scrollPositions[path] = { | ||
x: window.scrollX, | ||
y: window.scrollY | ||
}; | ||
} | ||
function updateScrollPosition(path) { | ||
var p = PathStore.getScrollPosition(path); | ||
window.scrollTo(p.x, p.y); | ||
} | ||
var _location; | ||
@@ -62,2 +78,5 @@ | ||
/** | ||
* Returns the location object currently in use. | ||
*/ | ||
getLocation: function () { | ||
@@ -67,22 +86,48 @@ return _location; | ||
push: function (path) { | ||
if (_location.getCurrentPath() !== path) | ||
_location.push(path); | ||
/** | ||
* Returns the current URL path. | ||
*/ | ||
getCurrentPath: function () { | ||
return _location.getCurrentPath(); | ||
}, | ||
replace: function (path) { | ||
if (_location.getCurrentPath() !== path) | ||
_location.replace(path); | ||
/** | ||
* Returns the last known scroll position for the given path. | ||
*/ | ||
getScrollPosition: function (path) { | ||
return _scrollPositions[path] || { x: 0, y: 0 }; | ||
}, | ||
pop: function () { | ||
_location.pop(); | ||
}, | ||
dispatchToken: LocationDispatcher.register(function (payload) { | ||
var action = payload.action; | ||
var currentPath = _location.getCurrentPath(); | ||
getCurrentPath: function () { | ||
return _location.getCurrentPath(); | ||
} | ||
switch (action.type) { | ||
case LocationActions.PUSH: | ||
if (currentPath !== action.path) { | ||
recordScrollPosition(currentPath); | ||
_location.push(action.path); | ||
} | ||
break; | ||
case LocationActions.REPLACE: | ||
if (currentPath !== action.path) { | ||
recordScrollPosition(currentPath); | ||
_location.replace(action.path); | ||
} | ||
break; | ||
case LocationActions.POP: | ||
recordScrollPosition(currentPath); | ||
_location.pop(); | ||
break; | ||
case LocationActions.UPDATE_SCROLL: | ||
updateScrollPosition(currentPath); | ||
break; | ||
} | ||
}) | ||
}; | ||
module.exports = PathStore; |
@@ -51,11 +51,17 @@ var React = require('react'); | ||
// Default routes have no name, path, or children. | ||
var isDefault = !(props.path || props.name || props.children); | ||
var parentPath = (parentRoute && parentRoute.props.path) || '/'; | ||
if (props.path || props.name) { | ||
props.path = Path.normalize(props.path || props.name); | ||
} else if (parentRoute && parentRoute.props.path) { | ||
props.path = parentRoute.props.path; | ||
if ((props.path || props.name) && !props.isDefault && !props.catchAll) { | ||
var path = props.path || props.name; | ||
// Relative paths extend their parent. | ||
if (!Path.isAbsolute(path)) | ||
path = Path.join(parentPath, path); | ||
props.path = Path.normalize(path); | ||
} else { | ||
props.path = '/'; | ||
props.path = parentPath; | ||
if (props.catchAll) | ||
props.path += '*'; | ||
} | ||
@@ -89,4 +95,25 @@ | ||
if (parentRoute && isDefault) { | ||
if (props.catchAll) { | ||
invariant( | ||
parentRoute, | ||
'<NotFoundRoute> must have a parent <Route>' | ||
); | ||
invariant( | ||
parentRoute.props.notFoundRoute == null, | ||
'You may not have more than one <NotFoundRoute> per <Route>' | ||
); | ||
parentRoute.props.notFoundRoute = route; | ||
return null; | ||
} | ||
if (props.isDefault) { | ||
invariant( | ||
parentRoute, | ||
'<DefaultRoute> must have a parent <Route>' | ||
); | ||
invariant( | ||
parentRoute.props.defaultRoute == null, | ||
@@ -93,0 +120,0 @@ 'You may not have more than one <DefaultRoute> per <Route>' |
{ | ||
"name": "react-router", | ||
"version": "0.5.3", | ||
"version": "0.6.0", | ||
"description": "A complete routing library for React.js", | ||
@@ -15,2 +15,3 @@ "tags": [ | ||
"homepage": "https://github.com/rackt/react-router", | ||
"bugs": "https://github.com/rackt/react-router/issues", | ||
"directories": { | ||
@@ -51,6 +52,15 @@ "example": "examples" | ||
"dependencies": { | ||
"es6-promise": "^1.0.0", | ||
"events": "^1.0.1", | ||
"querystring": "^0.2.0" | ||
"es6-promise": "1.0.0", | ||
"events": "1.0.1", | ||
"flux": "2.0.0", | ||
"qs": "1.2.2" | ||
}, | ||
"keywords": [ | ||
"react", | ||
"react-component", | ||
"routing", | ||
"route", | ||
"routes", | ||
"router" | ||
], | ||
"browserify-shim": { | ||
@@ -57,0 +67,0 @@ "react": "global:React" |
@@ -73,9 +73,13 @@ React Router | ||
<Routes location="history"> | ||
<Route handler={App}> | ||
<Route name="about" handler={About}/> | ||
<Route path="/" handler={App}> | ||
<DefaultRoute handler={Home} /> | ||
<Route name="about" handler={About} /> | ||
<Route name="users" handler={Users}> | ||
<Route name="user" path="/user/:userId" handler={User}/> | ||
<Route name="recent-users" path="recent" handler={User} /> | ||
<Route name="user" path="/user/:userId" handler={User} /> | ||
<NotFoundRoute handler={UserRouteNotFound}/> | ||
</Route> | ||
</Route> | ||
<Route path="*" handler={NotFound}/> | ||
<NotFoundRoute handler={NotFound}/> | ||
<Redirect path="company" to="about" /> | ||
</Routes> | ||
@@ -85,2 +89,4 @@ ), document.body); | ||
All of the `handler`s will render inside their parent route `handler`. | ||
See more in the [overview guide](/docs/guides/overview.md). | ||
@@ -87,0 +93,0 @@ |
@@ -1,1 +0,1 @@ | ||
module.exports = require('./modules/helpers/replaceWith'); | ||
module.exports = require('./modules/actions/LocationActions').replaceWith; |
@@ -1,1 +0,1 @@ | ||
module.exports = require('./modules/helpers/transitionTo'); | ||
module.exports = require('./modules/actions/LocationActions').transitionTo; |
@@ -8,2 +8,118 @@ Upgrade Guide | ||
0.5.x -> 0.6.x | ||
-------------- | ||
### Path Matching | ||
Paths that start with `/` are absolute and work exactly as they used to. | ||
Paths that don't start with `/` are now relative, meaning they extend | ||
their parent route. | ||
Simply add `/` in front of all your paths to keep things working. | ||
```xml | ||
<!-- 0.5.x --> | ||
<Route path="/foo"> | ||
<Route path="bar"/> | ||
</Route> | ||
<!-- 0.6.x --> | ||
<Route path="/foo"> | ||
<Route path="/bar"/> | ||
</Route> | ||
``` | ||
Though, you may want to embrace this new feature: | ||
```js | ||
<!-- 0.5.x --> | ||
<Route path="/course/:courseId"> | ||
<Route path="/course/:courseId/assignments"/> | ||
<Route path="/course/:courseId/announcements"/> | ||
</Route> | ||
<!-- 0.6.x --> | ||
<Route path="/course/:courseId"> | ||
<Route path="assignments"/> | ||
<Route path="announcements"/> | ||
</Route> | ||
``` | ||
Also `.` is no longer matched in dynamic segments. | ||
```js | ||
<!-- 0.5.x --> | ||
<Route path="/file/:filename" /> | ||
<!-- 0.6.x --> | ||
<Route path="/file/:filename.?:ext?" /> | ||
<!-- | ||
or for a looser match to allow for multiple `.` note that the data | ||
will be available on `this.props.params.splat` instead of | ||
`this.props.params.filename` | ||
--> | ||
<Route path="/file/*" /> | ||
``` | ||
### Link params | ||
Links should now pass their params in the `params` property, though the | ||
old behavior will still work, you should update your code soon because | ||
it will be removed by `v1.0` | ||
```js | ||
// 0.5.x | ||
<Link to="user" userId="123"/> | ||
// 0.6.x | ||
<Link to="user" params={{userId: "123"}}/> | ||
``` | ||
### Dynamic Segments, keys, and lifecycle methods | ||
If you have dynamic segments and are depending on `getInitialState`, | ||
`componentWillMount`, or `componentDidMount` to fire between transitions | ||
to the same route--like `users/123` and `users/456`--then you have two | ||
options: | ||
- add `addHandlerKey={true}` to your route and keep the previous | ||
behavior (but lose out on performance), or | ||
- implement `componentWillReceiveProps`. | ||
```js | ||
// 0.5.x | ||
<Route handler={User} path="/user/:userId"/> | ||
// 0.6.x | ||
<Route handler={User} path="/user/:userId" addHandlerKey={true} /> | ||
// 0.5.x | ||
var User = React.createClass({ | ||
getInitialState: function() { | ||
return { | ||
user: getUser(this.props.params.userId); | ||
} | ||
} | ||
}); | ||
// 0.6.x | ||
var User = React.createClass({ | ||
getInitialState: function() { | ||
return this.getState();{ | ||
}, | ||
componentWillReceiveProps: function(newProps) { | ||
this.setState(this.getState(newProps)); | ||
}, | ||
getState: function(props) { | ||
props = props || this.props; | ||
return { | ||
user: getUser(props.params.userId) | ||
}; | ||
} | ||
}); | ||
``` | ||
0.4.x -> 0.5.x | ||
@@ -10,0 +126,0 @@ -------------- |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
276402
66
5219
136
37
10
211
5
55
+ Addedflux@2.0.0
+ Addedqs@1.2.2
+ Addedevents@1.0.1(transitive)
+ Addedflux@2.0.0(transitive)
+ Addedqs@1.2.2(transitive)
- Removedquerystring@^0.2.0
- Removedevents@1.1.1(transitive)
- Removedquerystring@0.2.1(transitive)
Updatedes6-promise@1.0.0
Updatedevents@1.0.1