4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-Object'>/**
19 </span> * @author Jacky Nguyen <jacky@sencha.com>
20 * @docauthor Jacky Nguyen <jacky@sencha.com>
23 * A collection of useful static methods to deal with objects.
30 var ExtObject = Ext.Object = {
32 <span id='Ext-Object-method-toQueryObjects'> /**
33 </span> * Converts a `name` - `value` pair to an array of objects with support for nested structures. Useful to construct
34 * query strings. For example:
36 * var objects = Ext.Object.toQueryObjects('hobbies', ['reading', 'cooking', 'swimming']);
38 * // objects then equals:
40 * { name: 'hobbies', value: 'reading' },
41 * { name: 'hobbies', value: 'cooking' },
42 * { name: 'hobbies', value: 'swimming' },
45 * var objects = Ext.Object.toQueryObjects('dateOfBirth', {
53 * }, true); // Recursive
55 * // objects then equals:
57 * { name: 'dateOfBirth[day]', value: 3 },
58 * { name: 'dateOfBirth[month]', value: 8 },
59 * { name: 'dateOfBirth[year]', value: 1987 },
60 * { name: 'dateOfBirth[extra][hour]', value: 4 },
61 * { name: 'dateOfBirth[extra][minute]', value: 30 },
64 * @param {String} name
65 * @param {Object/Array} value
66 * @param {Boolean} [recursive=false] True to traverse object recursively
69 toQueryObjects: function(name, value, recursive) {
70 var self = ExtObject.toQueryObjects,
74 if (Ext.isArray(value)) {
75 for (i = 0, ln = value.length; i < ln; i++) {
77 objects = objects.concat(self(name + '[' + i + ']', value[i], true));
87 else if (Ext.isObject(value)) {
89 if (value.hasOwnProperty(i)) {
91 objects = objects.concat(self(name + '[' + i + ']', value[i], true));
112 <span id='Ext-Object-method-toQueryString'> /**
113 </span> * Takes an object and converts it to an encoded query string.
117 * Ext.Object.toQueryString({foo: 1, bar: 2}); // returns "foo=1&bar=2"
118 * Ext.Object.toQueryString({foo: null, bar: 2}); // returns "foo=&bar=2"
119 * Ext.Object.toQueryString({'some price': '$300'}); // returns "some%20price=%24300"
120 * Ext.Object.toQueryString({date: new Date(2011, 0, 1)}); // returns "date=%222011-01-01T00%3A00%3A00%22"
121 * Ext.Object.toQueryString({colors: ['red', 'green', 'blue']}); // returns "colors=red&colors=green&colors=blue"
125 * Ext.Object.toQueryString({
132 * hobbies: ['coding', 'eating', 'sleeping', ['nested', 'stuff']]
133 * }, true); // returns the following string (broken down and url-decoded for ease of reading purpose):
135 * // &dateOfBirth[day]=1&dateOfBirth[month]=2&dateOfBirth[year]=1911
136 * // &hobbies[0]=coding&hobbies[1]=eating&hobbies[2]=sleeping&hobbies[3][0]=nested&hobbies[3][1]=stuff
138 * @param {Object} object The object to encode
139 * @param {Boolean} [recursive=false] Whether or not to interpret the object in recursive format.
140 * (PHP / Ruby on Rails servers and similar).
141 * @return {String} queryString
143 toQueryString: function(object, recursive) {
144 var paramObjects = [],
146 i, j, ln, paramObject, value;
149 if (object.hasOwnProperty(i)) {
150 paramObjects = paramObjects.concat(ExtObject.toQueryObjects(i, object[i], recursive));
154 for (j = 0, ln = paramObjects.length; j < ln; j++) {
155 paramObject = paramObjects[j];
156 value = paramObject.value;
158 if (Ext.isEmpty(value)) {
161 else if (Ext.isDate(value)) {
162 value = Ext.Date.toString(value);
165 params.push(encodeURIComponent(paramObject.name) + '=' + encodeURIComponent(String(value)));
168 return params.join('&');
171 <span id='Ext-Object-method-fromQueryString'> /**
172 </span> * Converts a query string back into an object.
176 * Ext.Object.fromQueryString(foo=1&bar=2); // returns {foo: 1, bar: 2}
177 * Ext.Object.fromQueryString(foo=&bar=2); // returns {foo: null, bar: 2}
178 * Ext.Object.fromQueryString(some%20price=%24300); // returns {'some price': '$300'}
179 * Ext.Object.fromQueryString(colors=red&colors=green&colors=blue); // returns {colors: ['red', 'green', 'blue']}
183 * Ext.Object.fromQueryString("username=Jacky&dateOfBirth[day]=1&dateOfBirth[month]=2&dateOfBirth[year]=1911&hobbies[0]=coding&hobbies[1]=eating&hobbies[2]=sleeping&hobbies[3][0]=nested&hobbies[3][1]=stuff", true);
192 * hobbies: ['coding', 'eating', 'sleeping', ['nested', 'stuff']]
195 * @param {String} queryString The query string to decode
196 * @param {Boolean} [recursive=false] Whether or not to recursively decode the string. This format is supported by
197 * PHP / Ruby on Rails servers and similar.
200 fromQueryString: function(queryString, recursive) {
201 var parts = queryString.replace(/^\?/, '').split('&'),
203 temp, components, name, value, i, ln,
204 part, j, subLn, matchedKeys, matchedName,
207 for (i = 0, ln = parts.length; i < ln; i++) {
210 if (part.length > 0) {
211 components = part.split('=');
212 name = decodeURIComponent(components[0]);
213 value = (components[1] !== undefined) ? decodeURIComponent(components[1]) : '';
216 if (object.hasOwnProperty(name)) {
217 if (!Ext.isArray(object[name])) {
218 object[name] = [object[name]];
221 object[name].push(value);
224 object[name] = value;
228 matchedKeys = name.match(/(\[):?([^\]]*)\]/g);
229 matchedName = name.match(/^([^\[]+)/);
231 //<debug error>
234 sourceClass: "Ext.Object",
235 sourceMethod: "fromQueryString",
236 queryString: queryString,
237 recursive: recursive,
238 msg: 'Malformed query string given, failed parsing name from "' + part + '"'
243 name = matchedName[0];
246 if (matchedKeys === null) {
247 object[name] = value;
251 for (j = 0, subLn = matchedKeys.length; j < subLn; j++) {
252 key = matchedKeys[j];
253 key = (key.length === 2) ? '' : key.substring(1, key.length - 1);
261 for (j = 0, subLn = keys.length; j < subLn; j++) {
264 if (j === subLn - 1) {
265 if (Ext.isArray(temp) && key === '') {
273 if (temp[key] === undefined || typeof temp[key] === 'string') {
276 temp[key] = (Ext.isNumeric(nextKey) || nextKey === '') ? [] : {};
289 <span id='Ext-Object-method-each'> /**
290 </span> * Iterates through an object and invokes the given callback function for each iteration.
291 * The iteration can be stopped by returning `false` in the callback function. For example:
296 * loves: ['food', 'sleeping', 'wife']
299 * Ext.Object.each(person, function(key, value, myself) {
300 * console.log(key + ":" + value);
302 * if (key === 'hairColor') {
303 * return false; // stop the iteration
307 * @param {Object} object The object to iterate
308 * @param {Function} fn The callback function.
309 * @param {String} fn.key
310 * @param {Object} fn.value
311 * @param {Object} fn.object The object itself
312 * @param {Object} [scope] The execution scope (`this`) of the callback function
314 each: function(object, fn, scope) {
315 for (var property in object) {
316 if (object.hasOwnProperty(property)) {
317 if (fn.call(scope || object, property, object[property], object) === false) {
324 <span id='Ext-Object-method-merge'> /**
325 </span> * Merges any number of objects recursively without referencing them or their children.
328 * companyName: 'Ext JS',
329 * products: ['Ext JS', 'Ext GWT', 'Ext Designer'],
333 * location: 'Palo Alto',
339 * companyName: 'Sencha Inc.',
340 * products: ['Ext JS', 'Ext GWT', 'Ext Designer', 'Sencha Touch', 'Sencha Animator'],
343 * location: 'Redwood City'
347 * var sencha = Ext.Object.merge(extjs, newStuff);
349 * // extjs and sencha then equals to
351 * companyName: 'Sencha Inc.',
352 * products: ['Ext JS', 'Ext GWT', 'Ext Designer', 'Sencha Touch', 'Sencha Animator'],
356 * location: 'Redwood City'
361 * @param {Object...} object Any number of objects to merge.
362 * @return {Object} merged The object that is created as a result of merging all the objects passed in.
364 merge: function(source, key, value) {
365 if (typeof key === 'string') {
366 if (value && value.constructor === Object) {
367 if (source[key] && source[key].constructor === Object) {
368 ExtObject.merge(source[key], value);
371 source[key] = Ext.clone(value);
382 ln = arguments.length,
385 for (; i < ln; i++) {
386 object = arguments[i];
388 for (property in object) {
389 if (object.hasOwnProperty(property)) {
390 ExtObject.merge(source, property, object[property]);
398 <span id='Ext-Object-method-getKey'> /**
399 </span> * Returns the first matching key corresponding to the given value.
400 * If no matching value is found, null is returned.
407 * alert(Ext.Object.getKey(person, 'food')); // alerts 'loves'
409 * @param {Object} object
410 * @param {Object} value The value to find
412 getKey: function(object, value) {
413 for (var property in object) {
414 if (object.hasOwnProperty(property) && object[property] === value) {
422 <span id='Ext-Object-method-getValues'> /**
423 </span> * Gets all values of the given object as an array.
425 * var values = Ext.Object.getValues({
428 * }); // ['Jacky', 'food']
430 * @param {Object} object
431 * @return {Array} An array of values from the object
433 getValues: function(object) {
437 for (property in object) {
438 if (object.hasOwnProperty(property)) {
439 values.push(object[property]);
446 <span id='Ext-Object-method-getKeys'> /**
447 </span> * Gets all keys of the given object as an array.
449 * var values = Ext.Object.getKeys({
452 * }); // ['name', 'loves']
454 * @param {Object} object
455 * @return {String[]} An array of keys from the object
458 getKeys: ('keys' in Object.prototype) ? Object.keys : function(object) {
462 for (property in object) {
463 if (object.hasOwnProperty(property)) {
471 <span id='Ext-Object-method-getSize'> /**
472 </span> * Gets the total number of this object's own properties
474 * var size = Ext.Object.getSize({
477 * }); // size equals 2
479 * @param {Object} object
480 * @return {Number} size
482 getSize: function(object) {
486 for (property in object) {
487 if (object.hasOwnProperty(property)) {
497 <span id='Ext-method-merge'>/**
498 </span> * A convenient alias method for {@link Ext.Object#merge}.
502 * @alias Ext.Object#merge
504 Ext.merge = Ext.Object.merge;
506 <span id='Ext-method-urlEncode'>/**
507 </span> * Alias for {@link Ext.Object#toQueryString}.
511 * @alias Ext.Object#toQueryString
512 * @deprecated 4.0.0 Use {@link Ext.Object#toQueryString} instead
514 Ext.urlEncode = function() {
515 var args = Ext.Array.from(arguments),
518 // Support for the old `pre` argument
519 if ((typeof args[1] === 'string')) {
520 prefix = args[1] + '&';
524 return prefix + Ext.Object.toQueryString.apply(Ext.Object, args);
527 <span id='Ext-method-urlDecode'>/**
528 </span> * Alias for {@link Ext.Object#fromQueryString}.
532 * @alias Ext.Object#fromQueryString
533 * @deprecated 4.0.0 Use {@link Ext.Object#fromQueryString} instead
535 Ext.urlDecode = function() {
536 return Ext.Object.fromQueryString.apply(Ext.Object, arguments);