Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / pkgs / extras.js
index 77728fd..f4c99d7 100644 (file)
@@ -14,7 +14,7 @@ If you are unsure which license is appropriate for your use, please contact the
 */
 /**
  * @class Ext.JSON
- * Modified version of Douglas Crockford"s json.js that doesn"t
+ * Modified version of Douglas Crockford's JSON.js that doesn't
  * mess with the Object prototype
  * http://www.json.org/js.html
  * @singleton
@@ -107,15 +107,15 @@ Ext.JSON = new(function() {
      * <b>The returned value includes enclosing double quotation marks.</b></p>
      * <p>The default return format is "yyyy-mm-ddThh:mm:ss".</p>
      * <p>To override this:</p><pre><code>
-     Ext.JSON.encodeDate = function(d) {
-     return d.format('"Y-m-d"');
-     };
+Ext.JSON.encodeDate = function(d) {
+    return Ext.Date.format(d, '"Y-m-d"');
+};
      </code></pre>
      * @param {Date} d The Date to encode
      * @return {String} The string literal to use in a JSON string.
      */
     this.encodeDate = function(o) {
-        return '"' + o.getFullYear() + "-" 
+        return '"' + o.getFullYear() + "-"
         + pad(o.getMonth() + 1) + "-"
         + pad(o.getDate()) + "T"
         + pad(o.getHours()) + ":"
@@ -125,7 +125,7 @@ Ext.JSON = new(function() {
 
     /**
      * Encodes an Object, Array or other value
-     * @param {Mixed} o The variable to encode
+     * @param {Object} o The variable to encode
      * @return {String} The JSON string
      */
     this.encode = function() {
@@ -171,19 +171,16 @@ Ext.JSON = new(function() {
 })();
 /**
  * Shorthand for {@link Ext.JSON#encode}
- * @param {Mixed} o The variable to encode
- * @return {String} The JSON string
  * @member Ext
  * @method encode
+ * @alias Ext.JSON#encode
  */
 Ext.encode = Ext.JSON.encode;
 /**
  * Shorthand for {@link Ext.JSON#decode}
- * @param {String} json The JSON string
- * @param {Boolean} safe (optional) Whether to return null or throw an exception if the JSON is invalid.
- * @return {Object} The resulting object
  * @member Ext
  * @method decode
+ * @alias Ext.JSON#decode
  */
 Ext.decode = Ext.JSON.decode;
 
@@ -221,8 +218,6 @@ Ext.apply(Ext, {
     userAgent: navigator.userAgent.toLowerCase(),
     cache: {},
     idSeed: 1000,
-    BLANK_IMAGE_URL : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
-    isStrict: document.compatMode == "CSS1Compat",
     windowId: 'ext-window',
     documentId: 'ext-document',
 
@@ -233,20 +228,20 @@ Ext.apply(Ext, {
     isReady: false,
 
     /**
-     * True to automatically uncache orphaned Ext.core.Elements periodically (defaults to true)
+     * True to automatically uncache orphaned Ext.Elements periodically
      * @type Boolean
      */
     enableGarbageCollector: true,
 
     /**
-     * True to automatically purge event listeners during garbageCollection (defaults to true).
+     * True to automatically purge event listeners during garbageCollection.
      * @type Boolean
      */
     enableListenerCollection: true,
 
     /**
      * 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 {HTMLElement/Ext.Element} el (optional) The element to generate an id for
      * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
      * @return {String} The generated Id.
      */
@@ -273,16 +268,16 @@ Ext.apply(Ext, {
     },
 
     /**
-     * Returns the current document body as an {@link Ext.core.Element}.
-     * @return Ext.core.Element The document body
+     * Returns the current document body as an {@link Ext.Element}.
+     * @return Ext.Element The document body
      */
     getBody: function() {
         return Ext.get(document.body || false);
     },
 
     /**
-     * Returns the current document head as an {@link Ext.core.Element}.
-     * @return Ext.core.Element The document head
+     * Returns the current document head as an {@link Ext.Element}.
+     * @return Ext.Element The document head
      * @method
      */
     getHead: function() {
@@ -298,8 +293,8 @@ Ext.apply(Ext, {
     }(),
 
     /**
-     * Returns the current HTML document object as an {@link Ext.core.Element}.
-     * @return Ext.core.Element The document
+     * Returns the current HTML document object as an {@link Ext.Element}.
+     * @return Ext.Element The document
      */
     getDoc: function() {
         return Ext.get(document);
@@ -327,12 +322,11 @@ Ext.apply(Ext, {
     /**
      * 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.core.Element} and {@link Ext.Component}, but any subclass of
+     * 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.core.Element}, {@link Ext.Component}, or an Array of either of these to destroy
-     * @param {Mixed} arg2 (optional)
-     * @param {Mixed} etc... (optional)
+     * @param {Ext.Element/Ext.Component/Ext.Element[]/Ext.Component[]...} arg1
+     * An {@link Ext.Element}, {@link Ext.Component}, or an Array of either of these to destroy
      */
     destroy: function() {
         var ln = arguments.length,
@@ -356,12 +350,12 @@ Ext.apply(Ext, {
 
     /**
      * Execute a callback function in a particular scope. If no function is passed the call is ignored.
-     * 
+     *
      * For example, these lines are equivalent:
-     * 
+     *
      *     Ext.callback(myFunc, this, [arg1, arg2]);
      *     Ext.isFunction(myFunc) && myFunc.apply(this, [arg1, arg2]);
-     * 
+     *
      * @param {Function} callback The callback to execute
      * @param {Object} scope (optional) The scope to execute in
      * @param {Array} args (optional) The arguments to pass to the function
@@ -424,9 +418,30 @@ window.undefined = window.undefined;
  * @singleton
  */
 (function(){
+/*
+FF 3.6      - Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.17) Gecko/20110420 Firefox/3.6.17
+FF 4.0.1    - Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+FF 5.0      - Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
+
+IE6         - Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)
+IE7         - Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1;)
+IE8         - Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
+IE9         - Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
+
+Chrome 11   - Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.60 Safari/534.24
+
+Safari 5    - Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1
+
+Opera 11.11 - Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11
+*/
     var check = function(regex){
             return regex.test(Ext.userAgent);
         },
+        isStrict = document.compatMode == "CSS1Compat",
+        version = function (is, regex) {
+            var m;
+            return (is && (m = regex.exec(Ext.userAgent))) ? parseFloat(m[1]) : 0;
+        },
         docMode = document.documentMode,
         isOpera = check(/opera/),
         isOpera10_5 = isOpera && check(/version\/10\.5/),
@@ -436,6 +451,7 @@ window.undefined = window.undefined;
         isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2
         isSafari3 = isSafari && check(/version\/3/),
         isSafari4 = isSafari && check(/version\/4/),
+        isSafari5 = isSafari && check(/version\/5/),
         isIE = !isOpera && check(/msie/),
         isIE7 = isIE && (check(/msie 7/) || docMode == 7),
         isIE8 = isIE && (check(/msie 8/) && docMode != 7 && docMode != 9 || docMode == 8),
@@ -444,6 +460,7 @@ window.undefined = window.undefined;
         isGecko = !isWebKit && check(/gecko/),
         isGecko3 = isGecko && check(/rv:1\.9/),
         isGecko4 = isGecko && check(/rv:2\.0/),
+        isGecko5 = isGecko && check(/rv:5\./),
         isFF3_0 = isGecko3 && check(/rv:1\.9\.0/),
         isFF3_5 = isGecko3 && check(/rv:1\.9\.1/),
         isFF3_6 = isGecko3 && check(/rv:1\.9\.2/),
@@ -451,21 +468,162 @@ window.undefined = window.undefined;
         isMac = check(/macintosh|mac os x/),
         isLinux = check(/linux/),
         scrollbarSize = null,
-        webKitVersion = isWebKit && (/webkit\/(\d+\.\d+)/.exec(Ext.userAgent));
+        chromeVersion = version(true, /\bchrome\/(\d+\.\d+)/),
+        firefoxVersion = version(true, /\bfirefox\/(\d+\.\d+)/),
+        ieVersion = version(isIE, /msie (\d+\.\d+)/),
+        operaVersion = version(isOpera, /version\/(\d+\.\d+)/),
+        safariVersion = version(isSafari, /version\/(\d+\.\d+)/),
+        webKitVersion = version(isWebKit, /webkit\/(\d+\.\d+)/),
+        isSecure = /^https/i.test(window.location.protocol);
 
     // remove css image flicker
     try {
         document.execCommand("BackgroundImageCache", false, true);
     } catch(e) {}
 
-    Ext.setVersion('extjs', '4.0.2');
+    //<debug>
+    function dumpObject (object) {
+        var member, members = [];
+
+        // Cannot use Ext.encode since it can recurse endlessly (if we're lucky)
+        // ...and the data could be prettier!
+        Ext.Object.each(object, function (name, value) {
+            if (typeof(value) === "function") {
+                return;
+            }
+
+            if (!Ext.isDefined(value) || value === null ||
+                    Ext.isDate(value) ||
+                    Ext.isString(value) || (typeof(value) == "number") ||
+                    Ext.isBoolean(value)) {
+                member = Ext.encode(value);
+            } else if (Ext.isArray(value)) {
+                member = '[ ]';
+            } else if (Ext.isObject(value)) {
+                member = '{ }';
+            } else {
+                member = 'undefined';
+            }
+            members.push(Ext.encode(name) + ': ' + member);
+        });
+
+        if (members.length) {
+            return ' \nData: {\n  ' + members.join(',\n  ') + '\n}';
+        }
+        return '';
+    }
+
+    function log (message) {
+        var options, dump,
+            con = Ext.global.console,
+            level = 'log',
+            indent = log.indent || 0,
+            stack;
+
+        log.indent = indent;
+
+        if (!Ext.isString(message)) {
+            options = message;
+            message = options.msg || '';
+            level = options.level || level;
+            dump = options.dump;
+            stack = options.stack;
+
+            if (options.indent) {
+                ++log.indent;
+            } else if (options.outdent) {
+                log.indent = indent = Math.max(indent - 1, 0);
+            }
+
+            if (dump && !(con && con.dir)) {
+                message += dumpObject(dump);
+                dump = null;
+            }
+        }
+
+        if (arguments.length > 1) {
+            message += Array.prototype.slice.call(arguments, 1).join('');
+        }
+
+        message = indent ? Ext.String.repeat('   ', indent) + message : message;
+        // w/o console, all messages are equal, so munge the level into the message:
+        if (level != 'log') {
+            message = '[' + level.charAt(0).toUpperCase() + '] ' + message;
+        }
+
+        // Not obvious, but 'console' comes and goes when Firebug is turned on/off, so
+        // an early test may fail either direction if Firebug is toggled.
+        //
+        if (con) { // if (Firebug-like console)
+            if (con[level]) {
+                con[level](message);
+            } else {
+                con.log(message);
+            }
+
+            if (dump) {
+                con.dir(dump);
+            }
+
+            if (stack && con.trace) {
+                // Firebug's console.error() includes a trace already...
+                if (!con.firebug || level != 'error') {
+                    con.trace();
+                }
+            }
+        } else {
+            if (Ext.isOpera) {
+                opera.postError(message);
+            } else {
+                var out = log.out,
+                    max = log.max;
+
+                if (out.length >= max) {
+                    // this formula allows out.max to change (via debugger), where the
+                    // more obvious "max/4" would not quite be the same
+                    Ext.Array.erase(out, 0, out.length - 3 * Math.floor(max / 4)); // keep newest 75%
+                }
+
+                out.push(message);
+            }
+        }
+
+        // Mostly informational, but the Ext.Error notifier uses them:
+        ++log.count;
+        ++log.counters[level];
+    }
+
+    log.count = 0;
+    log.counters = { error: 0, warn: 0, info: 0, log: 0 };
+    log.out = [];
+    log.max = 250;
+    log.show = function () {
+        window.open('','extlog').document.write([
+            '<html><head><script type="text/javascript">',
+                'var lastCount = 0;',
+                'function update () {',
+                    'var ext = window.opener.Ext,',
+                        'extlog = ext && ext.log;',
+                    'if (extlog && extlog.out && lastCount != extlog.count) {',
+                        'lastCount = extlog.count;',
+                        'var s = "<tt>" + extlog.out.join("<br>").replace(/[ ]/g, "&nbsp;") + "</tt>";',
+                        'document.body.innerHTML = s;',
+                    '}',
+                    'setTimeout(update, 1000);',
+                '}',
+                'setTimeout(update, 1000);',
+            '</script></head><body></body></html>'].join(''));
+    };
+    //</debug>
+
+    Ext.setVersion('extjs', '4.0.7');
     Ext.apply(Ext, {
         /**
          * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent
          * the IE insecure content warning (<tt>'about:blank'</tt>, except for IE in secure mode, which is <tt>'javascript:""'</tt>).
          * @type String
          */
-        SSL_SECURE_URL : Ext.isSecure && isIE ? 'javascript:""' : 'about:blank',
+        SSL_SECURE_URL : isSecure && isIE ? 'javascript:""' : 'about:blank',
 
         /**
          * True if the {@link Ext.fx.Anim} Class is available
@@ -498,7 +656,7 @@ window.undefined = window.undefined;
         USE_NATIVE_JSON : false,
 
         /**
-         * Return the dom node for the passed String (id), dom node, or Ext.core.Element.
+         * 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:
@@ -509,7 +667,7 @@ var elDom = Ext.getDom('elId');
 var elDom1 = Ext.getDom(elDom);
 
 // If we don&#39;t know if we are working with an
-// Ext.core.Element or a dom node use Ext.getDom
+// Ext.Element or a dom node use Ext.getDom
 function(el){
     var dom = Ext.getDom(el);
     // do something with the dom node
@@ -517,7 +675,7 @@ function(el){
          * </code></pre>
          * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc)
          * when this method is called to be successful.
-         * @param {Mixed} el
+         * @param {String/HTMLElement/Ext.Element} el
          * @return HTMLElement
          */
         getDom : function(el, strict) {
@@ -573,6 +731,10 @@ function(el){
             }
         },
 
+        isStrict: isStrict,
+
+        isIEQuirks: isIE && !isStrict,
+
         /**
          * True if the detected browser is Opera.
          * @type Boolean
@@ -615,6 +777,12 @@ function(el){
          */
         isSafari4 : isSafari4,
 
+        /**
+         * True if the detected browser is Safari 5.x.
+         * @type Boolean
+         */
+        isSafari5 : isSafari5,
+
         /**
          * True if the detected browser is Safari 2.x.
          * @type Boolean
@@ -670,23 +838,41 @@ function(el){
         isGecko4 : isGecko4,
 
         /**
-         * True if the detected browser uses FireFox 3.0
+         * True if the detected browser uses a Gecko 5.0+ layout engine (e.g. Firefox 5.x).
          * @type Boolean
          */
+        isGecko5 : isGecko5,
 
+        /**
+         * True if the detected browser uses FireFox 3.0
+         * @type Boolean
+         */
         isFF3_0 : isFF3_0,
+
         /**
          * True if the detected browser uses FireFox 3.5
          * @type Boolean
          */
-
         isFF3_5 : isFF3_5,
+
         /**
          * True if the detected browser uses FireFox 3.6
          * @type Boolean
          */
         isFF3_6 : isFF3_6,
 
+        /**
+         * True if the detected browser uses FireFox 4
+         * @type Boolean
+         */
+        isFF4 : 4 <= firefoxVersion && firefoxVersion < 5,
+
+        /**
+         * True if the detected browser uses FireFox 5
+         * @type Boolean
+         */
+        isFF5 : 5 <= firefoxVersion && firefoxVersion < 6,
+
         /**
          * True if the detected platform is Linux.
          * @type Boolean
@@ -706,10 +892,52 @@ function(el){
         isMac : isMac,
 
         /**
-         * The current version of WebKit (-1 if the browser does not use WebKit).
-         * @type Float
+         * The current version of Chrome (0 if the browser is not Chrome).
+         * @type Number
+         */
+        chromeVersion: chromeVersion,
+
+        /**
+         * The current version of Firefox (0 if the browser is not Firefox).
+         * @type Number
+         */
+        firefoxVersion: firefoxVersion,
+
+        /**
+         * The current version of IE (0 if the browser is not IE). This does not account
+         * for the documentMode of the current page, which is factored into {@link #isIE7},
+         * {@link #isIE8} and {@link #isIE9}. Thus this is not always true:
+         *
+         *      Ext.isIE8 == (Ext.ieVersion == 8)
+         *
+         * @type Number
+         * @markdown
+         */
+        ieVersion: ieVersion,
+
+        /**
+         * The current version of Opera (0 if the browser is not Opera).
+         * @type Number
+         */
+        operaVersion: operaVersion,
+
+        /**
+         * The current version of Safari (0 if the browser is not Safari).
+         * @type Number
+         */
+        safariVersion: safariVersion,
+
+        /**
+         * The current version of WebKit (0 if the browser does not use WebKit).
+         * @type Number
          */
-        webKitVersion: webKitVersion ? parseFloat(webKitVersion[1]) : -1,
+        webKitVersion: webKitVersion,
+
+        /**
+         * True if the page is running over SSL
+         * @type Boolean
+         */
+        isSecure: isSecure,
 
         /**
          * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images.
@@ -717,7 +945,7 @@ function(el){
          * For other browsers it uses an inline data URL.
          * @type String
          */
-        BLANK_IMAGE_URL : (isIE6 || isIE7) ? 'http:/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
+        BLANK_IMAGE_URL : (isIE6 || isIE7) ? '/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
 
         /**
          * <p>Utility method for returning a default value if the passed value is empty.</p>
@@ -727,10 +955,10 @@ function(el){
          * <li>an empty array</li>
          * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
          * </ul></div>
-         * @param {Mixed} value The value to test
-         * @param {Mixed} defaultValue The value to return if the original value is empty
+         * @param {Object} value The value to test
+         * @param {Object} 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
+         * @return {Object} value, if non-empty, else defaultValue
          * @deprecated 4.0.0 Use {@link Ext#valueFrom} instead
          */
         value : function(v, defaultValue, allowBlank){
@@ -854,7 +1082,7 @@ Ext.addBehaviors({
          *
          * @param {Object} dest The destination object.
          * @param {Object} source The source object.
-         * @param {Array/String} names Either an Array of property names, or a comma-delimited list
+         * @param {String/String[]} names Either an Array of property names, or a comma-delimited list
          * of property names to copy.
          * @param {Boolean} usePrototypeKeys (Optional) Defaults to false. Pass true to copy keys off of the prototype as well as the instance.
          * @return {Object} The modified object.
@@ -874,8 +1102,7 @@ Ext.addBehaviors({
         /**
          * 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.
+         * @param {String...} args One or more names of the properties to destroy and remove from the object.
          */
         destroyMembers : function(o){
             for (var i = 1, a = arguments, len = a.length; i < len; i++) {
@@ -888,123 +1115,42 @@ Ext.addBehaviors({
          * Logs a message. If a console is present it will be used. On Opera, the method
          * "opera.postError" is called. In other cases, the message is logged to an array
          * "Ext.log.out". An attached debugger can watch this array and view the log. The
-         * log buffer is limited to a maximum of "Ext.log.max" entries (defaults to 100).
+         * log buffer is limited to a maximum of "Ext.log.max" entries (defaults to 250).
+         * The `Ext.log.out` array can also be written to a popup window by entering the
+         * following in the URL bar (a "bookmarklet"):
+         *
+         *    javascript:void(Ext.log.show());
          *
          * If additional parameters are passed, they are joined and appended to the message.
-         * 
+         * A technique for tracing entry and exit of a function is this:
+         *
+         *      function foo () {
+         *          Ext.log({ indent: 1 }, '>> foo');
+         *
+         *          // log statements in here or methods called from here will be indented
+         *          // by one step
+         *
+         *          Ext.log({ outdent: 1 }, '<< foo');
+         *      }
+         *
          * This method does nothing in a release build.
          *
-         * @param {String|Object} message The message to log or an options object with any
+         * @param {String/Object} message The message to log or an options object with any
          * of the following properties:
          *
          *  - `msg`: The message to log (required).
          *  - `level`: One of: "error", "warn", "info" or "log" (the default is "log").
          *  - `dump`: An object to dump to the log as part of the message.
          *  - `stack`: True to include a stack trace in the log.
+         *  - `indent`: Cause subsequent log statements to be indented one step.
+         *  - `outdent`: Cause this and following statements to be one step less indented.
          * @markdown
          */
-        log : function (message) {
+        log :
             //<debug>
-            var options, dump,
-                con = Ext.global.console,
-                log = Ext.log,
-                level = 'log',
-                stack,
-                members,
-                member;
-
-            if (!Ext.isString(message)) {
-                options = message;
-                message = options.msg || '';
-                level = options.level || level;
-                dump = options.dump;
-                stack = options.stack;
-
-                if (dump && !(con && con.dir)) {
-                    members = [];
-
-                    // Cannot use Ext.encode since it can recurse endlessly (if we're lucky)
-                    // ...and the data could be prettier!
-                    Ext.Object.each(dump, function (name, value) {
-                        if (typeof(value) === "function") {
-                            return;
-                        }
-
-                        if (!Ext.isDefined(value) || value === null ||
-                                Ext.isDate(value) ||
-                                Ext.isString(value) || (typeof(value) == "number") ||
-                                Ext.isBoolean(value)) {
-                            member = Ext.encode(value);
-                        } else if (Ext.isArray(value)) {
-                            member = '[ ]';
-                        } else if (Ext.isObject(value)) {
-                            member = '{ }';
-                        } else {
-                            member = 'undefined';
-                        }
-                        members.push(Ext.encode(name) + ': ' + member);
-                    });
-
-                    if (members.length) {
-                        message += ' \nData: {\n  ' + members.join(',\n  ') + '\n}';
-                    }
-                    dump = null;
-                }
-            }
-
-            if (arguments.length > 1) {
-                message += Array.prototype.slice.call(arguments, 1).join('');
-            }
-
-            // Not obvious, but 'console' comes and goes when Firebug is turned on/off, so
-            // an early test may fail either direction if Firebug is toggled.
-            //
-            if (con) { // if (Firebug-like console)
-                if (con[level]) {
-                    con[level](message);
-                } else {
-                    con.log(message);
-                }
-
-                if (dump) {
-                    con.dir(dump);
-                }
-
-                if (stack && con.trace) {
-                    // Firebug's console.error() includes a trace already...
-                    if (!con.firebug || level != 'error') {
-                        con.trace();
-                    }
-                }
-            } else {
-                // w/o console, all messages are equal, so munge the level into the message:
-                if (level != 'log') {
-                    message = level.toUpperCase() + ': ' + message;
-                }
-
-                if (Ext.isOpera) {
-                    opera.postError(message);
-                } else {
-                    var out = log.out || (log.out = []),
-                        max = log.max || (log.max = 100);
-
-                    if (out.length >= max) {
-                        // this formula allows out.max to change (via debugger), where the
-                        // more obvious "max/4" would not quite be the same
-                        Ext.Array.erase(out, 0, out.length - 3 * Math.floor(max / 4)); // keep newest 75%
-                    }
-
-                    out.push(message);
-                }
-            }
-
-            // Mostly informational, but the Ext.Error notifier uses them:
-            var counters = log.counters ||
-                          (log.counters = { error: 0, warn: 0, info: 0, log: 0 });
-
-            ++counters[level];
+            log ||
             //</debug>
-        },
+            Ext.emptyFn,
 
         /**
          * Partitions the set into two sets: a true set and a false set.
@@ -1024,7 +1170,7 @@ Ext.partition(
 // true are those paragraph elements with a className of "class1",
 // false set are those that do not have that className.
          * </code></pre>
-         * @param {Array|NodeList} arr The array to partition
+         * @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} [array of truish values, array of falsy values]
@@ -1045,9 +1191,9 @@ Ext.partition(
 Ext.invoke(Ext.query("p"), "getAttribute", "id");
 // [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")]
          * </code></pre>
-         * @param {Array|NodeList} arr The Array of items to invoke the method on.
+         * @param {Array/NodeList} arr The Array of items to invoke the method on.
          * @param {String} methodName The method name to invoke.
-         * @param {...*} args Arguments to send into the method invocation.
+         * @param {Object...} args Arguments to send into the method invocation.
          * @return {Array} The results of invoking the method on each item in the array.
          * @deprecated 4.0.0 Will be removed in the next major version
          */
@@ -1079,7 +1225,7 @@ Ext.zip(
     }
 ); // ["$+12.43", "$-10.15", "$+22.96"]
          * </code></pre>
-         * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values.
+         * @param {Array/NodeList...} 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.
          * @deprecated 4.0.0 Will be removed in the next major version
@@ -1108,7 +1254,7 @@ Ext.zip(
          * Turns an array into a sentence, joined by a specified connector - e.g.:
          * Ext.toSentence(['Adama', 'Tigh', 'Roslin']); //'Adama, Tigh and Roslin'
          * Ext.toSentence(['Adama', 'Tigh', 'Roslin'], 'or'); //'Adama, Tigh or Roslin'
-         * @param {Array} items The array to create a sentence from
+         * @param {String[]} items The array to create a sentence from
          * @param {String} connector The string to use to connect the last two words. Usually 'and' or 'or' - defaults to 'and'.
          * @return {String} The sentence string
          * @deprecated 4.0.0 Will be removed in the next major version
@@ -1153,7 +1299,7 @@ Ext.application = function(config) {
 /**
  * @class Ext.util.Format
 
-This class is a centralized place for formatting functions inside the library. It includes
+This class is a centralized place for formatting functions. It includes
 functions to format various different types of data, such as text, dates and numeric values.
 
 __Localization__
@@ -1168,7 +1314,7 @@ Options include:
 This class also uses the default date format defined here: {@link Ext.Date#defaultFormat}.
 
 __Using with renderers__
-There are two helper functions that return a new function that can be used in conjunction with 
+There are two helper functions that return a new function that can be used in conjunction with
 grid renderers:
 
     columns: [{
@@ -1178,7 +1324,7 @@ grid renderers:
         dataIndex: 'time',
         renderer: Ext.util.Format.numberRenderer('0.000')
     }]
-    
+
 Functions that only take a single argument can also be passed directly:
     columns: [{
         dataIndex: 'cost',
@@ -1187,7 +1333,7 @@ Functions that only take a single argument can also be passed directly:
         dataIndex: 'productCode',
         renderer: Ext.util.Format.uppercase
     }]
-    
+
 __Using with XTemplates__
 XTemplates can also directly use Ext.util.Format functions:
 
@@ -1217,50 +1363,45 @@ XTemplates can also directly use Ext.util.Format functions:
 
     Ext.apply(UtilFormat, {
         /**
-         * @type String
-         * @property thousandSeparator
+         * @property {String} thousandSeparator
          * <p>The character that the {@link #number} function uses as a thousand separator.</p>
-         * <p>This defaults to <code>,</code>, but may be overridden in a locale file.</p>
+         * <p>This may be overridden in a locale file.</p>
          */
         thousandSeparator: ',',
 
         /**
-         * @type String
-         * @property decimalSeparator
+         * @property {String} decimalSeparator
          * <p>The character that the {@link #number} function uses as a decimal point.</p>
-         * <p>This defaults to <code>.</code>, but may be overridden in a locale file.</p>
+         * <p>This may be overridden in a locale file.</p>
          */
         decimalSeparator: '.',
 
         /**
-         * @type Number
-         * @property currencyPrecision
+         * @property {Number} currencyPrecision
          * <p>The number of decimal places that the {@link #currency} function displays.</p>
-         * <p>This defaults to <code>2</code>, but may be overridden in a locale file.</p>
+         * <p>This may be overridden in a locale file.</p>
          */
         currencyPrecision: 2,
 
         /**
-         * @type String
-         * @property currencySign
+         * @property {String} currencySign
          * <p>The currency sign that the {@link #currency} function displays.</p>
-         * <p>This defaults to <code>$</code>, but may be overridden in a locale file.</p>
+         * <p>This may be overridden in a locale file.</p>
          */
         currencySign: '$',
 
         /**
-         * @type Boolean
-         * @property currencyAtEnd
+         * @property {Boolean} currencyAtEnd
          * <p>This may be set to <code>true</code> to make the {@link #currency} function
          * append the currency sign to the formatted value.</p>
-         * <p>This defaults to <code>false</code>, but may be overridden in a locale file.</p>
+         * <p>This may be overridden in a locale file.</p>
          */
         currencyAtEnd: false,
 
         /**
          * Checks a reference and converts it to empty string if it is undefined
-         * @param {Mixed} value Reference to check
-         * @return {Mixed} Empty string if converted, otherwise the original value
+         * @param {Object} value Reference to check
+         * @return {Object} Empty string if converted, otherwise the original value
          */
         undef : function(value) {
             return value !== undefined ? value : "";
@@ -1268,7 +1409,7 @@ XTemplates can also directly use Ext.util.Format functions:
 
         /**
          * Checks a reference and converts it to the default value if it's empty
-         * @param {Mixed} value Reference to check
+         * @param {Object} value Reference to check
          * @param {String} defaultValue The value to insert of it's undefined (defaults to "")
          * @return {String}
          */
@@ -1336,7 +1477,7 @@ XTemplates can also directly use Ext.util.Format functions:
             for (; i < decimals; i++) {
                 format += '0';
             }
-            v = UtilFormat.number(v, format); 
+            v = UtilFormat.number(v, format);
             if ((end || UtilFormat.currencyAtEnd) === true) {
                 return Ext.String.format("{0}{1}{2}", negativeSign, v, currencySign || UtilFormat.currencySign);
             } else {
@@ -1374,7 +1515,7 @@ XTemplates can also directly use Ext.util.Format functions:
 
         /**
          * Strips all HTML tags
-         * @param {Mixed} value The text from which to strip tags
+         * @param {Object} value The text from which to strip tags
          * @return {String} The stripped text
          */
         stripTags : function(v) {
@@ -1383,7 +1524,7 @@ XTemplates can also directly use Ext.util.Format functions:
 
         /**
          * Strips all script tags
-         * @param {Mixed} value The text from which to strip script tags
+         * @param {Object} value The text from which to strip script tags
          * @return {String} The stripped text
          */
         stripScripts : function(v) {
@@ -1445,7 +1586,7 @@ XTemplates can also directly use Ext.util.Format functions:
          * <p>The <i>presence</i> of a thousand separator character in the format string specifies that
          * the <u>locale-specific</u> thousand separator (if any) is inserted separating thousand groups.</p>
          * <p>By default, "," is expected as the thousand separator, and "." is expected as the decimal separator.</p>
-         * <p><b>New to Ext4</b></p>
+         * <p><b>New to Ext JS 4</b></p>
          * <p>Locale-specific characters are always used in the formatted output when inserting
          * thousand and decimal separators.</p>
          * <p>The format string must specify separator characters according to US/UK conventions ("," as the
@@ -1546,7 +1687,7 @@ XTemplates can also directly use Ext.util.Format functions:
                     fnum = psplit[0] + dec + psplit[1];
                 }
             }
-            
+
             if (neg) {
                 /*
                  * Edge case. If we have a very small negative number it will get rounded to 0,
@@ -1592,54 +1733,58 @@ XTemplates can also directly use Ext.util.Format functions:
         },
 
         /**
-         * Capitalize the given string. See {@link Ext.String#capitalize}.
+         * Alias for {@link Ext.String#capitalize}.
          * @method
+         * @alias Ext.String#capitalize
          */
         capitalize: Ext.String.capitalize,
 
         /**
-         * Truncate a string and add an ellipsis ('...') to the end if it exceeds the specified length.
-         * See {@link Ext.String#ellipsis}.
+         * Alias for {@link Ext.String#ellipsis}.
          * @method
+         * @alias Ext.String#ellipsis
          */
         ellipsis: Ext.String.ellipsis,
 
         /**
-         * Formats to a string. See {@link Ext.String#format}
+         * Alias for {@link Ext.String#format}.
          * @method
+         * @alias Ext.String#format
          */
         format: Ext.String.format,
 
         /**
-         * Convert certain characters (&, <, >, and ') from their HTML character equivalents.
-         * See {@link Ext.String#htmlDecode}.
+         * Alias for {@link Ext.String#htmlDecode}.
          * @method
+         * @alias Ext.String#htmlDecode
          */
         htmlDecode: Ext.String.htmlDecode,
 
         /**
-         * Convert certain characters (&, <, >, and ') to their HTML character equivalents for literal display in web pages.
-         * See {@link Ext.String#htmlEncode}.
+         * Alias for {@link Ext.String#htmlEncode}.
          * @method
+         * @alias Ext.String#htmlEncode
          */
         htmlEncode: Ext.String.htmlEncode,
 
         /**
-         * Adds left padding to a string. See {@link Ext.String#leftPad}
+         * Alias for {@link Ext.String#leftPad}.
          * @method
+         * @alias Ext.String#leftPad
          */
         leftPad: Ext.String.leftPad,
 
         /**
-         * Trims any whitespace from either side of a string. See {@link Ext.String#trim}.
+         * Alias for {@link Ext.String#trim}.
          * @method
+         * @alias Ext.String#trim
          */
         trim : Ext.String.trim,
 
         /**
          * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations
          * (e.g. 10, "10", "10 10", "10 10 10" and "10 10 10 10" are all valid options and would return the same result)
-         * @param {Number|String} v The encoded margins
+         * @param {Number/String} v The encoded margins
          * @return {Object} An object with margin sizes for top, right, bottom and left
          */
         parseBox : function(box) {
@@ -1709,8 +1854,7 @@ Ext.TaskManager.start({
  * Also see {@link Ext.util.DelayedTask}. 
  * 
  * @constructor
- * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance
- * (defaults to 10)
+ * @param {Number} [interval=10] The minimum precision in milliseconds supported by this TaskRunner instance
  */
 Ext.ns('Ext.util');