/ext-4.1.0_b3/src/core/src/Ext.js
https://bitbucket.org/srogerf/javascript · JavaScript · 656 lines · 340 code · 87 blank · 229 comment · 79 complexity · c0bafa206e26aa97c2ea39efa3048a99 MD5 · raw file
- /**
- * @class Ext
- * @singleton
- */
- var Ext = Ext || {};
- Ext._startTime = new Date().getTime();
- (function() {
- var global = this,
- objectPrototype = Object.prototype,
- toString = objectPrototype.toString,
- enumerables = true,
- enumerablesTest = { toString: 1 },
- emptyFn = function(){},
- i;
- Ext.global = global;
- for (i in enumerablesTest) {
- enumerables = null;
- }
- if (enumerables) {
- enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable',
- 'toLocaleString', 'toString', 'constructor'];
- }
- /**
- * An array containing extra enumerables for old browsers
- * @property {String[]}
- */
- Ext.enumerables = enumerables;
- /**
- * Copies all the properties of config to the specified object.
- * Note that if recursive merging and cloning without referencing the original objects / arrays is needed, use
- * {@link Ext.Object#merge} instead.
- * @param {Object} object The receiver of the properties
- * @param {Object} config The source of the properties
- * @param {Object} defaults A different object that will also be applied for default values
- * @return {Object} returns obj
- */
- Ext.apply = function(object, config, defaults) {
- if (defaults) {
- Ext.apply(object, defaults);
- }
- if (object && config && typeof config === 'object') {
- var i, j, k;
- for (i in config) {
- object[i] = config[i];
- }
- if (enumerables) {
- for (j = enumerables.length; j--;) {
- k = enumerables[j];
- if (config.hasOwnProperty(k)) {
- object[k] = config[k];
- }
- }
- }
- }
- return object;
- };
- Ext.buildSettings = Ext.apply({
- baseCSSPrefix: 'x-',
- scopeResetCSS: false
- }, Ext.buildSettings || {});
- Ext.apply(Ext, {
- /**
- * @property {String} [name='Ext']
- * <p>The name of the property in the global namespace (The <code>window</code> in browser environments) which refers to the current instance of Ext.</p>
- * <p>This is usually <code>"Ext"</code>, but if a sandboxed build of ExtJS is being used, this will be an alternative name.</p>
- * <p>If code is being generated for use by <code>eval</code> or to create a <code>new Function</code>, and the global instance
- * of Ext must be referenced, this is the name that should be built into the code.</p>
- */
- name: Ext.sandboxName || 'Ext',
- /**
- * A reusable empty function
- */
- emptyFn: emptyFn,
- /**
- * A zero length string which will pass a truth test. Useful for passing to methods
- * which use a truth test to reject <i>falsy</i> values where a string value must be cleared.
- */
- emptyString: new String(),
- baseCSSPrefix: Ext.buildSettings.baseCSSPrefix,
- /**
- * Copies all the properties of config to object if they don't already exist.
- * @param {Object} object The receiver of the properties
- * @param {Object} config The source of the properties
- * @return {Object} returns obj
- */
- applyIf: function(object, config) {
- var property;
- if (object) {
- for (property in config) {
- if (object[property] === undefined) {
- object[property] = config[property];
- }
- }
- }
- return object;
- },
- /**
- * Iterates either an array or an object. This method delegates to
- * {@link Ext.Array#each Ext.Array.each} if the given value is iterable, and {@link Ext.Object#each Ext.Object.each} otherwise.
- *
- * @param {Object/Array} object The object or array to be iterated.
- * @param {Function} fn The function to be called for each iteration. See and {@link Ext.Array#each Ext.Array.each} and
- * {@link Ext.Object#each Ext.Object.each} for detailed lists of arguments passed to this function depending on the given object
- * type that is being iterated.
- * @param {Object} scope (Optional) The scope (`this` reference) in which the specified function is executed.
- * Defaults to the object being iterated itself.
- * @markdown
- */
- iterate: function(object, fn, scope) {
- if (Ext.isEmpty(object)) {
- return;
- }
- if (scope === undefined) {
- scope = object;
- }
- if (Ext.isIterable(object)) {
- Ext.Array.each.call(Ext.Array, object, fn, scope);
- }
- else {
- Ext.Object.each.call(Ext.Object, object, fn, scope);
- }
- }
- });
- Ext.apply(Ext, {
- /**
- * This method deprecated. Use {@link Ext#define Ext.define} instead.
- * @method
- * @param {Function} superclass
- * @param {Object} overrides
- * @return {Function} The subclass constructor from the <tt>overrides</tt> parameter, or a generated one if not provided.
- * @deprecated 4.0.0 Use {@link Ext#define Ext.define} instead
- */
- extend: function() {
- // inline overrides
- var objectConstructor = objectPrototype.constructor,
- inlineOverrides = function(o) {
- for (var m in o) {
- if (!o.hasOwnProperty(m)) {
- continue;
- }
- this[m] = o[m];
- }
- };
- return function(subclass, superclass, overrides) {
- // First we check if the user passed in just the superClass with overrides
- if (Ext.isObject(superclass)) {
- overrides = superclass;
- superclass = subclass;
- subclass = overrides.constructor !== objectConstructor ? overrides.constructor : function() {
- superclass.apply(this, arguments);
- };
- }
- //<debug>
- if (!superclass) {
- Ext.Error.raise({
- sourceClass: 'Ext',
- sourceMethod: 'extend',
- msg: 'Attempting to extend from a class which has not been loaded on the page.'
- });
- }
- //</debug>
- // We create a new temporary class
- var F = function() {},
- subclassProto, superclassProto = superclass.prototype;
- F.prototype = superclassProto;
- subclassProto = subclass.prototype = new F();
- subclassProto.constructor = subclass;
- subclass.superclass = superclassProto;
- if (superclassProto.constructor === objectConstructor) {
- superclassProto.constructor = superclass;
- }
- subclass.override = function(overrides) {
- Ext.override(subclass, overrides);
- };
- subclassProto.override = inlineOverrides;
- subclassProto.proto = subclassProto;
- subclass.override(overrides);
- subclass.extend = function(o) {
- return Ext.extend(subclass, o);
- };
- return subclass;
- };
- }(),
- /**
- * Proxy to {@link Ext.Base#override}. Please refer {@link Ext.Base#override} for further details.
- *
- * @param {Object} cls The class to override
- * @param {Object} overrides The properties to add to origClass. This should be specified as an object literal
- * containing one or more properties.
- * @method override
- * @markdown
- * @deprecated 4.1.0 Use {@link Ext#define Ext.define} instead
- */
- override: function(cls, overrides) {
- if (cls.$isClass) {
- return cls.override(overrides);
- }
- else {
- Ext.apply(cls.prototype, overrides);
- }
- }
- });
- // A full set of static methods to do type checking
- Ext.apply(Ext, {
- /**
- * Returns the given value itself if it's not empty, as described in {@link Ext#isEmpty}; returns the default
- * value (second argument) otherwise.
- *
- * @param {Object} value The value to test
- * @param {Object} defaultValue The value to return if the original value is empty
- * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false)
- * @return {Object} value, if non-empty, else defaultValue
- */
- valueFrom: function(value, defaultValue, allowBlank){
- return Ext.isEmpty(value, allowBlank) ? defaultValue : value;
- },
- /**
- * Returns the type of the given variable in string format. List of possible values are:
- *
- * - `undefined`: If the given value is `undefined`
- * - `null`: If the given value is `null`
- * - `string`: If the given value is a string
- * - `number`: If the given value is a number
- * - `boolean`: If the given value is a boolean value
- * - `date`: If the given value is a `Date` object
- * - `function`: If the given value is a function reference
- * - `object`: If the given value is an object
- * - `array`: If the given value is an array
- * - `regexp`: If the given value is a regular expression
- * - `element`: If the given value is a DOM Element
- * - `textnode`: If the given value is a DOM text node and contains something other than whitespace
- * - `whitespace`: If the given value is a DOM text node and contains only whitespace
- *
- * @param {Object} value
- * @return {String}
- * @markdown
- */
- typeOf: function(value) {
- if (value === null) {
- return 'null';
- }
- var type = typeof value;
- if (type === 'undefined' || type === 'string' || type === 'number' || type === 'boolean') {
- return type;
- }
- var typeToString = toString.call(value);
- switch(typeToString) {
- case '[object Array]':
- return 'array';
- case '[object Date]':
- return 'date';
- case '[object Boolean]':
- return 'boolean';
- case '[object Number]':
- return 'number';
- case '[object RegExp]':
- return 'regexp';
- }
- if (type === 'function') {
- return 'function';
- }
- if (type === 'object') {
- if (value.nodeType !== undefined) {
- if (value.nodeType === 3) {
- return (/\S/).test(value.nodeValue) ? 'textnode' : 'whitespace';
- }
- else {
- return 'element';
- }
- }
- return 'object';
- }
- //<debug error>
- Ext.Error.raise({
- sourceClass: 'Ext',
- sourceMethod: 'typeOf',
- msg: 'Failed to determine the type of the specified value "' + value + '". This is most likely a bug.'
- });
- //</debug>
- },
- /**
- * Returns true if the passed value is empty, false otherwise. The value is deemed to be empty if it is either:
- *
- * - `null`
- * - `undefined`
- * - a zero-length array
- * - a zero-length string (Unless the `allowEmptyString` parameter is set to `true`)
- *
- * @param {Object} value The value to test
- * @param {Boolean} allowEmptyString (optional) true to allow empty strings (defaults to false)
- * @return {Boolean}
- * @markdown
- */
- isEmpty: function(value, allowEmptyString) {
- return (value === null) || (value === undefined) || (!allowEmptyString ? value === '' : false) || (Ext.isArray(value) && value.length === 0);
- },
- /**
- * Returns true if the passed value is a JavaScript Array, false otherwise.
- *
- * @param {Object} target The target to test
- * @return {Boolean}
- * @method
- */
- isArray: ('isArray' in Array) ? Array.isArray : function(value) {
- return toString.call(value) === '[object Array]';
- },
- /**
- * Returns true if the passed value is a JavaScript Date object, false otherwise.
- * @param {Object} object The object to test
- * @return {Boolean}
- */
- isDate: function(value) {
- return toString.call(value) === '[object Date]';
- },
- /**
- * Returns true if the passed value is a JavaScript Object, false otherwise.
- * @param {Object} value The value to test
- * @return {Boolean}
- * @method
- */
- isObject: (toString.call(null) === '[object Object]') ?
- function(value) {
- // check ownerDocument here as well to exclude DOM nodes
- return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.ownerDocument === undefined;
- } :
- function(value) {
- return toString.call(value) === '[object Object]';
- },
- /**
- * @private
- */
- isSimpleObject: function(value) {
- return value instanceof Object && value.constructor === Object;
- },
- /**
- * Returns true if the passed value is a JavaScript 'primitive', a string, number or boolean.
- * @param {Object} value The value to test
- * @return {Boolean}
- */
- isPrimitive: function(value) {
- var type = typeof value;
- return type === 'string' || type === 'number' || type === 'boolean';
- },
- /**
- * Returns true if the passed value is a JavaScript Function, false otherwise.
- * @param {Object} value The value to test
- * @return {Boolean}
- * @method
- */
- isFunction:
- // Safari 3.x and 4.x returns 'function' for typeof <NodeList>, hence we need to fall back to using
- // Object.prototype.toString (slower)
- (typeof document !== 'undefined' && typeof document.getElementsByTagName('body') === 'function') ? function(value) {
- return toString.call(value) === '[object Function]';
- } : function(value) {
- return typeof value === 'function';
- },
- /**
- * Returns true if the passed value is a number. Returns false for non-finite numbers.
- * @param {Object} value The value to test
- * @return {Boolean}
- */
- isNumber: function(value) {
- return typeof value === 'number' && isFinite(value);
- },
- /**
- * Validates that a value is numeric.
- * @param {Object} value Examples: 1, '1', '2.34'
- * @return {Boolean} True if numeric, false otherwise
- */
- isNumeric: function(value) {
- return !isNaN(parseFloat(value)) && isFinite(value);
- },
- /**
- * Returns true if the passed value is a string.
- * @param {Object} value The value to test
- * @return {Boolean}
- */
- isString: function(value) {
- return typeof value === 'string';
- },
- /**
- * Returns true if the passed value is a boolean.
- *
- * @param {Object} value The value to test
- * @return {Boolean}
- */
- isBoolean: function(value) {
- return typeof value === 'boolean';
- },
- /**
- * Returns true if the passed value is an HTMLElement
- * @param {Object} value The value to test
- * @return {Boolean}
- */
- isElement: function(value) {
- return value ? value.nodeType === 1 : false;
- },
- /**
- * Returns true if the passed value is a TextNode
- * @param {Object} value The value to test
- * @return {Boolean}
- */
- isTextNode: function(value) {
- return value ? value.nodeName === "#text" : false;
- },
- /**
- * Returns true if the passed value is defined.
- * @param {Object} value The value to test
- * @return {Boolean}
- */
- isDefined: function(value) {
- return typeof value !== 'undefined';
- },
- /**
- * Returns true if the passed value is iterable, false otherwise
- * @param {Object} value The value to test
- * @return {Boolean}
- */
- isIterable: function(value) {
- var type = typeof value,
- checkLength = false;
- if (value && type != 'string') {
- // Functions have a length property, so we need to filter them out
- if (type == 'function') {
- // In Safari, NodeList/HTMLCollection both return "function" when using typeof, so we need
- // to explicitly check them here.
- if (Ext.isSafari) {
- checkLength = value instanceof NodeList || value instanceof HTMLCollection;
- }
- } else {
- checkLength = true;
- }
- }
- return checkLength ? value.length !== undefined : false;
- }
- });
- Ext.apply(Ext, {
- /**
- * Clone almost any type of variable including array, object, DOM nodes and Date without keeping the old reference
- * @param {Object} item The variable to clone
- * @return {Object} clone
- */
- clone: function(item) {
- if (item === null || item === undefined) {
- return item;
- }
- // DOM nodes
- // TODO proxy this to Ext.Element.clone to handle automatic id attribute changing
- // recursively
- if (item.nodeType && item.cloneNode) {
- return item.cloneNode(true);
- }
- var type = toString.call(item);
- // Date
- if (type === '[object Date]') {
- return new Date(item.getTime());
- }
- var i, j, k, clone, key;
- // Array
- if (type === '[object Array]') {
- i = item.length;
- clone = [];
- while (i--) {
- clone[i] = Ext.clone(item[i]);
- }
- }
- // Object
- else if (type === '[object Object]' && item.constructor === Object) {
- clone = {};
- for (key in item) {
- clone[key] = Ext.clone(item[key]);
- }
- if (enumerables) {
- for (j = enumerables.length; j--;) {
- k = enumerables[j];
- clone[k] = item[k];
- }
- }
- }
- return clone || item;
- },
- /**
- * @private
- * Generate a unique reference of Ext in the global scope, useful for sandboxing
- */
- getUniqueGlobalNamespace: function() {
- var uniqueGlobalNamespace = this.uniqueGlobalNamespace;
- if (uniqueGlobalNamespace === undefined) {
- var i = 0;
- do {
- uniqueGlobalNamespace = 'ExtBox' + (++i);
- } while (Ext.global[uniqueGlobalNamespace] !== undefined);
- Ext.global[uniqueGlobalNamespace] = Ext;
- this.uniqueGlobalNamespace = uniqueGlobalNamespace;
- }
- return uniqueGlobalNamespace;
- },
-
- /**
- * @private
- */
- functionFactoryCache: {},
-
- cacheableFunctionFactory: function() {
- var me = this,
- args = Array.prototype.slice.call(arguments),
- cache = me.functionFactoryCache,
- idx, fn, ln;
-
- if (Ext.isSandboxed) {
- ln = args.length;
- if (ln > 0) {
- ln--;
- args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];
- }
- }
- idx = args.join('');
- fn = cache[idx];
- if (!fn) {
- fn = Function.prototype.constructor.apply(Function.prototype, args);
-
- cache[idx] = fn;
- }
- return fn;
- },
-
- functionFactory: function() {
- var me = this,
- args = Array.prototype.slice.call(arguments),
- ln;
-
- if (Ext.isSandboxed) {
- ln = args.length;
- if (ln > 0) {
- ln--;
- args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];
- }
- }
-
- return Function.prototype.constructor.apply(Function.prototype, args);
- },
- /**
- * @property
- * @private
- */
- globalEval: ('execScript' in global) ? function(code) {
- global.execScript(code)
- } : function(code) {
- (function(){
- eval(code);
- })();
- },
- /**
- * @private
- * @property
- */
- Logger: {
- verbose: emptyFn,
- log: emptyFn,
- info: emptyFn,
- warn: emptyFn,
- error: function(message) {
- throw new Error(message);
- },
- deprecate: emptyFn
- }
- });
- /**
- * Old alias to {@link Ext#typeOf}
- * @deprecated 4.0.0 Use {@link Ext#typeOf} instead
- * @method
- * @inheritdoc Ext#typeOf
- */
- Ext.type = Ext.typeOf;
- })();