Skip to content

Commit

Permalink
fixing issue #51 - allow query parameter duplication
Browse files Browse the repository at this point in the history
  • Loading branch information
rodneyrehm committed Nov 10, 2012
1 parent b43f7b8 commit 17fe1f9
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 7 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ URI.js is published under the [MIT license](http://www.opensource.org/licenses/m
* adding [`.resource()`](http://medialize.github.com/URI.js/docs.html#accessors-resource) as compound of [path, query, fragment]
* adding jQuery 1.8.x compatibility for jQuery.URI.js (remaining backwards compatibility!)
* adding default ports for gopher, ws, wss
* adding [`.duplicateQueryParameters()`](http://medialize.github.com/URI.js/docs.html#setting-duplicateQueryParameters) to control if `key=value` duplicates have to be preserved or reduced ([Issue #51](https://github.com/medialize/URI.js/issues/51)
* updating [Punycode.js](https://github.com/bestiejs/punycode.js/) to version 1.1.1
* improving AMD/Node using [UMD returnExports](https://github.com/umdjs/umd/blob/master/returnExports.js) - ([Issue #44](https://github.com/medialize/URI.js/issues/44), [Issue #47](https://github.com/medialize/URI.js/issues/47))
* fixing `.addQuery("empty")` to properly add `?empty` - ([Issue #46](https://github.com/medialize/URI.js/issues/46))
Expand All @@ -221,6 +222,7 @@ URI.js is published under the [MIT license](http://www.opensource.org/licenses/m
* adding documentation for various [encode/decode functions](http://medialize.github.com/URI.js/docs.html#encoding-decoding)
* adding tests for fragment abuse and splitting tests into separate scopes


Note: QUnit seems to be having some difficulties on IE8. While the jQuery-plugin tests fail, the plugin itself works. We're still trying to figure out what's making QUnit "lose its config state".

### 1.7.4 (October 21st 2012) ###
Expand Down
18 changes: 18 additions & 0 deletions docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,24 @@ <h3 id="static-buildQuery">URI.buildQuery(<em>object</em> data, [<em>boolean</em
URI.addQuery(data, "hello", "world");
uri.query(URI.buildQuery(data, true));</pre>

<p id="setting-duplicateQueryParameters">As of v1.8.0 you can configure query parameter de/duplication:</p>
<pre class="prettyprint lang-js">// make all new URI instances allow duplicates:
URI.duplicateQueryParameters = true; // default is false

// make a specific URI instance allow duplicates:
var withDuplicates = URI("?bar=1&amp;bar=1")
.duplicateQueryParameters(true)
.normalizeQuery()
.toString();

// make a specific URI instance avoid duplicates (default):
var noDuplicates = URI("?bar=1&amp;bar=1")
.duplicateQueryParameters(false)
.normalizeQuery()
.toString();

withDuplicates === "?bar=1&amp;bar=1";
noDuplicates === "?bar=1";</pre>

<h2 id="encoding-decoding">Encoding and Decoding URLs</h2>

Expand Down
26 changes: 19 additions & 7 deletions src/URI.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ function filterArrayValues(data, value) {
return data;
}

// state: allow duplicate query parameters (a=1&a=1)
URI.duplicateQueryParameters = false;
// static properties
URI.protocol_expression = /^[a-z][a-z0-9-+-]*$/i;
URI.idn_expression = /[^a-z0-9\.-]/i;
Expand Down Expand Up @@ -223,9 +225,11 @@ for (_part in _parts) {

URI.encodeReserved = generateAccessor("reserved", "encode");

URI.parse = function(string) {
URI.parse = function(string, parts) {
var pos, t;
var parts = {};
if (!parts) {
parts = {};
}
// [protocol"://"[username[":"password]"@"]hostname[":"port]"/"?][path]["?"querystring]["#"fragment]

// extract fragment
Expand Down Expand Up @@ -684,7 +688,9 @@ p.href = function(href, build) {
port: null,
path: null,
query: null,
fragment: null
fragment: null,
// state
duplicateQueryParameters: URI.duplicateQueryParameters
};

var _URI = href instanceof URI;
Expand All @@ -703,7 +709,7 @@ p.href = function(href, build) {
}

if (typeof href === "string") {
this._parts = URI.parse(href);
this._parts = URI.parse(href, this._parts);
} else if (_URI || _object) {
var src = _URI ? href._parts : href;
for (key in src) {
Expand Down Expand Up @@ -1226,7 +1232,7 @@ p.query = function(v, build) {
if (v === true) {
return URI.parseQuery(this._parts.query);
} else if (v !== undefined && typeof v !== "string") {
this._parts.query = URI.buildQuery(v);
this._parts.query = URI.buildQuery(v, this._parts.duplicateQueryParameters);
this.build(!build);
return this;
} else {
Expand All @@ -1236,7 +1242,7 @@ p.query = function(v, build) {
p.addQuery = function(name, value, build) {
var data = URI.parseQuery(this._parts.query);
URI.addQuery(data, name, value === undefined ? null : value);
this._parts.query = URI.buildQuery(data);
this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters);
if (typeof name !== "string") {
build = value;
}
Expand All @@ -1247,7 +1253,7 @@ p.addQuery = function(name, value, build) {
p.removeQuery = function(name, value, build) {
var data = URI.parseQuery(this._parts.query);
URI.removeQuery(data, name, value);
this._parts.query = URI.buildQuery(data);
this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters);
if (typeof name !== "string") {
build = value;
}
Expand Down Expand Up @@ -1621,5 +1627,11 @@ p.equals = function(uri) {
return true;
};

// state
p.duplicateQueryParameters = function(v) {
this._parts.duplicateQueryParameters = !!v;
return this;
};

return URI;
}));
22 changes: 22 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,28 @@ test("removeQuery", function() {
u.removeQuery({foo: 'bar', obj: undefined, bar: ["1", "2"]});
equal(u.query(), 'foo=baz&foo=bam&bar=3', 'removing object');
});
test("duplicateQueryParameters", function() {
var u = new URI('?bar=1&bar=1&bar=1');

u.normalizeQuery();
equal(u.toString(), '?bar=1', "parameters de-duplicated");

u = new URI('?bar=1&bar=1&bar=1')
u.duplicateQueryParameters(true);
u.normalizeQuery();
equal(u.toString(), '?bar=1&bar=1&bar=1', "parameters NOT de-duplicated");

u.duplicateQueryParameters(false);
u.normalizeQuery();
equal(u.toString(), '?bar=1', "parameters de-duplicated again");

URI.duplicateQueryParameters = true;
u = new URI('?bar=1&bar=1&bar=1');
u.normalizeQuery();
equal(u.toString(), '?bar=1&bar=1&bar=1', "global configuration");

URI.duplicateQueryParameters = false;
});

module("normalizing");
test("normalize", function() {
Expand Down

0 comments on commit 17fe1f9

Please sign in to comment.