/*! * Ext JS Library 3.4.0 * Copyright(c) 2006-2011 Sencha Inc. * licensing@sencha.com * http://www.sencha.com/license */ // 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.0', versionDetail : { major : 3, minor : 4, patch : 0 } }; /** * 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 == 7), isIE8 = isIE && (check(/msie 8/) && docMode != 7), isIE9 = isIE && check(/msie 9/), isIE6 = isIE && !isIE7 && !isIE8 && !isIE9, 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{ 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 ('about:blank', except for IE in secure mode, which is 'javascript:""'). * @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. * Note: Native JSON methods will not work with objects that have functions. * Also, property names must be quoted, otherwise the data will not parse. (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; }, /** *

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.

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

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.
    }
});
* *

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:

*
* * @param {Function} superclass The constructor of class being extended. * @param {Object} overrides

A literal with members which are copied into the subclass's * prototype, and are therefore shared between all instances of the new class.

*

This may contain a special member named constructor. This is used * to define the constructor of the new class, and is returned. If this property is * not specified, a constructor is generated and returned which just calls the * superclass's constructor passing on its parameters.

*

It is essential that you call the superclass constructor in any provided constructor. See example code.

* @return {Function} The subclass constructor from the overrides 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; }; }(), /** * 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; Ext.apply(p, overrides); if(Ext.isIE && overrides.hasOwnProperty('toString')){ p.toString = overrides.toString; } } }, /** * 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: *

Ext.namespace('Company', 'Company.data');
Ext.namespace('Company.data'); // equivalent and preferable to above syntax
Company.Widget = function() { ... }
Company.data.CustomStore = function(config) { ... }
* @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:

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(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 index. This function is called with * the following arguments: *
* @param {Object} scope The scope (this reference) in which the specified function is executed. * Defaults to the item at the current index * within the passed array. * @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. * Note: 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: *
* @param {Object} scope The scope (this reference) in which the specified function is executed. Defaults to * the object 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: *

// 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
}
         * 
* Note: 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 */ getHead : function() { var head; return function() { if (head == undefined) { head = Ext.get(DOC.getElementsByTagName("head")[0]); } return head; }; }(), /** * Removes a DOM node from the document. */ /** *

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 * true, then DOM event listeners are also removed from all child nodes. The body node * will be ignored if passed in.

* @param {HTMLElement} node The node to remove */ 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]; } }, /** *

Returns true if the passed value is empty.

*

The value is deemed to be empty if it is

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

Ext.namespace('Company', 'Company.data');
Ext.namespace('Company.data'); // equivalent and preferable to above syntax
Company.Widget = function() { ... }
Company.data.CustomStore = function(config) { ... }
* @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: *

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 (this reference) in which the passed function is executed. * If omitted, defaults to the scope in which the original function is called or the browser window. * @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: 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, 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} scope (optional) The scope (this reference) in which the function is executed. * If omitted, defaults to the browser window. * @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: *

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 less than or equal to 0 the function is executed immediately) * @param {Object} scope (optional) The scope (this reference) in which the function is executed. * If omitted, defaults to the browser window. * @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: *

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 = 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; } }); /** * @class Ext.util.TaskRunner * Provides the ability to execute one or more arbitrary tasks in a multithreaded * manner. Generally, you can use the singleton {@link Ext.TaskMgr} instead, but * if needed, you can create separate instances of TaskRunner. Any number of * separate tasks can be started at any time and will run independently of each * other. Example usage: *

// Start a simple clock task that updates a div once per second
var updateClock = function(){
    Ext.fly('clock').update(new Date().format('g:i:s A'));
} 
var task = {
    run: updateClock,
    interval: 1000 //1 second
}
var runner = new Ext.util.TaskRunner();
runner.start(task);

// equivalent using TaskMgr
Ext.TaskMgr.start({
    run: updateClock,
    interval: 1000
});

 * 
*

See the {@link #start} method for details about how to configure a task object.

* Also see {@link Ext.util.DelayedTask}. * * @constructor * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance * (defaults to 10) */ Ext.util.TaskRunner = function(interval){ interval = interval || 10; var tasks = [], removeQueue = [], id = 0, running = false, // private stopThread = function(){ running = false; clearInterval(id); id = 0; }, // private startThread = function(){ if(!running){ running = true; id = setInterval(runTasks, interval); } }, // private removeTask = function(t){ removeQueue.push(t); if(t.onStop){ t.onStop.apply(t.scope || t); } }, // private runTasks = function(){ var rqLen = removeQueue.length, now = new Date().getTime(); if(rqLen > 0){ for(var i = 0; i < rqLen; i++){ tasks.remove(removeQueue[i]); } removeQueue = []; if(tasks.length < 1){ stopThread(); return; } } for(var i = 0, t, itime, rt, len = tasks.length; i < len; ++i){ t = tasks[i]; itime = now - t.taskRunTime; if(t.interval <= itime){ rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]); t.taskRunTime = now; if(rt === false || t.taskRunCount === t.repeat){ removeTask(t); return; } } if(t.duration && t.duration <= (now - t.taskStartTime)){ removeTask(t); } } }; /** * Starts a new task. * @method start * @param {Object} task

A config object that supports the following properties:

*

Before each invocation, Ext injects the property taskRunCount into the task object so * that calculations based on the repeat count can be performed.

* @return {Object} The task */ this.start = function(task){ tasks.push(task); task.taskStartTime = new Date().getTime(); task.taskRunTime = 0; task.taskRunCount = 0; startThread(); return task; }; /** * Stops an existing running task. * @method stop * @param {Object} task The task to stop * @return {Object} The task */ this.stop = function(task){ removeTask(task); return task; }; /** * Stops all tasks that are currently running. * @method stopAll */ this.stopAll = function(){ stopThread(); for(var i = 0, len = tasks.length; i < len; i++){ if(tasks[i].onStop){ tasks[i].onStop(); } } tasks = []; removeQueue = []; }; }; /** * @class Ext.TaskMgr * @extends Ext.util.TaskRunner * A static {@link Ext.util.TaskRunner} instance that can be used to start and stop arbitrary tasks. See * {@link Ext.util.TaskRunner} for supported methods and task config properties. *

// Start a simple clock task that updates a div once per second
var task = {
    run: function(){
        Ext.fly('clock').update(new Date().format('g:i:s A'));
    },
    interval: 1000 //1 second
}
Ext.TaskMgr.start(task);
*

See the {@link #start} method for details about how to configure a task object.

* @singleton */ Ext.TaskMgr = new Ext.util.TaskRunner();if(typeof YAHOO == "undefined"){ throw "Unable to load Ext, core YUI utilities (yahoo, dom, event) not found."; } (function(){ var E = YAHOO.util.Event, D = YAHOO.util.Dom, CN = YAHOO.util.Connect, ES = YAHOO.util.Easing, A = YAHOO.util.Anim, libFlyweight, version = YAHOO.env.getVersion('yahoo').version.split('.'), mouseEnterSupported = parseInt(version[0], 10) >= 3, mouseCache = {}, elContains = function(parent, child){ if(parent && parent.firstChild){ while(child){ if(child === parent){ return true; } child = child.parentNode; if(child && (child.nodeType != 1)){ child = null; } } } return false; }, checkRelatedTarget = function(e){ return !elContains(e.currentTarget, Ext.lib.Event.getRelatedTarget(e)); }; Ext.lib.Dom = { getViewWidth : function(full){ return full ? D.getDocumentWidth() : D.getViewportWidth(); }, getViewHeight : function(full){ return full ? D.getDocumentHeight() : D.getViewportHeight(); }, isAncestor : function(haystack, needle){ return D.isAncestor(haystack, needle); }, getRegion : function(el){ return D.getRegion(el); }, getY : function(el){ return this.getXY(el)[1]; }, getX : function(el){ return this.getXY(el)[0]; }, // original version based on YahooUI getXY // this version fixes several issues in Safari and FF // and boosts performance by removing the batch overhead, repetitive dom lookups and array index calls getXY : function(el){ var p, pe, b, scroll, bd = (document.body || document.documentElement); el = Ext.getDom(el); if(el == bd){ return [0, 0]; } if (el.getBoundingClientRect) { b = el.getBoundingClientRect(); scroll = fly(document).getScroll(); return [Math.round(b.left + scroll.left), Math.round(b.top + scroll.top)]; } var x = 0, y = 0; p = el; var hasAbsolute = fly(el).getStyle("position") == "absolute"; while (p) { x += p.offsetLeft; y += p.offsetTop; if (!hasAbsolute && fly(p).getStyle("position") == "absolute") { hasAbsolute = true; } if (Ext.isGecko) { pe = fly(p); var bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0; var bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0; x += bl; y += bt; if (p != el && pe.getStyle('overflow') != 'visible') { x += bl; y += bt; } } p = p.offsetParent; } if (Ext.isSafari && hasAbsolute) { x -= bd.offsetLeft; y -= bd.offsetTop; } if (Ext.isGecko && !hasAbsolute) { var dbd = fly(bd); x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0; y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0; } p = el.parentNode; while (p && p != bd) { if (!Ext.isOpera || (p.tagName != 'TR' && fly(p).getStyle("display") != "inline")) { x -= p.scrollLeft; y -= p.scrollTop; } p = p.parentNode; } return [x, y]; }, setXY : function(el, xy){ el = Ext.fly(el, '_setXY'); el.position(); var pts = el.translatePoints(xy); if(xy[0] !== false){ el.dom.style.left = pts.left + "px"; } if(xy[1] !== false){ el.dom.style.top = pts.top + "px"; } }, setX : function(el, x){ this.setXY(el, [x, false]); }, setY : function(el, y){ this.setXY(el, [false, y]); } }; Ext.lib.Event = { getPageX : function(e){ return E.getPageX(e.browserEvent || e); }, getPageY : function(e){ return E.getPageY(e.browserEvent || e); }, getXY : function(e){ return E.getXY(e.browserEvent || e); }, getTarget : function(e){ return E.getTarget(e.browserEvent || e); }, getRelatedTarget : function(e){ return E.getRelatedTarget(e.browserEvent || e); }, on : function(el, eventName, fn, scope, override){ if((eventName == 'mouseenter' || eventName == 'mouseleave') && !mouseEnterSupported){ var item = mouseCache[el.id] || (mouseCache[el.id] = {}); item[eventName] = fn; fn = fn.createInterceptor(checkRelatedTarget); eventName = (eventName == 'mouseenter') ? 'mouseover' : 'mouseout'; } E.on(el, eventName, fn, scope, override); }, un : function(el, eventName, fn){ if((eventName == 'mouseenter' || eventName == 'mouseleave') && !mouseEnterSupported){ var item = mouseCache[el.id], ev = item && item[eventName]; if(ev){ fn = ev.fn; delete item[eventName]; eventName = (eventName == 'mouseenter') ? 'mouseover' : 'mouseout'; } } E.removeListener(el, eventName, fn);; }, purgeElement : function(el){ E.purgeElement(el); }, preventDefault : function(e){ E.preventDefault(e.browserEvent || e); }, stopPropagation : function(e){ E.stopPropagation(e.browserEvent || e); }, stopEvent : function(e){ E.stopEvent(e.browserEvent || e); }, onAvailable : function(el, fn, scope, override){ return E.onAvailable(el, fn, scope, override); } }; Ext.lib.Ajax = { request : function(method, uri, cb, data, options){ if(options){ var hs = options.headers; if(hs){ for(var h in hs){ if(hs.hasOwnProperty(h)){ CN.initHeader(h, hs[h], false); } } } if(options.xmlData){ if (!hs || !hs['Content-Type']){ CN.initHeader('Content-Type', 'text/xml', false); } method = (method ? method : (options.method ? options.method : 'POST')); data = options.xmlData; }else if(options.jsonData){ if (!hs || !hs['Content-Type']){ CN.initHeader('Content-Type', 'application/json', false); } method = (method ? method : (options.method ? options.method : 'POST')); data = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData; } } return CN.asyncRequest(method, uri, cb, data); }, formRequest : function(form, uri, cb, data, isUpload, sslUri){ CN.setForm(form, isUpload, sslUri); return CN.asyncRequest(Ext.getDom(form).method ||'POST', uri, cb, data); }, isCallInProgress : function(trans){ return CN.isCallInProgress(trans); }, abort : function(trans){ return CN.abort(trans); }, serializeForm : function(form){ var d = CN.setForm(form.dom || form); CN.resetFormState(); return d; } }; Ext.lib.Region = YAHOO.util.Region; Ext.lib.Point = YAHOO.util.Point; Ext.lib.Anim = { scroll : function(el, args, duration, easing, cb, scope){ this.run(el, args, duration, easing, cb, scope, YAHOO.util.Scroll); }, motion : function(el, args, duration, easing, cb, scope){ this.run(el, args, duration, easing, cb, scope, YAHOO.util.Motion); }, color : function(el, args, duration, easing, cb, scope){ this.run(el, args, duration, easing, cb, scope, YAHOO.util.ColorAnim); }, run : function(el, args, duration, easing, cb, scope, type){ type = type || YAHOO.util.Anim; if(typeof easing == "string"){ easing = YAHOO.util.Easing[easing]; } var anim = new type(el, args, duration, easing); anim.animateX(function(){ Ext.callback(cb, scope); }); return anim; } }; // all lib flyweight calls use their own flyweight to prevent collisions with developer flyweights function fly(el){ if(!libFlyweight){ libFlyweight = new Ext.Element.Flyweight(); } libFlyweight.dom = el; return libFlyweight; } // prevent IE leaks if(Ext.isIE) { function fnCleanUp() { var p = Function.prototype; delete p.createSequence; delete p.defer; delete p.createDelegate; delete p.createCallback; delete p.createInterceptor; window.detachEvent("onunload", fnCleanUp); } window.attachEvent("onunload", fnCleanUp); } // various overrides // add ability for callbacks with animations if(YAHOO.util.Anim){ YAHOO.util.Anim.prototype.animateX = function(callback, scope){ var f = function(){ this.onComplete.unsubscribe(f); if(typeof callback == "function"){ callback.call(scope || this, this); } }; this.onComplete.subscribe(f, this, true); this.animate(); }; } if(YAHOO.util.DragDrop && Ext.dd.DragDrop){ YAHOO.util.DragDrop.defaultPadding = Ext.dd.DragDrop.defaultPadding; YAHOO.util.DragDrop.constrainTo = Ext.dd.DragDrop.constrainTo; } YAHOO.util.Dom.getXY = function(el) { var f = function(el) { return Ext.lib.Dom.getXY(el); }; return YAHOO.util.Dom.batch(el, f, YAHOO.util.Dom, true); }; // workaround for Safari anim duration speed problems if(YAHOO.util.AnimMgr){ YAHOO.util.AnimMgr.fps = 1000; } YAHOO.util.Region.prototype.adjust = function(t, l, b, r){ this.top += t; this.left += l; this.right += r; this.bottom += b; return this; }; YAHOO.util.Region.prototype.constrainTo = function(r) { this.top = this.top.constrain(r.top, r.bottom); this.bottom = this.bottom.constrain(r.top, r.bottom); this.left = this.left.constrain(r.left, r.right); this.right = this.right.constrain(r.left, r.right); return this; }; })();