yahoo.js
上传用户:q2283699q
上传日期:2022-05-17
资源大小:10704k
文件大小:29k
源码类别:

Ftp客户端

开发平台:

Visual C++

  1. /*
  2. Copyright (c) 2007, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.net/yui/license.txt
  5. version: 2.3.0
  6. */
  7. /**
  8.  * The YAHOO object is the single global object used by YUI Library.  It
  9.  * contains utility function for setting up namespaces, inheritance, and
  10.  * logging.  YAHOO.util, YAHOO.widget, and YAHOO.example are namespaces
  11.  * created automatically for and used by the library.
  12.  * @module yahoo
  13.  * @title  YAHOO Global
  14.  */
  15. /**
  16.  * YAHOO_config is not included as part of the library.  Instead it is an 
  17.  * object that can be defined by the implementer immediately before 
  18.  * including the YUI library.  The properties included in this object
  19.  * will be used to configure global properties needed as soon as the 
  20.  * library begins to load.
  21.  * @class YAHOO_config
  22.  * @static
  23.  */
  24. /**
  25.  * A reference to a function that will be executed every time a YAHOO module
  26.  * is loaded.  As parameter, this function will receive the version
  27.  * information for the module. See <a href="YAHOO.env.html#getVersion">
  28.  * YAHOO.env.getVersion</a> for the description of the version data structure.
  29.  * @property listener
  30.  * @type Function
  31.  * @static
  32.  * @default undefined
  33.  */
  34. /**
  35.  * Set to true if the library will be dynamically loaded after window.onload.
  36.  * Defaults to false 
  37.  * @property injecting
  38.  * @type boolean
  39.  * @static
  40.  * @default undefined
  41.  */
  42. /**
  43.  * Instructs the yuiloader component to dynamically load yui components and
  44.  * their dependencies.  See the yuiloader documentation for more information
  45.  * about dynamic loading
  46.  * @property load
  47.  * @static
  48.  * @default undefined
  49.  * @see yuiloader
  50.  */
  51. if (typeof YAHOO == "undefined") {
  52.     /**
  53.      * The YAHOO global namespace object.  If YAHOO is already defined, the
  54.      * existing YAHOO object will not be overwritten so that defined
  55.      * namespaces are preserved.
  56.      * @class YAHOO
  57.      * @static
  58.      */
  59.     var YAHOO = {};
  60. }
  61. /**
  62.  * Returns the namespace specified and creates it if it doesn't exist
  63.  * <pre>
  64.  * YAHOO.namespace("property.package");
  65.  * YAHOO.namespace("YAHOO.property.package");
  66.  * </pre>
  67.  * Either of the above would create YAHOO.property, then
  68.  * YAHOO.property.package
  69.  *
  70.  * Be careful when naming packages. Reserved words may work in some browsers
  71.  * and not others. For instance, the following will fail in Safari:
  72.  * <pre>
  73.  * YAHOO.namespace("really.long.nested.namespace");
  74.  * </pre>
  75.  * This fails because "long" is a future reserved word in ECMAScript
  76.  *
  77.  * @method namespace
  78.  * @static
  79.  * @param  {String*} arguments 1-n namespaces to create 
  80.  * @return {Object}  A reference to the last namespace object created
  81.  */
  82. YAHOO.namespace = function() {
  83.     var a=arguments, o=null, i, j, d;
  84.     for (i=0; i<a.length; i=i+1) {
  85.         d=a[i].split(".");
  86.         o=YAHOO;
  87.         // YAHOO is implied, so it is ignored if it is included
  88.         for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) {
  89.             o[d[j]]=o[d[j]] || {};
  90.             o=o[d[j]];
  91.         }
  92.     }
  93.     return o;
  94. };
  95. /**
  96.  * Uses YAHOO.widget.Logger to output a log message, if the widget is
  97.  * available.
  98.  *
  99.  * @method log
  100.  * @static
  101.  * @param  {String}  msg  The message to log.
  102.  * @param  {String}  cat  The log category for the message.  Default
  103.  *                        categories are "info", "warn", "error", time".
  104.  *                        Custom categories can be used as well. (opt)
  105.  * @param  {String}  src  The source of the the message (opt)
  106.  * @return {Boolean}      True if the log operation was successful.
  107.  */
  108. YAHOO.log = function(msg, cat, src) {
  109.     var l=YAHOO.widget.Logger;
  110.     if(l && l.log) {
  111.         return l.log(msg, cat, src);
  112.     } else {
  113.         return false;
  114.     }
  115. };
  116. /**
  117.  * Registers a module with the YAHOO object
  118.  * @method register
  119.  * @static
  120.  * @param {String}   name    the name of the module (event, slider, etc)
  121.  * @param {Function} mainClass a reference to class in the module.  This
  122.  *                             class will be tagged with the version info
  123.  *                             so that it will be possible to identify the
  124.  *                             version that is in use when multiple versions
  125.  *                             have loaded
  126.  * @param {Object}   data      metadata object for the module.  Currently it
  127.  *                             is expected to contain a "version" property
  128.  *                             and a "build" property at minimum.
  129.  */
  130. YAHOO.register = function(name, mainClass, data) {
  131.     var mods = YAHOO.env.modules;
  132.     if (!mods[name]) {
  133.         mods[name] = { versions:[], builds:[] };
  134.     }
  135.     var m=mods[name],v=data.version,b=data.build,ls=YAHOO.env.listeners;
  136.     m.name = name;
  137.     m.version = v;
  138.     m.build = b;
  139.     m.versions.push(v);
  140.     m.builds.push(b);
  141.     m.mainClass = mainClass;
  142.     // fire the module load listeners
  143.     for (var i=0;i<ls.length;i=i+1) {
  144.         ls[i](m);
  145.     }
  146.     // label the main class
  147.     if (mainClass) {
  148.         mainClass.VERSION = v;
  149.         mainClass.BUILD = b;
  150.     } else {
  151.         YAHOO.log("mainClass is undefined for module " + name, "warn");
  152.     }
  153. };
  154. /**
  155.  * YAHOO.env is used to keep track of what is known about the YUI library and
  156.  * the browsing environment
  157.  * @class YAHOO.env
  158.  * @static
  159.  */
  160. YAHOO.env = YAHOO.env || {
  161.     /**
  162.      * Keeps the version info for all YUI modules that have reported themselves
  163.      * @property modules
  164.      * @type Object[]
  165.      */
  166.     modules: [],
  167.     
  168.     /**
  169.      * List of functions that should be executed every time a YUI module
  170.      * reports itself.
  171.      * @property listeners
  172.      * @type Function[]
  173.      */
  174.     listeners: []
  175. };
  176. /**
  177.  * Returns the version data for the specified module:
  178.  *      <dl>
  179.  *      <dt>name:</dt>      <dd>The name of the module</dd>
  180.  *      <dt>version:</dt>   <dd>The version in use</dd>
  181.  *      <dt>build:</dt>     <dd>The build number in use</dd>
  182.  *      <dt>versions:</dt>  <dd>All versions that were registered</dd>
  183.  *      <dt>builds:</dt>    <dd>All builds that were registered.</dd>
  184.  *      <dt>mainClass:</dt> <dd>An object that was was stamped with the
  185.  *                 current version and build. If 
  186.  *                 mainClass.VERSION != version or mainClass.BUILD != build,
  187.  *                 multiple versions of pieces of the library have been
  188.  *                 loaded, potentially causing issues.</dd>
  189.  *       </dl>
  190.  *
  191.  * @method getVersion
  192.  * @static
  193.  * @param {String}  name the name of the module (event, slider, etc)
  194.  * @return {Object} The version info
  195.  */
  196. YAHOO.env.getVersion = function(name) {
  197.     return YAHOO.env.modules[name] || null;
  198. };
  199. /**
  200.  * Do not fork for a browser if it can be avoided.  Use feature detection when
  201.  * you can.  Use the user agent as a last resort.  YAHOO.env.ua stores a version
  202.  * number for the browser engine, 0 otherwise.  This value may or may not map
  203.  * to the version number of the browser using the engine.  The value is 
  204.  * presented as a float so that it can easily be used for boolean evaluation 
  205.  * as well as for looking for a particular range of versions.  Because of this, 
  206.  * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9 
  207.  * reports 1.8).
  208.  * @class YAHOO.env.ua
  209.  * @static
  210.  */
  211. YAHOO.env.ua = function() {
  212.     var o={
  213.         /**
  214.          * Internet Explorer version number or 0.  Example: 6
  215.          * @property ie
  216.          * @type float
  217.          */
  218.         ie:0,
  219.         /**
  220.          * Opera version number or 0.  Example: 9.2
  221.          * @property opera
  222.          * @type float
  223.          */
  224.         opera:0,
  225.         /**
  226.          * Gecko engine revision number.  Will evaluate to 1 if Gecko 
  227.          * is detected but the revision could not be found. Other browsers
  228.          * will be 0.  Example: 1.8
  229.          * <pre>
  230.          * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
  231.          * Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8
  232.          * Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8
  233.          * Firefox 3 alpha: 1.9a4   <-- Reports 1.9
  234.          * </pre>
  235.          * @property gecko
  236.          * @type float
  237.          */
  238.         gecko:0,
  239.         /**
  240.          * AppleWebKit version.  KHTML browsers that are not WebKit browsers 
  241.          * will evaluate to 1, other browsers 0.  Example: 418.9.1
  242.          * <pre>
  243.          * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the 
  244.          *                                   latest available for Mac OSX 10.3.
  245.          * Safari 2.0.2:         416     <-- hasOwnProperty introduced
  246.          * Safari 2.0.4:         418     <-- preventDefault fixed
  247.          * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
  248.          *                                   different versions of webkit
  249.          * Safari 2.0.4 (419.3): 419     <-- Current Safari release
  250.          * Webkit 212 nightly:   522+    <-- Safari 3.0 (with native SVG) should
  251.          *                                   be higher than this
  252.          *                                   
  253.          * </pre>
  254.          * http://developer.apple.com/internet/safari/uamatrix.html
  255.          * @property webkit
  256.          * @type float
  257.          */
  258.         webkit:0
  259.     };
  260.     var ua=navigator.userAgent, m;
  261.     // Modern KHTML browsers should qualify as Safari X-Grade
  262.     if ((/KHTML/).test(ua)) {
  263.         o.webkit=1;
  264.     }
  265.     // Modern WebKit browsers are at least X-Grade
  266.     m=ua.match(/AppleWebKit/([^s]*)/);
  267.     if (m&&m[1]) {
  268.         o.webkit=parseFloat(m[1]);
  269.     }
  270.     if (!o.webkit) { // not webkit
  271.         // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
  272.         m=ua.match(/Opera[s/]([^s]*)/);
  273.         if (m&&m[1]) {
  274.             o.opera=parseFloat(m[1]);
  275.         } else { // not opera or webkit
  276.             m=ua.match(/MSIEs([^;]*)/);
  277.             if (m&&m[1]) {
  278.                 o.ie=parseFloat(m[1]);
  279.             } else { // not opera, webkit, or ie
  280.                 m=ua.match(/Gecko/([^s]*)/);
  281.                 if (m) {
  282.                     o.gecko=1; // Gecko detected, look for revision
  283.                     m=ua.match(/rv:([^s)]*)/);
  284.                     if (m&&m[1]) {
  285.                         o.gecko=parseFloat(m[1]);
  286.                     }
  287.                 }
  288.             }
  289.         }
  290.     }
  291.     
  292.     return o;
  293. }();
  294. /*
  295.  * Initializes the global by creating the default namespaces and applying
  296.  * any new configuration information that is detected.  This is the setup
  297.  * for env.
  298.  * @method init
  299.  * @static
  300.  * @private
  301.  */
  302. (function() {
  303.     YAHOO.namespace("util", "widget", "example");
  304.     if (typeof YAHOO_config != "undefined") {
  305.         var l=YAHOO_config.listener,ls=YAHOO.env.listeners,unique=true,i;
  306.         if (l) {
  307.             // if YAHOO is loaded multiple times we need to check to see if
  308.             // this is a new config object.  If it is, add the new component
  309.             // load listener to the stack
  310.             for (i=0;i<ls.length;i=i+1) {
  311.                 if (ls[i]==l) {
  312.                     unique=false;
  313.                     break;
  314.                 }
  315.             }
  316.             if (unique) {
  317.                 ls.push(l);
  318.             }
  319.         }
  320.     }
  321. })();
  322. /**
  323.  * Provides the language utilites and extensions used by the library
  324.  * @class YAHOO.lang
  325.  */
  326. YAHOO.lang = {
  327.     /**
  328.      * Determines whether or not the provided object is an array.
  329.      * Testing typeof/instanceof/constructor of arrays across frame 
  330.      * boundaries isn't possible in Safari unless you have a reference
  331.      * to the other frame to test against its Array prototype.  To
  332.      * handle this case, we test well-known array properties instead.
  333.      * properties.
  334.      * @method isArray
  335.      * @param {any} o The object being testing
  336.      * @return Boolean
  337.      */
  338.     isArray: function(o) { 
  339.         if (o) {
  340.            var l = YAHOO.lang;
  341.            return l.isNumber(o.length) && l.isFunction(o.splice) && 
  342.                   !l.hasOwnProperty(o.length);
  343.         }
  344.         return false;
  345.     },
  346.     /**
  347.      * Determines whether or not the provided object is a boolean
  348.      * @method isBoolean
  349.      * @param {any} o The object being testing
  350.      * @return Boolean
  351.      */
  352.     isBoolean: function(o) {
  353.         return typeof o === 'boolean';
  354.     },
  355.     
  356.     /**
  357.      * Determines whether or not the provided object is a function
  358.      * @method isFunction
  359.      * @param {any} o The object being testing
  360.      * @return Boolean
  361.      */
  362.     isFunction: function(o) {
  363.         return typeof o === 'function';
  364.     },
  365.         
  366.     /**
  367.      * Determines whether or not the provided object is null
  368.      * @method isNull
  369.      * @param {any} o The object being testing
  370.      * @return Boolean
  371.      */
  372.     isNull: function(o) {
  373.         return o === null;
  374.     },
  375.         
  376.     /**
  377.      * Determines whether or not the provided object is a legal number
  378.      * @method isNumber
  379.      * @param {any} o The object being testing
  380.      * @return Boolean
  381.      */
  382.     isNumber: function(o) {
  383.         return typeof o === 'number' && isFinite(o);
  384.     },
  385.       
  386.     /**
  387.      * Determines whether or not the provided object is of type object
  388.      * or function
  389.      * @method isObject
  390.      * @param {any} o The object being testing
  391.      * @return Boolean
  392.      */  
  393.     isObject: function(o) {
  394. return (o && (typeof o === 'object' || YAHOO.lang.isFunction(o))) || false;
  395.     },
  396.         
  397.     /**
  398.      * Determines whether or not the provided object is a string
  399.      * @method isString
  400.      * @param {any} o The object being testing
  401.      * @return Boolean
  402.      */
  403.     isString: function(o) {
  404.         return typeof o === 'string';
  405.     },
  406.         
  407.     /**
  408.      * Determines whether or not the provided object is undefined
  409.      * @method isUndefined
  410.      * @param {any} o The object being testing
  411.      * @return Boolean
  412.      */
  413.     isUndefined: function(o) {
  414.         return typeof o === 'undefined';
  415.     },
  416.     
  417.     /**
  418.      * Determines whether or not the property was added
  419.      * to the object instance.  Returns false if the property is not present
  420.      * in the object, or was inherited from the prototype.
  421.      * This abstraction is provided to enable hasOwnProperty for Safari 1.3.x.
  422.      * There is a discrepancy between YAHOO.lang.hasOwnProperty and
  423.      * Object.prototype.hasOwnProperty when the property is a primitive added to
  424.      * both the instance AND prototype with the same value:
  425.      * <pre>
  426.      * var A = function() {};
  427.      * A.prototype.foo = 'foo';
  428.      * var a = new A();
  429.      * a.foo = 'foo';
  430.      * alert(a.hasOwnProperty('foo')); // true
  431.      * alert(YAHOO.lang.hasOwnProperty(a, 'foo')); // false when using fallback
  432.      * </pre>
  433.      * @method hasOwnProperty
  434.      * @param {any} o The object being testing
  435.      * @return Boolean
  436.      */
  437.     hasOwnProperty: function(o, prop) {
  438.         if (Object.prototype.hasOwnProperty) {
  439.             return o.hasOwnProperty(prop);
  440.         }
  441.         
  442.         return !YAHOO.lang.isUndefined(o[prop]) && 
  443.                 o.constructor.prototype[prop] !== o[prop];
  444.     },
  445.  
  446.     /**
  447.      * IE will not enumerate native functions in a derived object even if the
  448.      * function was overridden.  This is a workaround for specific functions 
  449.      * we care about on the Object prototype. 
  450.      * @property _IEEnumFix
  451.      * @param {Function} r  the object to receive the augmentation
  452.      * @param {Function} s  the object that supplies the properties to augment
  453.      * @static
  454.      * @private
  455.      */
  456.     _IEEnumFix: function(r, s) {
  457.         if (YAHOO.env.ua.ie) {
  458.             var add=["toString", "valueOf"];
  459.             for (i=0;i<add.length;i=i+1) {
  460.                 var fname=add[i],f=s[fname];
  461.                 if (YAHOO.lang.isFunction(f) && f!=Object.prototype[fname]) {
  462.                     r[fname]=f;
  463.                 }
  464.             }
  465.         }
  466.     },
  467.        
  468.     /**
  469.      * Utility to set up the prototype, constructor and superclass properties to
  470.      * support an inheritance strategy that can chain constructors and methods.
  471.      * Static members will not be inherited.
  472.      *
  473.      * @method extend
  474.      * @static
  475.      * @param {Function} subc   the object to modify
  476.      * @param {Function} superc the object to inherit
  477.      * @param {Object} overrides  additional properties/methods to add to the
  478.      *                              subclass prototype.  These will override the
  479.      *                              matching items obtained from the superclass 
  480.      *                              if present.
  481.      */
  482.     extend: function(subc, superc, overrides) {
  483.         if (!superc||!subc) {
  484.             throw new Error("YAHOO.lang.extend failed, please check that " +
  485.                             "all dependencies are included.");
  486.         }
  487.         var F = function() {};
  488.         F.prototype=superc.prototype;
  489.         subc.prototype=new F();
  490.         subc.prototype.constructor=subc;
  491.         subc.superclass=superc.prototype;
  492.         if (superc.prototype.constructor == Object.prototype.constructor) {
  493.             superc.prototype.constructor=superc;
  494.         }
  495.     
  496.         if (overrides) {
  497.             for (var i in overrides) {
  498.                 subc.prototype[i]=overrides[i];
  499.             }
  500.             YAHOO.lang._IEEnumFix(subc.prototype, overrides);
  501.         }
  502.     },
  503.    
  504.     /**
  505.      * Applies all properties in the supplier to the receiver if the
  506.      * receiver does not have these properties yet.  Optionally, one or 
  507.      * more methods/properties can be specified (as additional 
  508.      * parameters).  This option will overwrite the property if receiver 
  509.      * has it already.  If true is passed as the third parameter, all 
  510.      * properties will be applied and _will_ overwrite properties in 
  511.      * the receiver.
  512.      *
  513.      * @method augmentObject
  514.      * @static
  515.      * @since 2.3.0
  516.      * @param {Function} r  the object to receive the augmentation
  517.      * @param {Function} s  the object that supplies the properties to augment
  518.      * @param {String*|boolean}  arguments zero or more properties methods 
  519.      *        to augment the receiver with.  If none specified, everything
  520.      *        in the supplier will be used unless it would
  521.      *        overwrite an existing property in the receiver. If true
  522.      *        is specified as the third parameter, all properties will
  523.      *        be applied and will overwrite an existing property in
  524.      *        the receiver
  525.      */
  526.     augmentObject: function(r, s) {
  527.         if (!s||!r) {
  528.             throw new Error("Absorb failed, verify dependencies.");
  529.         }
  530.         var a=arguments, i, p, override=a[2];
  531.         if (override && override!==true) { // only absorb the specified properties
  532.             for (i=2; i<a.length; i=i+1) {
  533.                 r[a[i]] = s[a[i]];
  534.             }
  535.         } else { // take everything, overwriting only if the third parameter is true
  536.             for (p in s) { 
  537.                 if (override || !r[p]) {
  538.                     r[p] = s[p];
  539.                 }
  540.             }
  541.             
  542.             YAHOO.lang._IEEnumFix(r, s);
  543.         }
  544.     },
  545.  
  546.     /**
  547.      * Same as YAHOO.lang.augmentObject, except it only applies prototype properties
  548.      * @see YAHOO.lang.augmentObject
  549.      * @method augmentProto
  550.      * @static
  551.      * @param {Function} r  the object to receive the augmentation
  552.      * @param {Function} s  the object that supplies the properties to augment
  553.      * @param {String*|boolean}  arguments zero or more properties methods 
  554.      *        to augment the receiver with.  If none specified, everything 
  555.      *        in the supplier will be used unless it would overwrite an existing 
  556.      *        property in the receiver.  if true is specified as the third 
  557.      *        parameter, all properties will be applied and will overwrite an 
  558.      *        existing property in the receiver
  559.      */
  560.     augmentProto: function(r, s) {
  561.         if (!s||!r) {
  562.             throw new Error("Augment failed, verify dependencies.");
  563.         }
  564.         //var a=[].concat(arguments);
  565.         var a=[r.prototype,s.prototype];
  566.         for (var i=2;i<arguments.length;i=i+1) {
  567.             a.push(arguments[i]);
  568.         }
  569.         YAHOO.lang.augmentObject.apply(this, a);
  570.     },
  571.       
  572.     /**
  573.      * Returns a simple string representation of the object or array.
  574.      * Other types of objects will be returned unprocessed.  Arrays
  575.      * are expected to be indexed.  Use object notation for
  576.      * associative arrays.
  577.      * @method dump
  578.      * @since 2.3.0
  579.      * @param o {Object} The object to dump
  580.      * @param d {int} How deep to recurse child objects, default 3
  581.      * @return {String} the dump result
  582.      */
  583.     dump: function(o, d) {
  584.         var l=YAHOO.lang,i,len,s=[],OBJ="{...}",FUN="f(){...}",
  585.             COMMA=', ', ARROW=' => ';
  586.         // Skip non-objects
  587.         // Skip dates because the std toString is what we want
  588.         // Skip HTMLElement-like objects because trying to dump 
  589.         // an element will cause an unhandled exception in FF 2.x
  590.         if (!l.isObject(o) || o instanceof Date || 
  591.             ("nodeType" in o && "tagName" in o)) {
  592.             return o;
  593.         } else if  (l.isFunction(o)) {
  594.             return FUN;
  595.         }
  596.         // dig into child objects the depth specifed. Default 3
  597.         d = (l.isNumber(d)) ? d : 3;
  598.         // arrays [1, 2, 3]
  599.         if (l.isArray(o)) {
  600.             s.push("[");
  601.             for (i=0,len=o.length;i<len;i=i+1) {
  602.                 if (l.isObject(o[i])) {
  603.                     s.push((d > 0) ? l.dump(o[i], d-1) : OBJ);
  604.                 } else {
  605.                     s.push(o[i]);
  606.                 }
  607.                 s.push(COMMA);
  608.             }
  609.             if (s.length > 1) {
  610.                 s.pop();
  611.             }
  612.             s.push("]");
  613.         // objects {k1 => v1, k2 => v2}
  614.         } else {
  615.             s.push("{");
  616.             for (i in o) {
  617.                 if (l.hasOwnProperty(o, i)) {
  618.                     s.push(i + ARROW);
  619.                     if (l.isObject(o[i])) {
  620.                         s.push((d > 0) ? l.dump(o[i], d-1) : OBJ);
  621.                     } else {
  622.                         s.push(o[i]);
  623.                     }
  624.                     s.push(COMMA);
  625.                 }
  626.             }
  627.             if (s.length > 1) {
  628.                 s.pop();
  629.             }
  630.             s.push("}");
  631.         }
  632.         return s.join("");
  633.     },
  634.     /**
  635.      * Does variable substitution on a string. It scans through the string 
  636.      * looking for expressions enclosed in { } braces. If an expression 
  637.      * is found, it is used a key on the object.  If there is a space in
  638.      * the key, the first word is used for the key and the rest is provided
  639.      * to an optional function to be used to programatically determine the
  640.      * value (the extra information might be used for this decision). If 
  641.      * the value for the key in the object, or what is returned from the
  642.      * function has a string value, number value, or object value, it is 
  643.      * substituted for the bracket expression and it repeats.  If this
  644.      * value is an object, it uses the Object's toString() if this has
  645.      * been overridden, otherwise it does a shallow dump of the key/value
  646.      * pairs.
  647.      * @method substitute
  648.      * @since 2.3.0
  649.      * @param s {String} The string that will be modified.
  650.      * @param o {Object} An object containing the replacement values
  651.      * @param f {Function} An optional function that can be used to
  652.      *                     process each match.  It receives the key,
  653.      *                     value, and any extra metadata included with
  654.      *                     the key inside of the braces.
  655.      * @return {String} the substituted string
  656.      */
  657.     substitute: function (s, o, f) {
  658.         var i, j, k, key, v, meta, l=YAHOO.lang, saved=[], token, 
  659.             DUMP='dump', SPACE=' ', LBRACE='{', RBRACE='}';
  660.         for (;;) {
  661.             i = s.lastIndexOf(LBRACE);
  662.             if (i < 0) {
  663.                 break;
  664.             }
  665.             j = s.indexOf(RBRACE, i);
  666.             if (i + 1 >= j) {
  667.                 break;
  668.             }
  669.             //Extract key and meta info 
  670.             token = s.substring(i + 1, j);
  671.             key = token;
  672.             meta = null;
  673.             k = key.indexOf(SPACE);
  674.             if (k > -1) {
  675.                 meta = key.substring(k + 1);
  676.                 key = key.substring(0, k);
  677.             }
  678.             // lookup the value
  679.             v = o[key];
  680.             // if a substitution function was provided, execute it
  681.             if (f) {
  682.                 v = f(key, v, meta);
  683.             }
  684.             if (l.isObject(v)) {
  685.                 if (l.isArray(v)) {
  686.                     v = l.dump(v, parseInt(meta, 10));
  687.                 } else {
  688.                     meta = meta || "";
  689.                     // look for the keyword 'dump', if found force obj dump
  690.                     var dump = meta.indexOf(DUMP);
  691.                     if (dump > -1) {
  692.                         meta = meta.substring(4);
  693.                     }
  694.                     // use the toString if it is not the Object toString 
  695.                     // and the 'dump' meta info was not found
  696.                     if (v.toString===Object.prototype.toString||dump>-1) {
  697.                         v = l.dump(v, parseInt(meta, 10));
  698.                     } else {
  699.                         v = v.toString();
  700.                     }
  701.                 }
  702.             } else if (!l.isString(v) && !l.isNumber(v)) {
  703.                 // This {block} has no replace string. Save it for later.
  704.                 v = "~-" + saved.length + "-~";
  705.                 saved[saved.length] = token;
  706.                 // break;
  707.             }
  708.             s = s.substring(0, i) + v + s.substring(j + 1);
  709.         }
  710.         // restore saved {block}s
  711.         for (i=saved.length-1; i>=0; i=i-1) {
  712.             s = s.replace(new RegExp("~-" + i + "-~"), "{"  + saved[i] + "}", "g");
  713.         }
  714.         return s;
  715.     },
  716.     /**
  717.      * Returns a string without any leading or trailing whitespace.  If 
  718.      * the input is not a string, the input will be returned untouched.
  719.      * @method trim
  720.      * @since 2.3.0
  721.      * @param s {string} the string to trim
  722.      * @return {string} the trimmed string
  723.      */
  724.     trim: function(s){
  725.         try {
  726.             return s.replace(/^s+|s+$/g, "");
  727.         } catch(e) {
  728.             return s;
  729.         }
  730.     },
  731.     /**
  732.      * Returns a new object containing all of the properties of
  733.      * all the supplied objects.  The properties from later objects
  734.      * will overwrite those in earlier objects.
  735.      * @method merge
  736.      * @since 2.3.0
  737.      * @param arguments {Object*} the objects to merge
  738.      * @return the new merged object
  739.      */
  740.     merge: function() {
  741.         var o={}, a=arguments, i;
  742.         for (i=0; i<a.length; i=i+1) {
  743.             YAHOO.lang.augmentObject(o, a[i], true);
  744.             /*
  745.             for (var j in a[i]) {
  746.                 o[j] = a[i][j];
  747.             }
  748.             */
  749.         }
  750.         return o;
  751.     },
  752.     /**
  753.      * A convenience method for detecting a legitimate non-null value.
  754.      * Returns false for null/undefined/NaN, true for other values, 
  755.      * including 0/false/''
  756.      * @method isValue
  757.      * @since 2.3.0
  758.      * @param o {any} the item to test
  759.      * @return {boolean} true if it is not null/undefined/NaN || false
  760.      */
  761.     isValue: function(o) {
  762.         // return (o || o === false || o === 0 || o === ''); // Infinity fails
  763.         var l = YAHOO.lang;
  764. return (l.isObject(o) || l.isString(o) || l.isNumber(o) || l.isBoolean(o));
  765.     }
  766. };
  767. /*
  768.  * An alias for <a href="YAHOO.lang.html">YAHOO.lang</a>
  769.  * @class YAHOO.util.Lang
  770.  */
  771. YAHOO.util.Lang = YAHOO.lang;
  772.  
  773. /**
  774.  * Same as YAHOO.lang.augmentObject, except it only applies prototype 
  775.  * properties.  This is an alias for augmentProto.
  776.  * @see YAHOO.lang.augmentObject
  777.  * @method augment
  778.  * @static
  779.  * @param {Function} r  the object to receive the augmentation
  780.  * @param {Function} s  the object that supplies the properties to augment
  781.  * @param {String*|boolean}  arguments zero or more properties methods to 
  782.  *        augment the receiver with.  If none specified, everything
  783.  *        in the supplier will be used unless it would
  784.  *        overwrite an existing property in the receiver.  if true
  785.  *        is specified as the third parameter, all properties will
  786.  *        be applied and will overwrite an existing property in
  787.  *        the receiver
  788.  */
  789. YAHOO.lang.augment = YAHOO.lang.augmentProto;
  790. /**
  791.  * An alias for <a href="YAHOO.lang.html#augment">YAHOO.lang.augment</a>
  792.  * @for YAHOO
  793.  * @method augment
  794.  * @static
  795.  * @param {Function} r  the object to receive the augmentation
  796.  * @param {Function} s  the object that supplies the properties to augment
  797.  * @param {String*}  arguments zero or more properties methods to 
  798.  *        augment the receiver with.  If none specified, everything
  799.  *        in the supplier will be used unless it would
  800.  *        overwrite an existing property in the receiver
  801.  */
  802. YAHOO.augment = YAHOO.lang.augmentProto;
  803.        
  804. /**
  805.  * An alias for <a href="YAHOO.lang.html#extend">YAHOO.lang.extend</a>
  806.  * @method extend
  807.  * @static
  808.  * @param {Function} subc   the object to modify
  809.  * @param {Function} superc the object to inherit
  810.  * @param {Object} overrides  additional properties/methods to add to the
  811.  *        subclass prototype.  These will override the
  812.  *        matching items obtained from the superclass if present.
  813.  */
  814. YAHOO.extend = YAHOO.lang.extend;
  815. YAHOO.register("yahoo", YAHOO, {version: "2.3.0", build: "442"});