linuxwindowsinboxwhatsappicloudtweetdeckhipchattelegramhangoutsslackgmailskypefacebook-workplaceoutlookemailmicrosoft-teamsdiscordmessengercustom-servicesmacos
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
814 lines
25 KiB
814 lines
25 KiB
/** |
|
* @class Ext.Object |
|
* |
|
* A collection of useful static methods to deal with objects. |
|
* |
|
* @singleton |
|
*/ |
|
|
|
(function() { |
|
|
|
// The "constructor" for chain: |
|
var TemplateClass = function(){}, |
|
queryRe = /^\?/, |
|
keyRe = /(\[):?([^\]]*)\]/g, |
|
nameRe = /^([^\[]+)/, |
|
plusRe = /\+/g, |
|
ExtObject = Ext.Object = { |
|
// @define Ext.lang.Object |
|
// @define Ext.Object |
|
// @require Ext |
|
// @require Ext.lang.Date |
|
|
|
/** |
|
* Returns a new object with the given object as the prototype chain. This method is |
|
* designed to mimic the ECMA standard `Object.create` method and is assigned to that |
|
* function when it is available. |
|
* |
|
* **NOTE** This method does not support the property definitions capability of the |
|
* `Object.create` method. Only the first argument is supported. |
|
* |
|
* @param {Object} object The prototype chain for the new object. |
|
*/ |
|
chain: Object.create || function (object) { |
|
TemplateClass.prototype = object; |
|
var result = new TemplateClass(); |
|
TemplateClass.prototype = null; |
|
return result; |
|
}, |
|
|
|
/** |
|
* This method removes all keys from the given object. |
|
* @param {Object} object The object from which to remove all keys. |
|
* @return {Object} The given object. |
|
*/ |
|
clear: function (object) { |
|
// Safe to delete during iteration |
|
for (var key in object) { |
|
delete object[key]; |
|
} |
|
|
|
return object; |
|
}, |
|
|
|
/** |
|
* Freezes the given object making it immutable. This operation is by default shallow |
|
* and does not effect objects referenced by the given object. |
|
* |
|
* @method |
|
* @param {Object} obj The object to freeze. |
|
* @param {Boolean} [deep=false] Pass `true` to freeze sub-objects recursively. |
|
* @return {Object} The given object `obj`. |
|
*/ |
|
freeze: Object.freeze ? function (obj, deep) { |
|
if (obj && typeof obj === 'object' && !Object.isFrozen(obj)) { |
|
Object.freeze(obj); |
|
|
|
if (deep) { |
|
for (var name in obj) { |
|
ExtObject.freeze(obj[name], deep); |
|
} |
|
} |
|
} |
|
return obj; |
|
} : Ext.identityFn, |
|
|
|
/** |
|
* 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; |
|
}, |
|
|
|
/** |
|
* 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('&'); |
|
}, |
|
|
|
/** |
|
* 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(queryRe, '').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 = components[0]; |
|
name = name.replace(plusRe, '%20'); |
|
name = decodeURIComponent(name); |
|
|
|
value = components[1]; |
|
if (value !== undefined) { |
|
value = value.replace(plusRe, '%20'); |
|
value = decodeURIComponent(value); |
|
} else { |
|
value = ''; |
|
} |
|
|
|
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(keyRe); |
|
matchedName = name.match(nameRe); |
|
|
|
//<debug> |
|
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; |
|
}, |
|
|
|
/** |
|
* 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) { |
|
var enumerables = Ext.enumerables, |
|
i, property; |
|
|
|
if (object) { |
|
scope = scope || object; |
|
|
|
for (property in object) { |
|
if (object.hasOwnProperty(property)) { |
|
if (fn.call(scope, property, object[property], object) === false) { |
|
return; |
|
} |
|
} |
|
} |
|
|
|
if (enumerables) { |
|
for (i = enumerables.length; i--; ) { |
|
if (object.hasOwnProperty(property = enumerables[i])) { |
|
if (fn.call(scope, property, object[property], object) === false) { |
|
return; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* 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 items = { |
|
* 1: 'Hello', |
|
* 2: 'World' |
|
* }; |
|
* |
|
* Ext.Object.eachValue(items, function (value) { |
|
* console.log("Value: " + value); |
|
* }); |
|
* |
|
* This will log 'Hello' and 'World' in no particular order. This method is useful |
|
* in cases where the keys are not important to the processing, just the values. |
|
* |
|
* @param {Object} object The object to iterate |
|
* @param {Function} fn The callback function. |
|
* @param {Object} fn.value The value of |
|
* @param {Object} [scope] The execution scope (`this`) of the callback function |
|
*/ |
|
eachValue: function(object, fn, scope) { |
|
var enumerables = Ext.enumerables, |
|
i, property; |
|
|
|
scope = scope || object; |
|
|
|
for (property in object) { |
|
if (object.hasOwnProperty(property)) { |
|
if (fn.call(scope, object[property]) === false) { |
|
return; |
|
} |
|
} |
|
} |
|
|
|
if (enumerables) { |
|
for (i = enumerables.length; i--; ) { |
|
if (object.hasOwnProperty(property = enumerables[i])) { |
|
if (fn.call(scope, object[property]) === false) { |
|
return; |
|
} |
|
} |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* 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; |
|
}, |
|
|
|
/** |
|
* @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; |
|
}, |
|
|
|
/** |
|
* Returns all keys of the given object as an array. |
|
* |
|
* @param {Object} object |
|
* @return {String[]} An array of keys from the object or any of its prototypes. |
|
* @method |
|
*/ |
|
getAllKeys: function (object) { |
|
var keys = [], |
|
property; |
|
|
|
for (property in object) { |
|
keys.push(property); |
|
} |
|
|
|
return keys; |
|
}, |
|
|
|
/** |
|
* 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; |
|
}, |
|
|
|
/** |
|
* 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; |
|
}, |
|
|
|
/** |
|
* Returns the `hasOwnProperty` 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; |
|
}, |
|
|
|
/** |
|
* 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; |
|
}, |
|
|
|
/** |
|
* Checks if there are any properties on this object. |
|
* @param {Object} object |
|
* @return {Boolean} `true` if there no properties on the object. |
|
*/ |
|
isEmpty: function(object){ |
|
for (var key in object) { |
|
if (object.hasOwnProperty(key)) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
}, |
|
|
|
/** |
|
* Shallow compares the contents of 2 objects using strict equality. Objects are |
|
* considered equal if they both have the same set of properties and the |
|
* value for those properties equals the other in the corresponding object. |
|
* |
|
* // Returns true |
|
* Ext.Object.equals({ |
|
* foo: 1, |
|
* bar: 2 |
|
* }, { |
|
* foo: 1, |
|
* bar: 2 |
|
* }); |
|
* |
|
* @param {Object} object1 |
|
* @param {Object} object2 |
|
* @return {Boolean} `true` if the objects are equal. |
|
*/ |
|
equals: (function() { |
|
var check = function(o1, o2) { |
|
var key; |
|
|
|
for (key in o1) { |
|
if (o1.hasOwnProperty(key)) { |
|
if (o1[key] !== o2[key]) { |
|
return false; |
|
} |
|
} |
|
} |
|
return true; |
|
}; |
|
|
|
return function(object1, object2) { |
|
|
|
// Short circuit if the same object is passed twice |
|
if (object1 === object2) { |
|
return true; |
|
} if (object1 && object2) { |
|
// Do the second check because we could have extra keys in |
|
// object2 that don't exist in object1. |
|
return check(object1, object2) && check(object2, object1); |
|
} else if (!object1 && !object2) { |
|
return object1 === object2; |
|
} else { |
|
return false; |
|
} |
|
}; |
|
})(), |
|
|
|
/** |
|
* @private |
|
*/ |
|
fork: function (obj) { |
|
var ret, key, value; |
|
|
|
if (obj && obj.constructor === Object) { |
|
ret = ExtObject.chain(obj); |
|
|
|
for (key in obj) { |
|
value = obj[key]; |
|
|
|
if (value) { |
|
if (value.constructor === Object) { |
|
ret[key] = ExtObject.fork(value); |
|
} else if (value instanceof Array) { |
|
ret[key] = Ext.Array.clone(value); |
|
} |
|
} |
|
} |
|
} else { |
|
ret = obj; |
|
} |
|
|
|
return ret; |
|
}, |
|
|
|
defineProperty: ('defineProperty' in Object) ? Object.defineProperty : |
|
function(object, name, descriptor) { |
|
if (!Object.prototype.__defineGetter__) { |
|
return; |
|
} |
|
if (descriptor.get) { |
|
object.__defineGetter__(name, descriptor.get); |
|
} |
|
|
|
if (descriptor.set) { |
|
object.__defineSetter__(name, descriptor.set); |
|
} |
|
}, |
|
|
|
/** |
|
* @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; |
|
} |
|
}; |
|
|
|
/** |
|
* A convenient alias method for {@link Ext.Object#merge}. |
|
* |
|
* @member Ext |
|
* @method merge |
|
* @inheritdoc Ext.Object#merge |
|
*/ |
|
Ext.merge = Ext.Object.merge; |
|
|
|
/** |
|
* @private |
|
* @member Ext |
|
*/ |
|
Ext.mergeIf = Ext.Object.mergeIf; |
|
|
|
}());
|
|
|