diff --git a/modules/locations/HashLocation.js b/modules/locations/HashLocation.js index aa4ae25902..7f1a503391 100644 --- a/modules/locations/HashLocation.js +++ b/modules/locations/HashLocation.js @@ -4,7 +4,7 @@ var LocationActions = require('../actions/LocationActions'); var Path = require('../utils/Path'); /** - * Returns the current URL path from `window.location.hash`, including query string + * Returns the current URL path from the `hash` section of the URL, including query string */ function getHashPath() { invariant( @@ -13,7 +13,9 @@ function getHashPath() { ); return Path.decode( - window.location.hash.substr(1) + //cannot use window.location.hash because its not consistent + //across browsers - Firefox will pre-decode it + window.location.href.split('#')[1] || '' ); } diff --git a/modules/locations/__tests__/HashLocation-test.js b/modules/locations/__tests__/HashLocation-test.js new file mode 100644 index 0000000000..b425dd5aeb --- /dev/null +++ b/modules/locations/__tests__/HashLocation-test.js @@ -0,0 +1,45 @@ +var expect = require('expect'); +var HashLocation = require('../HashLocation'); + +describe('HashLocation.getCurrentPath', function() { + + //this test is needed because Firefox will pre-decode the value retrieved from + //window.location.hash + it('returns a properly decoded equivalent of what window.location.hash is set to', function() { + window.location.hash = ''; + expect(HashLocation.getCurrentPath()).toBe(''); + + window.location.hash = 'asdf'; + expect(HashLocation.getCurrentPath()).toBe('asdf'); + + window.location.hash = 'test+spaces'; + expect(HashLocation.getCurrentPath()).toBe('test spaces'); + + window.location.hash = 'first%2Fsecond'; + expect(HashLocation.getCurrentPath()).toBe('first%2Fsecond'); + + window.location.hash = 'first/second'; + expect(HashLocation.getCurrentPath()).toBe('first/second'); + + window.location.hash = 'first%252Fsecond'; + expect(HashLocation.getCurrentPath()).toBe('first%2Fsecond'); + + //decodeURI doesn't handle lone percents + window.location.hash = '%'; + expect(function() { + HashLocation.getCurrentPath(); + }).toThrow(URIError); + + window.location.hash = '%25'; + expect(HashLocation.getCurrentPath()).toBe('%'); + + window.location.hash = + 'complicated+string/full%2Fof%3Fspecial%25chars%2520and%23escapes%E1%88%B4'; + expect(HashLocation.getCurrentPath()) + .toBe('complicated string/full%2Fof%3Fspecial%chars%20and%23escapesሴ'); + }); + + afterEach(function() { + window.location.hash = ''; + }); +});