Permalink
Browse files

Cherry picking route changes from donejs branch

  • Loading branch information...
ccummings
ccummings committed May 1, 2012
1 parent 5277f6f commit b0e59d287caba8fcb98871e4814b924588aef138
Showing with 115 additions and 6 deletions.
  1. +28 −5 route/route.js
  2. +87 −1 route/route_test.js
View
@@ -27,13 +27,25 @@ steal('can/observe', 'can/util/string/deparam', function() {
// variables are present in the data, the number of matches is returned
// to allow discerning between general and more specific routes.
matchesData = function(route, data) {
- var count = 0, i = 0;
+ var count = 0, i = 0, defaults = {};
+ // look at default values, if they match ...
+ for( var name in route.defaults ) {
+ if(route.defaults[name] === data[name]){
+ // mark as matched
+ defaults[name] = 1;
+ count++;
+ }
+ }
for (; i < route.names.length; i++ ) {
if (!data.hasOwnProperty(route.names[i]) ) {
return -1;
}
- count++;
+ if(!defaults[route.names[i]]){
+ count++;
+ }
+
}
+
return count;
},
onready = !0,
@@ -102,17 +114,26 @@ steal('can/observe', 'can/util/string/deparam', function() {
// Need to have at least 1 match.
matches = 0,
matchCount,
- routeName = data.route;
+ routeName = data.route,
+ propCount = 0;
+
delete data.route;
// If we have a route name in our `can.route` data, use it.
if ( ! ( routeName && (route = can.route.routes[routeName]))){
+ each(data, function(){propCount++});
// Otherwise find route.
each(can.route.routes, function(temp, name){
+ // best route is the first with all defaults matching
+
+
matchCount = matchesData(temp, data);
if ( matchCount > matches ) {
route = temp;
matches = matchCount
}
+ if(matchCount >= propCount){
+ return false;
+ }
});
}
@@ -394,9 +415,11 @@ steal('can/observe', 'can/util/string/deparam', function() {
can.route.bind("change", function() {
clearTimeout( timer );
timer = setTimeout(function() {
- location.hash = "#!" + can.route.param(can.route.data.serialize())
+ var serialized = can.route.data.serialize();
+ delete serialized.route;
+ location.hash = "#!" + can.route.param(serialized)
}, 1);
});
// `onready` event...
can.bind.call(document,"ready",can.route.ready);
-});
+});
View
@@ -195,6 +195,16 @@ test("param-deparam", function(){
same(data, obj)
})
+test("deparam-param", function(){
+ can.route.routes = {};
+ can.route(":foo/:bar",{foo: 1, bar: 2});
+ var res = can.route.param({foo: 1, bar: 2});
+ equals(res,"/","empty slash")
+
+ var deparamed = can.route.deparam("/")
+ same(deparamed, {foo: 1, bar: 2, route: ":foo/:bar"})
+})
+
test("precident", function(){
can.route.routes = {};
can.route(":who",{who: "index"});
@@ -223,7 +233,7 @@ test("precident", function(){
"can.Control" );
})
-test("precident2", function(){
+test("better matching precident", function(){
can.route.routes = {};
can.route(":type",{who: "index"});
can.route(":type/:id");
@@ -282,13 +292,45 @@ test("updating the hash", function(){
equal(after,"#!bar/"+encodeURIComponent("\/"));
start();
+ can.remove(can.$(iframe))
+
},30);
}
var iframe = document.createElement('iframe');
iframe.src = steal.root.join("can/route/testing.html");
can.$("#qunit-test-area")[0].appendChild(iframe);
});
+test("unsticky routes", function(){
+ stop();
+ window.routeTestReady = function(iCanRoute, loc){
+ iCanRoute(":type")
+ iCanRoute(":type/:id");
+ iCanRoute.attr({type: "bar"});
+
+ setTimeout(function(){
+
+ iCanRoute.attr({type: "bar", id: "\/"});
+
+ setTimeout(function(){
+ var after = loc.href.substr(loc.href.indexOf("#"));
+ equal(after,"#!bar/"+encodeURIComponent("\/"));
+ start();
+
+ can.remove(can.$(iframe))
+
+ },30);
+
+ },30)
+
+
+ }
+ var iframe = document.createElement('iframe');
+ iframe.src = steal.root.join("can/route/testing.html");
+ can.$("#qunit-test-area")[0].appendChild(iframe);
+});
+
+
test("empty default is matched even if last", function(){
can.route.routes = {};
@@ -301,3 +343,47 @@ test("empty default is matched even if last", function(){
route: ""
});
});
+
+
+test("order matched", function(){
+ can.route.routes = {};
+ can.route(":foo");
+ can.route(":bar")
+
+ var obj = can.route.deparam("abc");
+ same(obj, {
+ foo : "abc",
+ route: ":foo"
+ });
+});
+
+test("param order matching", function(){
+ can.route.routes = {};
+ can.route("",{
+ bar: "foo"
+ });
+ can.route("something/:bar");
+ var res = can.route.param({bar: "foo"});
+ equal(res, "", "picks the shortest, best match");
+
+ // picks the first that matches everything ...
+ can.route.routes = {};
+
+ can.route(":recipe",{
+ recipe: "recipe1",
+ task: "task3"
+ });
+
+ can.route(":recipe/:task",{
+ recipe: "recipe1",
+ task: "task3"
+ });
+
+ res = can.route.param({recipe: "recipe1", task: "task3"});
+
+ equals(res, "", "picks the first match of everything");
+
+ res = can.route.param({recipe: "recipe1", task: "task2"});
+ equals(res,"/task2")
+})
+

0 comments on commit b0e59d2

Please sign in to comment.