Ext.js
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:33k
源码类别:

中间件编程

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.0.0  * Copyright(c) 2006-2009 Ext JS, LLC  * licensing@extjs.com  * http://www.extjs.com/license  */
  2. // for old browsers
  3. window.undefined = window.undefined;
  4. /**
  5.  * @class Ext
  6.  * Ext core utilities and functions.
  7.  * @singleton
  8.  */
  9. Ext = {
  10.     /**
  11.      * The version of the framework
  12.      * @type String
  13.      */
  14.     version : '3.0'
  15. };
  16. /**
  17.  * Copies all the properties of config to obj.
  18.  * @param {Object} obj The receiver of the properties
  19.  * @param {Object} config The source of the properties
  20.  * @param {Object} defaults A different object that will also be applied for default values
  21.  * @return {Object} returns obj
  22.  * @member Ext apply
  23.  */
  24. Ext.apply = function(o, c, defaults){
  25.     // no "this" reference for friendly out of scope calls
  26.     if(defaults){
  27.         Ext.apply(o, defaults);
  28.     }
  29.     if(o && c && typeof c == 'object'){
  30.         for(var p in c){
  31.             o[p] = c[p];
  32.         }
  33.     }
  34.     return o;
  35. };
  36. (function(){
  37.     var idSeed = 0,
  38.         toString = Object.prototype.toString,
  39.         //assume it's not null and not an array
  40.         isIterable = function(v){
  41.             //check for array or arguments
  42.             if(Ext.isArray(v) || v.callee){
  43.                 return true;
  44.             }
  45.             //check for node list type
  46.             if(/NodeList|HTMLCollection/.test(toString.call(v))){
  47.                 return true;
  48.             }
  49.             //NodeList has an item and length property
  50.             //IXMLDOMNodeList has nextNode method, needs to be checked first.
  51.             return ((v.nextNode || v.item) && Ext.isNumber(v.length));
  52.         },
  53.         ua = navigator.userAgent.toLowerCase(),
  54.         check = function(r){
  55.             return r.test(ua);
  56.         },
  57.         DOC = document,
  58.         isStrict = DOC.compatMode == "CSS1Compat",
  59.         isOpera = check(/opera/),
  60.         isChrome = check(/chrome/),
  61.         isWebKit = check(/webkit/),
  62.         isSafari = !isChrome && check(/safari/),
  63.         isSafari2 = isSafari && check(/applewebkit/4/), // unique to Safari 2
  64.         isSafari3 = isSafari && check(/version/3/),
  65.         isSafari4 = isSafari && check(/version/4/),
  66.         isIE = !isOpera && check(/msie/),
  67.         isIE7 = isIE && check(/msie 7/),
  68.         isIE8 = isIE && check(/msie 8/),
  69.         isIE6 = isIE && !isIE7 && !isIE8,
  70.         isGecko = !isWebKit && check(/gecko/),
  71.         isGecko2 = isGecko && check(/rv:1.8/),
  72.         isGecko3 = isGecko && check(/rv:1.9/),
  73.         isBorderBox = isIE && !isStrict,
  74.         isWindows = check(/windows|win32/),
  75.         isMac = check(/macintosh|mac os x/),
  76.         isAir = check(/adobeair/),
  77.         isLinux = check(/linux/),
  78.         isSecure = /^https/i.test(window.location.protocol);
  79.     // remove css image flicker
  80.     if(isIE6){
  81.         try{
  82.             DOC.execCommand("BackgroundImageCache", false, true);
  83.         }catch(e){}
  84.     }
  85.     Ext.apply(Ext, {
  86.         /**
  87.          * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent
  88.          * the IE insecure content warning (defaults to javascript:false).
  89.          * @type String
  90.          */
  91.         SSL_SECURE_URL : 'javascript:false',
  92.         /**
  93.          * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode
  94.          * @type Boolean
  95.          */
  96.         isStrict : isStrict,
  97.         /**
  98.          * True if the page is running over SSL
  99.          * @type Boolean
  100.          */
  101.         isSecure : isSecure,
  102.         /**
  103.          * True when the document is fully initialized and ready for action
  104.          * @type Boolean
  105.          */
  106.         isReady : false,
  107.         /**
  108.          * True if the {@link Ext.Fx} Class is available
  109.          * @type Boolean
  110.          * @property enableFx
  111.          */
  112.         /**
  113.          * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)
  114.          * @type Boolean
  115.          */
  116.         enableGarbageCollector : true,
  117.         /**
  118.          * True to automatically purge event listeners after uncaching an element (defaults to false).
  119.          * Note: this only happens if {@link #enableGarbageCollector} is true.
  120.          * @type Boolean
  121.          */
  122.         enableListenerCollection : false,
  123.         /**
  124.          * Indicates whether to use native browser parsing for JSON methods.
  125.          * This option is ignored if the browser does not support native JSON methods.
  126.          * <b>Note: Native JSON methods will not work with objects that have functions.
  127.          * Also, property names must be quoted, otherwise the data will not parse.</b> (Defaults to false)
  128.          * @type Boolean
  129.          */
  130.         USE_NATIVE_JSON : false,
  131.         /**
  132.          * Copies all the properties of config to obj if they don't already exist.
  133.          * @param {Object} obj The receiver of the properties
  134.          * @param {Object} config The source of the properties
  135.          * @return {Object} returns obj
  136.          */
  137.         applyIf : function(o, c){
  138.             if(o){
  139.                 for(var p in c){
  140.                     if(Ext.isEmpty(o[p])){
  141.                         o[p] = c[p];
  142.                     }
  143.                 }
  144.             }
  145.             return o;
  146.         },
  147.         /**
  148.          * Generates unique ids. If the element already has an id, it is unchanged
  149.          * @param {Mixed} el (optional) The element to generate an id for
  150.          * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
  151.          * @return {String} The generated Id.
  152.          */
  153.         id : function(el, prefix){
  154.             return (el = Ext.getDom(el) || {}).id = el.id || (prefix || "ext-gen") + (++idSeed);
  155.         },
  156.         /**
  157.          * Extends one class with another class and optionally overrides members with the passed literal. This class
  158.          * also adds the function "override()" to the class that can be used to override
  159.          * members on an instance.
  160.          * * <p>
  161.          * This function also supports a 2-argument call in which the subclass's constructor is
  162.          * not passed as an argument. In this form, the parameters are as follows:</p><p>
  163.          * <div class="mdetail-params"><ul>
  164.          * <li><code>superclass</code>
  165.          * <div class="sub-desc">The class being extended</div></li>
  166.          * <li><code>overrides</code>
  167.          * <div class="sub-desc">A literal with members which are copied into the subclass's
  168.          * prototype, and are therefore shared among all instances of the new class.<p>
  169.          * This may contain a special member named <tt><b>constructor</b></tt>. This is used
  170.          * to define the constructor of the new class, and is returned. If this property is
  171.          * <i>not</i> specified, a constructor is generated and returned which just calls the
  172.          * superclass's constructor passing on its parameters.</p></div></li>
  173.          * </ul></div></p><p>
  174.          * For example, to create a subclass of the Ext GridPanel:
  175.          * <pre><code>
  176. MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
  177.     constructor: function(config) {
  178.         // Your preprocessing here
  179.         MyGridPanel.superclass.constructor.apply(this, arguments);
  180.         // Your postprocessing here
  181.     },
  182.     yourMethod: function() {
  183.         // etc.
  184.     }
  185. });
  186. </code></pre>
  187.          * </p>
  188.          * @param {Function} subclass The class inheriting the functionality
  189.          * @param {Function} superclass The class being extended
  190.          * @param {Object} overrides (optional) A literal with members which are copied into the subclass's
  191.          * prototype, and are therefore shared between all instances of the new class.
  192.          * @return {Function} The subclass constructor.
  193.          * @method extend
  194.          */
  195.         extend : function(){
  196.             // inline overrides
  197.             var io = function(o){
  198.                 for(var m in o){
  199.                     this[m] = o[m];
  200.                 }
  201.             };
  202.             var oc = Object.prototype.constructor;
  203.             return function(sb, sp, overrides){
  204.                 if(Ext.isObject(sp)){
  205.                     overrides = sp;
  206.                     sp = sb;
  207.                     sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
  208.                 }
  209.                 var F = function(){},
  210.                     sbp,
  211.                     spp = sp.prototype;
  212.                 F.prototype = spp;
  213.                 sbp = sb.prototype = new F();
  214.                 sbp.constructor=sb;
  215.                 sb.superclass=spp;
  216.                 if(spp.constructor == oc){
  217.                     spp.constructor=sp;
  218.                 }
  219.                 sb.override = function(o){
  220.                     Ext.override(sb, o);
  221.                 };
  222.                 sbp.superclass = sbp.supr = (function(){
  223.                     return spp;
  224.                 });
  225.                 sbp.override = io;
  226.                 Ext.override(sb, overrides);
  227.                 sb.extend = function(o){Ext.extend(sb, o);};
  228.                 return sb;
  229.             };
  230.         }(),
  231.         /**
  232.          * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.
  233.          * Usage:<pre><code>
  234. Ext.override(MyClass, {
  235.     newMethod1: function(){
  236.         // etc.
  237.     },
  238.     newMethod2: function(foo){
  239.         // etc.
  240.     }
  241. });
  242. </code></pre>
  243.          * @param {Object} origclass The class to override
  244.          * @param {Object} overrides The list of functions to add to origClass.  This should be specified as an object literal
  245.          * containing one or more methods.
  246.          * @method override
  247.          */
  248.         override : function(origclass, overrides){
  249.             if(overrides){
  250.                 var p = origclass.prototype;
  251.                 Ext.apply(p, overrides);
  252.                 if(Ext.isIE && overrides.toString != origclass.toString){
  253.                     p.toString = overrides.toString;
  254.                 }
  255.             }
  256.         },
  257.         /**
  258.          * Creates namespaces to be used for scoping variables and classes so that they are not global.
  259.          * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
  260.          * <pre><code>
  261. Ext.namespace('Company', 'Company.data');
  262. Ext.namespace('Company.data'); // equivalent and preferable to above syntax
  263. Company.Widget = function() { ... }
  264. Company.data.CustomStore = function(config) { ... }
  265. </code></pre>
  266.          * @param {String} namespace1
  267.          * @param {String} namespace2
  268.          * @param {String} etc
  269.          * @method namespace
  270.          */
  271.         namespace : function(){
  272.             var o, d;
  273.             Ext.each(arguments, function(v) {
  274.                 d = v.split(".");
  275.                 o = window[d[0]] = window[d[0]] || {};
  276.                 Ext.each(d.slice(1), function(v2){
  277.                     o = o[v2] = o[v2] || {};
  278.                 });
  279.             });
  280.             return o;
  281.         },
  282.         /**
  283.          * Takes an object and converts it to an encoded URL. e.g. Ext.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2".  Optionally, property values can be arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value.
  284.          * @param {Object} o
  285.          * @param {String} pre (optional) A prefix to add to the url encoded string
  286.          * @return {String}
  287.          */
  288.         urlEncode: function(o, pre){
  289.             var undef, buf = [], key, e = encodeURIComponent;
  290.             for(key in o){
  291.                 undef = !Ext.isDefined(o[key]);
  292.                 Ext.each(undef ? key : o[key], function(val, i){
  293.                     buf.push("&", e(key), "=", (val != key || !undef) ? e(val) : "");
  294.                 });
  295.             }
  296.             if(!pre){
  297.                 buf.shift();
  298.                 pre = "";
  299.             }
  300.             return pre + buf.join('');
  301.         },
  302.         /**
  303.          * Takes an encoded URL and and converts it to an object. Example: <pre><code>
  304. Ext.urlDecode("foo=1&bar=2"); // returns {foo: "1", bar: "2"}
  305. Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); // returns {foo: "1", bar: ["2", "3", "4"]}
  306. </code></pre>
  307.          * @param {String} string
  308.          * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
  309.          * @return {Object} A literal with members
  310.          */
  311.         urlDecode : function(string, overwrite){
  312.             var obj = {},
  313.                 pairs = string.split('&'),
  314.                 d = decodeURIComponent,
  315.                 name,
  316.                 value;
  317.             Ext.each(pairs, function(pair) {
  318.                 pair = pair.split('=');
  319.                 name = d(pair[0]);
  320.                 value = d(pair[1]);
  321.                 obj[name] = overwrite || !obj[name] ? value :
  322.                             [].concat(obj[name]).concat(value);
  323.             });
  324.             return obj;
  325.         },
  326.         /**
  327.          * Appends content to the query string of a URL, which handles logic for whether to place
  328.          * a question mark or ampersand.
  329.          * @param {String} url The url to append to.
  330.          * @@param {String} s The content to append to the url.
  331.          * @return (String) The appended string
  332.          */
  333.         urlAppend : function(url, s){
  334.             if(!Ext.isEmpty(s)){
  335.                 return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
  336.             }
  337.             return url;
  338.         },
  339.         /**
  340.          * Converts any iterable (numeric indices and a length property) into a true array
  341.          * Don't use this on strings. IE doesn't support "abc"[0] which this implementation depends on.
  342.          * For strings, use this instead: "abc".match(/./g) => [a,b,c];
  343.          * @param {Iterable} the iterable object to be turned into a true Array.
  344.          * @return (Array) array
  345.          */
  346.         toArray : function(){
  347.             return isIE ?
  348.                 function(a, i, j, res){
  349.                     res = [];
  350.                     Ext.each(a, function(v) {
  351.                         res.push(v);
  352.                     });
  353.                     return res.slice(i || 0, j || res.length);
  354.                 } :
  355.                 function(a, i, j){
  356.                     return Array.prototype.slice.call(a, i || 0, j || a.length);
  357.                 }
  358.         }(),
  359.         /**
  360.          * Iterates an array calling the passed function with each item, stopping if your function returns false. If the
  361.          * passed array is not really an array, your function is called once with it.
  362.          * The supplied function is called with (Object item, Number index, Array allItems).
  363.          * @param {Array/NodeList/Mixed} array
  364.          * @param {Function} fn
  365.          * @param {Object} scope
  366.          */
  367.         each: function(array, fn, scope){
  368.             if(Ext.isEmpty(array, true)){
  369.                 return;
  370.             }
  371.             if(!isIterable(array) || Ext.isPrimitive(array)){
  372.                 array = [array];
  373.             }
  374.             for(var i = 0, len = array.length; i < len; i++){
  375.                 if(fn.call(scope || array[i], array[i], i, array) === false){
  376.                     return i;
  377.                 };
  378.             }
  379.         },
  380.         /**
  381.          * Iterates either the elements in an array, or each of the properties in an object.
  382.          * <b>Note</b>: If you are only iterating arrays, it is better to call {@link #each}.
  383.          * @param {Object/Array} object The object or array to be iterated
  384.          * @param {Function} fn The function to be called for each iteration.
  385.          * The iteration will stop if the supplied function returns false, or
  386.          * all array elements / object properties have been covered. The signature
  387.          * varies depending on the type of object being interated:
  388.          * <div class="mdetail-params"><ul>
  389.          * <li>Arrays : <tt>(Object item, Number index, Array allItems)</tt>
  390.          * <div class="sub-desc">
  391.          * When iterating an array, the supplied function is called with each item.</div></li>
  392.          * <li>Objects : <tt>(String key, Object value)</tt>
  393.          * <div class="sub-desc">
  394.          * When iterating an object, the supplied function is called with each key-value pair in
  395.          * the object.</div></li>
  396.          * </ul></div>
  397.          * @param {Object} scope The scope to call the supplied function with, defaults to
  398.          * the specified <tt>object</tt>
  399.          */
  400.         iterate : function(obj, fn, scope){
  401.             if(isIterable(obj)){
  402.                 Ext.each(obj, fn, scope);
  403.                 return;
  404.             }else if(Ext.isObject(obj)){
  405.                 for(var prop in obj){
  406.                     if(obj.hasOwnProperty(prop)){
  407.                         if(fn.call(scope || obj, prop, obj[prop]) === false){
  408.                             return;
  409.                         };
  410.                     }
  411.                 }
  412.             }
  413.         },
  414.         /**
  415.          * Return the dom node for the passed String (id), dom node, or Ext.Element.
  416.          * Here are some examples:
  417.          * <pre><code>
  418. // gets dom node based on id
  419. var elDom = Ext.getDom('elId');
  420. // gets dom node based on the dom node
  421. var elDom1 = Ext.getDom(elDom);
  422. // If we don&#39;t know if we are working with an
  423. // Ext.Element or a dom node use Ext.getDom
  424. function(el){
  425.     var dom = Ext.getDom(el);
  426.     // do something with the dom node
  427. }
  428.          * </code></pre>
  429.          * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc)
  430.          * when this method is called to be successful.
  431.          * @param {Mixed} el
  432.          * @return HTMLElement
  433.          */
  434.         getDom : function(el){
  435.             if(!el || !DOC){
  436.                 return null;
  437.             }
  438.             return el.dom ? el.dom : (Ext.isString(el) ? DOC.getElementById(el) : el);
  439.         },
  440.         /**
  441.          * Returns the current document body as an {@link Ext.Element}.
  442.          * @return Ext.Element The document body
  443.          */
  444.         getBody : function(){
  445.             return Ext.get(DOC.body || DOC.documentElement);
  446.         },
  447.         /**
  448.          * Removes a DOM node from the document.  The body node will be ignored if passed in.
  449.          * @param {HTMLElement} node The node to remove
  450.          */
  451.         removeNode : isIE ? function(){
  452.             var d;
  453.             return function(n){
  454.                 if(n && n.tagName != 'BODY'){
  455.                     d = d || DOC.createElement('div');
  456.                     d.appendChild(n);
  457.                     d.innerHTML = '';
  458.                 }
  459.             }
  460.         }() : function(n){
  461.             if(n && n.parentNode && n.tagName != 'BODY'){
  462.                 n.parentNode.removeChild(n);
  463.             }
  464.         },
  465.         /**
  466.          * <p>Returns true if the passed value is empty.</p>
  467.          * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
  468.          * <li>null</li>
  469.          * <li>undefined</li>
  470.          * <li>an empty array</li>
  471.          * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
  472.          * </ul></div>
  473.          * @param {Mixed} value The value to test
  474.          * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
  475.          * @return {Boolean}
  476.          */
  477.         isEmpty : function(v, allowBlank){
  478.             return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
  479.         },
  480.         /**
  481.          * Returns true if the passed object is a JavaScript array, otherwise false.
  482.          * @param {Object} object The object to test
  483.          * @return {Boolean}
  484.          */
  485.         isArray : function(v){
  486.             return toString.apply(v) === '[object Array]';
  487.         },
  488.         /**
  489.          * Returns true if the passed object is a JavaScript Object, otherwise false.
  490.          * @param {Object} object The object to test
  491.          * @return {Boolean}
  492.          */
  493.         isObject : function(v){
  494.             return v && typeof v == "object";
  495.         },
  496.         /**
  497.          * Returns true if the passed object is a JavaScript 'primitive', a string, number or boolean.
  498.          * @param {Mixed} value The value to test
  499.          * @return {Boolean}
  500.          */
  501.         isPrimitive : function(v){
  502.             return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v);
  503.         },
  504.         /**
  505.          * Returns true if the passed object is a JavaScript Function, otherwise false.
  506.          * @param {Object} object The object to test
  507.          * @return {Boolean}
  508.          */
  509.         isFunction : function(v){
  510.             return toString.apply(v) === '[object Function]';
  511.         },
  512.         /**
  513.          * Returns true if the passed object is a number. Returns false for non-finite numbers.
  514.          * @param {Object} v The object to test
  515.          * @return {Boolean}
  516.          */
  517.         isNumber: function(v){
  518.             return typeof v === 'number' && isFinite(v);
  519.         },
  520.         /**
  521.          * Returns true if the passed object is a string.
  522.          * @param {Object} v The object to test
  523.          * @return {Boolean}
  524.          */
  525.         isString: function(v){
  526.             return typeof v === 'string';
  527.         },
  528.         /**
  529.          * Returns true if the passed object is a boolean.
  530.          * @param {Object} v The object to test
  531.          * @return {Boolean}
  532.          */
  533.         isBoolean: function(v){
  534.             return typeof v === 'boolean';
  535.         },
  536.         /**
  537.          * Returns true if the passed object is not undefined.
  538.          * @param {Object} v The object to test
  539.          * @return {Boolean}
  540.          */
  541.         isDefined: function(v){
  542.             return typeof v !== 'undefined';
  543.         },
  544.         /**
  545.          * True if the detected browser is Opera.
  546.          * @type Boolean
  547.          */
  548.         isOpera : isOpera,
  549.         /**
  550.          * True if the detected browser uses WebKit.
  551.          * @type Boolean
  552.          */
  553.         isWebKit: isWebKit,
  554.         /**
  555.          * True if the detected browser is Chrome.
  556.          * @type Boolean
  557.          */
  558.         isChrome : isChrome,
  559.         /**
  560.          * True if the detected browser is Safari.
  561.          * @type Boolean
  562.          */
  563.         isSafari : isSafari,
  564.         /**
  565.          * True if the detected browser is Safari 3.x.
  566.          * @type Boolean
  567.          */
  568.         isSafari3 : isSafari3,
  569.         /**
  570.          * True if the detected browser is Safari 4.x.
  571.          * @type Boolean
  572.          */
  573.         isSafari4 : isSafari4,
  574.         /**
  575.          * True if the detected browser is Safari 2.x.
  576.          * @type Boolean
  577.          */
  578.         isSafari2 : isSafari2,
  579.         /**
  580.          * True if the detected browser is Internet Explorer.
  581.          * @type Boolean
  582.          */
  583.         isIE : isIE,
  584.         /**
  585.          * True if the detected browser is Internet Explorer 6.x.
  586.          * @type Boolean
  587.          */
  588.         isIE6 : isIE6,
  589.         /**
  590.          * True if the detected browser is Internet Explorer 7.x.
  591.          * @type Boolean
  592.          */
  593.         isIE7 : isIE7,
  594.         /**
  595.          * True if the detected browser is Internet Explorer 8.x.
  596.          * @type Boolean
  597.          */
  598.         isIE8 : isIE8,
  599.         /**
  600.          * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
  601.          * @type Boolean
  602.          */
  603.         isGecko : isGecko,
  604.         /**
  605.          * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x).
  606.          * @type Boolean
  607.          */
  608.         isGecko2 : isGecko2,
  609.         /**
  610.          * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
  611.          * @type Boolean
  612.          */
  613.         isGecko3 : isGecko3,
  614.         /**
  615.          * True if the detected browser is Internet Explorer running in non-strict mode.
  616.          * @type Boolean
  617.          */
  618.         isBorderBox : isBorderBox,
  619.         /**
  620.          * True if the detected platform is Linux.
  621.          * @type Boolean
  622.          */
  623.         isLinux : isLinux,
  624.         /**
  625.          * True if the detected platform is Windows.
  626.          * @type Boolean
  627.          */
  628.         isWindows : isWindows,
  629.         /**
  630.          * True if the detected platform is Mac OS.
  631.          * @type Boolean
  632.          */
  633.         isMac : isMac,
  634.         /**
  635.          * True if the detected platform is Adobe Air.
  636.          * @type Boolean
  637.          */
  638.         isAir : isAir
  639.     });
  640.     /**
  641.      * Creates namespaces to be used for scoping variables and classes so that they are not global.
  642.      * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
  643.      * <pre><code>
  644. Ext.namespace('Company', 'Company.data');
  645. Ext.namespace('Company.data'); // equivalent and preferable to above syntax
  646. Company.Widget = function() { ... }
  647. Company.data.CustomStore = function(config) { ... }
  648. </code></pre>
  649.      * @param {String} namespace1
  650.      * @param {String} namespace2
  651.      * @param {String} etc
  652.      * @method namespace
  653.      */
  654.     Ext.ns = Ext.namespace;
  655. })();
  656. Ext.ns("Ext", "Ext.util", "Ext.lib", "Ext.data");
  657. /**
  658.  * @class Function
  659.  * These functions are available on every Function object (any JavaScript function).
  660.  */
  661. Ext.apply(Function.prototype, {
  662.      /**
  663.      * Creates an interceptor function. The passed fcn is called before the original one. If it returns false,
  664.      * the original one is not called. The resulting function returns the results of the original function.
  665.      * The passed fcn is called with the parameters of the original function. Example usage:
  666.      * <pre><code>
  667. var sayHi = function(name){
  668.     alert('Hi, ' + name);
  669. }
  670. sayHi('Fred'); // alerts "Hi, Fred"
  671. // create a new function that validates input without
  672. // directly modifying the original function:
  673. var sayHiToFriend = sayHi.createInterceptor(function(name){
  674.     return name == 'Brian';
  675. });
  676. sayHiToFriend('Fred');  // no alert
  677. sayHiToFriend('Brian'); // alerts "Hi, Brian"
  678. </code></pre>
  679.      * @param {Function} fcn The function to call before the original
  680.      * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
  681.      * @return {Function} The new function
  682.      */
  683.     createInterceptor : function(fcn, scope){
  684.         var method = this;
  685.         return !Ext.isFunction(fcn) ?
  686.                 this :
  687.                 function() {
  688.                     var me = this,
  689.                         args = arguments;
  690.                     fcn.target = me;
  691.                     fcn.method = method;
  692.                     return (fcn.apply(scope || me || window, args) !== false) ?
  693.                             method.apply(me || window, args) :
  694.                             null;
  695.                 };
  696.     },
  697.      /**
  698.      * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
  699.      * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code>
  700.      * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the
  701.      * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always
  702.      * executes in the window scope.
  703.      * <p>This method is required when you want to pass arguments to a callback function.  If no arguments
  704.      * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn).
  705.      * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function
  706.      * would simply execute immediately when the code is parsed. Example usage:
  707.      * <pre><code>
  708. var sayHi = function(name){
  709.     alert('Hi, ' + name);
  710. }
  711. // clicking the button alerts "Hi, Fred"
  712. new Ext.Button({
  713.     text: 'Say Hi',
  714.     renderTo: Ext.getBody(),
  715.     handler: sayHi.createCallback('Fred')
  716. });
  717. </code></pre>
  718.      * @return {Function} The new function
  719.     */
  720.     createCallback : function(/*args...*/){
  721.         // make args available, in function below
  722.         var args = arguments,
  723.             method = this;
  724.         return function() {
  725.             return method.apply(window, args);
  726.         };
  727.     },
  728.     /**
  729.      * Creates a delegate (callback) that sets the scope to obj.
  730.      * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code>
  731.      * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
  732.      * callback points to obj. Example usage:
  733.      * <pre><code>
  734. var sayHi = function(name){
  735.     // Note this use of "this.text" here.  This function expects to
  736.     // execute within a scope that contains a text property.  In this
  737.     // example, the "this" variable is pointing to the btn object that
  738.     // was passed in createDelegate below.
  739.     alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
  740. }
  741. var btn = new Ext.Button({
  742.     text: 'Say Hi',
  743.     renderTo: Ext.getBody()
  744. });
  745. // This callback will execute in the scope of the
  746. // button instance. Clicking the button alerts
  747. // "Hi, Fred. You clicked the "Say Hi" button."
  748. btn.on('click', sayHi.createDelegate(btn, ['Fred']));
  749. </code></pre>
  750.      * @param {Object} obj (optional) The object for which the scope is set
  751.      * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
  752.      * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
  753.      *                                             if a number the args are inserted at the specified position
  754.      * @return {Function} The new function
  755.      */
  756.     createDelegate : function(obj, args, appendArgs){
  757.         var method = this;
  758.         return function() {
  759.             var callArgs = args || arguments;
  760.             if (appendArgs === true){
  761.                 callArgs = Array.prototype.slice.call(arguments, 0);
  762.                 callArgs = callArgs.concat(args);
  763.             }else if (Ext.isNumber(appendArgs)){
  764.                 callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
  765.                 var applyArgs = [appendArgs, 0].concat(args); // create method call params
  766.                 Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
  767.             }
  768.             return method.apply(obj || window, callArgs);
  769.         };
  770.     },
  771.     /**
  772.      * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
  773.      * <pre><code>
  774. var sayHi = function(name){
  775.     alert('Hi, ' + name);
  776. }
  777. // executes immediately:
  778. sayHi('Fred');
  779. // executes after 2 seconds:
  780. sayHi.defer(2000, this, ['Fred']);
  781. // this syntax is sometimes useful for deferring
  782. // execution of an anonymous function:
  783. (function(){
  784.     alert('Anonymous');
  785. }).defer(100);
  786. </code></pre>
  787.      * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
  788.      * @param {Object} obj (optional) The object for which the scope is set
  789.      * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
  790.      * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
  791.      *                                             if a number the args are inserted at the specified position
  792.      * @return {Number} The timeout id that can be used with clearTimeout
  793.      */
  794.     defer : function(millis, obj, args, appendArgs){
  795.         var fn = this.createDelegate(obj, args, appendArgs);
  796.         if(millis > 0){
  797.             return setTimeout(fn, millis);
  798.         }
  799.         fn();
  800.         return 0;
  801.     }
  802. });
  803. /**
  804.  * @class String
  805.  * These functions are available on every String object.
  806.  */
  807. Ext.applyIf(String, {
  808.     /**
  809.      * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens.  Each
  810.      * token must be unique, and must increment in the format {0}, {1}, etc.  Example usage:
  811.      * <pre><code>
  812. var cls = 'my-class', text = 'Some text';
  813. var s = String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
  814. // s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
  815.      * </code></pre>
  816.      * @param {String} string The tokenized string to be formatted
  817.      * @param {String} value1 The value to replace token {0}
  818.      * @param {String} value2 Etc...
  819.      * @return {String} The formatted string
  820.      * @static
  821.      */
  822.     format : function(format){
  823.         var args = Ext.toArray(arguments, 1);
  824.         return format.replace(/{(d+)}/g, function(m, i){
  825.             return args[i];
  826.         });
  827.     }
  828. });
  829. /**
  830.  * @class Array
  831.  */
  832. Ext.applyIf(Array.prototype, {
  833.     /**
  834.      * Checks whether or not the specified object exists in the array.
  835.      * @param {Object} o The object to check for
  836.      * @return {Number} The index of o in the array (or -1 if it is not found)
  837.      */
  838.     indexOf : function(o){
  839.         for (var i = 0, len = this.length; i < len; i++){
  840.             if(this[i] == o){
  841.                 return i;
  842.             }
  843.         }
  844.         return -1;
  845.     },
  846.     /**
  847.      * Removes the specified object from the array.  If the object is not found nothing happens.
  848.      * @param {Object} o The object to remove
  849.      * @return {Array} this array
  850.      */
  851.     remove : function(o){
  852.         var index = this.indexOf(o);
  853.         if(index != -1){
  854.             this.splice(index, 1);
  855.         }
  856.         return this;
  857.     }
  858. });