| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627 | 
							- <!DOCTYPE html>
 
- <html>
 
- <head>
 
-   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
-   <title>The source code</title>
 
-   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
 
-   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
 
-   <style type="text/css">
 
-     .highlight { display: block; background-color: #ddd; }
 
-   </style>
 
-   <script type="text/javascript">
 
-     function highlight() {
 
-       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
 
-     }
 
-   </script>
 
- </head>
 
- <body onload="prettyPrint(); highlight();">
 
-   <pre class="prettyprint lang-js"><span id='Ext-Object'>/**
 
- </span> * @author Jacky Nguyen <jacky@sencha.com>
 
-  * @docauthor Jacky Nguyen <jacky@sencha.com>
 
-  * @class Ext.Object
 
-  *
 
-  * A collection of useful static methods to deal with objects.
 
-  *
 
-  * @singleton
 
-  */
 
- (function() {
 
- // The "constructor" for chain:
 
- var TemplateClass = function(){},
 
-     ExtObject = Ext.Object = {
 
- <span id='Ext-Object-method-chain'>    /**
 
- </span>     * Returns a new object with the given object as the prototype chain.
 
-      * @param {Object} object The prototype chain for the new object.
 
-      */
 
-     chain: function (object) {
 
-         TemplateClass.prototype = object;
 
-         var result = new TemplateClass();
 
-         TemplateClass.prototype = null;
 
-         return result;
 
-     },
 
- <span id='Ext-Object-method-toQueryObjects'>    /**
 
- </span>     * Converts a `name` - `value` pair to an array of objects with support for nested structures. Useful to construct
 
-      * query strings. For example:
 
-      *
 
-      *     var objects = Ext.Object.toQueryObjects('hobbies', ['reading', 'cooking', 'swimming']);
 
-      *
 
-      *     // objects then equals:
 
-      *     [
 
-      *         { name: 'hobbies', value: 'reading' },
 
-      *         { name: 'hobbies', value: 'cooking' },
 
-      *         { name: 'hobbies', value: 'swimming' },
 
-      *     ];
 
-      *
 
-      *     var objects = Ext.Object.toQueryObjects('dateOfBirth', {
 
-      *         day: 3,
 
-      *         month: 8,
 
-      *         year: 1987,
 
-      *         extra: {
 
-      *             hour: 4
 
-      *             minute: 30
 
-      *         }
 
-      *     }, true); // Recursive
 
-      *
 
-      *     // objects then equals:
 
-      *     [
 
-      *         { name: 'dateOfBirth[day]', value: 3 },
 
-      *         { name: 'dateOfBirth[month]', value: 8 },
 
-      *         { name: 'dateOfBirth[year]', value: 1987 },
 
-      *         { name: 'dateOfBirth[extra][hour]', value: 4 },
 
-      *         { name: 'dateOfBirth[extra][minute]', value: 30 },
 
-      *     ];
 
-      *
 
-      * @param {String} name
 
-      * @param {Object/Array} value
 
-      * @param {Boolean} [recursive=false] True to traverse object recursively
 
-      * @return {Array}
 
-      */
 
-     toQueryObjects: function(name, value, recursive) {
 
-         var self = ExtObject.toQueryObjects,
 
-             objects = [],
 
-             i, ln;
 
-         if (Ext.isArray(value)) {
 
-             for (i = 0, ln = value.length; i < ln; i++) {
 
-                 if (recursive) {
 
-                     objects = objects.concat(self(name + '[' + i + ']', value[i], true));
 
-                 }
 
-                 else {
 
-                     objects.push({
 
-                         name: name,
 
-                         value: value[i]
 
-                     });
 
-                 }
 
-             }
 
-         }
 
-         else if (Ext.isObject(value)) {
 
-             for (i in value) {
 
-                 if (value.hasOwnProperty(i)) {
 
-                     if (recursive) {
 
-                         objects = objects.concat(self(name + '[' + i + ']', value[i], true));
 
-                     }
 
-                     else {
 
-                         objects.push({
 
-                             name: name,
 
-                             value: value[i]
 
-                         });
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         else {
 
-             objects.push({
 
-                 name: name,
 
-                 value: value
 
-             });
 
-         }
 
-         return objects;
 
-     },
 
- <span id='Ext-Object-method-toQueryString'>    /**
 
- </span>     * Takes an object and converts it to an encoded query string.
 
-      *
 
-      * Non-recursive:
 
-      *
 
-      *     Ext.Object.toQueryString({foo: 1, bar: 2}); // returns "foo=1&bar=2"
 
-      *     Ext.Object.toQueryString({foo: null, bar: 2}); // returns "foo=&bar=2"
 
-      *     Ext.Object.toQueryString({'some price': '$300'}); // returns "some%20price=%24300"
 
-      *     Ext.Object.toQueryString({date: new Date(2011, 0, 1)}); // returns "date=%222011-01-01T00%3A00%3A00%22"
 
-      *     Ext.Object.toQueryString({colors: ['red', 'green', 'blue']}); // returns "colors=red&colors=green&colors=blue"
 
-      *
 
-      * Recursive:
 
-      *
 
-      *     Ext.Object.toQueryString({
 
-      *         username: 'Jacky',
 
-      *         dateOfBirth: {
 
-      *             day: 1,
 
-      *             month: 2,
 
-      *             year: 1911
 
-      *         },
 
-      *         hobbies: ['coding', 'eating', 'sleeping', ['nested', 'stuff']]
 
-      *     }, true); // returns the following string (broken down and url-decoded for ease of reading purpose):
 
-      *     // 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
 
-      *
 
-      * @param {Object} object The object to encode
 
-      * @param {Boolean} [recursive=false] Whether or not to interpret the object in recursive format.
 
-      * (PHP / Ruby on Rails servers and similar).
 
-      * @return {String} queryString
 
-      */
 
-     toQueryString: function(object, recursive) {
 
-         var paramObjects = [],
 
-             params = [],
 
-             i, j, ln, paramObject, value;
 
-         for (i in object) {
 
-             if (object.hasOwnProperty(i)) {
 
-                 paramObjects = paramObjects.concat(ExtObject.toQueryObjects(i, object[i], recursive));
 
-             }
 
-         }
 
-         for (j = 0, ln = paramObjects.length; j < ln; j++) {
 
-             paramObject = paramObjects[j];
 
-             value = paramObject.value;
 
-             if (Ext.isEmpty(value)) {
 
-                 value = '';
 
-             }
 
-             else if (Ext.isDate(value)) {
 
-                 value = Ext.Date.toString(value);
 
-             }
 
-             params.push(encodeURIComponent(paramObject.name) + '=' + encodeURIComponent(String(value)));
 
-         }
 
-         return params.join('&');
 
-     },
 
- <span id='Ext-Object-method-fromQueryString'>    /**
 
- </span>     * Converts a query string back into an object.
 
-      *
 
-      * Non-recursive:
 
-      *
 
-      *     Ext.Object.fromQueryString("foo=1&bar=2"); // returns {foo: 1, bar: 2}
 
-      *     Ext.Object.fromQueryString("foo=&bar=2"); // returns {foo: null, bar: 2}
 
-      *     Ext.Object.fromQueryString("some%20price=%24300"); // returns {'some price': '$300'}
 
-      *     Ext.Object.fromQueryString("colors=red&colors=green&colors=blue"); // returns {colors: ['red', 'green', 'blue']}
 
-      *
 
-      * Recursive:
 
-      *
 
-      *     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);
 
-      *
 
-      *     // returns
 
-      *     {
 
-      *         username: 'Jacky',
 
-      *         dateOfBirth: {
 
-      *             day: '1',
 
-      *             month: '2',
 
-      *             year: '1911'
 
-      *         },
 
-      *         hobbies: ['coding', 'eating', 'sleeping', ['nested', 'stuff']]
 
-      *     }
 
-      *
 
-      * @param {String} queryString The query string to decode
 
-      * @param {Boolean} [recursive=false] Whether or not to recursively decode the string. This format is supported by
 
-      * PHP / Ruby on Rails servers and similar.
 
-      * @return {Object}
 
-      */
 
-     fromQueryString: function(queryString, recursive) {
 
-         var parts = queryString.replace(/^\?/, '').split('&'),
 
-             object = {},
 
-             temp, components, name, value, i, ln,
 
-             part, j, subLn, matchedKeys, matchedName,
 
-             keys, key, nextKey;
 
-         for (i = 0, ln = parts.length; i < ln; i++) {
 
-             part = parts[i];
 
-             if (part.length > 0) {
 
-                 components = part.split('=');
 
-                 name = decodeURIComponent(components[0]);
 
-                 value = (components[1] !== undefined) ? decodeURIComponent(components[1]) : '';
 
-                 if (!recursive) {
 
-                     if (object.hasOwnProperty(name)) {
 
-                         if (!Ext.isArray(object[name])) {
 
-                             object[name] = [object[name]];
 
-                         }
 
-                         object[name].push(value);
 
-                     }
 
-                     else {
 
-                         object[name] = value;
 
-                     }
 
-                 }
 
-                 else {
 
-                     matchedKeys = name.match(/(\[):?([^\]]*)\]/g);
 
-                     matchedName = name.match(/^([^\[]+)/);
 
-                     //<debug error>
 
-                     if (!matchedName) {
 
-                         throw new Error('[Ext.Object.fromQueryString] Malformed query string given, failed parsing name from "' + part + '"');
 
-                     }
 
-                     //</debug>
 
-                     name = matchedName[0];
 
-                     keys = [];
 
-                     if (matchedKeys === null) {
 
-                         object[name] = value;
 
-                         continue;
 
-                     }
 
-                     for (j = 0, subLn = matchedKeys.length; j < subLn; j++) {
 
-                         key = matchedKeys[j];
 
-                         key = (key.length === 2) ? '' : key.substring(1, key.length - 1);
 
-                         keys.push(key);
 
-                     }
 
-                     keys.unshift(name);
 
-                     temp = object;
 
-                     for (j = 0, subLn = keys.length; j < subLn; j++) {
 
-                         key = keys[j];
 
-                         if (j === subLn - 1) {
 
-                             if (Ext.isArray(temp) && key === '') {
 
-                                 temp.push(value);
 
-                             }
 
-                             else {
 
-                                 temp[key] = value;
 
-                             }
 
-                         }
 
-                         else {
 
-                             if (temp[key] === undefined || typeof temp[key] === 'string') {
 
-                                 nextKey = keys[j+1];
 
-                                 temp[key] = (Ext.isNumeric(nextKey) || nextKey === '') ? [] : {};
 
-                             }
 
-                             temp = temp[key];
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         return object;
 
-     },
 
- <span id='Ext-Object-method-each'>    /**
 
- </span>     * Iterates through an object and invokes the given callback function for each iteration.
 
-      * The iteration can be stopped by returning `false` in the callback function. For example:
 
-      *
 
-      *     var person = {
 
-      *         name: 'Jacky'
 
-      *         hairColor: 'black'
 
-      *         loves: ['food', 'sleeping', 'wife']
 
-      *     };
 
-      *
 
-      *     Ext.Object.each(person, function(key, value, myself) {
 
-      *         console.log(key + ":" + value);
 
-      *
 
-      *         if (key === 'hairColor') {
 
-      *             return false; // stop the iteration
 
-      *         }
 
-      *     });
 
-      *
 
-      * @param {Object} object The object to iterate
 
-      * @param {Function} fn The callback function.
 
-      * @param {String} fn.key
 
-      * @param {Object} fn.value
 
-      * @param {Object} fn.object The object itself
 
-      * @param {Object} [scope] The execution scope (`this`) of the callback function
 
-      */
 
-     each: function(object, fn, scope) {
 
-         for (var property in object) {
 
-             if (object.hasOwnProperty(property)) {
 
-                 if (fn.call(scope || object, property, object[property], object) === false) {
 
-                     return;
 
-                 }
 
-             }
 
-         }
 
-     },
 
- <span id='Ext-Object-method-merge'>    /**
 
- </span>     * Merges any number of objects recursively without referencing them or their children.
 
-      *
 
-      *     var extjs = {
 
-      *         companyName: 'Ext JS',
 
-      *         products: ['Ext JS', 'Ext GWT', 'Ext Designer'],
 
-      *         isSuperCool: true,
 
-      *         office: {
 
-      *             size: 2000,
 
-      *             location: 'Palo Alto',
 
-      *             isFun: true
 
-      *         }
 
-      *     };
 
-      *
 
-      *     var newStuff = {
 
-      *         companyName: 'Sencha Inc.',
 
-      *         products: ['Ext JS', 'Ext GWT', 'Ext Designer', 'Sencha Touch', 'Sencha Animator'],
 
-      *         office: {
 
-      *             size: 40000,
 
-      *             location: 'Redwood City'
 
-      *         }
 
-      *     };
 
-      *
 
-      *     var sencha = Ext.Object.merge(extjs, newStuff);
 
-      *
 
-      *     // extjs and sencha then equals to
 
-      *     {
 
-      *         companyName: 'Sencha Inc.',
 
-      *         products: ['Ext JS', 'Ext GWT', 'Ext Designer', 'Sencha Touch', 'Sencha Animator'],
 
-      *         isSuperCool: true,
 
-      *         office: {
 
-      *             size: 40000,
 
-      *             location: 'Redwood City',
 
-      *             isFun: true
 
-      *         }
 
-      *     }
 
-      *
 
-      * @param {Object} destination The object into which all subsequent objects are merged.
 
-      * @param {Object...} object Any number of objects to merge into the destination.
 
-      * @return {Object} merged The destination object with all passed objects merged in.
 
-      */
 
-     merge: function(destination) {
 
-         var i = 1,
 
-             ln = arguments.length,
 
-             mergeFn = ExtObject.merge,
 
-             cloneFn = Ext.clone,
 
-             object, key, value, sourceKey;
 
-         for (; i < ln; i++) {
 
-             object = arguments[i];
 
-             for (key in object) {
 
-                 value = object[key];
 
-                 if (value && value.constructor === Object) {
 
-                     sourceKey = destination[key];
 
-                     if (sourceKey && sourceKey.constructor === Object) {
 
-                         mergeFn(sourceKey, value);
 
-                     }
 
-                     else {
 
-                         destination[key] = cloneFn(value);
 
-                     }
 
-                 }
 
-                 else {
 
-                     destination[key] = value;
 
-                 }
 
-             }
 
-         }
 
-         return destination;
 
-     },
 
- <span id='Ext-Object-method-mergeIf'>    /**
 
- </span>     * @private
 
-      * @param destination
 
-      */
 
-     mergeIf: function(destination) {
 
-         var i = 1,
 
-             ln = arguments.length,
 
-             cloneFn = Ext.clone,
 
-             object, key, value;
 
-         for (; i < ln; i++) {
 
-             object = arguments[i];
 
-             for (key in object) {
 
-                 if (!(key in destination)) {
 
-                     value = object[key];
 
-                     if (value && value.constructor === Object) {
 
-                         destination[key] = cloneFn(value);
 
-                     }
 
-                     else {
 
-                         destination[key] = value;
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         return destination;
 
-     },
 
- <span id='Ext-Object-method-getKey'>    /**
 
- </span>     * Returns the first matching key corresponding to the given value.
 
-      * If no matching value is found, null is returned.
 
-      *
 
-      *     var person = {
 
-      *         name: 'Jacky',
 
-      *         loves: 'food'
 
-      *     };
 
-      *
 
-      *     alert(Ext.Object.getKey(person, 'food')); // alerts 'loves'
 
-      *
 
-      * @param {Object} object
 
-      * @param {Object} value The value to find
 
-      */
 
-     getKey: function(object, value) {
 
-         for (var property in object) {
 
-             if (object.hasOwnProperty(property) && object[property] === value) {
 
-                 return property;
 
-             }
 
-         }
 
-         return null;
 
-     },
 
- <span id='Ext-Object-method-getValues'>    /**
 
- </span>     * Gets all values of the given object as an array.
 
-      *
 
-      *     var values = Ext.Object.getValues({
 
-      *         name: 'Jacky',
 
-      *         loves: 'food'
 
-      *     }); // ['Jacky', 'food']
 
-      *
 
-      * @param {Object} object
 
-      * @return {Array} An array of values from the object
 
-      */
 
-     getValues: function(object) {
 
-         var values = [],
 
-             property;
 
-         for (property in object) {
 
-             if (object.hasOwnProperty(property)) {
 
-                 values.push(object[property]);
 
-             }
 
-         }
 
-         return values;
 
-     },
 
- <span id='Ext-Object-method-getKeys'>    /**
 
- </span>     * Gets all keys of the given object as an array.
 
-      *
 
-      *     var values = Ext.Object.getKeys({
 
-      *         name: 'Jacky',
 
-      *         loves: 'food'
 
-      *     }); // ['name', 'loves']
 
-      *
 
-      * @param {Object} object
 
-      * @return {String[]} An array of keys from the object
 
-      * @method
 
-      */
 
-     getKeys: (typeof Object.keys == 'function')
 
-         ? function(object){
 
-             if (!object) {
 
-                 return [];
 
-             }
 
-             return Object.keys(object);
 
-         }
 
-         : function(object) {
 
-             var keys = [],
 
-                 property;
 
-             for (property in object) {
 
-                 if (object.hasOwnProperty(property)) {
 
-                     keys.push(property);
 
-                 }
 
-             }
 
-             return keys;
 
-         },
 
- <span id='Ext-Object-method-getSize'>    /**
 
- </span>     * Gets the total number of this object's own properties
 
-      *
 
-      *     var size = Ext.Object.getSize({
 
-      *         name: 'Jacky',
 
-      *         loves: 'food'
 
-      *     }); // size equals 2
 
-      *
 
-      * @param {Object} object
 
-      * @return {Number} size
 
-      */
 
-     getSize: function(object) {
 
-         var size = 0,
 
-             property;
 
-         for (property in object) {
 
-             if (object.hasOwnProperty(property)) {
 
-                 size++;
 
-             }
 
-         }
 
-         return size;
 
-     },
 
- <span id='Ext-Object-method-classify'>    /**
 
- </span>     * @private
 
-      */
 
-     classify: function(object) {
 
-         var prototype = object,
 
-             objectProperties = [],
 
-             propertyClassesMap = {},
 
-             objectClass = function() {
 
-                 var i = 0,
 
-                     ln = objectProperties.length,
 
-                     property;
 
-                 for (; i < ln; i++) {
 
-                     property = objectProperties[i];
 
-                     this[property] = new propertyClassesMap[property]();
 
-                 }
 
-             },
 
-             key, value;
 
-         for (key in object) {
 
-             if (object.hasOwnProperty(key)) {
 
-                 value = object[key];
 
-                 if (value && value.constructor === Object) {
 
-                     objectProperties.push(key);
 
-                     propertyClassesMap[key] = ExtObject.classify(value);
 
-                 }
 
-             }
 
-         }
 
-         objectClass.prototype = prototype;
 
-         return objectClass;
 
-     }
 
- };
 
- <span id='Ext-method-merge'>/**
 
- </span> * A convenient alias method for {@link Ext.Object#merge}.
 
-  *
 
-  * @member Ext
 
-  * @method merge
 
-  * @inheritdoc Ext.Object#merge
 
-  */
 
- Ext.merge = Ext.Object.merge;
 
- <span id='Ext-property-mergeIf'>/**
 
- </span> * @private
 
-  * @member Ext
 
-  */
 
- Ext.mergeIf = Ext.Object.mergeIf;
 
- <span id='Ext-method-urlEncode'>/**
 
- </span> *
 
-  * @member Ext
 
-  * @method urlEncode
 
-  * @inheritdoc Ext.Object#toQueryString
 
-  * @deprecated 4.0.0 Use {@link Ext.Object#toQueryString} instead
 
-  */
 
- Ext.urlEncode = function() {
 
-     var args = Ext.Array.from(arguments),
 
-         prefix = '';
 
-     // Support for the old `pre` argument
 
-     if ((typeof args[1] === 'string')) {
 
-         prefix = args[1] + '&';
 
-         args[1] = false;
 
-     }
 
-     return prefix + ExtObject.toQueryString.apply(ExtObject, args);
 
- };
 
- <span id='Ext-method-urlDecode'>/**
 
- </span> * Alias for {@link Ext.Object#fromQueryString}.
 
-  *
 
-  * @member Ext
 
-  * @method urlDecode
 
-  * @inheritdoc Ext.Object#fromQueryString
 
-  * @deprecated 4.0.0 Use {@link Ext.Object#fromQueryString} instead
 
-  */
 
- Ext.urlDecode = function() {
 
-     return ExtObject.fromQueryString.apply(ExtObject, arguments);
 
- };
 
- }());
 
- </pre>
 
- </body>
 
- </html>
 
 
  |