/*======================================================================== * * This section contains stuff that should be in Ext4, or stuff that * is up for discussion. It should be removed prior to Ext 4 final. * *========================================================================*/ // Beefed up getDockedItems to make it easier to find specific items like top toolbars only //Ext.apply(Ext.panel.AbstractPanel.prototype, { // /** // * Retrieve an array of all currently docked components, optionally matching a // * specific docked side and/or component type. // * @param {Array} options // * @return {Array} An array of matching components // */ // // ex: {dock: 'top', alias: 'widget.toolbar'} // getDockedItems : function(options) { // var me = this, // items = []; // // if (me.dockedItems && me.dockedItems.items.length) { // items = me.dockedItems.items.slice(); // } // // if (options && items.length > 0) { // var i = 0, // ln = items.length, // matches = [], // item; // // for (; i < ln; i++) { // item = items[i]; // if (options.dock && options.dock !== item.dock){ // continue; // } // if (options.alias && options.alias !== item.alias){ // continue; // } // matches.push(item); // } // return matches; // } // return items; // } //}); /*======================================================================== * * This section contains the Ext.Compat object definition. * Also shared by ext3-compat.js. * *========================================================================*/ Ext.Compat = function(){ // private var notificationCache = [], // private getMsg = function(o, tag){ var version = o.version ? o.version : '4.0', pkg = o.pkg ? '[' + o.pkg + ']': '', member = o.member ? ' ' + o.member : '', type = o.type ? ' (' + o.type + ')' : '', use = o.type === 'event' ? ' Handle ' : ' Use ', alt = o.alt ? use + o.alt + ' instead.' : '', msg = o.msg ? ' ' + o.msg : ''; return '[' + tag + '][' + version + ']' + pkg + member + type + ':' + alt + msg; }, // private showMsg = function(msg, method, single){ var isNew = Ext.Array.indexOf(notificationCache, msg) == -1; if (isNew || !single) { Ext.Compat[method](msg); if (single) { notificationCache.push(msg); } } }, // private consoleOut = function(type, msg){ if (Ext.Compat.silent === true) { return; } if (!Ext.isDefined(Ext.global.console)){ if (type === 'error' && Ext.Array.indexOf(notificationCache, '__consoleMsg') == -1) { notificationCache.push('__consoleMsg'); alert('You have Ext compatibility errors that must be resolved. Please enable your browser\'s console '+ '(or switch to a console-capable browser) to see complete error details.'); } return; } var con = Ext.global.console; if(Ext.Array.indexOf(notificationCache, '__initMsg') == -1){ notificationCache.push('__initMsg'); con.info('#### Ext 3 compatibility mode active. See the Migration Guide included with the Ext 4 download for details.'); if(!Ext.Compat.showErrors){ var errMsg = '#### Set "Ext.Compat.showErrors = true;" in your code to include a stack trace with each warning.'; con.info(con.firebug ? errMsg : errMsg + ' (Firebug required)'); } con.log(' '); } con[Ext.Compat.showErrors ? 'error' : type](msg); }; return { /** * False to display console messages (default), true to skip displaying console messages. Useful * when running an app in compatibility mode for end users prior to completing full migration to Ext 4. */ silent: false, /** * True to ignore informational messages and show only warnings, false to show all messages (default) */ ignoreInfo: false, /** * True to display messages via console.error instead of console.warn/info (defaults to false). When * viewing the console in Firebug in particular this can be a useful option to enable as Firebug will * capture the stack trace and include it in the displayed error object, which can make finding the * source of warnings much easier in most cases. In other browsers enabling this option will simply * display the message as an error cosmetically but won't provide any additional benefit. */ showErrors: false, /** * Wrapper for the browser console.warn() method that checks for the existence of console * and also honors the Ext.Compat.silent flag. Should be used for any breaking change * or deprecation warnings. * @param {String} msg The console message to log */ warn: function(msg) { consoleOut('warn', msg); }, /** * Wrapper for the browser console.info() method that checks for the existence of console * and also honors the Ext.Compat.silent flag. Should be used for informational * messages or non-breaking changes that modify existing behavior. * @param {String} msg The console message to log */ info: function(msg){ if(this.ignoreInfo !== true){ consoleOut('info', msg); } }, /** * This method should generally be eschewed in favor of Ext.compat.deprecate. However it might be necessary * to log a console error in certain cases, e.g. when backwards-compatibility is only conditionally possible. * @param {String} msg The console message to log */ error: function(msg){ consoleOut('error', msg); }, /** * Display a standard deprecation message. The method takes a single object argument that contains * properties as described below. All properties are optional, although typically the pkg and member would be * specified along with a descriptive message. * @param {String} pkg (optional) The package ("Core") or component ("Ext.grid.Grid") being referenced (defaults to '') * @param {String} member (optional) The member being deprecated (defaults to '') * @param {String} alt (optional) An alternate member that is replacing the deprecated member (defaults to '') * @param {String} type (optional) The member type (method, config, property, xtype, etc.) Defaults to 'method', * which does not get displayed -- any other specified type will be displayed in the output. * @param {String} msg (optional) An additional message to provide more explanation about the change (defaults to '') * @param {String} tag (optional) The first bracketed item in the output that describes the message type (defaults to 'DEPRECATED') * @param {Boolean} single (optional) True to limit each unique message to being displayed only one time (defaults to false, * meaning the same message can be displayed multiple times). Usually it's good to set single:true for logging issues * that can happen repetitively with the same root cause (e.g., the same issue within each row of a grid). */ deprecate: function(o) { var msg = getMsg(o, o.tag || 'DEPRECATED'); showMsg(msg, 'warn', o.single); }, /** * Display a console error with the special tag "BREAKING" to signify a breaking change that cannot be * resolved in the compatibility layer. These issues generally must be resolved immediately before the * compatibility layer be successfully applied. The method takes a single object argument that contains * properties as described below. All properties are optional, although typically the pkg and member would be * specified along with a descriptive message. * @param {String} msg (optional) A message to provide more explanation about the breaking change (defaults to '') * @param {String} pkg (optional) The package ("Core") or component ("Ext.grid.Grid") being referenced (defaults to '') * @param {String} member (optional) The member being referenced in relation to the change (defaults to '') * @param {String} type (optional) The member type (method, config, property, xtype, etc.) Defaults to 'method', * which does not get displayed -- any other specified type will be displayed in the output. * @param {String} tag (optional) The first bracketed item in the output that describes the message type (defaults to 'BREAKING') * @param {Boolean} single (optional) True to limit each unique message to being displayed only one time (defaults to false, * meaning the same message can be displayed multiple times). Usually it's good to set single:true for logging issues * that can happen repetitively with the same root cause (e.g., the same issue within each row of a grid). */ breaking: function(o){ o.msg = (o.msg || '') + ' This is a breaking change that cannot be resolved in the compatibility layer!'; var msg = getMsg(o, o.tag || 'BREAKING'); showMsg(msg, 'error', o.single); }, /** * Display a freeform notification that a compatibility change exists. This would be used, for example, * if an existing method has changed its default behavior, or has a different argument signature. * The method takes either a string message or an object argument that contains properties as described below. * If a member is being deprecated you might consider using deprecate instead. * @param {String} msg A message explaining the change * @param {String} pkg (optional) The package ("Core") or component ("Ext.grid.Grid") being referenced (defaults to '') * @param {String} member (optional) The member being referenced in relation to the change (defaults to '') * @param {String} type (optional) The member type (method, config, property, xtype, etc.) Defaults to 'method', * which does not get displayed -- any other specified type will be displayed in the output. * @param {String} tag (optional) The first bracketed item in the output that describes the message type (defaults to 'INFO') * @param {Boolean} single (optional) True to limit each unique message to being displayed only one time (defaults to false, * meaning the same message can be displayed multiple times). Usually it's good to set single:true for logging issues * that can happen repetitively with the same root cause (e.g., the same issue within each row of a grid). */ notify: function(o) { if(Ext.isString(o)){ o = {msg:o}; } if(o.msg){ var msg = getMsg(o, o.tag || 'INFO'), single = Ext.isDefined(o.single) ? o.single : !this.showErrors; showMsg(msg, 'info', single); } }, /* * Currently experimental */ bindProperty: function(options) { var localValue, o = options; if (o.owner.__defineGetter__) { o.owner.__defineGetter__(o.name, function(){ if (o.getterMsg) { o.getterMsg(); } return localValue ? localValue : (o.getter ? o.getter() : o.defaultValue); }); o.owner.__defineSetter__(o.name, function(val){ if (o.setterMsg) { o.setterMsg(); } if (o.setter) { o.setter(val); } else { o.owner[o.name] = val; } localValue = val; }); } else { o.owner[o.name] = o.defaultValue; } } }; }(); /*======================================================================== * * This section contains compatibility overrides for Ext Core * *========================================================================*/ (function(){ var compat = Ext.Compat, deprecate = Ext.bind(compat.deprecate, compat), notify = Ext.bind(compat.notify, compat), breaking = Ext.bind(compat.breaking, compat), bindProperty = Ext.bind(compat.bindProperty, compat); /*------------------------------------------------------------- * Ext *-------------------------------------------------------------*/ Ext.apply(Ext, { createDelegate: function() { deprecate({pkg:'Ext', member:'createDelegate', alt:'Ext.bind'}); return Ext.Function.bind.apply(Ext.Function, arguments); }, createCallback: function() { deprecate({pkg:'Ext', member:'createCallback', alt:'Ext.pass'}); return Ext.Function.pass.apply(Ext.Function, arguments); }, createInterceptor: function() { deprecate({pkg:'Ext', member:'createInterceptor', alt:'Ext.Function.createInterceptor'}); return Ext.Function.createInterceptor.apply(Ext.Function, arguments); }, createSequence: function() { deprecate({pkg:'Ext', member:'createSequence', alt:'Ext.Function.createSequence'}); return Ext.Function.createSequence.apply(Ext.Function, arguments); }, // This is still aliased in Ext.Array // toArray: function() { // deprecate({pkg:'Ext', member:'toArray', alt:'Ext.Array.toArray'}); // return Ext.Array.toArray.apply(Ext.Array, arguments); // }, pluck: function(arr, prop) { deprecate({pkg:'Ext', member:'pluck', alt:'Ext.Array.pluck'}); return Ext.Array.pluck.apply(Ext.Array, arguments); } // TODO: Verify if this is really deprecated or not: // iterate: function() { // Ext.each.apply(this, arguments); // deprecate({pkg:'Ext', member:'iterate', alt:'each', // msg:'Ext.each is now a wrapper for both Ext.Array.forEach and Ext.Object.each.'}); // } }); /*------------------------------------------------------------- * Ext properties *-------------------------------------------------------------*/ var versionObj = Ext.getVersion('extjs'); bindProperty({owner:Ext, name:'version', defaultValue:versionObj.version, getterMsg: function(){ deprecate({pkg:'Ext', member:'version', type:'property', alt:'getVersion (method)', msg:'Ext.getVersion() takes one argument which is the package name to look up. This will be defaulted '+ 'to "extjs" but could also be "core" or "touch". Note also that getVersion returns an object. For the '+ 'simple string representation use the Ext.getVersion("extjs").version property.'}); } }); // For no logical reason this one causes Firebug to go into an infinite loop. It makes no sense... // bindProperty({owner:Ext, name:'versionDetail', defaultValue: { // major: versionObj.major, // minor: versionObj.minor, // patch: versionObj.patch // }, // getterMsg: function(){ // deprecate({pkg:'Ext', member:'versionDetail', type:'property', alt:'getVersion (method)', // msg:'Ext.getVersion() takes one argument which is the package name to look up. This will be defaulted '+ // 'to "extjs" but could also be "core" or "touch". Note also that getVersion returns an object. For the '+ // 'version detail representation use Ext.getVersion("extjs") and inspect the properties major, minor and patch.'}); // } // }); /*------------------------------------------------------------- * Ext.lib.Dom *-------------------------------------------------------------*/ // Helper function for aliasing Ext.lib.Dom var aliasDom = function(name, args){ deprecate({pkg:'Ext.lib.Dom', member:name, alt:'Ext.core.Element.'+name}); return Ext.core.Element[name].apply(Ext.core.Element, args); }; Ext.lib = {}; Ext.lib.Dom = { isAncestor : function(p, c) { return aliasDom('isAncestor', arguments); }, getViewWidth : function(full) { return aliasDom('getViewWidth', arguments); }, getViewHeight : function(full) { return aliasDom('getViewHeight', arguments); }, getDocumentHeight: function() { return aliasDom('getDocumentHeight', arguments); }, getDocumentWidth: function() { return aliasDom('getDocumentWidth', arguments); }, getViewportHeight: function(){ return aliasDom('getViewportHeight', arguments); }, getViewportWidth : function() { return aliasDom('getViewportWidth', arguments); }, getY : function(el) { return aliasDom('getY', arguments); }, getX : function(el) { return aliasDom('getX', arguments); }, getXY : function(el) { return aliasDom('getXY', arguments); }, setXY : function(el, xy) { aliasDom('setXY', arguments); }, setX : function(el, x) { aliasDom('setX', arguments); }, setY : function(el, y) { aliasDom('setY', arguments); } }; /*------------------------------------------------------------- * Ext.lib.Event *-------------------------------------------------------------*/ // Helper function for aliasing Ext.lib.Event var aliasEvent = function(e, name, args){ deprecate({pkg:'Ext.lib.Event', member:name, alt:'.'+name}); return e[name].apply(e, args); }; Ext.lib.Event = { getTarget : function(e) { return aliasEvent(e, 'getTarget', arguments); }, getRelatedTarget : function(ev) { return aliasEvent(e, 'getRelatedTarget', arguments); }, getPageX : function(e) { return aliasEvent(e, 'getPageX', arguments); }, getPageY : function(e) { return aliasEvent(e, 'getPageY', arguments); }, getXY : function(e) { return aliasEvent(e, 'getXY', arguments); }, stopEvent : function(e) { return aliasEvent(e, 'stopEvent', arguments); }, stopPropagation : function(e) { return aliasEvent(e, 'stopPropagation', arguments); }, preventDefault : function(e) { return aliasEvent(e, 'preventDefault', arguments); }, getCharCode : function(e) { return aliasEvent(e, 'getCharCode', arguments); }, getEvent : function(e) { deprecate({pkg:'Ext.lib.Event', member:'getEvent', alt:'', msg:'Just use the event instance directly.'}); return e; } }; /*------------------------------------------------------------- * Ext.lib.Point *-------------------------------------------------------------*/ Ext.lib.Point = function(x, y) { deprecate({pkg:'Ext.lib.Point', alt:'Ext.util.Point'}); return new Ext.util.Point(x, y); }; /*------------------------------------------------------------- * Ext.lib.Ajax *-------------------------------------------------------------*/ Ext.lib.Ajax = { request : function() { deprecate({pkg:'Ext.lib.Ajax', member:'request', alt:'Ext.Ajax.request', msg:'This method is not backwards-compatible and must be updated manually.'}); }, serializeForm : function(form) { deprecate({pkg:'Ext.lib.Ajax', member:'serializeForm', alt:'Ext.core.Element.serializeForm'}); return Ext.core.Element.serializeForm(form); }, abort : function() { deprecate({pkg:'Ext.lib.Ajax', member:'abort', alt:'Ext.Ajax.abort', msg:'This method is not backwards-compatible and must be updated manually.'}); }, isCallInProgress : function() { deprecate({pkg:'Ext.lib.Ajax', member:'isCallInProgress', alt:'Ext.Ajax.isLoading', msg:'This method is not backwards-compatible and must be updated manually.'}); } }; /*------------------------------------------------------------- * Function prototype overrides *-------------------------------------------------------------*/ Ext.apply(Function.prototype, { createInterceptor : function(){ deprecate({pkg:'Function', member:'.createInterceptor', alt:'Ext.Function.createInterceptor', msg:'Note that this is now a static method, so the function will be the first argument to the new version.'}); return Ext.Function.createInterceptor.apply(Ext.Function, [this].concat(Array.prototype.slice.call(arguments))); }, createSequence : function(){ deprecate({pkg:'Function', member:'.createSequence', alt:'Ext.Function.createSequence', msg:'Note that this is now a static method, so the function will be the first argument to the new version.'}); return Ext.Function.createInterceptor.apply(Ext.Function, [this].concat(Array.prototype.slice.call(arguments))); }, createCallback : function(){ deprecate({pkg:'Function', member:'.createCallback', alt:'Ext.pass', msg:'Note that this is now a static method, so the function will be the first argument to the new version.'}); return Ext.pass.apply(Ext.Function, [this].concat(Array.prototype.slice.call(arguments))); }, createDelegate : function(obj, args, appendArgs){ deprecate({pkg:'Function', member:'.createDelegate', alt:'Ext.bind', msg:'Note that this is now a static method, so the function will be the first argument to the new version.'}); return Ext.bind.apply(Ext.Function, [this].concat(Array.prototype.slice.call(arguments))); }, defer : function(){ deprecate({pkg:'Function', member:'.defer', alt:'Ext.defer', msg:'Note that this is now a static method, so the function will be the first argument to the new version.'}); return Ext.defer.apply(Ext.Function, [this].concat(Array.prototype.slice.call(arguments))); } }); /*------------------------------------------------------------- * String overrides *-------------------------------------------------------------*/ // String static methods: Ext.applyIf(String, { format : function(){ deprecate({pkg:'String', member:'format', alt:'Ext.String.format'}); return Ext.String.format.apply(Ext.String, arguments); }, escape : function(string) { deprecate({pkg:'String', member:'escape', alt:'Ext.String.escape'}); return Ext.String.escape.apply(Ext.String, arguments); }, leftPad : function (val, size, ch) { deprecate({pkg:'String', member:'leftPad', alt:'Ext.String.leftPad'}); return Ext.String.leftPad.apply(Ext.String, arguments); } }); // String instance methods: Ext.applyIf(String.prototype, { toggle : function(value, other){ deprecate({pkg:'String', member:'.toggle', alt:'Ext.String.toggle', msg:'Note that this is now a static method, so the string instance will be the first argument to the new version.'}); return Ext.String.toggle.call(Ext.String, this, value, other); }, trim : function(){ deprecate({pkg:'String', member:'.trim', alt:'Ext.String.trim', msg:'Note that this is now a static method, so the string instance will be the first argument to the new version.'}); return Ext.String.trim.call(Ext.String, this); } }); /*------------------------------------------------------------- * Array overrides *-------------------------------------------------------------*/ Ext.applyIf(Array.prototype, { indexOf : function(o){ deprecate({pkg:'Array', member:'.indexOf', alt:'Ext.Array.indexOf', msg:'Note that this is now a static method, so the array instance will be the first argument to the new version. '+ 'Also the new version adds an optional "from index" as the last argument.'}); return Ext.Array.indexOf.call(Ext.Array, this, o); }, remove : function(o){ deprecate({pkg:'Array', member:'.remove', alt:'Ext.Array.remove', msg:'Note that this is now a static method, so the array instance will be the first argument to the new version.'}); return Ext.Array.remove.call(Ext.Array, this, o); } }); /*------------------------------------------------------------- * Number overrides *-------------------------------------------------------------*/ Ext.applyIf(Number.prototype, { constrain : function(min, max){ deprecate({pkg:'Number', member:'.constrain', alt:'Ext.Number.constrain', msg:'Note that this is now a static method, so the number instance will be the first argument to the new version.'}); return Ext.Number.constrain.call(Ext.Number, this, min, max); } }); /*------------------------------------------------------------- * Date overrides. * NOTE: The methods from the Date class under Ext.util * in 3.x are aliased separately in ext3-compat.js. *-------------------------------------------------------------*/ Ext.applyIf(Date.prototype, { /** Returns the number of milliseconds between this date and date @param {Date} date (optional) Defaults to now @return {Number} The diff in milliseconds @member Date getElapsed @deprecated */ getElapsed : function(date) { deprecate({pkg:'Core', member:'.getElapsed', alt:'Ext.Date.getElapsed'}); return Ext.Date.getElapsed.call(Ext.Date, this, date); } }); /*------------------------------------------------------------- * Element *-------------------------------------------------------------*/ Ext.apply(Ext.core.Element.prototype, { getMargins : function(){ deprecate({pkg:'Ext.Element', member:'getMargins', alt:'getMargin'}); return this.getMargin.apply(this, arguments); }, addClass : function(){ deprecate({pkg:'Ext.Element', member:'addClass', alt:'addCls'}); return this.addCls.apply(this, arguments); }, addClassOnClick : function(){ deprecate({pkg:'Ext.Element', member:'addClassOnClick', alt:'addClsOnClick'}); return this.addClsOnClick.apply(this, arguments); }, addClassOnFocus : function(){ deprecate({pkg:'Ext.Element', member:'addClassOnFocus', alt:'addClsOnFocus'}); return this.addClsOnFocus.apply(this, arguments); }, addClassOnOver : function(){ deprecate({pkg:'Ext.Element', member:'addClassOnOver', alt:'addClsOnOver'}); return this.addClsOnOver.apply(this, arguments); }, hasClass : function(){ deprecate({pkg:'Ext.Element', member:'hasClass', alt:'hasCls'}); return this.hasCls.apply(this, arguments); }, radioClass : function(){ deprecate({pkg:'Ext.Element', member:'radioClass', alt:'radioCls'}); return this.radioCls.apply(this, arguments); }, removeClass : function(){ deprecate({pkg:'Ext.Element', member:'removeClass', alt:'removeCls'}); return this.removeCls.apply(this, arguments); }, replaceClass : function(){ deprecate({pkg:'Ext.Element', member:'replaceClass', alt:'replaceCls'}); return this.replaceCls.apply(this, arguments); }, toggleClass : function(){ deprecate({pkg:'Ext.Element', member:'toggleClass', alt:'toggleCls'}); return this.toggleCls.apply(this, arguments); }, // Can't do this since Ext internally uses these calls. Reverting them will break Ext 4 code, so have to doc as breaking changes. // child : function(selector, returnDom){ // notify('Ext.Element.child now returns a single direct child in 4.0 (switched with Ext.Element.down). '+ // 'Reverting to the 3.x behavior that matches at any depth -- please verify this call when migrating to Ext 4.'); // // var n = Ext.DomQuery.selectNode(selector, this.dom); // return returnDom ? n : Ext.get(n); // }, // down : function(selector, returnDom){ // notify('Ext.Element.down now returns a single child at any depth in 4.0 (switched with Ext.Element.child). '+ // 'Reverting to the 3.x behavior that matches a direct child only -- please verify this call when migrating to Ext 4.'); // // var n = Ext.DomQuery.selectNode(" > " + selector, this.dom); // return returnDom ? n : Ext.get(n); // }, animate: function(args, duration, onComplete, easing) { if (arguments.length > 1 || Ext.isEmpty(args)) { deprecate({pkg:'Ext.Element', member:'animate', msg:'Ext.Element.animate should be called with a single configuration object. '+ 'See the header API docs for Ext.util.Animate for details on the supported config attribute syntax.'}); } var me = this; if (!me.id) { me = Ext.get(me.dom); } if (Ext.fx.Manager.hasFxBlock(me.id)) { return me; } args = args || {}; if (duration) { args.duration = duration; } if (onComplete) { args.callback = onComplete; } if (easing) { args.easing = easing; } Ext.fx.Manager.queueFx(Ext.create('Ext.fx.Anim', me.anim(args))); return this; }, anim: Ext.Function.createInterceptor(Ext.core.Element.prototype.anim, function(config) { if (Ext.isObject(config)) { if (config.delay && config.delay < 10) { config.delay *= 1000; notify({pkg:'Ext.Element', member:'animate', msg:'Detected an extremely small animation delay, assuming the '+ 'deprecated unit seconds were used. Please change to milliseconds.'}); } if (config.duration && config.duration < 10) { config.duration *= 1000; notify({pkg:'Ext.Element', member:'animate', msg:'Detected an extremely small animation duration, assuming the '+ 'deprecated unit seconds were used. Please change to milliseconds.'}); } if (config.endOpacity) { config.opacity = config.endOpacity; delete config.endOpacity; deprecate({pkg:'Ext.Element', member:'animate', msg:'The endOpacity attribute of the animate config object is '+ 'no longer supported. Please use opacity instead.'}); } } }) }); /*------------------------------------------------------------- * Ajax *-------------------------------------------------------------*/ Ext.Ajax.serializeForm = function(form) { deprecate({pkg:'Ext.Ajax', member:'serializeForm', alt:'Ext.core.Element.serializeForm'}); return Ext.core.Element.serializeForm(form); }; // Ext.extend = function(subclass, superclass, members) { // deprecate({pkg:'Ext', member:'extend', alt:'Ext.define', // msg:'Declare your class with Ext.define() and use the "extend" config to specify the superclass.'}); // // if (arguments.length === 2 && Ext.isObject(superclass)) { // members = superclass; // superclass = subclass; // subclass = null; // } // // var cls; // // if (!superclass) { // compat.error("Attempting to extend from a class which has not been loaded on the page."); // } // members = members || {}; // members.extend = superclass; // members.preprocessors = ['extend', 'mixins', 'config', 'statics']; // // if (subclass) { // if (!subclass.hasOwnProperty('constructor')) { // subclass.constructor = Ext.apply({}, subclass); // } // cls = new Ext.Class(subclass, members); // } // else { // cls = new Ext.Class(members); // } // // cls.prototype.override = function(o) { // for (var m in o) { // if (o.hasOwnProperty(m)) { // this[m] = o[m]; // } // } // }; // // return cls; // }; })();