/* * Ext JS Library 2.3.0 * Copyright(c) 2006-2009, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ Ext = {version: '2.3.0'}; // for old browsers window["undefined"] = window["undefined"]; /** * @class Ext * Ext core utilities and functions. * @singleton */ /** * 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){ if(defaults){ // no "this" reference for friendly out of scope calls 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; var ua = navigator.userAgent.toLowerCase(), check = function(r){ return r.test(ua); }, isStrict = document.compatMode == "CSS1Compat", isOpera = check(/opera/), isChrome = check(/chrome/), 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/), isIE8 = isIE && check(/msie 8/), isIE6 = isIE && !isIE7 && !isIE8, isGecko = !isWebKit && check(/gecko/), isGecko2 = isGecko && check(/rv:1\.8/), isGecko3 = isGecko && check(/rv:1\.9/), isBorderBox = isIE && !isStrict, isWindows = check(/windows|win32/), isMac = check(/macintosh|mac os x/), isAir = check(/adobeair/), isLinux = check(/linux/), isSecure = /^https/i.test(window.location.protocol); // remove css image flicker if(isIE6){ try{ document.execCommand("BackgroundImageCache", false, true); }catch(e){} } Ext.apply(Ext, { /** * 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 to automatically uncache orphaned Ext.Elements periodically (defaults to true) * @type Boolean */ enableGarbageCollector : true, /** * True to automatically purge event listeners after uncaching an element (defaults to false). * Note: this only happens if enableGarbageCollector is true. * @type Boolean */ enableListenerCollection:false, /** * 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 (defaults to javascript:false). * @type String */ SSL_SECURE_URL : "javascript:false", /** * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images. (Defaults to * "http://extjs.com/s.gif" and you should change this to a URL on your server). * @type String */ BLANK_IMAGE_URL : "http:/"+"/extjs.com/s.gif", /** * A reusable empty function * @property * @type Function */ emptyFn : function(){}, /** * 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 && c){ for(var p in c){ if(typeof o[p] == "undefined"){ o[p] = c[p]; } } } return o; }, /** * Applies event listeners to elements by selectors when the document is ready. * The event name is specified with an @ suffix.

Ext.addBehaviors({
   // add a listener for click on all anchors in element with id foo
   '#foo a@click' : function(e, t){
       // do something
   },

   // add the same listener to multiple selectors (separated by comma BEFORE the @)
   '#foo a, #bar span.some-class@mouseover' : function(){
       // do something
   }
});
* @param {Object} obj The list of behaviors to apply */ addBehaviors : function(o){ if(!Ext.isReady){ Ext.onReady(function(){ Ext.addBehaviors(o); }); return; } var cache = {}; // simple cache for applying multiple behaviors to same selector does query multiple times for(var b in o){ var parts = b.split('@'); if(parts[1]){ // for Object prototype breakers var s = parts[0]; if(!cache[s]){ cache[s] = Ext.select(s); } cache[s].on(parts[1], o[b]); } } cache = null; }, /** * 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){ prefix = prefix || "ext-gen"; el = Ext.getDom(el); var id = prefix + (++idSeed); return el ? (el.id ? el.id : (el.id = id)) : id; }, /** * Extends one class with another class and optionally overrides members with the passed literal. This class * also adds the function "override()" to the class that can be used to override * members on an instance. * *

* This function also supports a 2-argument call in which the subclass's constructor is * not passed as an argument. In this form, the parameters are as follows:

*

* For example, to create a subclass of the Ext GridPanel: *


    MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
        constructor: function(config) {
            // Your preprocessing here
            MyGridPanel.superclass.constructor.apply(this, arguments);
            // Your postprocessing here
        },

        yourMethod: function() {
            // etc.
        }
    });
*

* @param {Function} subclass The class inheriting the functionality * @param {Function} superclass The class being extended * @param {Object} overrides (optional) A literal with members which are copied into the subclass's * prototype, and are therefore shared between all instances of the new class. * @return {Function} The subclass constructor. * @method extend */ 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.override = io; Ext.override(sb, overrides); sb.extend = function(o){Ext.extend(sb, o);}; return sb; }; }(), /** * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name. * Usage:

Ext.override(MyClass, {
    newMethod1: function(){
        // etc.
    },
    newMethod2: function(foo){
        // etc.
    }
});
 
* @param {Object} origclass The class to override * @param {Object} overrides The list of functions to add to origClass. This should be specified as an object literal * containing one or more methods. * @method override */ override : function(origclass, overrides){ if(overrides){ var p = origclass.prototype; for(var method in overrides){ p[method] = overrides[method]; } if(Ext.isIE && overrides.toString != origclass.toString){ p.toString = overrides.toString; } } }, /** * Creates namespaces to be used for scoping variables and classes so that they are not global. Usage: *

Ext.namespace('Company', 'Company.data');
Company.Widget = function() { ... }
Company.data.CustomStore = function(config) { ... }
* @param {String} namespace1 * @param {String} namespace2 * @param {String} etc * @method namespace */ namespace : function(){ var a=arguments, o=null, i, j, d, rt; for (i=0; i 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"]} * * @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(!string || !string.length){ return {}; } var obj = {}; var pairs = string.split('&'); var pair, name, value; for(var i = 0, len = pairs.length; i < len; i++){ pair = pairs[i].split('='); name = decodeURIComponent(pair[0]); value = decodeURIComponent(pair[1]); if(overwrite !== true){ if(typeof obj[name] == "undefined"){ obj[name] = value; }else if(typeof obj[name] == "string"){ obj[name] = [obj[name]]; obj[name].push(value); }else{ obj[name].push(value); } }else{ obj[name] = value; } } return obj; }, /** * Iterates an array calling the passed function with each item, stopping if your function returns false. If the * passed array is not really an array, your function is called once with it. * The supplied function is called with (Object item, Number index, Array allItems). * @param {Array/NodeList/Mixed} array * @param {Function} fn * @param {Object} scope */ each : function(array, fn, scope){ if(typeof array.length == "undefined" || typeof array == "string"){ 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; }; } }, // deprecated combine : function(){ var as = arguments, l = as.length, r = []; for(var i = 0; i < l; i++){ var a = as[i]; if(Ext.isArray(a)){ r = r.concat(a); }else if(a.length !== undefined && !a.substr){ r = r.concat(Array.prototype.slice.call(a, 0)); }else{ r.push(a); } } return r; }, /** * Escapes the passed string for use in a regular expression * @param {String} str * @return {String} */ escapeRe : function(s) { return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1"); }, // internal callback : function(cb, scope, args, delay){ if(typeof cb == "function"){ if(delay){ cb.defer(delay, scope, args || []); }else{ cb.apply(scope, args || []); } } }, /** * Return the dom node for the passed string (id), dom node, or Ext.Element * @param {Mixed} el * @return HTMLElement */ getDom : function(el){ if(!el || !document){ return null; } return el.dom ? el.dom : (typeof el == 'string' ? document.getElementById(el) : el); }, /** * Returns the current HTML document object as an {@link Ext.Element}. * @return Ext.Element The document */ getDoc : function(){ return Ext.get(document); }, /** * Returns the current document body as an {@link Ext.Element}. * @return Ext.Element The document body */ getBody : function(){ return Ext.get(document.body || document.documentElement); }, /** * Shorthand for {@link Ext.ComponentMgr#get} * @param {String} id * @return Ext.Component */ getCmp : function(id){ return Ext.ComponentMgr.get(id); }, /** * Utility method for validating that a value is numeric, returning the specified default value if it is not. * @param {Mixed} value Should be a number, but any type will be handled appropriately * @param {Number} defaultValue The value to return if the original value is non-numeric * @return {Number} Value, if numeric, else defaultValue */ num : function(v, defaultValue){ v = Number(v == null || typeof v == 'boolean'? NaN : v); return isNaN(v)? defaultValue : v; }, /** * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the * DOM (if applicable) and calling their destroy functions (if available). This method is primarily * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of * {@link Ext.util.Observable} can be passed in. Any number of elements and/or components can be * passed into this function in a single call as separate arguments. * @param {Mixed} arg1 An {@link Ext.Element} or {@link Ext.Component} to destroy * @param {Mixed} arg2 (optional) * @param {Mixed} etc... (optional) */ destroy : function(){ for(var i = 0, a = arguments, len = a.length; i < len; i++) { var as = a[i]; if(as){ if(typeof as.destroy == 'function'){ as.destroy(); } else if(as.dom){ as.removeAllListeners(); as.remove(); } } } }, /** * Removes a DOM node from the document. The body node will be ignored if passed in. * @param {HTMLElement} node The node to remove */ removeNode : isIE ? function(){ var d; return function(n){ if(n && n.tagName != 'BODY'){ d = d || document.createElement('div'); d.appendChild(n); d.innerHTML = ''; } } }() : function(n){ if(n && n.parentNode && n.tagName != 'BODY'){ n.parentNode.removeChild(n); } }, // inpired by a similar function in mootools library /** * Returns the type of object that is passed in. If the object passed in is null or undefined it * return false otherwise it returns one of the following values: