X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6a7e4474cba9d8be4b2ec445e10f1691f7277c50..3789b528d8dd8aad4558e38e22d775bcab1cbd36:/docs/source/Ext-more.html diff --git a/docs/source/Ext-more.html b/docs/source/Ext-more.html index fe231487..bc197784 100644 --- a/docs/source/Ext-more.html +++ b/docs/source/Ext-more.html @@ -1,121 +1,581 @@ +
- +/*! - * Ext JS Library 3.2.0 - * Copyright(c) 2006-2010 Ext JS, Inc. - * licensing@extjs.com - * http://www.extjs.com/license - */ -/** - * @class Ext + +- \ No newline at end of file +/** + * @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, + BLANK_IMAGE_URL : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', + isStrict: document.compatMode == "CSS1Compat", + windowId: 'ext-window', + documentId: 'ext-document', + + /** + * True when the document is fully initialized and ready for action + * @type Boolean + */ + isReady: false, -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 + /** + * True to automatically uncache orphaned Ext.core.Elements periodically (defaults to true) + * @type Boolean */ + enableGarbageCollector: true, -Ext.apply(Ext, function(){ - var E = Ext, - idSeed = 0, - scrollWidth = null; + /** + * True to automatically purge event listeners during garbageCollection (defaults to true). + * @type Boolean + */ + enableListenerCollection: true, - return { - /** - * A reusable empty function - * @property - * @type Function - */ - emptyFn : function(){}, + /** + * Generates unique ids. If the element already has an id, it is unchanged + * @param {Mixed} el (optional) The element to generate an id for + * @param {String} prefix (optional) Id prefix (defaults "ext-gen") + * @return {String} The generated Id. + */ + id: function(el, prefix) { + el = Ext.getDom(el, true) || {}; + if (el === document) { + el.id = this.documentId; + } + else if (el === window) { + el.id = this.windowId; + } + if (!el.id) { + el.id = (prefix || "ext-gen") + (++Ext.idSeed); + } + return el.id; + }, - /** - * 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. + /** + * Returns the current document body as an {@link Ext.core.Element}. + * @return Ext.core.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 + * @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.core.Element}. + * @return Ext.core.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.core.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) + */ + 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. + * @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(){ + var check = function(regex){ + return regex.test(Ext.userAgent); + }, + 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/), + 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/), + 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/), + scrollWidth = null, + webKitVersion = isWebKit && (/webkit\/(\d+\.\d+)/.exec(Ext.userAgent)); + + // remove css image flicker + try { + document.execCommand("BackgroundImageCache", false, true); + } catch(e) {} + + Ext.setVersion('extjs', '4.0.0'); + 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 */ - BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ? - 'http:/' + '/extjs.com/s.gif' : - 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', + SSL_SECURE_URL : Ext.isSecure && isIE ? 'javascript:""' : 'about:blank', - extendX : function(supr, fn){ - return Ext.extend(supr, fn(supr.prototype)); - }, + /** + * True if the {@link Ext.fx.Anim} Class is available + * @type Boolean + * @property enableFx + */ - /** - * Returns the current HTML document object as an {@link Ext.Element}. - * @return Ext.Element The document + /** + * 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.core.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't know if we are working with an +// Ext.core.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 {Mixed} el + * @return HTMLElement */ - getDoc : function(){ - return Ext.get(document); + 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; + } + } }, - /** - * 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 + /** + * 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 */ - num : function(v, defaultValue){ - 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; + 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]; + } }, - /** - *+Utility method for returning a default value if the passed value is empty.
- *The value is deemed to be empty if it is
+ /** + * 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 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 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 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 WebKit (-1 if the browser does not use WebKit). + * @type Float + */ + webKitVersion: webKitVersion ? parseFloat(webKitVersion[1]) : -1, + + /** + * 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) ? 'http:/' + '/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 {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 + * @deprecated 4.0.0 Use {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 + /** + * 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"); + return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1"); }, - sequence : function(o, name, fn, scope){ - 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. - *- *
- null
- *- undefined
- *- an empty array
- *- a zero length string (Unless the allowBlank parameter is true)
- *+ * </code></pre> * @param {Object} obj The list of behaviors to apply */ addBehaviors : function(o){ @@ -140,9 +600,9 @@ Ext.addBehaviors({ cache = null; } }, - - /** - * Utility method for getting the width of the browser scrollbar. This can differ depending on + + /** + * 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. @@ -151,10 +611,14 @@ Ext.addBehaviors({ if(!Ext.isReady){ return 0; } - + if(force === true || scrollWidth === 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 - var div = Ext.getBody().createChild(' '), + var 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); var w1 = child.offsetWidth; div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll'); @@ -166,244 +630,222 @@ Ext.addBehaviors({ return scrollWidth; }, - - // deprecated - combine : function(){ - var as = arguments, l = as.length, r = []; - for(var i = 0; i < l; i++){ - var a = as[i]; - if(Ext.isArray(a)){ - r = r.concat(a); - }else if(a.length !== undefined && !a.substr){ - r = r.concat(Array.prototype.slice.call(a, 0)); - }else{ - r.push(a); - } - } - return r; - }, - - /** - * Copies a set of named properties fom the source object to the destination object. - *+ /** + * Applies event listeners to elements by selectors when the document is ready. + * The event name is specified with an <tt>@</tt> suffix. + * <pre><code> Ext.addBehaviors({ // add a listener for click on all anchors in element with id foo - '#foo a@click' : function(e, t){ + '#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(){ + + // add the same listener to multiple selectors (separated by comma BEFORE the @) + '#foo a, #bar span.some-class@mouseover' : function(){ // do something } }); - *
example:
+ * </code></pre> + * 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 {Array/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){ - if(Ext.isString(names)){ + copyTo : function(dest, source, names, usePrototypeKeys){ + if(typeof names == 'string'){ names = names.split(/[,;\s]/); } Ext.each(names, function(name){ - if(source.hasOwnProperty(name)){ + if(usePrototypeKeys || source.hasOwnProperty(name)){ dest[name] = source[name]; } }, this); 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){ - if(Ext.isArray(arg)){ - this.destroy.apply(this, arg); - }else if(Ext.isFunction(arg.destroy)){ - arg.destroy(); - }else if(arg.dom){ - arg.remove(); - } - } - }, this); - }, - - /** - * Attempts to destroy and then remove a set of named properties of the passed object. + /** + * 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++) { + for (var i = 1, a = arguments, len = a.length; i < len; i++) { Ext.destroy(o[a[i]]); delete o[a[i]]; } }, - /** - * 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. + /** + * 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). + * + * If additional parameters are passed, they are joined and appended to the message. + * + * 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. + * @markdown */ - clean : function(arr){ - var ret = []; - Ext.each(arr, function(v){ - if(!!v){ - ret.push(v); + log : function (message) { + //<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; } - }); - 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 = {}; + if (arguments.length > 1) { + message += Array.prototype.slice.call(arguments, 1).join(''); + } - Ext.each(arr, function(v) { - if(!collect[v]){ - ret.push(v); + // 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); } - collect[v] = true; - }); - 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) { - Ext.each(a, function(v) { - if(Ext.isArray(v)){ - rFlatten(v); - }else{ - worker.push(v); + if (stack && con.trace) { + // Firebug's console.error() includes a trace already... + if (!con.firebug || level != 'error') { + con.trace(); } - }); - return worker; - } - return rFlatten(arr); - }, + } + } else { + // w/o console, all messages are equal, so munge the level into the message: + if (level != 'log') { + message = level.toUpperCase() + ': ' + message; + } - /** - * 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; }; - Ext.each(arr, function(v) { - ret = comp(ret, v) == -1 ? ret : v; - }); - return ret; - }, + if (Ext.isOpera) { + opera.postError(message); + } else { + var out = log.out || (log.out = []), + max = log.max || (log.max = 100); - /** - * 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; }; - Ext.each(arr, function(v) { - ret = comp(ret, v) == 1 ? ret : v; - }); - return ret; - }, + 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 + out.splice(0, out.length - 3 * Math.floor(max / 4)); // keep newest 75% + } - /** - * 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 arr.length > 0 ? Ext.sum(arr) / arr.length : undefined; - }, + 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 }); - /** - * 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) { - ret += v; - }); - return ret; + ++counters[level]; + //</debug> }, - /** - * Partitions the set into two sets: a true set and a false set. - * Example: - * Example2: - *-ImageComponent = Ext.extend(Ext.BoxComponent, { + /** + * Copies a set of named properties fom the source object to the destination object. + * <p>example:<pre><code> +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'); } }); - *
+ * </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} [true+ /** + * 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"), + Ext.query("p"), function(val){ - return val.className == "class1" + return val.className == "class1" } ); -// true are those paragraph elements with a className of "class1", +// true are those paragraph elements with a className of "class1", // false set are those that do not have that className. - *
,false ] + * @return {Array} [true<Array>,false<Array>] + * @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); + ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v); }); return ret; }, - /** - * Invokes a method on each item in an Array. - * +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 {...*} 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 && Ext.isFunction(v[methodName])) { + if (v && typeof v[methodName] == 'function') { ret.push(v[methodName].apply(v, args)); } else { ret.push(undefined); @@ -412,56 +854,39 @@ Ext.invoke(Ext.query("p"), "getAttribute", "id"); return ret; }, - /** - * Plucks the value of a property from each item in the Array - *+ /** + * 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")] - *
- * @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) { - ret.push( v[prop] ); - }); - return ret; - }, - - /** - *-// Example: -Ext.pluck(Ext.query("p"), "className"); // [el1.className, el2.className, ..., elN.className] - *
Zips N sets together.
- *+); // ["$+12.43", "$-10.15", "$+22.96"] + * </code></pre> * @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. + * @deprecated 4.0.0 Will be removed in the next major version */ zip : function(){ - var parts = Ext.partition(arguments, function( val ){ return !Ext.isFunction(val); }), + 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")), + len = Ext.max(Ext.pluck(arrs, "length")), ret = []; - for (var i = 0; i < len; i++) { + 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++){ + for (var j = 0, aLen = arrs.length; j < aLen; j++){ ret[i].push( arrs[j][i] ); } } @@ -469,231 +894,49 @@ Ext.zip( 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 + /** + * 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} 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 */ - 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:+ /** + * <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 + return "$" + a + "" + b + "." + c } -); // ["$+12.43", "$-10.15", "$+22.96"] - *
- * @param {Mixed} object - * @return {String} - */ - type : function(o){ - if(o === undefined || o === null){ - return false; - } - if(o.htmlElement){ - return 'element'; - } - var t = typeof o; - if(t == 'object' && o.nodeName) { - switch(o.nodeType) { - case 1: return 'element'; - case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace'; - } - } - if(t == 'object' || t == 'function') { - switch(o.constructor) { - case Array: return 'array'; - case RegExp: return 'regexp'; - case Date: return 'date'; - } - if(Ext.isNumber(o.length) && Ext.isFunction(o.item)) { - return 'nodelist'; - } - } - return t; - }, + toSentence: function(items, connector) { + var length = items.length; - intercept : function(o, name, fn, scope){ - o[name] = o[name].createInterceptor(fn, scope); - }, + if (length <= 1) { + return items[0]; + } else { + var head = items.slice(0, length - 1), + tail = items[length - 1]; - // internal - callback : function(cb, scope, args, delay){ - if(Ext.isFunction(cb)){ - if(delay){ - cb.defer(delay, scope, args || []); - }else{ - cb.apply(scope, args || []); - } + return Ext.util.Format.format("{0} {1} {2}", head.join(", "), connector || 'and', tail); } - } - }; -}()); - -/** - * @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: - *- *
- 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 {Function} fcn The function to sequence - * @param {Object} scope (optional) The scope (-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 -
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) ? - this : - function(){ - var retval = method.apply(this || window, arguments); - fcn.apply(scope || this || window, arguments); - return retval; - }; - } -}); - - -/** - * @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: - *- * @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) { - ch = " "; - } - while (result.length < size) { - result = ch + result; - } - return result; - } -}); + }, -/** - * 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. - *-var s = String.leftPad('123', 5, '0'); -// s now contains the string: '00123' - *
- * @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 + /** + * 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 + }); +})(); + +/** + * TBD + * @param {Object} config + * @method */ -String.prototype.toggle = function(value, other){ - return this == value ? other : value; -}; +Ext.application = function(config) { + Ext.require('Ext.app.Application'); -/** - * Trims whitespace from either end of a string, leaving spaces within the string intact. Example: - *-// alternate sort directions -sort = sort.toggle('ASC', 'DESC'); - -// instead of conditional logic: -sort = (sort == 'ASC' ? 'DESC' : 'ASC'); -
- * @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()); + Ext.onReady(function() { + Ext.create('Ext.app.Application', config); + }); }; - - -/** - * @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); - } -}); --var s = ' foo bar '; -alert('-' + s + '-'); //alerts "- foo bar -" -alert('-' + s.trim() + '-'); //alerts "-foo bar-" -