X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/7a654f8d43fdb43d78b63d90528bed6e86b608cc..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/docs/source/Ext-more.html diff --git a/docs/source/Ext-more.html b/docs/source/Ext-more.html index 8e4a9d52..630b8927 100644 --- a/docs/source/Ext-more.html +++ b/docs/source/Ext-more.html @@ -1 +1,1130 @@ -Sencha Documentation Project
\ No newline at end of file + + + + + The source code + + + + + + +
/**
+ * @class Ext
+
+ The Ext namespace (global object) encapsulates all classes, singletons, and utility methods provided by Sencha's libraries.</p>
+ Most user interface Components are at a lower level of nesting in the namespace, but many common utility functions are provided
+ as direct properties of the Ext namespace.
+
+ Also many frequently used methods from other classes are provided as shortcuts within the Ext namespace.
+ For example {@link Ext#getCmp Ext.getCmp} aliases {@link Ext.ComponentManager#get Ext.ComponentManager.get}.
+
+ Many applications are initiated with {@link Ext#onReady Ext.onReady} which is called once the DOM is ready.
+ This ensures all scripts have been loaded, preventing dependency issues. For example
+
+     Ext.onReady(function(){
+         new Ext.Component({
+             renderTo: document.body,
+             html: 'DOM ready!'
+         });
+     });
+
+For more information about how to use the Ext classes, see
+
+- <a href="http://www.sencha.com/learn/">The Learning Center</a>
+- <a href="http://www.sencha.com/learn/Ext_FAQ">The FAQ</a>
+- <a href="http://www.sencha.com/forum/">The forums</a>
+
+ * @singleton
+ * @markdown
+ */
+Ext.apply(Ext, {
+    userAgent: navigator.userAgent.toLowerCase(),
+    cache: {},
+    idSeed: 1000,
+    windowId: 'ext-window',
+    documentId: 'ext-document',
+
+    /**
+     * True when the document is fully initialized and ready for action
+     * @type Boolean
+     */
+    isReady: false,
+
+    /**
+     * True to automatically uncache orphaned Ext.Elements periodically
+     * @type Boolean
+     */
+    enableGarbageCollector: 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 {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.
+     */
+    id: function(el, prefix) {
+        var me = this,
+            sandboxPrefix = '';
+        el = Ext.getDom(el, true) || {};
+        if (el === document) {
+            el.id = me.documentId;
+        }
+        else if (el === window) {
+            el.id = me.windowId;
+        }
+        if (!el.id) {
+            if (me.isSandboxed) {
+                if (!me.uniqueGlobalNamespace) {
+                    me.getUniqueGlobalNamespace();
+                }
+                sandboxPrefix = me.uniqueGlobalNamespace + '-';
+            }
+            el.id = sandboxPrefix + (prefix || "ext-gen") + (++Ext.idSeed);
+        }
+        return el.id;
+    },
+
+    /**
+     * 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.Element}.
+     * @return Ext.Element The document head
+     * @method
+     */
+    getHead: function() {
+        var head;
+
+        return function() {
+            if (head == undefined) {
+                head = Ext.get(document.getElementsByTagName("head")[0]);
+            }
+
+            return head;
+        };
+    }(),
+
+    /**
+     * Returns the current HTML document object as an {@link Ext.Element}.
+     * @return Ext.Element The document
+     */
+    getDoc: function() {
+        return Ext.get(document);
+    },
+
+    /**
+     * This is shorthand reference to {@link Ext.ComponentManager#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, <tt>undefined</tt> if not found, or <tt>null</tt> if a
+     * Class was found.
+    */
+    getCmp: function(id) {
+        return Ext.ComponentManager.get(id);
+    },
+
+    /**
+     * Returns the current orientation of the mobile device
+     * @return {String} Either 'portrait' or 'landscape'
+     */
+    getOrientation: function() {
+        return window.innerHeight > window.innerWidth ? 'portrait' : 'landscape';
+    },
+
+    /**
+     * 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 {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,
+        i, arg;
+
+        for (i = 0; i < ln; i++) {
+            arg = arguments[i];
+            if (arg) {
+                if (Ext.isArray(arg)) {
+                    this.destroy.apply(this, arg);
+                }
+                else if (Ext.isFunction(arg.destroy)) {
+                    arg.destroy();
+                }
+                else if (arg.dom) {
+                    arg.remove();
+                }
+            }
+        }
+    },
+
+    /**
+     * 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
+     * @param {Number} delay (optional) Pass a number to delay the call by a number of milliseconds.
+     */
+    callback: function(callback, scope, args, delay){
+        if(Ext.isFunction(callback)){
+            args = args || [];
+            scope = scope || window;
+            if (delay) {
+                Ext.defer(callback, delay, scope, args);
+            } else {
+                callback.apply(scope, args);
+            }
+        }
+    },
+
+    /**
+     * Convert certain characters (&, <, >, and ') to their HTML character equivalents for literal display in web pages.
+     * @param {String} value The string to encode
+     * @return {String} The encoded text
+     */
+    htmlEncode : function(value) {
+        return Ext.String.htmlEncode(value);
+    },
+
+    /**
+     * Convert certain characters (&, <, >, and ') from their HTML character equivalents.
+     * @param {String} value The string to decode
+     * @return {String} The decoded text
+     */
+    htmlDecode : function(value) {
+         return Ext.String.htmlDecode(value);
+    },
+
+    /**
+     * Appends content to the query string of a URL, handling logic for whether to place
+     * a question mark or ampersand.
+     * @param {String} url The URL to append to.
+     * @param {String} s The content to append to the URL.
+     * @return (String) The resulting URL
+     */
+    urlAppend : function(url, s) {
+        if (!Ext.isEmpty(s)) {
+            return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
+        }
+        return url;
+    }
+});
+
+
+Ext.ns = Ext.namespace;
+
+// for old browsers
+window.undefined = window.undefined;
+
+/**
+ * @class Ext
+ * Ext core utilities and functions.
+ * @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/),
+        isChrome = check(/\bchrome\b/),
+        isWebKit = check(/webkit/),
+        isSafari = !isChrome && check(/safari/),
+        isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2
+        isSafari3 = isSafari && check(/version\/3/),
+        isSafari4 = isSafari && check(/version\/4/),
+        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),
+        isIE9 = isIE && (check(/msie 9/) && docMode != 7 && docMode != 8 || docMode == 9),
+        isIE6 = isIE && check(/msie 6/),
+        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/),
+        isWindows = check(/windows|win32/),
+        isMac = check(/macintosh|mac os x/),
+        isLinux = check(/linux/),
+        scrollbarSize = null,
+        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) {}
+
+    //<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 : isSecure && isIE ? 'javascript:""' : 'about:blank',
+
+        /**
+         * True if the {@link Ext.fx.Anim} Class is available
+         * @type Boolean
+         * @property enableFx
+         */
+
+        /**
+         * True to scope the reset CSS to be just applied to Ext components. Note that this wraps root containers
+         * with an additional element. Also remember that when you turn on this option, you have to use ext-all-scoped {
+         * unless you use the bootstrap.js to load your javascript, in which case it will be handled for you.
+         * @type Boolean
+         */
+        scopeResetCSS : Ext.buildSettings.scopeResetCSS,
+
+        /**
+         * 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.
+         * <b>Note: Native JSON methods will not work with objects that have functions.
+         * Also, property names must be quoted, otherwise the data will not parse.</b> (Defaults to false)
+         * @type Boolean
+         */
+        USE_NATIVE_JSON : false,
+
+        /**
+         * 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:
+         * <pre><code>
+// 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&#39;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
+}
+         * </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 {String/HTMLElement/Ext.Element} el
+         * @return HTMLElement
+         */
+        getDom : function(el, strict) {
+            if (!el || !document) {
+                return null;
+            }
+            if (el.dom) {
+                return el.dom;
+            } else {
+                if (typeof el == 'string') {
+                    var e = document.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;
+                }
+            }
+        },
+
+        /**
+         * Removes a DOM node from the document.
+         * <p>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 Ext.enableNestedListenerRemoval} is
+         * <code>true</code>, then DOM event listeners are also removed from all child nodes. The body node
+         * will be ignored if passed in.</p>
+         * @param {HTMLElement} node The node to remove
+         * @method
+         */
+        removeNode : isIE6 || isIE7 ? function() {
+            var d;
+            return function(n){
+                if(n && n.tagName != 'BODY'){
+                    (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n) : Ext.EventManager.removeAll(n);
+                    d = d || document.createElement('div');
+                    d.appendChild(n);
+                    d.innerHTML = '';
+                    delete Ext.cache[n.id];
+                }
+            };
+        }() : function(n) {
+            if (n && n.parentNode && n.tagName != 'BODY') {
+                (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n) : Ext.EventManager.removeAll(n);
+                n.parentNode.removeChild(n);
+                delete Ext.cache[n.id];
+            }
+        },
+
+        isStrict: isStrict,
+
+        isIEQuirks: isIE && !isStrict,
+
+        /**
+         * True if the detected browser is Opera.
+         * @type Boolean
+         */
+        isOpera : isOpera,
+
+        /**
+         * True if the detected browser is Opera 10.5x.
+         * @type Boolean
+         */
+        isOpera10_5 : isOpera10_5,
+
+        /**
+         * 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 5.x.
+         * @type Boolean
+         */
+        isSafari5 : isSafari5,
+
+        /**
+         * True if the detected browser is Safari 2.x.
+         * @type Boolean
+         */
+        isSafari2 : isSafari2,
+
+        /**
+         * True if the detected browser is Internet Explorer.
+         * @type Boolean
+         */
+        isIE : isIE,
+
+        /**
+         * True if the detected browser is Internet Explorer 6.x.
+         * @type Boolean
+         */
+        isIE6 : isIE6,
+
+        /**
+         * True if the detected browser is Internet Explorer 7.x.
+         * @type Boolean
+         */
+        isIE7 : isIE7,
+
+        /**
+         * True if the detected browser is Internet Explorer 8.x.
+         * @type Boolean
+         */
+        isIE8 : isIE8,
+
+        /**
+         * True if the detected browser is Internet Explorer 9.x.
+         * @type Boolean
+         */
+        isIE9 : isIE9,
+
+        /**
+         * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
+         * @type Boolean
+         */
+        isGecko : isGecko,
+
+        /**
+         * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
+         * @type Boolean
+         */
+        isGecko3 : isGecko3,
+
+        /**
+         * True if the detected browser uses a Gecko 2.0+ layout engine (e.g. Firefox 4.x).
+         * @type Boolean
+         */
+        isGecko4 : isGecko4,
+
+        /**
+         * 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
+         */
+        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,
+
+        /**
+         * 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,
+
+        /**
+         * 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.
+         * In older versions of IE, this defaults to "http://sencha.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 : (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>
+         * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
+         * <li>null</li>
+         * <li>undefined</li>
+         * <li>an empty array</li>
+         * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
+         * </ul></div>
+         * @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 {Object} value, if non-empty, else defaultValue
+         * @deprecated 4.0.0 Use {@link Ext#valueFrom} instead
+         */
+        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}
+         * @deprecated 4.0.0 Use {@link Ext.String#escapeRegex} instead
+         */
+        escapeRe : function(s) {
+            return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
+        },
+
+        /**
+         * Applies event listeners to elements by selectors when the document is ready.
+         * The event name is specified with an <tt>&#64;</tt> suffix.
+         * <pre><code>
+Ext.addBehaviors({
+    // add a listener for click on all anchors in element with id foo
+    '#foo a&#64;click' : function(e, t){
+        // do something
+    },
+
+    // add the same listener to multiple selectors (separated by comma BEFORE the &#64;)
+    '#foo a, #bar span.some-class&#64;mouseover' : function(){
+        // do something
+    }
+});
+         * </code></pre>
+         * @param {Object} obj The list of behaviors to apply
+         */
+        addBehaviors : function(o){
+            if(!Ext.isReady){
+                Ext.onReady(function(){
+                    Ext.addBehaviors(o);
+                });
+            } else {
+                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]) { // for Object prototype breakers
+                        s = parts[0];
+                        if(!cache[s]){
+                            cache[s] = Ext.select(s);
+                        }
+                        cache[s].on(parts[1], o[b]);
+                    }
+                }
+                cache = null;
+            }
+        },
+
+        /**
+         * Returns the size of the browser scrollbars. 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 {Object} An object containing the width of a vertical scrollbar and the
+         * height of a horizontal scrollbar.
+         */
+        getScrollbarSize: function (force) {
+            if(!Ext.isReady){
+                return 0;
+            }
+
+            if(force === true || scrollbarSize === null){
+                // BrowserBug: IE9
+                // When IE9 positions an element offscreen via offsets, the offsetWidth is
+                // inaccurately reported. For IE9 only, we render on screen before removing.
+                var cssClass = Ext.isIE9 ? '' : Ext.baseCSSPrefix + 'hide-offsets',
+                    // Append our div, do our calculation and then remove it
+                    div = Ext.getBody().createChild('<div class="' + cssClass + '" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
+                    child = div.child('div', true),
+                    w1 = child.offsetWidth;
+
+                div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
+
+                var w2 = child.offsetWidth, width = w1 - w2;
+                div.remove();
+
+                // We assume width == height for now. TODO: is this always true?
+                scrollbarSize = { width: width, height: width };
+            }
+
+            return scrollbarSize;
+        },
+
+        /**
+         * Utility method for getting the width of the browser's vertical scrollbar. This
+         * can differ depending on operating system settings, such as the theme or font size.
+         *
+         * This method is deprected in favor of {@link #getScrollbarSize}.
+         *
+         * @param {Boolean} force (optional) true to force a recalculation of the value.
+         * @return {Number} The width of a vertical scrollbar.
+         * @deprecated
+         */
+        getScrollBarWidth: function(force){
+            var size = Ext.getScrollbarSize(force);
+            return size.width + 2; // legacy fudge factor
+        },
+
+        /**
+         * Copies a set of named properties fom the source object to the destination object.
+         *
+         * Example:
+         *
+         *     ImageComponent = Ext.extend(Ext.Component, {
+         *         initComponent: function() {
+         *             this.autoEl = { tag: 'img' };
+         *             MyComponent.superclass.initComponent.apply(this, arguments);
+         *             this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
+         *         }
+         *     });
+         *
+         * Important note: To borrow class prototype methods, use {@link Ext.Base#borrow} instead.
+         *
+         * @param {Object} dest The destination object.
+         * @param {Object} source The source object.
+         * @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.
+         */
+        copyTo : function(dest, source, names, usePrototypeKeys){
+            if(typeof names == 'string'){
+                names = names.split(/[,;\s]/);
+            }
+            Ext.each(names, function(name){
+                if(usePrototypeKeys || source.hasOwnProperty(name)){
+                    dest[name] = source[name];
+                }
+            }, this);
+            return dest;
+        },
+
+        /**
+         * 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 {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++) {
+                Ext.destroy(o[a[i]]);
+                delete o[a[i]];
+            }
+        },
+
+        /**
+         * 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 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
+         * 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 :
+            //<debug>
+            log ||
+            //</debug>
+            Ext.emptyFn,
+
+        /**
+         * Partitions the set into two sets: a true set and a false set.
+         * Example:
+         * Example2:
+         * <pre><code>
+// 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.
+         * </code></pre>
+         * @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]
+         * @deprecated 4.0.0 Will be removed in the next major version
+         */
+        partition : function(arr, truth){
+            var ret = [[],[]];
+            Ext.each(arr, function(v, i, a) {
+                ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
+            });
+            return ret;
+        },
+
+        /**
+         * Invokes a method on each item in an Array.
+         * <pre><code>
+// Example:
+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 {String} methodName The method name to invoke.
+         * @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
+         */
+        invoke : function(arr, methodName){
+            var ret = [],
+                args = Array.prototype.slice.call(arguments, 2);
+            Ext.each(arr, function(v,i) {
+                if (v && typeof v[methodName] == 'function') {
+                    ret.push(v[methodName].apply(v, args));
+                } else {
+                    ret.push(undefined);
+                }
+            });
+            return ret;
+        },
+
+        /**
+         * <p>Zips N sets together.</p>
+         * <pre><code>
+// 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"]
+         * </code></pre>
+         * @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
+         */
+        zip : function(){
+            var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }),
+                arrs = parts[0],
+                fn = parts[1][0],
+                len = Ext.max(Ext.pluck(arrs, "length")),
+                ret = [];
+
+            for (var i = 0; i < len; i++) {
+                ret[i] = [];
+                if(fn){
+                    ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
+                }else{
+                    for (var j = 0, aLen = arrs.length; j < aLen; j++){
+                        ret[i].push( arrs[j][i] );
+                    }
+                }
+            }
+            return ret;
+        },
+
+        /**
+         * 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 {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
+         */
+        toSentence: function(items, connector) {
+            var length = items.length;
+
+            if (length <= 1) {
+                return items[0];
+            } else {
+                var head = items.slice(0, length - 1),
+                    tail = items[length - 1];
+
+                return Ext.util.Format.format("{0} {1} {2}", head.join(", "), connector || 'and', tail);
+            }
+        },
+
+        /**
+         * 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: isIE6
+    });
+})();
+
+/**
+ * Loads Ext.app.Application class and starts it up with given configuration after the page is ready.
+ *
+ * See Ext.app.Application for details.
+ *
+ * @param {Object} config
+ */
+Ext.application = function(config) {
+    Ext.require('Ext.app.Application');
+
+    Ext.onReady(function() {
+        Ext.create('Ext.app.Application', config);
+    });
+};
+
+ +