Skip to content

Commit

Permalink
merging in hash fixer for FF
Browse files Browse the repository at this point in the history
  • Loading branch information
jashkenas committed Feb 27, 2012
2 parents b37a096 + 17459a3 commit 07604de
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
23 changes: 15 additions & 8 deletions backbone.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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, '');
},
Expand Down Expand Up @@ -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);
}

Expand All @@ -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
Expand Down Expand Up @@ -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) {
Expand All @@ -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();
Expand Down
8 changes: 8 additions & 0 deletions test/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.