Permalink
Browse files

merging in hash fixer for FF

  • Loading branch information...
jashkenas committed Feb 27, 2012
2 parents b37a096 + 17459a3 commit 07604deac0b6e00492d62b9523c19f74e5bd7542
Showing with 23 additions and 8 deletions.
  1. +15 −8 backbone.js
  2. +8 −0 test/router.js
View
@@ -905,6 +905,14 @@
// twenty times a second.
interval: 50,
+ // Gets the true hash value. Cannot use location.hash directly due to bug
+ // in Firefox where location.hash will always be decoded.
+ getHash: function(windowOverride) {
+ var loc = windowOverride ? windowOverride.location : window.location;
+ var match = loc.href.match(/#(.*)$/);
+ return match ? match[1] : '';
+ },
+
// Get the cross-browser normalized URL fragment, either from the URL,
// the hash, or the override.
getFragment: function(fragment, forcePushState) {
@@ -914,10 +922,9 @@
var search = window.location.search;
if (search) fragment += search;
} else {
- fragment = window.location.hash;
+ fragment = this.getHash();
}
}
- fragment = decodeURIComponent(fragment);
if (!fragment.indexOf(this.options.root)) fragment = fragment.substr(this.options.root.length);
return fragment.replace(routeStripper, '');
},
@@ -970,7 +977,7 @@
// Or if we've started out with a hash-based route, but we're currently
// in a browser where it could be `pushState`-based instead...
} else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
- this.fragment = loc.hash.replace(routeStripper, '');
+ this.fragment = this.getHash().replace(routeStripper, '');
window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
}
@@ -997,10 +1004,10 @@
// calls `loadUrl`, normalizing across the hidden iframe.
checkUrl: function(e) {
var current = this.getFragment();
- if (current == this.fragment && this.iframe) current = this.getFragment(this.iframe.location.hash);
- if (current == this.fragment || current == decodeURIComponent(this.fragment)) return false;
+ if (current == this.fragment && this.iframe) current = this.getFragment(this.getHash(this.iframe));
+ if (current == this.fragment) return false;
if (this.iframe) this.navigate(current);
- this.loadUrl() || this.loadUrl(window.location.hash);
+ this.loadUrl() || this.loadUrl(this.getHash());
},
// Attempt to load the current URL fragment. If a route succeeds with a
@@ -1028,7 +1035,7 @@
if (!History.started) return false;
if (!options || options === true) options = {trigger: options};
var frag = (fragment || '').replace(routeStripper, '');
- if (this.fragment == frag || this.fragment == decodeURIComponent(frag)) return;
+ if (this.fragment == frag) return;
// If pushState is available, we use it to set the fragment as a real URL.
if (this._hasPushState) {
@@ -1041,7 +1048,7 @@
} else if (this._wantsHashChange) {
this.fragment = frag;
this._updateHash(window.location, frag, options.replace);
- if (this.iframe && (frag != this.getFragment(this.iframe.location.hash))) {
+ if (this.iframe && (frag != this.getFragment(this.getHash(this.iframe)))) {
// Opening and closing the iframe tricks IE7 and earlier to push a history entry on hash-tag change.
// When replace is true, we don't want this.
if(!options.replace) this.iframe.document.open().close();
View
@@ -255,4 +255,12 @@ $(document).ready(function() {
history.start();
});
+ test("Router: route callback gets passed non-decoded values", function() {
+ var route = 'has%2Fslash/complex-has%23hash/has%20space';
+ Backbone.history.navigate(route, {trigger: true});
+ equal(router.first, 'has%2Fslash');
+ equal(router.part, 'has%23hash');
+ equal(router.rest, 'has%20space');
+ });
+
});

0 comments on commit 07604de

Please sign in to comment.