X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6e39d509471fe9b4e2660e0d1631b350d0c66f40..2e847cf21b8ab9d15fa167b315ca5b2fa92638fc:/adapter/ext/ext-base-debug.js diff --git a/adapter/ext/ext-base-debug.js b/adapter/ext/ext-base-debug.js index a768f47d..8d0a32a5 100644 --- a/adapter/ext/ext-base-debug.js +++ b/adapter/ext/ext-base-debug.js @@ -1,18 +1,37 @@ - - - +/*! + * Ext JS Library 3.1.1 + * Copyright(c) 2006-2010 Ext JS, LLC + * licensing@extjs.com + * http://www.extjs.com/license + */ + +// for old browsers window.undefined = window.undefined; - +/** + * @class Ext + * Ext core utilities and functions. + * @singleton + */ Ext = { - - version : '3.1.0' + /** + * The version of the framework + * @type String + */ + version : '3.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); } @@ -34,10 +53,10 @@ Ext.apply = function(o, c, defaults){ DOC = document, isStrict = DOC.compatMode == "CSS1Compat", isOpera = check(/opera/), - isChrome = check(/chrome/), + isChrome = check(/\bchrome\b/), isWebKit = check(/webkit/), isSafari = !isChrome && check(/safari/), - isSafari2 = isSafari && check(/applewebkit\/4/), + isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2 isSafari3 = isSafari && check(/version\/3/), isSafari4 = isSafari && check(/version\/4/), isIE = !isOpera && check(/msie/), @@ -54,7 +73,7 @@ Ext.apply = function(o, c, defaults){ isLinux = check(/linux/), isSecure = /^https/i.test(window.location.protocol); - + // remove css image flicker if(isIE6){ try{ DOC.execCommand("BackgroundImageCache", false, true); @@ -62,30 +81,68 @@ Ext.apply = function(o, c, defaults){ } 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 + */ - + /** + * 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){ @@ -97,14 +154,71 @@ Ext.apply = function(o, c, defaults){ 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){ - return (el = Ext.getDom(el) || {}).id = el.id || (prefix || "ext-gen") + (++idSeed); + 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]; @@ -142,7 +256,23 @@ Ext.apply = function(o, c, defaults){ }; }(), - + /** + * 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; @@ -153,7 +283,21 @@ Ext.apply = function(o, c, defaults){ } }, - + /** + * 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 o, d; Ext.each(arguments, function(v) { @@ -166,7 +310,12 @@ Ext.apply = function(o, c, defaults){ return o; }, - + /** + * 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 = [], @@ -185,7 +334,15 @@ Ext.apply = function(o, c, defaults){ 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 {}; @@ -205,7 +362,13 @@ Ext.apply = function(o, c, defaults){ 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; @@ -213,7 +376,13 @@ Ext.apply = function(o, c, defaults){ 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){ @@ -229,20 +398,42 @@ Ext.apply = function(o, c, defaults){ }(), 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; } - - - return ((v.nextNode || v.item) && Ext.isNumber(v.length)); - }, - - + //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; @@ -257,7 +448,26 @@ Ext.apply = function(o, c, defaults){ } }, - + /** + * 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; @@ -276,21 +486,72 @@ Ext.apply = function(o, c, defaults){ } }, - - getDom : function(el){ + /** + * 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; } - return el.dom ? el.dom : (Ext.isString(el) ? DOC.getElementById(el) : el); + if (el.dom){ + return el.dom; + } else { + if (Ext.isString(el)) { + 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); }, - - + /** + * 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){ @@ -310,102 +571,224 @@ Ext.apply = function(o, c, defaults){ } }, - + /** + *

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; }, - + /** + * 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 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; })(); @@ -413,9 +796,36 @@ Ext.ns("Ext.util", "Ext.lib", "Ext.data"); 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) ? @@ -431,9 +841,32 @@ Ext.apply(Function.prototype, { }; }, - - createCallback : function(){ - + /** + * 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() { @@ -441,7 +874,37 @@ Ext.apply(Function.prototype, { }; }, - + /** + * 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() { @@ -450,15 +913,41 @@ Ext.apply(Function.prototype, { callArgs = Array.prototype.slice.call(arguments, 0); callArgs = callArgs.concat(args); }else if (Ext.isNumber(appendArgs)){ - callArgs = Array.prototype.slice.call(arguments, 0); - var applyArgs = [appendArgs, 0].concat(args); - Array.prototype.splice.apply(callArgs, applyArgs); + 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){ @@ -469,9 +958,25 @@ Ext.apply(Function.prototype, { } }); - +/** + * @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){ @@ -480,9 +985,16 @@ Ext.applyIf(String, { } }); - +/** + * @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; @@ -495,7 +1007,11 @@ Ext.applyIf(Array.prototype, { 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){ @@ -504,11 +1020,17 @@ Ext.applyIf(Array.prototype, { return this; } }); - +/** + * @class Ext + */ Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu", "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct"); - + /** + * Namespace alloted for extensions to the framework. + * @property ux + * @type Object + */ Ext.apply(Ext, function(){ var E = Ext, @@ -516,10 +1038,19 @@ Ext.apply(Ext, function(){ scrollWidth = null; return { - + /** + * A reusable empty function + * @property + * @type Function + */ emptyFn : function(){}, - + /** + * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images. + * In older versions of IE, this defaults to "http://extjs.com/s.gif" and you should change this to a URL on your server. + * For other browsers it uses an inline data URL. + * @type String + */ BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ? 'http:/' + '/extjs.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', @@ -528,23 +1059,47 @@ Ext.apply(Ext, function(){ return Ext.extend(supr, fn(supr.prototype)); }, - + /** + * Returns the current HTML document object as an {@link Ext.Element}. + * @return Ext.Element The document + */ getDoc : function(){ return Ext.get(document); }, - + /** + * 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(Ext.isEmpty(v) || Ext.isBoolean(v) ? NaN : v); + v = Number(Ext.isEmpty(v) || Ext.isArray(v) || Ext.isBoolean(v) || (Ext.isString(v) && v.trim().length == 0) ? NaN : v); return isNaN(v) ? defaultValue : v; }, - + /** + *

Utility method for returning a default value if the passed value is empty.

+ *

The value is deemed to be empty 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 zero length strings to qualify as non-empty (defaults to false) + * @return {Mixed} value, if non-empty, else defaultValue + */ value : function(v, defaultValue, allowBlank){ return Ext.isEmpty(v, allowBlank) ? defaultValue : v; }, - + /** + * Escapes the passed string for use in a regular expression + * @param {String} str + * @return {String} + */ escapeRe : function(s) { return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1"); }, @@ -553,19 +1108,36 @@ Ext.apply(Ext, function(){ o[name] = o[name].createSequence(fn, scope); }, - + /** + * 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); }); } else { - var cache = {}, + var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times parts, b, s; for (b in o) { - if ((parts = b.split('@'))[1]) { + if ((parts = b.split('@'))[1]) { // for Object prototype breakers s = parts[0]; if(!cache[s]){ cache[s] = Ext.select(s); @@ -577,28 +1149,33 @@ Ext.apply(Ext, function(){ } }, - + /** + * Utility method for getting the width of the browser scrollbar. This can differ depending on + * operating system settings, such as the theme or font size. + * @param {Boolean} force (optional) true to force a recalculation of the value. + * @return {Number} The width of the scrollbar. + */ getScrollBarWidth: function(force){ if(!Ext.isReady){ return 0; } if(force === true || scrollWidth === null){ - + // Append our div, do our calculation and then remove it var div = Ext.getBody().createChild('
'), child = div.child('div', true); var w1 = child.offsetWidth; div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll'); var w2 = child.offsetWidth; div.remove(); - + // Need to add 2 to ensure we leave enough space scrollWidth = w1 - w2 + 2; } return scrollWidth; }, - + // deprecated combine : function(){ var as = arguments, l = as.length, r = []; for(var i = 0; i < l; i++){ @@ -614,7 +1191,23 @@ Ext.apply(Ext, function(){ return r; }, - + /** + * Copies a set of named properties fom the source object to the destination object. + *

example:


+ImageComponent = Ext.extend(Ext.BoxComponent, {
+    initComponent: function() {
+        this.autoEl = { tag: 'img' };
+        MyComponent.superclass.initComponent.apply(this, arguments);
+        this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
+    }
+});
+         * 
+ * @param {Object} The destination object. + * @param {Object} The source object. + * @param {Array/String} Either an Array of property names, or a comma-delimited list + * of property names to copy. + * @return {Object} The modified object. + */ copyTo : function(dest, source, names){ if(Ext.isString(names)){ names = names.split(/[,;\s]/); @@ -627,7 +1220,16 @@ Ext.apply(Ext, function(){ return dest; }, - + /** + * 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}, {@link Ext.Component}, or an Array of either of these to destroy + * @param {Mixed} arg2 (optional) + * @param {Mixed} etc... (optional) + */ destroy : function(){ Ext.each(arguments, function(arg){ if(arg){ @@ -642,7 +1244,12 @@ Ext.apply(Ext, function(){ }, this); }, - + /** + * Attempts to destroy and then remove a set of named properties of the passed object. + * @param {Object} o The object (most likely a Component) who's properties you wish to destroy. + * @param {Mixed} arg1 The name of the property to destroy and remove from the object. + * @param {Mixed} etc... More property names to destroy and remove. + */ destroyMembers : function(o, arg1, arg2, etc){ for(var i = 1, a = arguments, len = a.length; i < len; i++) { Ext.destroy(o[a[i]]); @@ -650,7 +1257,11 @@ Ext.apply(Ext, function(){ } }, - + /** + * Creates a copy of the passed Array with falsy values removed. + * @param {Array/NodeList} arr The Array from which to remove falsy values. + * @return {Array} The new, compressed Array. + */ clean : function(arr){ var ret = []; Ext.each(arr, function(v){ @@ -661,7 +1272,11 @@ Ext.apply(Ext, function(){ return ret; }, - + /** + * Creates a copy of the passed Array, filtered to contain only unique values. + * @param {Array} arr The Array to filter + * @return {Array} The new Array containing unique values. + */ unique : function(arr){ var ret = [], collect = {}; @@ -675,7 +1290,11 @@ Ext.apply(Ext, function(){ return ret; }, - + /** + * Recursively flattens into 1-d Array. Injects Arrays inline. + * @param {Array} arr The array to flatten + * @return {Array} The new, flattened array. + */ flatten : function(arr){ var worker = []; function rFlatten(a) { @@ -691,7 +1310,13 @@ Ext.apply(Ext, function(){ return rFlatten(arr); }, - + /** + * Returns the minimum value in the Array. + * @param {Array|NodeList} arr The Array from which to select the minimum value. + * @param {Function} comp (optional) a function to perform the comparision which determines minimization. + * If omitted the "<" operator will be used. Note: gt = 1; eq = 0; lt = -1 + * @return {Object} The minimum value in the Array. + */ min : function(arr, comp){ var ret = arr[0]; comp = comp || function(a,b){ return a < b ? -1 : 1; }; @@ -701,7 +1326,13 @@ Ext.apply(Ext, function(){ return ret; }, - + /** + * Returns the maximum value in the Array + * @param {Array|NodeList} arr The Array from which to select the maximum value. + * @param {Function} comp (optional) a function to perform the comparision which determines maximization. + * If omitted the ">" operator will be used. Note: gt = 1; eq = 0; lt = -1 + * @return {Object} The maximum value in the Array. + */ max : function(arr, comp){ var ret = arr[0]; comp = comp || function(a,b){ return a > b ? 1 : -1; }; @@ -711,12 +1342,20 @@ Ext.apply(Ext, function(){ return ret; }, - + /** + * Calculates the mean of the Array + * @param {Array} arr The Array to calculate the mean value of. + * @return {Number} The mean. + */ mean : function(arr){ - return Ext.sum(arr) / arr.length; + return arr.length > 0 ? Ext.sum(arr) / arr.length : undefined; }, - + /** + * Calculates the sum of the Array + * @param {Array} arr The Array to calculate the sum value of. + * @return {Number} The sum. + */ sum : function(arr){ var ret = 0; Ext.each(arr, function(v) { @@ -725,7 +1364,29 @@ Ext.apply(Ext, function(){ return ret; }, - + /** + * Partitions the set into two sets: a true set and a false set. + * Example: + * Example2: + *

+// Example 1:
+Ext.partition([true, false, true, true, false]); // [[true, true, true], [false, false]]
+
+// Example 2:
+Ext.partition(
+    Ext.query("p"),
+    function(val){
+        return val.className == "class1"
+    }
+);
+// true are those paragraph elements with a className of "class1",
+// false set are those that do not have that className.
+         * 
+ * @param {Array|NodeList} arr The array to partition + * @param {Function} truth (optional) a function to determine truth. If this is omitted the element + * itself must be able to be evaluated for its truthfulness. + * @return {Array} [true,false] + */ partition : function(arr, truth){ var ret = [[],[]]; Ext.each(arr, function(v, i, a) { @@ -734,7 +1395,18 @@ Ext.apply(Ext, function(){ return ret; }, - + /** + * Invokes a method on each item in an Array. + *

+// Example:
+Ext.invoke(Ext.query("p"), "getAttribute", "id");
+// [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")]
+         * 
+ * @param {Array|NodeList} arr The Array of items to invoke the method on. + * @param {String} methodName The method name to invoke. + * @param {Anything} ... Arguments to send into the method invocation. + * @return {Array} The results of invoking the method on each item in the array. + */ invoke : function(arr, methodName){ var ret = [], args = Array.prototype.slice.call(arguments, 2); @@ -748,7 +1420,16 @@ Ext.apply(Ext, function(){ return ret; }, - + /** + * Plucks the value of a property from each item in the Array + *

+// Example:
+Ext.pluck(Ext.query("p"), "className"); // [el1.className, el2.className, ..., elN.className]
+         * 
+ * @param {Array|NodeList} arr The Array of items to pluck the value from. + * @param {String} prop The property name to pluck from each element. + * @return {Array} The value from each item in the Array. + */ pluck : function(arr, prop){ var ret = []; Ext.each(arr, function(v) { @@ -757,7 +1438,25 @@ Ext.apply(Ext, function(){ return ret; }, - + /** + *

Zips N sets together.

+ *

+// Example 1:
+Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]]
+// Example 2:
+Ext.zip(
+    [ "+", "-", "+"],
+    [  12,  10,  22],
+    [  43,  15,  96],
+    function(a, b, c){
+        return "$" + a + "" + b + "." + c
+    }
+); // ["$+12.43", "$-10.15", "$+22.96"]
+         * 
+ * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values. + * @param {Function} zipper (optional) The last item in the argument list. This will drive how the items are zipped together. + * @return {Array} The zipped set. + */ zip : function(){ var parts = Ext.partition(arguments, function( val ){ return !Ext.isFunction(val); }), arrs = parts[0], @@ -778,16 +1477,44 @@ Ext.apply(Ext, function(){ return ret; }, - + /** + * This is shorthand reference to {@link Ext.ComponentMgr#get}. + * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id} + * @param {String} id The component {@link Ext.Component#id id} + * @return Ext.Component The Component, undefined if not found, or null if a + * Class was found. + */ getCmp : function(id){ return Ext.ComponentMgr.get(id); }, - + /** + * 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: E.isIE6 || (E.isMac && E.isGecko2), - - + // 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:
    + *
  • 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; @@ -819,7 +1546,7 @@ Ext.apply(Ext, function(){ o[name] = o[name].createInterceptor(fn, scope); }, - + // internal callback : function(cb, scope, args, delay){ if(Ext.isFunction(cb)){ if(delay){ @@ -832,9 +1559,33 @@ Ext.apply(Ext, function(){ }; }()); - +/** + * @class Function + * These functions are available on every Function object (any JavaScript function). + */ Ext.apply(Function.prototype, { - + /** + * 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 (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 + */ createSequence : function(fcn, scope){ var method = this; return !Ext.isFunction(fcn) ? @@ -848,15 +1599,35 @@ Ext.apply(Function.prototype, { }); - +/** + * @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 = String(val); if(!ch) { @@ -869,32 +1640,100 @@ Ext.applyIf(String, { } }); - +/** + * 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, ""); }; }(); - - +// here to prevent dependency on Date.js +/** + 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()); }; - +/** + * @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 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
+});
 
+ * 
+ * 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 = [], @@ -902,14 +1741,14 @@ Ext.util.TaskRunner = function(interval){ id = 0, running = false, - + // private stopThread = function(){ running = false; clearInterval(id); id = 0; }, - + // private startThread = function(){ if(!running){ running = true; @@ -917,7 +1756,7 @@ Ext.util.TaskRunner = function(interval){ } }, - + // private removeTask = function(t){ removeQueue.push(t); if(t.onStop){ @@ -925,7 +1764,7 @@ Ext.util.TaskRunner = function(interval){ } }, - + // private runTasks = function(){ var rqLen = removeQueue.length, now = new Date().getTime(); @@ -957,7 +1796,26 @@ Ext.util.TaskRunner = function(interval){ } }; - + /** + * Starts a new task. + * @method start + * @param {Object} task A config object that supports the following properties: + * @return {Object} The task + */ this.start = function(task){ tasks.push(task); task.taskStartTime = new Date().getTime(); @@ -967,13 +1825,21 @@ Ext.util.TaskRunner = function(interval){ 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++){ @@ -986,7 +1852,23 @@ Ext.util.TaskRunner = function(interval){ }; }; - +/** + * @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);
+
+ * @singleton + */ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ var libFlyweight; @@ -1161,7 +2043,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ win = window, doc = document, - + // constants POLL_RETRYS = 200, POLL_INTERVAL = 20, EL = 0, @@ -1175,7 +2057,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ UNLOAD = 'unload', MOUSEOVER = 'mouseover', MOUSEOUT = 'mouseout', - + // private doAdd = function() { var ret; if (win.addEventListener) { @@ -1201,7 +2083,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ } return ret; }(), - + // private doRemove = function(){ var ret; if (win.removeEventListener) { @@ -1242,7 +2124,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ return false; } - + // private function _tryPreloadAttach() { var ret = false, notAvail = [], @@ -1258,7 +2140,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) { element = v.override ? (v.override === true ? v.obj : v.override) : element; v.fn.call(element, v.obj); - v = null; + onAvailStack.remove(v); } else { notAvail.push(v); } @@ -1279,7 +2161,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ return ret; } - + // private function startInterval() { if(!_interval){ var callback = function() { @@ -1289,7 +2171,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ } } - + // private function getScroll() { var dd = doc.documentElement, db = doc.body; @@ -1302,7 +2184,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ } } - + // private function getPageCoord (ev, xy) { ev = ev.browserEvent || ev; var coord = ev['page' + xy]; @@ -1331,7 +2213,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ startInterval(); }, - + // This function should ALWAYS be called from Ext.EventManager addListener: function(el, eventName, fn) { el = Ext.getDom(el); if (el && fn) { @@ -1347,17 +2229,16 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ return false; }, - + // This function should ALWAYS be called from Ext.EventManager removeListener: function(el, eventName, fn) { el = Ext.getDom(el); - var i, len, li; + var i, len, li, lis; if (el && fn) { - if (eventName == UNLOAD) { - if (unloadListeners[id] !== undefined) { - for (i = 0, len = unloadListeners[id].length; i < len; i++) { - li = unloadListeners[id][i]; - if (li && li[TYPE] == eventName && li[FN] == fn) { - unloadListeners[id].splice(i, 1); + if(eventName == UNLOAD){ + if((lis = unloadListeners[el.id]) !== undefined){ + for(i = 0, len = lis.length; i < len; i++){ + if((li = lis[i]) && li[TYPE] == eventName && li[FN] == fn){ + unloadListeners[el.id].splice(i, 1); } } } @@ -1376,7 +2257,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ if(!node){ return; } - + // work around firefox bug, https://bugzilla.mozilla.org/show_bug.cgi?id=101197 var s = HTMLElement.prototype.toString.call(node); if(s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]'){ return; @@ -1449,13 +2330,13 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ return ev.charCode || ev.keyCode || 0; }, - - + //clearCache: function() {}, + // deprecated, call from EventManager getListeners : function(el, eventName) { Ext.EventManager.getListeners(el, eventName); }, - + // deprecated, call from EventManager purgeElement : function(el, recurse, eventName) { Ext.EventManager.purgeElement(el, recurse, eventName); }, @@ -1464,8 +2345,8 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ loadComplete = true; var EU = Ext.lib.Event; if (Ext.isIE && e !== true) { - - + // IE8 complains that _load is null or not an object + // so lets remove self via arguments.callee doRemove(win, "load", arguments.callee); } }, @@ -1495,7 +2376,7 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ } }; - + // Initialize stuff. pub.on = pub.addListener; pub.un = pub.removeListener; if (doc && doc.body) { @@ -1508,14 +2389,19 @@ Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ return pub; }(); - +/* +* Portions of this file are based on pieces of Yahoo User Interface Library +* Copyright (c) 2007, Yahoo! Inc. All rights reserved. +* YUI licensed under the BSD License: +* http://developer.yahoo.net/yui/license.txt +*/ Ext.lib.Ajax = function() { var activeX = ['MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'], CONTENTTYPE = 'Content-Type'; - + // private function setHeader(o) { var conn = o.conn, prop; @@ -1538,7 +2424,7 @@ Ext.lib.Ajax = function() { } } - + // private function createExceptionObject(tId, callbackArg, isAbort, isTimeout) { return { tId : tId, @@ -1550,12 +2436,12 @@ Ext.lib.Ajax = function() { }; } - + // private function initHeader(label, value) { (pub.headers = pub.headers || {})[label] = value; } - + // private function createResponseObject(o, callbackArg) { var headerObj = {}, headerStr, @@ -1589,13 +2475,13 @@ Ext.lib.Ajax = function() { }; } - + // private function releaseObject(o) { o.conn = null; o = null; } - + // private function handleTransactionResponse(o, callback, isAbort, isTimeout) { if (!callback) { releaseObject(o); @@ -1662,7 +2548,7 @@ Ext.lib.Ajax = function() { responseObject = null; } - + // private function handleReadyState(o, callback){ callback = callback || {}; var conn = o.conn, @@ -1693,7 +2579,7 @@ Ext.lib.Ajax = function() { pub.pollInterval); } - + // private function asyncRequest(method, uri, callback, postData) { var o = getConnectionObject() || null; @@ -1718,7 +2604,7 @@ Ext.lib.Ajax = function() { return o; } - + // private function getConnectionObject() { var o; @@ -1732,7 +2618,7 @@ Ext.lib.Ajax = function() { } } - + // private function createXhrObject(transactionId) { var http; @@ -1814,32 +2700,32 @@ Ext.lib.Ajax = function() { pollInterval : 50, transactionId : 0, - - - - - - - - - +// This is never called - Is it worth exposing this? +// setProgId : function(id) { +// activeX.unshift(id); +// }, + +// This is never called - Is it worth exposing this? +// setDefaultPostHeader : function(b) { +// this.useDefaultHeader = b; +// }, - - - - - - - - - - - +// This is never called - Is it worth exposing this? +// setDefaultXhrHeader : function(b) { +// this.useDefaultXhrHeader = b; +// }, + +// This is never called - Is it worth exposing this? +// setPollingInterval : function(i) { +// if (typeof i == 'number' && isFinite(i)) { +// this.pollInterval = i; +// } +// }, - - - - +// This is never called - Is it worth exposing this? +// resetDefaultHeaders : function() { +// this.defaultHeaders = null; +// }, abort : function(o, callback, isTimeout) { var me = this, @@ -1859,7 +2745,7 @@ Ext.lib.Ajax = function() { }, isCallInProgress : function(o) { - + // if there is a connection and readyState is not 0 or 4 return o.conn && !{0:true,4:true}[o.conn.readyState]; } }; @@ -2374,7 +3260,13 @@ Ext.lib.Ajax = function() { if(control.length > 0 && !Ext.isArray(control[0])){ control = [control]; }else{ - + /* + var tmp = []; + for (i = 0,len = control.length; i < len; ++i) { + tmp[i] = control[i]; + } + control = tmp; + */ } Ext.fly(el, '_anim').position(); @@ -2412,9 +3304,9 @@ Ext.lib.Ajax = function() { return [val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1]]; }; })(); -})(); +})();// Easing functions (function(){ - + // shortcuts to aid compression var abs = Math.abs, pi = Math.PI, asin = Math.asin, @@ -2545,7 +3437,7 @@ Ext.lib.Ajax = function() { (function() { var EXTLIB = Ext.lib; - + // Color Animation EXTLIB.Anim.color = function(el, args, duration, easing, cb, scope) { return EXTLIB.Anim.run(el, args, duration, easing, cb, scope, EXTLIB.ColorAnim); } @@ -2566,7 +3458,7 @@ Ext.lib.Ajax = function() { return typeof v !== 'undefined'; } - + // private function parseColor(s) { var pi = parseInt, base, @@ -2608,12 +3500,14 @@ Ext.lib.Ajax = function() { var me = this, val, floor = Math.floor, - i, len = start.length, v; + i, + len, + v; if(colorRE.test(attr)){ val = []; - for(i=0; i