| 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>
 |