diff --git a/src/prototype/ajax/request.js b/src/prototype/ajax/request.js index b26424903..44f178e83 100644 --- a/src/prototype/ajax/request.js +++ b/src/prototype/ajax/request.js @@ -193,7 +193,7 @@ Ajax.Request = Class.create(Ajax.Base, { // when GET, append parameters to URL this.url += (this.url.include('?') ? '&' : '?') + params; } - + this.parameters = params.toQueryParams(); try { diff --git a/src/prototype/lang/hash.js b/src/prototype/lang/hash.js index d934327c0..6d8edf870 100644 --- a/src/prototype/lang/hash.js +++ b/src/prototype/lang/hash.js @@ -104,6 +104,67 @@ var Hash = Class.create(Enumerable, (function() { } } + /** + * Hash#eachKey(iterator[, context]) -> Hash + * + * Iterates over the keys in the hash. + * + * ##### Example + * + * var hash = $H({England: 'London', Poland: 'Warsaw'}); + * + * h.eachKey(function(country) { + * alert(country); + * }); + * // Alerts: England + * // Alerts: Poland + * + **/ + function eachKey(iterator, context) { + this.keys().each(iterator, context); + } + + /** + * Hash#eachValue(iterator[, context]) -> Hash + * + * Iterates over the values in the hash. + * + * ##### Example + * + * var hash = $H({England: 'London', Poland: 'Warsaw'}); + * + * h.eachValue(function(capital) { + * alert(capital); + * }); + * // Alerts: London + * // Alerts: Warsaw + **/ + function eachValue(iterator, context) { + this.values().each(iterator, context); + } + + /** + * Hash#eachPair(iterator[, context]) -> Hash + * + * Iterates over the key/value pairs in the hash. + * + * ##### Example + * + * var hash = $H({England: 'London', Poland: 'Warsaw'}); + * + * h.eachPair(function(country, capital) { + * alert(capital + "is the capital of " + country); + * }); + * //Alerts: London is the capital of England + * //Alerts: Warsaw is the capital of Poland + * + **/ + function eachPair(iterator, context) { + this.each(function(pair) { + iterator.call(context, pair.key, pair.value) + }); + } + /** * Hash#set(key, value) -> value * - key (String): The key to use for this value. @@ -261,6 +322,27 @@ var Hash = Class.create(Enumerable, (function() { return this.clone().update(object); } + /** + * Hash#mergeWith(object, func) -> Hash + * - object (Object | Hash): The object to merge with this hash to produce + * the resulting hash. + * - func (Function): The function that will be applied to the values of the + * same keys. Takes two arguments. + * + * ##### Example + * + * var hash1 = $H({a: 1, b: 2, c: 2}); + * var func = function(v1, v2) { return v1 + v2; }; + * + * var hash2 = hash.mergeWith({a: 3, b: 4, c: 5, d: 9}, func); + * // -> {a: 4, b: 6, c: 7, d: 9} + * + * + **/ + function mergeWith(object, func) { + return this.clone().updateWith(object, func); + } + /** * Hash#update(object) -> Hash * - object (Object | Hash): The object to merge with this hash to produce @@ -287,6 +369,35 @@ var Hash = Class.create(Enumerable, (function() { }); } + /** + * Hash#updateWith(object, func) -> Hash + * - object (Object | Hash): The object to merge with this hash to produce + * the resulting hash. + * - func (Function): The function that will be applied to the values of the + * same keys. Takes two arguments. + * + * ##### Example + * + * var hash = $H({a: 1, b: 2, c: 2}); + * var func = function(v1, v2) { return v1 + v2; }; + * hash.updateWith({a: 3, b: 4, c: 5, d: 9}, func); + * // -> {a: 4, b: 6, c: 7, d: 9} + * + * + **/ + function updateWith(object, func) { + if (!Object.isFunction(func)) + throw new TypeError(); + + var keys = this.keys(); + var newHash = new Hash(object).inject(this, function(result, pair) { + var value = keys.include(pair.key)? func(this.get(pair.key), pair.value) : pair.value; + result.set(pair.key, value); + return result; + }.bind(this)); + return newHash; + } + // Private. No PDoc necessary. function toQueryPair(key, value) { if (Object.isUndefined(value)) return key; @@ -388,6 +499,9 @@ var Hash = Class.create(Enumerable, (function() { return { initialize: initialize, _each: _each, + eachKey: eachKey, + eachValue: eachValue, + eachPair: eachPair, set: set, get: get, unset: unset, @@ -397,7 +511,9 @@ var Hash = Class.create(Enumerable, (function() { values: values, index: index, merge: merge, + mergeWith: mergeWith, update: update, + updateWith: updateWith, toQueryString: toQueryString, inspect: inspect, toJSON: toObject, diff --git a/test/unit/hash_test.js b/test/unit/hash_test.js index d39f07840..c3c0c1a07 100644 --- a/test/unit/hash_test.js +++ b/test/unit/hash_test.js @@ -4,7 +4,6 @@ new Test.Unit.Runner({ this.assertEqual('B', h.set('b', 'B')); this.assertHashEqual({a: 'A', b: 'B'}, h); - this.assertUndefined(h.set('c')); this.assertHashEqual({a: 'A', b: 'B', c: undefined}, h); }, @@ -102,6 +101,16 @@ new Test.Unit.Runner({ this.assertHashEqual({a:'A#', b:'B', c:'C', d:'D#' }, h.merge(Fixtures.one)); }, + testMergeWith: function() { + var h1 = $H({a: 1, b: 2, c: 2}); + var func = function(v1, v2) { return v1 + v2;}; + var h2 = h1.mergeWith({a: 3, b: 4, c: 5, d: 9}, func); + this.assertHashEqual($H({'a': 4, 'b': 6, 'c': 7, 'd': 9}), h2); + //this.assertHashEqual($H({'a': 1, 'b': 2, 'c': 2}), h1); + /*TypeError when function not defined*/ + this.assertRaise('TypeError', function(){h1.mergeWith({});}); + }, + testUpdate: function() { var h = $H(Fixtures.many); this.assertIdentical(h, h.update()); @@ -112,6 +121,15 @@ new Test.Unit.Runner({ this.assertHashEqual({a:'A', b:'B', c:'C', d:'D#', aaa:'AAA' }, h.update({aaa: 'AAA'})); this.assertHashEqual({a:'A#', b:'B', c:'C', d:'D#', aaa:'AAA' }, h.update(Fixtures.one)); }, + + testUpdateWith: function() { + var h = $H({a: 1, b: 2, c: 2}); + var func = function(v1, v2) { return v1 + v2;}; + h.updateWith({a: 3, b: 4, c: 5, d: 9}, func); + this.assertHashEqual($H({'a': 4, 'b': 6, 'c': 7, 'd': 9}), h); + /*TypeError when function not defined*/ + this.assertRaise('TypeError', function(){h.updateWith({});}); + }, testToQueryString: function() { this.assertEqual('', $H({}).toQueryString()); @@ -191,6 +209,36 @@ new Test.Unit.Runner({ result.push(i); }); this.assertEnumEqual([0,1], result); + }, + + testIterationWithEachKey: function() { + var hash = $H({a:1, b:2, c:3}); + var keys = []; + hash.eachKey(function(key) { + keys.push(key); + }); + this.assertEnumEqual(['a', 'b', 'c'], keys); + }, + + testIterationWithEachValue: function() { + var hash = $H({a:1, b:2, c:3}); + var values = []; + hash.eachValue(function(value) { + values.push(value); + }); + this.assertEnumEqual([1, 2, 3], values); + }, + + testIterationWithEachPair: function() { + var hash = $H({a:1, b:2, c:3}); + var keys = []; + var values = []; + hash.eachPair(function(key, value) { + keys.push(key); + values.push(value); + }); + this.assertEnumEqual([1, 2, 3], values); + this.assertEnumEqual(['a', 'b', 'c'], keys); } }); \ No newline at end of file