From 27e9e4743c716433af4b1d75fcaddaba535b5295 Mon Sep 17 00:00:00 2001 From: Brad Dunbar Date: Thu, 14 Jun 2012 23:59:22 -0400 Subject: [PATCH] Fix #1387 - getFragment trims trailing slash before removing root. * The root should not be stripped when dealing with hashes. * The trailing slash can be removed since the fragment is stripped anyway. This could probably be done only once in `start`, but is saved for a later patch. * The mock pathname needs to prepend a slash in IE since anchor.pathname does not contain it. --- backbone.js | 6 +++++- test/router.js | 27 ++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/backbone.js b/backbone.js index afabb313..0b75e1a7 100644 --- a/backbone.js +++ b/backbone.js @@ -966,6 +966,9 @@ // Cached regex for detecting MSIE. var isExplorer = /msie [\w.]+/; + // Cached regex for removing a trailing slash. + var trailingSlash = /\/$/; + // Has the history handling already been started? History.started = false; @@ -989,11 +992,12 @@ if (fragment == null) { if (this._hasPushState || !this._wantsHashChange || forcePushState) { fragment = this.location.pathname; + var root = this.options.root.replace(trailingSlash, ''); + if (!fragment.indexOf(root)) fragment = fragment.substr(root.length); } else { fragment = this.getHash(); } } - if (!fragment.indexOf(this.options.root)) fragment = fragment.substr(this.options.root.length); return fragment.replace(routeStripper, ''); }, diff --git a/test/router.js b/test/router.js index d366243a..71b5bbe7 100644 --- a/test/router.js +++ b/test/router.js @@ -24,6 +24,9 @@ $(document).ready(function() { 'fragment', 'pathname' )); + // In IE, anchor.pathname does not contain a leading slash though + // window.location.pathname does. + if (!/^\//.test(this.pathname)) this.pathname = '/' + this.pathname; }, toString: function() { @@ -225,11 +228,17 @@ $(document).ready(function() { }); test("#933, #908 - leading slash", 2, function() { - var history = new Backbone.History(); - history.options = {root: '/root'}; - equal(history.getFragment('/root/foo'), 'foo'); - history.options.root = '/root/'; - equal(history.getFragment('/root/foo'), 'foo'); + location.replace('http://example.com/root/foo'); + + Backbone.history.stop(); + Backbone.history = new Backbone.History({location: location}); + Backbone.history.start({root: '/root', hashChange: false, silent: true}); + strictEqual(Backbone.history.getFragment(), 'foo'); + + Backbone.history.stop(); + Backbone.history = new Backbone.History({location: location}); + Backbone.history.start({root: '/root/', hashChange: false, silent: true}); + strictEqual(Backbone.history.getFragment(), 'foo'); }); test("#1003 - History is started before navigate is called", 1, function() { @@ -281,4 +290,12 @@ $(document).ready(function() { Backbone.history.navigate('/fragment'); }); + test("#1387 - Root fragment without trailing slash.", 1, function() { + Backbone.history.stop(); + location.replace('http://example.com/root'); + Backbone.history = new Backbone.History({location: location}); + Backbone.history.start({hashChange: false, root: '/root/', silent: true}); + strictEqual(Backbone.history.getFragment(), ''); + }); + });