Skip to content

Commit

Permalink
Fix redirects regression and update auth-flow example
Browse files Browse the repository at this point in the history
  • Loading branch information
mjackson committed Oct 6, 2014
1 parent bd413ff commit 4143b2c
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 75 deletions.
4 changes: 3 additions & 1 deletion examples/auth-flow/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ var Dashboard = React.createClass({
});

var Login = React.createClass({
mixins: [ Router.Navigation ],

statics: {
attemptedTransition: null
},
Expand All @@ -90,7 +92,7 @@ var Login = React.createClass({
Login.attemptedTransition = null;
transition.retry();
} else {
Router.replaceWith('/about');
this.replaceWith('/about');
}
}.bind(this));
},
Expand Down
127 changes: 107 additions & 20 deletions modules/components/Routes.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
var React = require('react');
var warning = require('react/lib/warning');
var invariant = require('react/lib/invariant');
var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM;
var copyProperties = require('react/lib/copyProperties');
var PathStore = require('../stores/PathStore');
var HashLocation = require('../locations/HashLocation');
var reversedArray = require('../utils/reversedArray');
var Transition = require('../utils/Transition');
var Redirect = require('../utils/Redirect');
Expand Down Expand Up @@ -262,36 +264,30 @@ function computeHandlerProps(matches, query) {

var BrowserTransitionHandling = {

handleTransitionError: function (error) {
handleTransitionError: function (component, error) {
throw error; // This error probably originated in a transition hook.
},

handleAbortedTransition: function (transition) {
handleAbortedTransition: function (component, transition) {
var reason = transition.abortReason;

if (reason instanceof Redirect) {
this.replaceWith(reason.to, reason.params, reason.query);
component.replaceWith(reason.to, reason.params, reason.query);
} else {
this.goBack();
component.goBack();
}
}

};

var ServerTransitionHandling = {

handleTransitionError: function (error) {
handleTransitionError: function (component, error) {
// TODO
},

handleAbortedTransition: function (transition) {
var reason = transition.abortReason;

if (reason instanceof Redirect) {
// TODO
} else {
// TODO
}
handleAbortedTransition: function (component, transition) {
// TODO
}

};
Expand Down Expand Up @@ -351,9 +347,9 @@ var Routes = React.createClass({

this.dispatch(path, function (error, transition) {
if (error) {
TransitionHandling.handleTransitionError.call(self, error);
TransitionHandling.handleTransitionError(self, error);
} else if (transition.isAborted) {
TransitionHandling.handleAbortedTransition.call(self, transition);
TransitionHandling.handleAbortedTransition(self, transition);
} else {
self.updateScroll(path, actionType);
}
Expand Down Expand Up @@ -417,6 +413,13 @@ var Routes = React.createClass({
return computeHandlerProps(this.state.matches, this.state.activeQuery);
},

/**
* Returns a reference to the active route handler's component instance.
*/
getActiveComponent: function () {
return this.refs.__activeRoute__;
},

/**
* Returns the current URL path.
*/
Expand All @@ -425,10 +428,84 @@ var Routes = React.createClass({
},

/**
* Returns a reference to the active route handler's component instance.
* Returns an absolute URL path created from the given route
* name, URL parameters, and query values.
*/
getActiveComponent: function () {
return this.refs.__activeRoute__;
makePath: function (to, params, query) {
var path;
if (Path.isAbsolute(to)) {
path = Path.normalize(to);
} else {
var namedRoutes = this.getNamedRoutes();
var route = namedRoutes[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);
},

/**
* Returns a string that may safely be used as the href of a
* link to the route with the given name.
*/
makeHref: function (to, params, query) {
var path = this.makePath(to, params, query);

if (this.getLocation() === HashLocation)
return '#' + path;

return path;
},

/**
* Transitions to the URL specified in the arguments by pushing
* a new URL onto the history stack.
*/
transitionTo: function (to, params, query) {
var location = this.getLocation();

invariant(
location,
'You cannot use transitionTo without a location'
);

location.push(this.makePath(to, params, query));
},

/**
* Transitions to the URL specified in the arguments by replacing
* the current URL in the history stack.
*/
replaceWith: function (to, params, query) {
var location = this.getLocation();

invariant(
location,
'You cannot use replaceWith without a location'
);

location.replace(this.makePath(to, params, query));
},

/**
* Transitions to the previous URL.
*/
goBack: function () {
var location = this.getLocation();

invariant(
location,
'You cannot use goBack without a location'
);

location.pop();
},

render: function () {
Expand All @@ -443,12 +520,22 @@ var Routes = React.createClass({
},

childContextTypes: {
currentPath: React.PropTypes.string
currentPath: React.PropTypes.string,
makePath: React.PropTypes.func.isRequired,
makeHref: React.PropTypes.func.isRequired,
transitionTo: React.PropTypes.func.isRequired,
replaceWith: React.PropTypes.func.isRequired,
goBack: React.PropTypes.func.isRequired
},

getChildContext: function () {
return {
currentPath: this.getCurrentPath()
currentPath: this.getCurrentPath(),
makePath: this.makePath,
makeHref: this.makeHref,
transitionTo: this.transitionTo,
replaceWith: this.replaceWith,
goBack: this.goBack
};
}

Expand Down
61 changes: 10 additions & 51 deletions modules/mixins/Navigation.js
Original file line number Diff line number Diff line change
@@ -1,96 +1,55 @@
var React = require('react');
var invariant = require('react/lib/invariant');
var HashLocation = require('../locations/HashLocation');
var Path = require('../utils/Path');

/**
* A mixin for components that modify the URL.
*/
var Navigation = {

contextTypes: {
location: React.PropTypes.object, // Not required on the server.
namedRoutes: React.PropTypes.object.isRequired
makePath: React.PropTypes.func.isRequired,
makeHref: React.PropTypes.func.isRequired,
transitionTo: React.PropTypes.func.isRequired,
replaceWith: React.PropTypes.func.isRequired,
goBack: React.PropTypes.func.isRequired
},

/**
* Returns an absolute URL path created from the given route
* name, URL parameters, and query values.
*/
makePath: function (to, params, query) {
var path;
if (Path.isAbsolute(to)) {
path = Path.normalize(to);
} else {
var route = this.context.namedRoutes[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);
return this.context.makePath(to, params, query);
},

/**
* Returns a string that may safely be used as the href of a
* link to the route with the given name.
*/
makeHref: function (to, params, query) {
var path = this.makePath(to, params, query);

if (this.context.location === HashLocation)
return '#' + path;

return path;
return this.context.makeHref(to, params, query);
},

/**
* Transitions to the URL specified in the arguments by pushing
* a new URL onto the history stack.
*/
transitionTo: function (to, params, query) {
var location = this.context.location;

invariant(
location,
'You cannot use transitionTo without a location'
);

location.push(this.makePath(to, params, query));
this.context.transitionTo(to, params, query);
},

/**
* Transitions to the URL specified in the arguments by replacing
* the current URL in the history stack.
*/
replaceWith: function (to, params, query) {
var location = this.context.location;

invariant(
location,
'You cannot use replaceWith without a location'
);

location.replace(this.makePath(to, params, query));
this.context.replaceWith(to, params, query);
},

/**
* Transitions to the previous URL.
*/
goBack: function () {
var location = this.context.location;

invariant(
location,
'You cannot use goBack without a location'
);

location.pop();
this.context.goBack();
}

};
Expand Down
6 changes: 3 additions & 3 deletions modules/utils/Transition.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ var Redirect = require('./Redirect');
* The willTransitionTo and willTransitionFrom handlers receive
* an instance of this class as their first argument.
*/
function Transition(pathDelegate, path) {
this.pathDelegate = pathDelegate;
function Transition(routesComponent, path) {
this.routesComponent = routesComponent;
this.path = path;
this.abortReason = null;
this.isAborted = false;
Expand All @@ -31,7 +31,7 @@ mixInto(Transition, {
},

retry: function () {
this.pathDelegate.replaceWith(this.path);
this.routesComponent.replaceWith(this.path);
}

});
Expand Down

0 comments on commit 4143b2c

Please sign in to comment.