diff --git a/src/Angular.js b/src/Angular.js index 2fb8f66c43f1..485acf90c07f 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -826,21 +826,38 @@ function startingTag(element) { * @returns Object.<(string|boolean)> */ function parseKeyValue(/**string*/keyValue) { - var obj = {}, key_value, key; + var obj = {}, key_value, key, value; forEach((keyValue || "").split('&'), function(keyValue){ if (keyValue) { key_value = keyValue.split('='); key = decodeURIComponent(key_value[0]); - obj[key] = isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true; + value = isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true; + if (isUndefined(obj[key])) { + obj[key] = value; + } + else if (isArray(obj[key])) { + obj[key].push(value); + } + else { + obj[key] = [obj[key], value]; + } } }); return obj; } function toKeyValue(obj) { - var parts = []; + var parts = [], key; forEach(obj, function(value, key) { - parts.push(encodeUriQuery(key, true) + (value === true ? '' : '=' + encodeUriQuery(value, true))); + key = encodeUriQuery(key, true); + if (isArray(value)) { + forEach(value, function(v) { + parts.push(key + (v === true ? '' : '=' + encodeUriQuery(v, true))); + }); + } + else { + parts.push(key + (value === true ? '' : '=' + encodeUriQuery(value, true))); + } }); return parts.length ? parts.join('&') : ''; } diff --git a/test/ng/locationSpec.js b/test/ng/locationSpec.js index 9e4b3bd641aa..127322f847eb 100644 --- a/test/ng/locationSpec.js +++ b/test/ng/locationSpec.js @@ -66,6 +66,30 @@ describe('$location', function() { }); + it('search() should accept array of params in string', function () { + url.search('x=a&x=b&z'); + + expect(url.search()).toEqual({x: ['a', 'b'], z: true}); + expect(url.absUrl()).toBe('http://www.domain.com:9877/path/b?x=a&x=b&z#hash'); + }); + + + it('search() should accept array of params in object', function () { + url.search({one: ['foo', 'bar'], two: true}); + + expect(url.search()).toEqual({one: ['foo', 'bar'], two: true}); + expect(url.absUrl()).toBe('http://www.domain.com:9877/path/b?one=foo&one=bar&two#hash'); + }); + + + it('search() should change single parameter to array of params', function() { + url.search({id: 'old', preserved: true}); + url.search('id', ['foo', 'bar']); + + expect(url.search()).toEqual({id: ['foo', 'bar'], preserved: true}); + }); + + it('hash() should change hash fragment', function() { url.hash('new-hash'); expect(url.hash()).toBe('new-hash');