Skip to content

Commit

Permalink
[state/unhashUrl] use encode-uri-query to generate cleanly encoded urls
Browse files Browse the repository at this point in the history
By default, the url.format function stringifies the query object and encodes each parameter with `encodeURIComponent()`. This is effective, but does not match the native browser behavior, which is to only encode the non-`pchar` characters as defined by [rfc3986][1]. Because of this, angular's `$location.search()` function uses a function internally called `encodeUriQuery()` to mimic the browser behavior before updating `location.href`.

To bring the same funtionality to the `unhashUrl()` function, the `encodeUriQuery()` was extracted into it's own package and used as the escape handler for `querystring.stringify()`

[1]: https://www.ietf.org/rfc/rfc3986.txt
  • Loading branch information
spalger committed Sep 9, 2016
1 parent fbaf4bf commit d9dac3f
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
"dragula": "3.7.0",
"elasticsearch": "12.0.0-rc5",
"elasticsearch-browser": "12.0.0-rc5",
"encode-uri-query": "1.0.0",
"even-better": "7.0.2",
"expiry-js": "0.1.7",
"exports-loader": "0.6.2",
Expand Down
15 changes: 14 additions & 1 deletion src/ui/public/state_management/state_hashing/unhash_url.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import {
format as formatUrl,
} from 'url';

import encodeUriQuery from 'encode-uri-query';

import {
stringify as stringifyQueryString
} from 'querystring';

import unhashQueryString from './unhash_query_string';

export default function unhashUrl(urlWithHashes, states) {
Expand All @@ -26,11 +32,18 @@ export default function unhashUrl(urlWithHashes, states) {
if (!appUrlParsed.query) return urlWithHashes;

const appQueryWithoutHashes = unhashQueryString(appUrlParsed.query || {}, states);

// encodeUriQuery implements the less-aggressive encoding done naturally by
// the browser. We use it to generate the same urls the browser would
const appQueryStringWithoutHashes = stringifyQueryString(appQueryWithoutHashes, null, null, {
encodeURIComponent: encodeUriQuery
});

return formatUrl({
...urlWithHashesParsed,
hash: formatUrl({
pathname: appUrlParsed.pathname,
query: appQueryWithoutHashes,
search: appQueryStringWithoutHashes,
})
});
}

0 comments on commit d9dac3f

Please sign in to comment.