// for old browsers window.undefined = window.undefined; /** * @class Ext * Ext core utilities and functions. * @singleton */ Ext = { /** * The version of the framework * @type String */ version : '3.4.1.1', versionDetail : { major : 3, minor : 4, patch : 1.1 } }; /** * Copies all the properties of config to obj. * @param {Object} obj 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 * @member Ext apply */ Ext.apply = function(o, c, defaults){ // no "this" reference for friendly out of scope calls if(defaults){ Ext.apply(o, defaults); } if(o && c && typeof c == 'object'){ for(var p in c){ o[p] = c[p]; } } return o; }; (function(){ var idSeed = 0, toString = Object.prototype.toString, ua = navigator.userAgent.toLowerCase(), check = function(r){ return r.test(ua); }, DOC = document, docMode = DOC.documentMode, isStrict = DOC.compatMode == "CSS1Compat", isOpera = check(/opera/), isChrome = check(/\bchrome\b/), isWebKit = check(/webkit/), isSafari = !isChrome && check(/safari/), isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2 isSafari3 = isSafari && check(/version\/3/), isSafari4 = isSafari && check(/version\/4/), isIE = !isOpera && check(/msie/), isIE7 = isIE && ((check(/msie 7/) && docMode != 8 && docMode != 9 && docMode != 10) || docMode == 7), isIE8 = isIE && ((check(/msie 8/) && docMode != 7 && docMode != 9 && docMode != 10) || docMode == 8), isIE9 = isIE && ((check(/msie 9/) && docMode != 7 && docMode != 8 && docMode != 10) || docMode == 9), isIE10 = isIE && ((check(/msie 10/) && docMode != 7 && docMode != 8 && docMode != 9) || docMode == 10), isIE6 = isIE && check(/msie 6/), isIE9m = isIE && (isIE6 || isIE7 || isIE8 || isIE9), isGecko = !isWebKit && check(/gecko/), isGecko2 = isGecko && check(/rv:1\.8/), isGecko3 = isGecko && check(/rv:1\.9/), isBorderBox = isIE9m && !isStrict, isWindows = check(/windows|win32/), isMac = check(/macintosh|mac os x/), isAir = check(/adobeair/), isLinux = check(/linux/), isSecure = /^https/i.test(window.location.protocol), noArgs = [], nonEnumerables = [], emptyFn = Ext.emptyFn, t = Ext.apply({}, { constructor: emptyFn, toString: emptyFn, valueOf: emptyFn }), callOverrideParent = function () { var method = callOverrideParent.caller.caller; // skip callParent (our caller) return method.$owner.prototype[method.$name].apply(this, arguments); }; if (t.constructor !== emptyFn) { nonEnumerables.push('constructor'); } if (t.toString !== emptyFn) { nonEnumerables.push('toString'); } if (t.valueOf !== emptyFn) { nonEnumerables.push('valueOf'); } if (!nonEnumerables.length) { nonEnumerables = null; } // Create the abstract Base class to provide an empty constructor and callParent implementations function Base () { // } Ext.apply(Base, { $isClass: true, callParent: function (args) { var method; // This code is intentionally inlined for the least number of debugger stepping return (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass.self[method.$name])).apply(this, args || noArgs); } }); Base.prototype = { constructor: function() { }, callParent: function(args) { // NOTE: this code is deliberately as few expressions (and no function calls) // as possible so that a debugger can skip over this noise with the minimum number // of steps. Basically, just hit Step Into until you are where you really wanted // to be. var method, superMethod = (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name])); return superMethod.apply(this, args || noArgs); } }; // remove css image flicker if(isIE6){ try{ DOC.execCommand("BackgroundImageCache", false, true); }catch(e){} } Ext.apply(Ext, { /** * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent * the IE insecure content warning (<tt>'about:blank'</tt>, except for IE in secure mode, which is <tt>'javascript:""'</tt>). * @type String */ SSL_SECURE_URL : isSecure && isIE ? 'javascript:""' : 'about:blank', /** * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode * @type Boolean */ isStrict : isStrict, /** * True if the page is running over SSL * @type Boolean */ isSecure : isSecure, /** * True when the document is fully initialized and ready for action * @type Boolean */ isReady : false, /** * True if the {@link Ext.Fx} Class is available * @type Boolean * @property enableFx */ /** * HIGHLY EXPERIMENTAL * True to force css based border-box model override and turning off javascript based adjustments. This is a * runtime configuration and must be set before onReady. * @type Boolean */ enableForcedBoxModel : false, /** * True to automatically uncache orphaned Ext.Elements periodically (defaults to true) * @type Boolean */ enableGarbageCollector : true, /** * True to automatically purge event listeners during garbageCollection (defaults to false). * @type Boolean */ enableListenerCollection : false, /** * EXPERIMENTAL - True to cascade listener removal to child elements when an element is removed. * Currently not optimized for performance. * @type Boolean */ enableNestedListenerRemoval : false, /** * Indicates whether to use native browser parsing for JSON methods. * This option is ignored if the browser does not support native JSON methods. * <b>Note: Native JSON methods will not work with objects that have functions. * Also, property names must be quoted, otherwise the data will not parse.</b> (Defaults to false) * @type Boolean */ USE_NATIVE_JSON : false, /** * Copies all the properties of config to obj if they don't already exist. * @param {Object} obj The receiver of the properties * @param {Object} config The source of the properties * @return {Object} returns obj */ applyIf : function(o, c){ if(o){ for(var p in c){ if(!Ext.isDefined(o[p])){ o[p] = c[p]; } } } return o; }, /** * Generates unique ids. If the element already has an id, it is unchanged * @param {Mixed} el (optional) The element to generate an id for * @param {String} prefix (optional) Id prefix (defaults "ext-gen") * @return {String} The generated Id. */ id : function(el, prefix){ el = Ext.getDom(el, true) || {}; if (!el.id) { el.id = (prefix || "ext-gen") + (++idSeed); } return el.id; }, /** * <p>Extends one class to create a subclass and optionally overrides members with the passed literal. This method * also adds the function "override()" to the subclass that can be used to override members of the class.</p> * For example, to create a subclass of Ext GridPanel: * <pre><code> MyGridPanel = Ext.extend(Ext.grid.GridPanel, { constructor: function(config) { // Create configuration for this Grid. var store = new Ext.data.Store({...}); var colModel = new Ext.grid.ColumnModel({...}); // Create a new config object containing our computed properties // *plus* whatever was in the config parameter. config = Ext.apply({ store: store, colModel: colModel }, config); MyGridPanel.superclass.constructor.call(this, config); // Your postprocessing here }, yourMethod: function() { // etc. } }); </code></pre> * * <p>This function also supports a 3-argument call in which the subclass's constructor is * passed as an argument. In this form, the parameters are as follows:</p> * <div class="mdetail-params"><ul> * <li><code>subclass</code> : Function <div class="sub-desc">The subclass constructor.</div></li> * <li><code>superclass</code> : Function <div class="sub-desc">The constructor of class being extended</div></li> * <li><code>overrides</code> : Object <div class="sub-desc">A literal with members which are copied into the subclass's * prototype, and are therefore shared among all instances of the new class.</div></li> * </ul></div> * * @param {Function} superclass The constructor of class being extended. * @param {Object} overrides <p>A literal with members which are copied into the subclass's * prototype, and are therefore shared between all instances of the new class.</p> * <p>This may contain a special member named <tt><b>constructor</b></tt>. This is used * to define the constructor of the new class, and is returned. If this property is * <i>not</i> specified, a constructor is generated and returned which just calls the * superclass's constructor passing on its parameters.</p> * <p><b>It is essential that you call the superclass constructor in any provided constructor. See example code.</b></p> * @return {Function} The subclass constructor from the <code>overrides</code> parameter, or a generated one if not provided. */ extend : function(){ // inline overrides var io = function(o){ for(var m in o){ this[m] = o[m]; } }; var oc = Object.prototype.constructor; return function(sb, sp, overrides){ if(typeof sp == 'object'){ overrides = sp; sp = sb; sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);}; } var F = function(){}, sbp, spp = sp.prototype; F.prototype = spp; sbp = sb.prototype = new F(); sbp.constructor=sb; sb.superclass=spp; if(spp.constructor == oc){ spp.constructor=sp; } sb.override = function(o){ Ext.override(sb, o); }; sbp.superclass = sbp.supr = (function(){ return spp; }); sbp.override = io; Ext.override(sb, overrides); sb.extend = function(o){return Ext.extend(sb, o);}; return sb; }; }(), global: (function () { return this; })(), Base: Base, namespaceCache: {}, createNamespace: function (namespaceOrClass, isClass) { var cache = Ext.namespaceCache, namespace = isClass ? namespaceOrClass.substring(0, namespaceOrClass.lastIndexOf('.')) : namespaceOrClass, ns = cache[namespace], i, n, part, parts, partials; if (!ns) { ns = Ext.global; if (namespace) { partials = []; parts = namespace.split('.'); for (i = 0, n = parts.length; i < n; ++i) { part = parts[i]; ns = ns[part] || (ns[part] = {}); partials.push(part); cache[partials.join('.')] = ns; // build up prefixes as we go } } } return ns; }, getClassByName: function (className) { var parts = className.split('.'), cls = Ext.global, n = parts.length, i; for (i = 0; cls && i < n; ++i) { cls = cls[parts[i]]; } return cls || null; }, addMembers: function (cls, target, members, handleNonEnumerables) { var i, name, member; for (name in members) { if (members.hasOwnProperty(name)) { member = members[name]; if (typeof member == 'function') { member.$owner = cls; member.$name = name; } target[name] = member; } } if (handleNonEnumerables && nonEnumerables) { for (i = nonEnumerables.length; i-- > 0; ) { name = nonEnumerables[i]; if (members.hasOwnProperty(name)) { member = members[name]; if (typeof member == 'function') { member.$owner = cls; member.$name = name; } target[name] = member; } } } }, /** * @method * Defines a class or override. A basic class is defined like this: * * Ext.define('My.awesome.Class', { * someProperty: 'something', * * someMethod: function(s) { * alert(s + this.someProperty); * } * * ... * }); * * var obj = new My.awesome.Class(); * * obj.someMethod('Say '); // alerts 'Say something' * * To create an anonymous class, pass `null` for the `className`: * * Ext.define(null, { * constructor: function () { * // ... * } * }); * * In some cases, it is helpful to create a nested scope to contain some private * properties. The best way to do this is to pass a function instead of an object * as the second parameter. This function will be called to produce the class * body: * * Ext.define('MyApp.foo.Bar', function () { * var id = 0; * * return { * nextId: function () { * return ++id; * } * }; * }); * * When using this form of `Ext.define`, the function is passed a reference to its * class. This can be used as an efficient way to access any static properties you * may have: * * Ext.define('MyApp.foo.Bar', function (Bar) { * return { * statics: { * staticMethod: function () { * // ... * } * }, * * method: function () { * return Bar.staticMethod(); * } * }; * }); * * To define an override, include the `override` property. The content of an * override is aggregated with the specified class in order to extend or modify * that class. This can be as simple as setting default property values or it can * extend and/or replace methods. This can also extend the statics of the class. * * One use for an override is to break a large class into manageable pieces. * * // File: /src/app/Panel.js * * Ext.define('My.app.Panel', { * extend: 'Ext.panel.Panel', * * constructor: function (config) { * this.callParent(arguments); // calls Ext.panel.Panel's constructor * //... * }, * * statics: { * method: function () { * return 'abc'; * } * } * }); * * // File: /src/app/PanelPart2.js * Ext.define('My.app.PanelPart2', { * override: 'My.app.Panel', * * constructor: function (config) { * this.callParent(arguments); // calls My.app.Panel's constructor * //... * } * }); * * Another use of overrides is to provide optional parts of classes that can be * independently required. In this case, the class may even be unaware of the * override altogether. * * Ext.define('My.ux.CoolTip', { * override: 'Ext.tip.ToolTip', * * constructor: function (config) { * this.callParent(arguments); // calls Ext.tip.ToolTip's constructor * //... * } * }); * * Overrides can also contain statics: * * Ext.define('My.app.BarMod', { * override: 'Ext.foo.Bar', * * statics: { * method: function (x) { * return this.callParent([x * 2]); // call Ext.foo.Bar.method * } * } * }); * * @param {String} className The class name to create in string dot-namespaced format, for example: * 'My.very.awesome.Class', 'FeedViewer.plugin.CoolPager' * It is highly recommended to follow this simple convention: * - The root and the class name are 'CamelCased' * - Everything else is lower-cased * Pass `null` to create an anonymous class. * @param {Object} data The key - value pairs of properties to apply to this class. Property names can be of any valid * strings, except those in the reserved listed below: * - `mixins` * - `statics` * - `config` * - `alias` * - `self` * - `singleton` * - `alternateClassName` * - `override` * * @param {Function} createdFn Optional callback to execute after the class is created, the execution scope of which * (`this`) will be the newly created class itself. * @return {Ext.Base} * @markdown * @member Ext * @method define */ define: function (className, body, createdFn) { var override = body.override, cls, extend, name, namespace; if (override) { delete body.override; cls = Ext.getClassByName(override); Ext.override(cls, body); } else { if (className) { namespace = Ext.createNamespace(className, true); name = className.substring(className.lastIndexOf('.')+1); } cls = function ctor () { this.constructor.apply(this, arguments); } if (className) { cls.displayName = className; } cls.$isClass = true; cls.callParent = Ext.Base.callParent; if (typeof body == 'function') { body = body(cls); } extend = body.extend; if (extend) { delete body.extend; if (typeof extend == 'string') { extend = Ext.getClassByName(extend); } } else { extend = Base; } Ext.extend(cls, extend, body); if (cls.prototype.constructor === cls) { delete cls.prototype.constructor; } // Not extending a class which derives from Base... if (!cls.prototype.$isClass) { Ext.applyIf(cls.prototype, Base.prototype); } cls.prototype.self = cls; if (body.xtype) { Ext.reg(body.xtype, cls); } cls = body.singleton ? new cls() : cls; if (className) { namespace[name] = cls; } } if (createdFn) { createdFn.call(cls); } return cls; }, /** * Overrides members of the specified `target` with the given values. * * If the `target` is a function, it is assumed to be a constructor and the contents * of `overrides` are applied to its `prototype` using {@link Ext#apply Ext.apply}. * * If the `target` is an instance of a class created using {@link #define}, * the `overrides` are applied to only that instance. In this case, methods are * specially processed to allow them to use {@link Ext.Base#callParent}. * * var panel = new Ext.Panel({ ... }); * * Ext.override(panel, { * initComponent: function () { * // extra processing... * * this.callParent(); * } * }); * * If the `target` is none of these, the `overrides` are applied to the `target` * using {@link Ext#apply Ext.apply}. * * Please refer to {@link Ext#define Ext.define} for further details. * * @param {Object} target The target to override. * @param {Object} overrides The properties to add or replace on `target`. * @method override */ override: function (target, overrides) { var proto, statics; if (overrides) { if (target.$isClass) { statics = overrides.statics; if (statics) { delete overrides.statics; } Ext.addMembers(target, target.prototype, overrides, true); if (statics) { Ext.addMembers(target, target, statics); } } else if (typeof target == 'function') { proto = target.prototype; Ext.apply(proto, overrides); if(Ext.isIE && overrides.hasOwnProperty('toString')){ proto.toString = overrides.toString; } } else { var owner = target.self, name, value; if (owner && owner.$isClass) { for (name in overrides) { if (overrides.hasOwnProperty(name)) { value = overrides[name]; if (typeof value == 'function') { //<debug> if (owner.$className) { value.displayName = owner.$className + '#' + name; } //</debug> value.$name = name; value.$owner = owner; value.$previous = target.hasOwnProperty(name) ? target[name] // already hooked, so call previous hook : callOverrideParent; // calls by name on prototype } target[name] = value; } } } else { Ext.apply(target, overrides); if (!target.constructor.$isClass) { target.constructor.prototype.callParent = Base.prototype.callParent; target.constructor.callParent = Base.callParent; } } } } }, /** * Creates namespaces to be used for scoping variables and classes so that they are not global. * Specifying the last node of a namespace implicitly creates all other nodes. Usage: * <pre><code> Ext.namespace('Company', 'Company.data'); Ext.namespace('Company.data'); // equivalent and preferable to above syntax Company.Widget = function() { ... } Company.data.CustomStore = function(config) { ... } </code></pre> * @param {String} namespace1 * @param {String} namespace2 * @param {String} etc * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created) * @method namespace */ namespace : function(){ var len1 = arguments.length, i = 0, len2, j, main, ns, sub, current; for(; i < len1; ++i) { main = arguments[i]; ns = arguments[i].split('.'); current = window[ns[0]]; if (current === undefined) { current = window[ns[0]] = {}; } sub = ns.slice(1); len2 = sub.length; for(j = 0; j < len2; ++j) { current = current[sub[j]] = current[sub[j]] || {}; } } return current; }, /** * Takes an object and converts it to an encoded URL. e.g. Ext.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2". Optionally, property values can be arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value. * @param {Object} o * @param {String} pre (optional) A prefix to add to the url encoded string * @return {String} */ urlEncode : function(o, pre){ var empty, buf = [], e = encodeURIComponent; Ext.iterate(o, function(key, item){ empty = Ext.isEmpty(item); Ext.each(empty ? key : item, function(val){ buf.push('&', e(key), '=', (!Ext.isEmpty(val) && (val != key || !empty)) ? (Ext.isDate(val) ? Ext.encode(val).replace(/"/g, '') : e(val)) : ''); }); }); if(!pre){ buf.shift(); pre = ''; } return pre + buf.join(''); }, /** * Takes an encoded URL and and converts it to an object. Example: <pre><code> Ext.urlDecode("foo=1&bar=2"); // returns {foo: "1", bar: "2"} Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); // returns {foo: "1", bar: ["2", "3", "4"]} </code></pre> * @param {String} string * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false). * @return {Object} A literal with members */ urlDecode : function(string, overwrite){ if(Ext.isEmpty(string)){ return {}; } var obj = {}, pairs = string.split('&'), d = decodeURIComponent, name, value; Ext.each(pairs, function(pair) { pair = pair.split('='); name = d(pair[0]); value = d(pair[1]); obj[name] = overwrite || !obj[name] ? value : [].concat(obj[name]).concat(value); }); return obj; }, /** * Appends content to the query string of a URL, handling logic for whether to place * a question mark or ampersand. * @param {String} url The URL to append to. * @param {String} s The content to append to the URL. * @return (String) The resulting URL */ urlAppend : function(url, s){ if(!Ext.isEmpty(s)){ return url + (url.indexOf('?') === -1 ? '?' : '&') + s; } return url; }, /** * Converts any iterable (numeric indices and a length property) into a true array * Don't use this on strings. IE doesn't support "abc"[0] which this implementation depends on. * For strings, use this instead: "abc".match(/./g) => [a,b,c]; * @param {Iterable} the iterable object to be turned into a true Array. * @return (Array) array */ toArray : function(){ return isIE ? function(a, i, j, res){ res = []; for(var x = 0, len = a.length; x < len; x++) { res.push(a[x]); } return res.slice(i || 0, j || res.length); } : function(a, i, j){ return Array.prototype.slice.call(a, i || 0, j || a.length); }; }(), isIterable : function(v){ //check for array or arguments if(Ext.isArray(v) || v.callee){ return true; } //check for node list type if(/NodeList|HTMLCollection/.test(toString.call(v))){ return true; } //NodeList has an item and length property //IXMLDOMNodeList has nextNode method, needs to be checked first. return ((typeof v.nextNode != 'undefined' || v.item) && Ext.isNumber(v.length)); }, /** * Iterates an array calling the supplied function. * @param {Array/NodeList/Mixed} array The array to be iterated. If this * argument is not really an array, the supplied function is called once. * @param {Function} fn The function to be called with each item. If the * supplied function returns false, iteration stops and this method returns * the current <code>index</code>. This function is called with * the following arguments: * <div class="mdetail-params"><ul> * <li><code>item</code> : <i>Mixed</i> * <div class="sub-desc">The item at the current <code>index</code> * in the passed <code>array</code></div></li> * <li><code>index</code> : <i>Number</i> * <div class="sub-desc">The current index within the array</div></li> * <li><code>allItems</code> : <i>Array</i> * <div class="sub-desc">The <code>array</code> passed as the first * argument to <code>Ext.each</code>.</div></li> * </ul></div> * @param {Object} scope The scope (<code>this</code> reference) in which the specified function is executed. * Defaults to the <code>item</code> at the current <code>index</code> * within the passed <code>array</code>. * @return See description for the fn parameter. */ each : function(array, fn, scope){ if(Ext.isEmpty(array, true)){ return; } if(!Ext.isIterable(array) || Ext.isPrimitive(array)){ array = [array]; } for(var i = 0, len = array.length; i < len; i++){ if(fn.call(scope || array[i], array[i], i, array) === false){ return i; }; } }, /** * Iterates either the elements in an array, or each of the properties in an object. * <b>Note</b>: If you are only iterating arrays, it is better to call {@link #each}. * @param {Object/Array} object The object or array to be iterated * @param {Function} fn The function to be called for each iteration. * The iteration will stop if the supplied function returns false, or * all array elements / object properties have been covered. The signature * varies depending on the type of object being interated: * <div class="mdetail-params"><ul> * <li>Arrays : <tt>(Object item, Number index, Array allItems)</tt> * <div class="sub-desc"> * When iterating an array, the supplied function is called with each item.</div></li> * <li>Objects : <tt>(String key, Object value, Object)</tt> * <div class="sub-desc"> * When iterating an object, the supplied function is called with each key-value pair in * the object, and the iterated object</div></li> * </ul></div> * @param {Object} scope The scope (<code>this</code> reference) in which the specified function is executed. Defaults to * the <code>object</code> being iterated. */ iterate : function(obj, fn, scope){ if(Ext.isEmpty(obj)){ return; } if(Ext.isIterable(obj)){ Ext.each(obj, fn, scope); return; }else if(typeof obj == 'object'){ for(var prop in obj){ if(obj.hasOwnProperty(prop)){ if(fn.call(scope || obj, prop, obj[prop], obj) === false){ return; }; } } } }, /** * Return the dom node for the passed String (id), dom node, or Ext.Element. * Optional 'strict' flag is needed for IE since it can return 'name' and * 'id' elements by using getElementById. * Here are some examples: * <pre><code> // gets dom node based on id var elDom = Ext.getDom('elId'); // gets dom node based on the dom node var elDom1 = Ext.getDom(elDom); // If we don't know if we are working with an // Ext.Element or a dom node use Ext.getDom function(el){ var dom = Ext.getDom(el); // do something with the dom node } * </code></pre> * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc) * when this method is called to be successful. * @param {Mixed} el * @return HTMLElement */ getDom : function(el, strict){ if(!el || !DOC){ return null; } if (el.dom){ return el.dom; } else { if (typeof el == 'string') { var e = DOC.getElementById(el); // IE returns elements with the 'name' and 'id' attribute. // we do a strict check to return the element with only the id attribute if (e && isIE && strict) { if (el == e.getAttribute('id')) { return e; } else { return null; } } return e; } else { return el; } } }, /** * Returns the current document body as an {@link Ext.Element}. * @return Ext.Element The document body */ getBody : function(){ return Ext.get(DOC.body || DOC.documentElement); }, /** * Returns the current document body as an {@link Ext.Element}. * @return Ext.Element The document body * @method */ getHead : function() { var head; return function() { if (head == undefined) { head = Ext.get(DOC.getElementsByTagName("head")[0]); } return head; }; }(), /** * <p>Removes this element from the document, removes all DOM event listeners, and deletes the cache reference. * All DOM event listeners are removed from this element. If {@link Ext#enableNestedListenerRemoval} is * <code>true</code>, then DOM event listeners are also removed from all child nodes. The body node * will be ignored if passed in.</p> * @param {HTMLElement} node The node to remove * @method */ removeNode : isIE && !isIE8 ? function(){ var d; return function(n){ if(n && n.tagName != 'BODY'){ (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n); d = d || DOC.createElement('div'); d.appendChild(n); d.innerHTML = ''; delete Ext.elCache[n.id]; } }; }() : function(n){ if(n && n.parentNode && n.tagName != 'BODY'){ (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n); n.parentNode.removeChild(n); delete Ext.elCache[n.id]; } }, /** * <p>Returns true if the passed value is empty.</p> * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul> * <li>null</li> * <li>undefined</li> * <li>an empty array</li> * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li> * </ul></div> * @param {Mixed} value The value to test * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false) * @return {Boolean} */ isEmpty : function(v, allowBlank){ return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false); }, /** * Returns true if the passed value is a JavaScript array, otherwise false. * @param {Mixed} value The value to test * @return {Boolean} */ isArray : function(v){ return toString.apply(v) === '[object Array]'; }, /** * Returns true if the passed object is a JavaScript date object, otherwise false. * @param {Object} object The object to test * @return {Boolean} */ isDate : function(v){ return toString.apply(v) === '[object Date]'; }, /** * Returns true if the passed value is a JavaScript Object, otherwise false. * @param {Mixed} value The value to test * @return {Boolean} */ isObject : function(v){ return !!v && Object.prototype.toString.call(v) === '[object Object]'; }, /** * Returns true if the passed value is a JavaScript 'primitive', a string, number or boolean. * @param {Mixed} value The value to test * @return {Boolean} */ isPrimitive : function(v){ return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v); }, /** * Returns true if the passed value is a JavaScript Function, otherwise false. * @param {Mixed} value The value to test * @return {Boolean} */ isFunction : function(v){ return toString.apply(v) === '[object Function]'; }, /** * Returns true if the passed value is a number. Returns false for non-finite numbers. * @param {Mixed} value The value to test * @return {Boolean} */ isNumber : function(v){ return typeof v === 'number' && isFinite(v); }, /** * Returns true if the passed value is a string. * @param {Mixed} value The value to test * @return {Boolean} */ isString : function(v){ return typeof v === 'string'; }, /** * Returns true if the passed value is a boolean. * @param {Mixed} value The value to test * @return {Boolean} */ isBoolean : function(v){ return typeof v === 'boolean'; }, /** * Returns true if the passed value is an HTMLElement * @param {Mixed} value The value to test * @return {Boolean} */ isElement : function(v) { return v ? !!v.tagName : false; }, /** * Returns true if the passed value is not undefined. * @param {Mixed} value The value to test * @return {Boolean} */ isDefined : function(v){ return typeof v !== 'undefined'; }, /** * True if the detected browser is Opera. * @type Boolean */ isOpera : isOpera, /** * True if the detected browser uses WebKit. * @type Boolean */ isWebKit : isWebKit, /** * True if the detected browser is Chrome. * @type Boolean */ isChrome : isChrome, /** * True if the detected browser is Safari. * @type Boolean */ isSafari : isSafari, /** * True if the detected browser is Safari 3.x. * @type Boolean */ isSafari3 : isSafari3, /** * True if the detected browser is Safari 4.x. * @type Boolean */ isSafari4 : isSafari4, /** * True if the detected browser is Safari 2.x. * @type Boolean */ isSafari2 : isSafari2, /** * True if the detected browser is Internet Explorer. * @type Boolean */ isIE : isIE, /** * True if the detected browser is Internet Explorer 6.x. * @type Boolean */ isIE6 : isIE6, /** * True if the detected browser is Internet Explorer 7.x. * @type Boolean */ isIE7 : isIE7, /** * True if the detected browser is Internet Explorer 8.x. * @type Boolean */ isIE8 : isIE8, /** * True if the detected browser is Internet Explorer 9.x. * @type Boolean */ isIE9 : isIE9, /** * True if the detected browser is Internet Explorer 10.x * @type Boolean */ isIE10 : isIE10, /** * True if the detected browser is Internet Explorer 9.x or lower * @type Boolean */ isIE9m : isIE9m, /** * True if the detected browser is Internet Explorer 10.x or higher * @type Boolean */ isIE10p : isIE && !(isIE6 || isIE7 || isIE8 || isIE9), // IE10 quirks behaves like Gecko/WebKit quirks, so don't include it here // Used internally isIEQuirks: isIE && (!isStrict && (isIE6 || isIE7 || isIE8 || isIE9)), /** * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox). * @type Boolean */ isGecko : isGecko, /** * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x). * @type Boolean */ isGecko2 : isGecko2, /** * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x). * @type Boolean */ isGecko3 : isGecko3, /** * True if the detected browser is Internet Explorer running in non-strict mode. * @type Boolean */ isBorderBox : isBorderBox, /** * True if the detected platform is Linux. * @type Boolean */ isLinux : isLinux, /** * True if the detected platform is Windows. * @type Boolean */ isWindows : isWindows, /** * True if the detected platform is Mac OS. * @type Boolean */ isMac : isMac, /** * True if the detected platform is Adobe Air. * @type Boolean */ isAir : isAir }); /** * Creates namespaces to be used for scoping variables and classes so that they are not global. * Specifying the last node of a namespace implicitly creates all other nodes. Usage: * <pre><code> Ext.namespace('Company', 'Company.data'); Ext.namespace('Company.data'); // equivalent and preferable to above syntax Company.Widget = function() { ... } Company.data.CustomStore = function(config) { ... } </code></pre> * @param {String} namespace1 * @param {String} namespace2 * @param {String} etc * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created) * @method ns */ Ext.ns = Ext.namespace; })(); Ext.ns('Ext.util', 'Ext.lib', 'Ext.data', 'Ext.supports'); Ext.elCache = {}; /** * @class Function * These functions are available on every Function object (any JavaScript function). */ Ext.apply(Function.prototype, { /** * Creates an interceptor function. The passed function is called before the original one. If it returns false, * the original one is not called. The resulting function returns the results of the original function. * The passed function is called with the parameters of the original function. Example usage: * <pre><code> var sayHi = function(name){ alert('Hi, ' + name); } sayHi('Fred'); // alerts "Hi, Fred" // create a new function that validates input without // directly modifying the original function: var sayHiToFriend = sayHi.createInterceptor(function(name){ return name == 'Brian'; }); sayHiToFriend('Fred'); // no alert sayHiToFriend('Brian'); // alerts "Hi, Brian" </code></pre> * @param {Function} fcn The function to call before the original * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed. * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b> * @return {Function} The new function */ createInterceptor : function(fcn, scope){ var method = this; return !Ext.isFunction(fcn) ? this : function() { var me = this, args = arguments; fcn.target = me; fcn.method = method; return (fcn.apply(scope || me || window, args) !== false) ? method.apply(me || window, args) : null; }; }, /** * Creates a callback that passes arguments[0], arguments[1], arguments[2], ... * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code> * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always * executes in the window scope. * <p>This method is required when you want to pass arguments to a callback function. If no arguments * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn). * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function * would simply execute immediately when the code is parsed. Example usage: * <pre><code> var sayHi = function(name){ alert('Hi, ' + name); } // clicking the button alerts "Hi, Fred" new Ext.Button({ text: 'Say Hi', renderTo: Ext.getBody(), handler: sayHi.createCallback('Fred') }); </code></pre> * @return {Function} The new function */ createCallback : function(/*args...*/){ // make args available, in function below var args = arguments, method = this; return function() { return method.apply(window, args); }; }, /** * Creates a delegate (callback) that sets the scope to obj. * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code> * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the * callback points to obj. Example usage: * <pre><code> var sayHi = function(name){ // Note this use of "this.text" here. This function expects to // execute within a scope that contains a text property. In this // example, the "this" variable is pointing to the btn object that // was passed in createDelegate below. alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.'); } var btn = new Ext.Button({ text: 'Say Hi', renderTo: Ext.getBody() }); // This callback will execute in the scope of the // button instance. Clicking the button alerts // "Hi, Fred. You clicked the "Say Hi" button." btn.on('click', sayHi.createDelegate(btn, ['Fred'])); </code></pre> * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed. * <b>If omitted, defaults to the browser window.</b> * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, * if a number the args are inserted at the specified position * @return {Function} The new function */ createDelegate : function(obj, args, appendArgs){ var method = this; return function() { var callArgs = args || arguments; if (appendArgs === true){ callArgs = Array.prototype.slice.call(arguments, 0); callArgs = callArgs.concat(args); }else if (Ext.isNumber(appendArgs)){ callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first var applyArgs = [appendArgs, 0].concat(args); // create method call params Array.prototype.splice.apply(callArgs, applyArgs); // splice them in } return method.apply(obj || window, callArgs); }; }, /** * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage: * <pre><code> var sayHi = function(name){ alert('Hi, ' + name); } // executes immediately: sayHi('Fred'); // executes after 2 seconds: sayHi.defer(2000, this, ['Fred']); // this syntax is sometimes useful for deferring // execution of an anonymous function: (function(){ alert('Anonymous'); }).defer(100); </code></pre> * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately) * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed. * <b>If omitted, defaults to the browser window.</b> * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, * if a number the args are inserted at the specified position * @return {Number} The timeout id that can be used with clearTimeout */ defer : function(millis, obj, args, appendArgs){ var fn = this.createDelegate(obj, args, appendArgs); if(millis > 0){ return setTimeout(fn, millis); } fn(); return 0; } }); /** * @class String * These functions are available on every String object. */ Ext.applyIf(String, { /** * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each * token must be unique, and must increment in the format {0}, {1}, etc. Example usage: * <pre><code> var cls = 'my-class', text = 'Some text'; var s = String.format('<div class="{0}">{1}</div>', cls, text); // s now contains the string: '<div class="my-class">Some text</div>' * </code></pre> * @param {String} string The tokenized string to be formatted * @param {String} value1 The value to replace token {0} * @param {String} value2 Etc... * @return {String} The formatted string * @static */ format : function(format){ var args = Ext.toArray(arguments, 1); return format.replace(/\{(\d+)\}/g, function(m, i){ return args[i]; }); } }); /** * @class Array */ Ext.applyIf(Array.prototype, { /** * Checks whether or not the specified object exists in the array. * @param {Object} o The object to check for * @param {Number} from (Optional) The index at which to begin the search * @return {Number} The index of o in the array (or -1 if it is not found) */ indexOf : function(o, from){ var len = this.length; from = from || 0; from += (from < 0) ? len : 0; for (; from < len; ++from){ if(this[from] === o){ return from; } } return -1; }, /** * Removes the specified object from the array. If the object is not found nothing happens. * @param {Object} o The object to remove * @return {Array} this array */ remove : function(o){ var index = this.indexOf(o); if(index != -1){ this.splice(index, 1); } return this; } });