From c1e70a28aabbbf2bcd2dc79dcef388a082ba5f1e Mon Sep 17 00:00:00 2001 From: Brad Dunbar Date: Tue, 28 Apr 2015 06:34:28 -0400 Subject: [PATCH] If the root doesn't match, no routes can match. --- backbone.js | 14 +++++++++++--- test/router.js | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/backbone.js b/backbone.js index 745d5cb35..6c7662bf4 100644 --- a/backbone.js +++ b/backbone.js @@ -1527,6 +1527,11 @@ return path === this.root && !this.getSearch(); }, + // Does the pathname match the root? + matchRoot: function() { + return this.rootMatcher.test(this.location.pathname); + }, + // Unicode characters in `location.pathname` are percent encoded so they're // decoded for comparison. `%25` should not be decoded since it may be part // of an encoded parameter. @@ -1552,9 +1557,7 @@ getPath: function() { var path = this.decodeFragment( this.location.pathname + this.getSearch() - ); - var root = this.root.slice(0, -1); - if (!path.indexOf(root)) path = path.slice(root.length); + ).slice(this.root.length - 1); return path.charAt(0) === '/' ? path.slice(1) : path; }, @@ -1591,6 +1594,9 @@ // Normalize root to always include a leading and trailing slash. this.root = ('/' + this.root + '/').replace(rootStripper, '/'); + // A regular expression for testing the pathname against the root. + this.rootMatcher = new RegExp('^' + this.root.slice(0, -1) + '(/|$)'); + // Transition from hashChange to pushState or vice versa if both are // requested. if (this._wantsHashChange && this._wantsPushState) { @@ -1696,6 +1702,8 @@ // match, returns `true`. If no defined routes matches the fragment, // returns `false`. loadUrl: function(fragment) { + // If the root doesn't match, no routes can match either. + if (!this.matchRoot()) return false; fragment = this.fragment = this.getFragment(fragment); return _.any(this.handlers, function(handler) { if (handler.route.test(fragment)) { diff --git a/test/router.js b/test/router.js index 4f8341529..045d9b591 100644 --- a/test/router.js +++ b/test/router.js @@ -932,4 +932,28 @@ Backbone.history.start({root: '/root', pushState: true}); }); + test("Paths that don't match the root should not match", 0, function() { + location.replace('http://example.com/foo'); + Backbone.history.stop(); + Backbone.history = _.extend(new Backbone.History, {location: location}); + var Router = Backbone.Router.extend({ + routes: {'foo': 'foo'}, + foo: function(){ ok(false, 'should not match unless root matches'); } + }); + var router = new Router; + Backbone.history.start({root: 'root', pushState: true}); + }); + + test("Paths that don't match the root should not match", 0, function() { + location.replace('http://example.com/xxxx/foo'); + Backbone.history.stop(); + Backbone.history = _.extend(new Backbone.History, {location: location}); + var Router = Backbone.Router.extend({ + routes: {'foo': 'foo'}, + foo: function(){ ok(false, 'should not match unless root matches'); } + }); + var router = new Router; + Backbone.history.start({root: 'root', pushState: true}); + }); + })();