Skip to content

Commit c2cc3f2

Browse files
author
Mark Nijhof
committed
added the notion of router hierarchy was #82
Now all routers are automatically added to a list and enabled the use of this.navigate('../other_route') which then takes the parent route to execute navigate on. Not tested but this should also enable this.navigate('../../other/route'). Works as well with [Link href=../other_route]home[/Link]
1 parent c177488 commit c2cc3f2

File tree

2 files changed

+171
-4
lines changed

2 files changed

+171
-4
lines changed

lib/RouterMixin.js

+19-3
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,25 @@ var RouterMixin = {
1717
},
1818

1919
childContextTypes: {
20-
router: React.PropTypes.any
20+
router: React.PropTypes.any,
21+
routers: React.PropTypes.any
2122
},
2223

2324
getChildContext: function() {
25+
var routers = this.context.routers || []
26+
if (routers.indexOf(this) === -1) {
27+
routers.unshift(this)
28+
}
29+
2430
return {
25-
router: this
31+
router: this,
32+
routers: routers
2633
};
2734
},
2835

2936
contextTypes: {
30-
router: React.PropTypes.any
37+
router: React.PropTypes.any,
38+
routers: React.PropTypes.any
3139
},
3240

3341
getInitialState: function() {
@@ -133,6 +141,14 @@ var RouterMixin = {
133141
* @param {Callback} cb
134142
*/
135143
navigate: function(path, navigation, cb) {
144+
var levels = path.split('../');
145+
if (levels.length > 1) {
146+
var newPath = "/" + levels[levels.length-1];
147+
var gotoContext = levels.length-1;
148+
this.context.routers[gotoContext].navigate(newPath, navigation, cb);
149+
return;
150+
}
151+
136152
path = join(this.state.prefix, path);
137153
this.getEnvironment().setPath(path, navigation, cb);
138154
},

tests/browser.js

+152-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ describe('Routing with async components', function() {
345345
});
346346

347347
beforeEach(function() {
348-
mainWasInLoadingState = false;
348+
mainWasInLoadingState = false;
349349
aboutWasInLoadingState = false;
350350

351351
mainSeenPendingUpdate = false;
@@ -553,6 +553,33 @@ describe('Contextual routers', function() {
553553

554554
if (!historyAPI) return;
555555

556+
var SubSubCat = React.createClass({
557+
558+
render: function() {
559+
return div(null,
560+
Router.Locations({ref: 'router', contextual: true},
561+
Router.Location({
562+
path: '/',
563+
handler: function(props) { return div(null, 'subcat/subsubcat/root') }
564+
}),
565+
Router.Location({
566+
path: '/back_to_parent',
567+
ref: 'link',
568+
handler: function(props) {
569+
return Router.Link({href: '../'}, 'subcat/subsubcat/back_to_parent')
570+
}
571+
}),
572+
Router.Location({
573+
path: '/back_to_root',
574+
ref: 'link',
575+
handler: function(props) {
576+
return Router.Link({href: '../../__zuul'}, 'subcat/subsubcat/back_to_root')
577+
}
578+
})
579+
));
580+
}
581+
});
582+
556583
var SubCat = React.createClass({
557584

558585
render: function() {
@@ -575,6 +602,18 @@ describe('Contextual routers', function() {
575602
handler: function(props) {
576603
return Router.Link({global: true, href: '/__zuul'}, 'subcat/escape')
577604
}
605+
}),
606+
Router.Location({
607+
path: '/back_to_parent',
608+
ref: 'link',
609+
handler: function(props) {
610+
return Router.Link({href: '../__zuul'}, 'subcat/back_to_parent')
611+
}
612+
}),
613+
Router.Location({
614+
path: '/subsubcat/*',
615+
handler: SubSubCat,
616+
ref: 'subsubcat'
578617
})
579618
));
580619
}
@@ -652,6 +691,42 @@ describe('Contextual routers', function() {
652691
});
653692
});
654693
});
694+
695+
it('does navigate to root context from nested', function(done) {
696+
assertRendered('mainpage');
697+
router.navigate('/__zuul/subcat/back_to_parent', function() {
698+
assertRendered('subcat/back_to_parent');
699+
clickOn(router.refs.subcat.refs.router.refs.link);
700+
delay(function() {
701+
assertRendered('mainpage');
702+
done();
703+
});
704+
});
705+
});
706+
707+
it('does navigate to nested context from double nested', function(done) {
708+
assertRendered('mainpage');
709+
router.navigate('/__zuul/subcat/subsubcat/back_to_parent', function() {
710+
assertRendered('subcat/subsubcat/back_to_parent');
711+
clickOn(router.refs.subcat.refs.router.refs.subsubcat.refs.router.refs.link);
712+
delay(function() {
713+
assertRendered('subcat/root');
714+
done();
715+
});
716+
});
717+
});
718+
719+
it('does navigate to root context from double nested', function(done) {
720+
assertRendered('mainpage');
721+
router.navigate('/__zuul/subcat/subsubcat/back_to_root', function() {
722+
assertRendered('subcat/subsubcat/back_to_root');
723+
clickOn(router.refs.subcat.refs.router.refs.subsubcat.refs.router.refs.link);
724+
delay(function() {
725+
assertRendered('mainpage');
726+
done();
727+
});
728+
});
729+
});
655730
});
656731

657732
describe('Multiple active routers', function() {
@@ -833,6 +908,33 @@ describe('Hash routing', function() {
833908

834909
describe('Contextual Hash routers', function() {
835910

911+
var SubSubCat = React.createClass({
912+
913+
render: function() {
914+
return div(null,
915+
Router.Locations({ref: 'router', contextual: true},
916+
Router.Location({
917+
path: '/',
918+
handler: function(props) { return div(null, 'subcat/subsubcat/root') }
919+
}),
920+
Router.Location({
921+
path: '/back_to_parent',
922+
ref: 'link',
923+
handler: function(props) {
924+
return Router.Link({href: '../'}, 'subcat/subsubcat/back_to_parent')
925+
}
926+
}),
927+
Router.Location({
928+
path: '/back_to_root',
929+
ref: 'link',
930+
handler: function(props) {
931+
return Router.Link({href: '../../'}, 'subcat/subsubcat/back_to_root')
932+
}
933+
})
934+
));
935+
}
936+
});
937+
836938
var SubCat = React.createClass({
837939

838940
render: function() {
@@ -848,6 +950,18 @@ describe('Contextual Hash routers', function() {
848950
handler: function(props) {
849951
return Router.Link({globalHash: true, href: '/'}, 'subcat/escape');
850952
}
953+
}),
954+
Router.Location({
955+
path: '/back_to_parent',
956+
ref: 'link',
957+
handler: function(props) {
958+
return Router.Link({href: '../'}, 'subcat/back_to_parent')
959+
}
960+
}),
961+
Router.Location({
962+
path: '/subsubcat/*',
963+
handler: SubSubCat,
964+
ref: 'subsubcat'
851965
})
852966
));
853967
}
@@ -889,6 +1003,43 @@ describe('Contextual Hash routers', function() {
8891003
});
8901004
});
8911005

1006+
1007+
it('does navigate to root context from nested', function(done) {
1008+
assertRendered('mainpage');
1009+
router.navigate('/subcat/back_to_parent', function() {
1010+
assertRendered('subcat/back_to_parent');
1011+
clickOn(router.refs.subcat.refs.router.refs.link);
1012+
delay(function() {
1013+
assertRendered('mainpage');
1014+
done();
1015+
});
1016+
});
1017+
});
1018+
1019+
it('does navigate to nested context from double nested', function(done) {
1020+
assertRendered('mainpage');
1021+
router.navigate('/subcat/subsubcat/back_to_parent', function() {
1022+
assertRendered('subcat/subsubcat/back_to_parent');
1023+
clickOn(router.refs.subcat.refs.router.refs.subsubcat.refs.router.refs.link);
1024+
delay(function() {
1025+
assertRendered('subcat/root');
1026+
done();
1027+
});
1028+
});
1029+
});
1030+
1031+
it('does navigate to root context from double nested', function(done) {
1032+
assertRendered('mainpage');
1033+
router.navigate('/subcat/subsubcat/back_to_root', function() {
1034+
assertRendered('subcat/subsubcat/back_to_root');
1035+
clickOn(router.refs.subcat.refs.router.refs.subsubcat.refs.router.refs.link);
1036+
delay(function() {
1037+
assertRendered('mainpage');
1038+
done();
1039+
});
1040+
});
1041+
});
1042+
8921043
});
8931044

8941045
});

0 commit comments

Comments
 (0)