/* * Ext JS Library 2.2.1 * Copyright(c) 2006-2009, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ Ext = {version: '2.2.1'}; // 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(); var isStrict = document.compatMode == "CSS1Compat", isOpera = ua.indexOf("opera") > -1, isChrome = ua.indexOf("chrome") > -1, isSafari = !isChrome && (/webkit|khtml/).test(ua), isSafari3 = isSafari && ua.indexOf('webkit/5') != -1, isIE = !isOpera && ua.indexOf("msie") > -1, isIE7 = !isOpera && ua.indexOf("msie 7") > -1, isIE8 = !isOpera && ua.indexOf("msie 8") > -1, isGecko = !isSafari && !isChrome && ua.indexOf("gecko") > -1, isGecko3 = isGecko && ua.indexOf("rv:1.9") > -1, isBorderBox = isIE && !isStrict, isWindows = (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1), isMac = (ua.indexOf("macintosh") != -1 || ua.indexOf("mac os x") != -1), isAir = (ua.indexOf("adobeair") != -1), isLinux = (ua.indexOf("linux") != -1), isSecure = window.location.href.toLowerCase().indexOf("https") === 0; // remove css image flicker if(isIE && !isIE7){ 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 *
  • string: If the object passed is a string
  • *
  • number: If the object passed is a number
  • *
  • boolean: If the object passed is a boolean value
  • *
  • date: If the object passed is a Date object
  • *
  • function: If the object passed is a function reference
  • *
  • object: If the object passed is an object
  • *
  • array: If the object passed is an array
  • *
  • regexp: If the object passed is a regular expression
  • *
  • element: If the object passed is a DOM Element
  • *
  • nodelist: If the object passed is a DOM NodeList
  • *
  • textnode: If the object passed is a DOM text node and contains something other than whitespace
  • *
  • whitespace: If the object passed is a DOM text node and contains only whitespace
  • * @param {Mixed} object * @return {String} */ type : function(o){ if(o === undefined || o === null){ return false; } if(o.htmlElement){ return 'element'; } var t = typeof o; if(t == 'object' && o.nodeName) { switch(o.nodeType) { case 1: return 'element'; case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace'; } } if(t == 'object' || t == 'function') { switch(o.constructor) { case Array: return 'array'; case RegExp: return 'regexp'; case Date: return 'date'; } if(typeof o.length == 'number' && typeof o.item == 'function') { return 'nodelist'; } } return t; }, /** * Returns true if the passed value is null, undefined or an empty string. * @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 || (!allowBlank ? v === '' : false); }, /** * Utility method for validating that a value is non-empty (i.e. i) not null, ii) not undefined, and iii) not an empty string), * returning the specified default value if it is. * @param {Mixed} value The value to test * @param {Mixed} defaultValue The value to return if the original value is empty * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false) * @return {Mixed} value, if non-empty, else defaultValue */ value : function(v, defaultValue, allowBlank){ return Ext.isEmpty(v, allowBlank) ? defaultValue : v; }, /** * Returns true if the passed object is a JavaScript array, otherwise false. * @param {Object} The object to test * @return {Boolean} */ isArray : function(v){ return v && typeof v.length == 'number' && typeof v.splice == 'function'; }, /** * Returns true if the passed object is a JavaScript date object, otherwise false. * @param {Object} The object to test * @return {Boolean} */ isDate : function(v){ return v && typeof v.getFullYear == 'function'; }, /** * True if the detected browser is Opera. * @type Boolean */ isOpera : isOpera, /** * 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 2.x. * @type Boolean */ isSafari2 : isSafari && !isSafari3, /** * 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 : isIE && !isIE7 && !isIE8, /** * 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 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 : isGecko && !isGecko3, /** * 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, /** * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash, * you may want to set this to true. * @type Boolean */ useShims : ((isIE && !isIE7) || (isMac && isGecko && !isGecko3)) }); // in intellij using keyword "namespace" causes parsing errors Ext.ns = Ext.namespace; })(); Ext.ns("Ext", "Ext.util", "Ext.grid", "Ext.dd", "Ext.tree", "Ext.data", "Ext.form", "Ext.menu", "Ext.state", "Ext.lib", "Ext.layout", "Ext.app", "Ext.ux"); /** * @class Function * These functions are available on every Function object (any JavaScript function). */ Ext.apply(Function.prototype, { /** * Creates a callback that passes arguments[0], arguments[1], arguments[2], ... * Call directly on any function. Example: myFunction.createCallback(arg1, arg2) * Will create a function that is bound to those 2 args. If a specific scope is required in the * callback, use {@link #createDelegate} instead. The function returned by createCallback always * executes in the window scope. *

    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: *

    
    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')
    });
    
    * @return {Function} The new function */ createCallback : function(/*args...*/){ // make args available, in function below var args = arguments; var 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: this.myFunction.createDelegate(this, [arg1, arg2]) * Will create a function that is automatically scoped to obj so that the this variable inside the * callback points to obj. Example usage: *
    
    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']));
    
    * @param {Object} obj (optional) The object for which the scope is set * @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(typeof appendArgs == "number"){ 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: *
    
    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);
    
    * @param {Number} millis The number of milliseconds for the setTimeout call (if 0 the function is executed immediately) * @param {Object} obj (optional) The object for which the scope is set * @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){ return setTimeout(fn, millis); } fn(); return 0; }, /** * Create a combined function call sequence of the original function + the passed function. * The resulting function returns the results of the original function. * The passed fcn is called with the parameters of the original function. Example usage: *
    
    var sayHi = function(name){
        alert('Hi, ' + name);
    }
    
    sayHi('Fred'); // alerts "Hi, Fred"
    
    var sayGoodbye = sayHi.createSequence(function(name){
        alert('Bye, ' + name);
    });
    
    sayGoodbye('Fred'); // both alerts show
    
    * @param {Function} fcn The function to sequence * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window) * @return {Function} The new function */ createSequence : function(fcn, scope){ if(typeof fcn != "function"){ return this; } var method = this; return function() { var retval = method.apply(this || window, arguments); fcn.apply(scope || this || window, arguments); return retval; }; }, /** * Creates an interceptor function. The passed fcn 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 fcn is called with the parameters of the original function. Example usage: *
    
    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"
    
    * @param {Function} fcn The function to call before the original * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window) * @return {Function} The new function */ createInterceptor : function(fcn, scope){ if(typeof fcn != "function"){ return this; } var method = this; return function() { fcn.target = this; fcn.method = method; if(fcn.apply(scope || this || window, arguments) === false){ return; } return method.apply(this || window, arguments); }; } }); /** * @class String * These functions are available as static methods on the JavaScript String object. */ Ext.applyIf(String, { /** * Escapes the passed string for ' and \ * @param {String} string The string to escape * @return {String} The escaped string * @static */ escape : function(string) { return string.replace(/('|\\)/g, "\\$1"); }, /** * Pads the left side of a string with a specified character. This is especially useful * for normalizing number and date strings. Example usage: *
    
    var s = String.leftPad('123', 5, '0');
    // s now contains the string: '00123'
    
    * @param {String} string The original string * @param {Number} size The total length of the output string * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ") * @return {String} The padded string * @static */ leftPad : function (val, size, ch) { var result = new String(val); if(!ch) { ch = " "; } while (result.length < size) { result = ch + result; } return result.toString(); }, /** * 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: *
    
    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>'
    
    * @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 = Array.prototype.slice.call(arguments, 1); return format.replace(/\{(\d+)\}/g, function(m, i){ return args[i]; }); } }); /** * Utility function that allows you to easily switch a string between two alternating values. The passed value * is compared to the current string, and if they are equal, the other value that was passed in is returned. If * they are already different, the first value passed in is returned. Note that this method returns the new value * but does not change the current string. *
    
    // alternate sort directions
    sort = sort.toggle('ASC', 'DESC');
    
    // instead of conditional logic:
    sort = (sort == 'ASC' ? 'DESC' : 'ASC');
    
    * @param {String} value The value to compare to the current string * @param {String} other The new value to use if the string already equals the first value passed in * @return {String} The new value */ String.prototype.toggle = function(value, other){ return this == value ? other : value; }; /** * Trims whitespace from either end of a string, leaving spaces within the string intact. Example: *
    
    var s = '  foo bar  ';
    alert('-' + s + '-');         //alerts "- foo bar -"
    alert('-' + s.trim() + '-');  //alerts "-foo bar-"
    
    * @return {String} The trimmed string */ String.prototype.trim = function(){ var re = /^\s+|\s+$/g; return function(){ return this.replace(re, ""); }; }(); /** * @class Number */ Ext.applyIf(Number.prototype, { /** * Checks whether or not the current number is within a desired range. If the number is already within the * range it is returned, otherwise the min or max value is returned depending on which side of the range is * exceeded. Note that this method returns the constrained value but does not change the current number. * @param {Number} min The minimum number in the range * @param {Number} max The maximum number in the range * @return {Number} The constrained value if outside the range, otherwise the current value */ constrain : function(min, max){ return Math.min(Math.max(this, min), max); } }); /** * @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 * @return {Number} The index of o in the array (or -1 if it is not found) */ indexOf : function(o){ for (var i = 0, len = this.length; i < len; i++){ if(this[i] == o) return i; } 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; } }); /** 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 */ Date.prototype.getElapsed = function(date) { return Math.abs((date || new Date()).getTime()-this.getTime()); };