Project

General

Profile

1 601 doc
/*
2 1263 Luisehahne
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 601 doc
Code licensed under the BSD License:
4
http://developer.yahoo.net/yui/license.txt
5 1263 Luisehahne
version: 2.8.0r4
6 601 doc
*/
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
/**
17
 * YAHOO_config is not included as part of the library.  Instead it is an
18
 * object that can be defined by the implementer immediately before
19
 * including the YUI library.  The properties included in this object
20
 * will be used to configure global properties needed as soon as the
21
 * library begins to load.
22
 * @class YAHOO_config
23
 * @static
24
 */
25
26
/**
27
 * A reference to a function that will be executed every time a YAHOO module
28
 * is loaded.  As parameter, this function will receive the version
29
 * information for the module. See <a href="YAHOO.env.html#getVersion">
30
 * YAHOO.env.getVersion</a> for the description of the version data structure.
31
 * @property listener
32
 * @type Function
33
 * @static
34
 * @default undefined
35
 */
36
37
/**
38
 * Set to true if the library will be dynamically loaded after window.onload.
39
 * Defaults to false
40
 * @property injecting
41
 * @type boolean
42
 * @static
43
 * @default undefined
44
 */
45
46
/**
47
 * Instructs the yuiloader component to dynamically load yui components and
48
 * their dependencies.  See the yuiloader documentation for more information
49
 * about dynamic loading
50
 * @property load
51
 * @static
52
 * @default undefined
53
 * @see yuiloader
54
 */
55
56
/**
57
 * Forces the use of the supplied locale where applicable in the library
58
 * @property locale
59
 * @type string
60
 * @static
61
 * @default undefined
62
 */
63
64
if (typeof YAHOO == "undefined" || !YAHOO) {
65
    /**
66
     * The YAHOO global namespace object.  If YAHOO is already defined, the
67
     * existing YAHOO object will not be overwritten so that defined
68
     * namespaces are preserved.
69 1374 Luisehahne
    * @class YAHOO
70
    * @static
71 601 doc
     */
72
    var YAHOO = {};
73
}
74
75
/**
76
 * Returns the namespace specified and creates it if it doesn't exist
77
 * <pre>
78
 * YAHOO.namespace("property.package");
79
 * YAHOO.namespace("YAHOO.property.package");
80
 * </pre>
81
 * Either of the above would create YAHOO.property, then
82
 * YAHOO.property.package
83
 *
84
 * Be careful when naming packages. Reserved words may work in some browsers
85
 * and not others. For instance, the following will fail in Safari:
86
 * <pre>
87
 * YAHOO.namespace("really.long.nested.namespace");
88
 * </pre>
89
 * This fails because "long" is a future reserved word in ECMAScript
90
 *
91 1263 Luisehahne
 * For implementation code that uses YUI, do not create your components
92
 * in the namespaces defined by YUI (
93
 * <code>YAHOO.util</code>,
94
 * <code>YAHOO.widget</code>,
95
 * <code>YAHOO.lang</code>,
96
 * <code>YAHOO.tool</code>,
97
 * <code>YAHOO.example</code>,
98
 * <code>YAHOO.env</code>) -- create your own namespace (e.g., 'companyname').
99
 *
100 601 doc
 * @method namespace
101
 * @static
102
 * @param  {String*} arguments 1-n namespaces to create
103
 * @return {Object}  A reference to the last namespace object created
104
 */
105
YAHOO.namespace = function() {
106
    var a=arguments, o=null, i, j, d;
107
    for (i=0; i<a.length; i=i+1) {
108 1263 Luisehahne
        d=(""+a[i]).split(".");
109 601 doc
        o=YAHOO;
110
111
        // YAHOO is implied, so it is ignored if it is included
112
        for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) {
113
            o[d[j]]=o[d[j]] || {};
114
            o=o[d[j]];
115
        }
116
    }
117
118
    return o;
119
};
120
121
/**
122
 * Uses YAHOO.widget.Logger to output a log message, if the widget is
123
 * available.
124
 *
125
 * @method log
126
 * @static
127
 * @param  {String}  msg  The message to log.
128
 * @param  {String}  cat  The log category for the message.  Default
129
 *                        categories are "info", "warn", "error", time".
130
 *                        Custom categories can be used as well. (opt)
131
 * @param  {String}  src  The source of the the message (opt)
132
 * @return {Boolean}      True if the log operation was successful.
133
 */
134
YAHOO.log = function(msg, cat, src) {
135
    var l=YAHOO.widget.Logger;
136
    if(l && l.log) {
137
        return l.log(msg, cat, src);
138
    } else {
139
        return false;
140
    }
141
};
142
143
/**
144
 * Registers a module with the YAHOO object
145
 * @method register
146
 * @static
147
 * @param {String}   name    the name of the module (event, slider, etc)
148
 * @param {Function} mainClass a reference to class in the module.  This
149
 *                             class will be tagged with the version info
150
 *                             so that it will be possible to identify the
151
 *                             version that is in use when multiple versions
152
 *                             have loaded
153
 * @param {Object}   data      metadata object for the module.  Currently it
154
 *                             is expected to contain a "version" property
155
 *                             and a "build" property at minimum.
156
 */
157
YAHOO.register = function(name, mainClass, data) {
158 1263 Luisehahne
    var mods = YAHOO.env.modules, m, v, b, ls, i;
159
160 601 doc
    if (!mods[name]) {
161 1263 Luisehahne
        mods[name] = {
162
            versions:[],
163
            builds:[]
164
        };
165 601 doc
    }
166 1263 Luisehahne
167
    m  = mods[name];
168
    v  = data.version;
169
    b  = data.build;
170
    ls = YAHOO.env.listeners;
171
172 601 doc
    m.name = name;
173
    m.version = v;
174
    m.build = b;
175
    m.versions.push(v);
176
    m.builds.push(b);
177
    m.mainClass = mainClass;
178 1263 Luisehahne
179 601 doc
    // fire the module load listeners
180 1263 Luisehahne
    for (i=0;i<ls.length;i=i+1) {
181 601 doc
        ls[i](m);
182
    }
183
    // label the main class
184
    if (mainClass) {
185
        mainClass.VERSION = v;
186
        mainClass.BUILD = b;
187
    } else {
188
        YAHOO.log("mainClass is undefined for module " + name, "warn");
189
    }
190
};
191
192
/**
193
 * YAHOO.env is used to keep track of what is known about the YUI library and
194
 * the browsing environment
195
 * @class YAHOO.env
196
 * @static
197
 */
198
YAHOO.env = YAHOO.env || {
199
200
    /**
201
     * Keeps the version info for all YUI modules that have reported themselves
202 1374 Luisehahne
    * @property modules
203
    * @type Object[]
204 601 doc
     */
205
    modules: [],
206
207
    /**
208
     * List of functions that should be executed every time a YUI module
209
     * reports itself.
210 1374 Luisehahne
    * @property listeners
211
    * @type Function[]
212 601 doc
     */
213
    listeners: []
214
};
215
216
/**
217
 * Returns the version data for the specified module:
218
 *      <dl>
219
 *      <dt>name:</dt>      <dd>The name of the module</dd>
220
 *      <dt>version:</dt>   <dd>The version in use</dd>
221
 *      <dt>build:</dt>     <dd>The build number in use</dd>
222
 *      <dt>versions:</dt>  <dd>All versions that were registered</dd>
223
 *      <dt>builds:</dt>    <dd>All builds that were registered.</dd>
224
 *      <dt>mainClass:</dt> <dd>An object that was was stamped with the
225
 *                 current version and build. If
226
 *                 mainClass.VERSION != version or mainClass.BUILD != build,
227
 *                 multiple versions of pieces of the library have been
228
 *                 loaded, potentially causing issues.</dd>
229
 *       </dl>
230
 *
231
 * @method getVersion
232
 * @static
233
 * @param {String}  name the name of the module (event, slider, etc)
234
 * @return {Object} The version info
235
 */
236
YAHOO.env.getVersion = function(name) {
237
    return YAHOO.env.modules[name] || null;
238
};
239
240
/**
241
 * Do not fork for a browser if it can be avoided.  Use feature detection when
242
 * you can.  Use the user agent as a last resort.  YAHOO.env.ua stores a version
243
 * number for the browser engine, 0 otherwise.  This value may or may not map
244
 * to the version number of the browser using the engine.  The value is
245
 * presented as a float so that it can easily be used for boolean evaluation
246
 * as well as for looking for a particular range of versions.  Because of this,
247
 * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9
248
 * reports 1.8).
249
 * @class YAHOO.env.ua
250
 * @static
251
 */
252
YAHOO.env.ua = function() {
253
254 1263 Luisehahne
        var numberfy = function(s) {
255
            var c = 0;
256
            return parseFloat(s.replace(/\./g, function() {
257
                return (c++ == 1) ? '' : '.';
258
            }));
259
        },
260
261
        nav = navigator,
262
263
        o = {
264
265 601 doc
        /**
266
         * Internet Explorer version number or 0.  Example: 6
267 1374 Luisehahne
        * @property ie
268
        * @type float
269 601 doc
         */
270 1263 Luisehahne
        ie: 0,
271 601 doc
272
        /**
273
         * Opera version number or 0.  Example: 9.2
274 1374 Luisehahne
        * @property opera
275
        * @type float
276 601 doc
         */
277 1263 Luisehahne
        opera: 0,
278 601 doc
279
        /**
280
         * Gecko engine revision number.  Will evaluate to 1 if Gecko
281
         * is detected but the revision could not be found. Other browsers
282
         * will be 0.  Example: 1.8
283
         * <pre>
284
         * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
285
         * Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8
286
         * Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8
287
         * Firefox 3 alpha: 1.9a4   <-- Reports 1.9
288
         * </pre>
289 1374 Luisehahne
        * @property gecko
290
        * @type float
291 601 doc
         */
292 1263 Luisehahne
        gecko: 0,
293 601 doc
294
        /**
295
         * AppleWebKit version.  KHTML browsers that are not WebKit browsers
296
         * will evaluate to 1, other browsers 0.  Example: 418.9.1
297
         * <pre>
298
         * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
299
         *                                   latest available for Mac OSX 10.3.
300
         * Safari 2.0.2:         416     <-- hasOwnProperty introduced
301
         * Safari 2.0.4:         418     <-- preventDefault fixed
302
         * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
303
         *                                   different versions of webkit
304 1263 Luisehahne
         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
305
         *                                   updated, but not updated
306
         *                                   to the latest patch.
307
         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native SVG
308
         *                                   and many major issues fixed).
309
         * 3.x yahoo.com, flickr:422     <-- Safari 3.x hacks the user agent
310
         *                                   string when hitting yahoo.com and
311
         *                                   flickr.com.
312
         * Safari 3.0.4 (523.12):523.12  <-- First Tiger release - automatic update
313
         *                                   from 2.x via the 10.4.11 OS patch
314
         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
315
         *                                   yahoo.com user agent hack removed.
316 601 doc
         *
317
         * </pre>
318
         * http://developer.apple.com/internet/safari/uamatrix.html
319 1374 Luisehahne
        * @property webkit
320
        * @type float
321 601 doc
         */
322 1263 Luisehahne
        webkit: 0,
323 601 doc
324
        /**
325
         * The mobile property will be set to a string containing any relevant
326
         * user agent information when a modern mobile browser is detected.
327
         * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
328
         * devices with the WebKit-based browser, and Opera Mini.
329 1374 Luisehahne
        * @property mobile
330
        * @type string
331 601 doc
         */
332 1263 Luisehahne
        mobile: null,
333 601 doc
334 1263 Luisehahne
        /**
335
         * Adobe AIR version number or 0.  Only populated if webkit is detected.
336
         * Example: 1.0
337 1374 Luisehahne
        * @property air
338
        * @type float
339 1263 Luisehahne
         */
340
        air: 0,
341 601 doc
342 1263 Luisehahne
        /**
343
         * Google Caja version number or 0.
344 1374 Luisehahne
        * @property caja
345
        * @type float
346 1263 Luisehahne
         */
347
        caja: nav.cajaVersion,
348 601 doc
349 1263 Luisehahne
        /**
350
         * Set to true if the page appears to be in SSL
351 1374 Luisehahne
        * @property secure
352
        * @type boolean
353
        * @static
354 1263 Luisehahne
         */
355
        secure: false,
356
357
        /**
358
         * The operating system.  Currently only detecting windows or macintosh
359 1374 Luisehahne
        * @property os
360
        * @type string
361
        * @static
362 1263 Luisehahne
         */
363
        os: null
364
365
    },
366
367
    ua = navigator && navigator.userAgent,
368
369
    loc = window && window.location,
370
371
    href = loc && loc.href,
372
373
    m;
374
375
    o.secure = href && (href.toLowerCase().indexOf("https") === 0);
376
377
    if (ua) {
378
379
        if ((/windows|win32/i).test(ua)) {
380
            o.os = 'windows';
381
        } else if ((/macintosh/i).test(ua)) {
382
            o.os = 'macintosh';
383 601 doc
        }
384 1263 Luisehahne
385
        // Modern KHTML browsers should qualify as Safari X-Grade
386
        if ((/KHTML/).test(ua)) {
387
            o.webkit=1;
388
        }
389 601 doc
390 1263 Luisehahne
        // Modern WebKit browsers are at least X-Grade
391
        m=ua.match(/AppleWebKit\/([^\s]*)/);
392
        if (m&&m[1]) {
393
            o.webkit=numberfy(m[1]);
394 601 doc
395 1263 Luisehahne
            // Mobile browser check
396
            if (/ Mobile\//.test(ua)) {
397
                o.mobile = "Apple"; // iPhone or iPod Touch
398
            } else {
399
                m=ua.match(/NokiaN[^\/]*/);
400
                if (m) {
401
                    o.mobile = m[0]; // Nokia N-series, ex: NokiaN95
402
                }
403
            }
404
405
            m=ua.match(/AdobeAIR\/([^\s]*)/);
406 601 doc
            if (m) {
407 1263 Luisehahne
                o.air = m[0]; // Adobe AIR 1.0 or better
408 601 doc
            }
409 1263 Luisehahne
410
        }
411
412
        if (!o.webkit) { // not webkit
413
            // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
414
            m=ua.match(/Opera[\s\/]([^\s]*)/);
415 601 doc
            if (m&&m[1]) {
416 1263 Luisehahne
                o.opera=numberfy(m[1]);
417
                m=ua.match(/Opera Mini[^;]*/);
418 601 doc
                if (m) {
419 1263 Luisehahne
                    o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
420
                }
421
            } else { // not opera or webkit
422
                m=ua.match(/MSIE\s([^;]*)/);
423
                if (m&&m[1]) {
424
                    o.ie=numberfy(m[1]);
425
                } else { // not opera, webkit, or ie
426
                    m=ua.match(/Gecko\/([^\s]*)/);
427
                    if (m) {
428
                        o.gecko=1; // Gecko detected, look for revision
429
                        m=ua.match(/rv:([^\s\)]*)/);
430
                        if (m&&m[1]) {
431
                            o.gecko=numberfy(m[1]);
432
                        }
433 601 doc
                    }
434
                }
435
            }
436
        }
437
    }
438 1263 Luisehahne
439 601 doc
    return o;
440
}();
441
442
/*
443
 * Initializes the global by creating the default namespaces and applying
444
 * any new configuration information that is detected.  This is the setup
445
 * for env.
446
 * @method init
447
 * @static
448
 * @private
449
 */
450
(function() {
451
    YAHOO.namespace("util", "widget", "example");
452 1263 Luisehahne
    /*global YAHOO_config*/
453 601 doc
    if ("undefined" !== typeof YAHOO_config) {
454 1263 Luisehahne
        var l=YAHOO_config.listener, ls=YAHOO.env.listeners,unique=true, i;
455 601 doc
        if (l) {
456
            // if YAHOO is loaded multiple times we need to check to see if
457
            // this is a new config object.  If it is, add the new component
458
            // load listener to the stack
459 1263 Luisehahne
            for (i=0; i<ls.length; i++) {
460
                if (ls[i] == l) {
461
                    unique = false;
462 601 doc
                    break;
463
                }
464
            }
465 1263 Luisehahne
466 601 doc
            if (unique) {
467
                ls.push(l);
468
            }
469
        }
470
    }
471
})();
472
/**
473
 * Provides the language utilites and extensions used by the library
474
 * @class YAHOO.lang
475
 */
476 1263 Luisehahne
YAHOO.lang = YAHOO.lang || {};
477
478
(function() {
479
480
481
var L = YAHOO.lang,
482
483
    OP = Object.prototype,
484
    ARRAY_TOSTRING = '[object Array]',
485
    FUNCTION_TOSTRING = '[object Function]',
486
    OBJECT_TOSTRING = '[object Object]',
487
    NOTHING = [],
488
489
    // ADD = ["toString", "valueOf", "hasOwnProperty"],
490
    ADD = ["toString", "valueOf"],
491
492
    OB = {
493
494 601 doc
    /**
495 1263 Luisehahne
     * Determines wheather or not the provided object is an array.
496 1374 Luisehahne
    * @method isArray
497
    * @param {any} o The object being testing
498
    * @return {boolean} the result
499 601 doc
     */
500
    isArray: function(o) {
501 1263 Luisehahne
        return OP.toString.apply(o) === ARRAY_TOSTRING;
502 601 doc
    },
503
504
    /**
505
     * Determines whether or not the provided object is a boolean
506 1374 Luisehahne
    * @method isBoolean
507
    * @param {any} o The object being testing
508
    * @return {boolean} the result
509 601 doc
     */
510
    isBoolean: function(o) {
511
        return typeof o === 'boolean';
512
    },
513
514
    /**
515 1263 Luisehahne
     * Determines whether or not the provided object is a function.
516
     * Note: Internet Explorer thinks certain functions are objects:
517
     *
518
     * var obj = document.createElement("object");
519
     * YAHOO.lang.isFunction(obj.getAttribute) // reports false in IE
520
     *
521
     * var input = document.createElement("input"); // append to body
522
     * YAHOO.lang.isFunction(input.focus) // reports false in IE
523
     *
524
     * You will have to implement additional tests if these functions
525
     * matter to you.
526
     *
527 1374 Luisehahne
    * @method isFunction
528
    * @param {any} o The object being testing
529
    * @return {boolean} the result
530 601 doc
     */
531
    isFunction: function(o) {
532 1263 Luisehahne
        return (typeof o === 'function') || OP.toString.apply(o) === FUNCTION_TOSTRING;
533 601 doc
    },
534
535
    /**
536
     * Determines whether or not the provided object is null
537 1374 Luisehahne
    * @method isNull
538
    * @param {any} o The object being testing
539
    * @return {boolean} the result
540 601 doc
     */
541
    isNull: function(o) {
542
        return o === null;
543
    },
544
545
    /**
546
     * Determines whether or not the provided object is a legal number
547 1374 Luisehahne
    * @method isNumber
548
    * @param {any} o The object being testing
549
    * @return {boolean} the result
550 601 doc
     */
551
    isNumber: function(o) {
552
        return typeof o === 'number' && isFinite(o);
553
    },
554
555
    /**
556
     * Determines whether or not the provided object is of type object
557
     * or function
558 1374 Luisehahne
    * @method isObject
559
    * @param {any} o The object being testing
560
    * @return {boolean} the result
561 601 doc
     */
562
    isObject: function(o) {
563 1263 Luisehahne
return (o && (typeof o === 'object' || L.isFunction(o))) || false;
564 601 doc
    },
565
566
    /**
567
     * Determines whether or not the provided object is a string
568 1374 Luisehahne
    * @method isString
569
    * @param {any} o The object being testing
570
    * @return {boolean} the result
571 601 doc
     */
572
    isString: function(o) {
573
        return typeof o === 'string';
574
    },
575
576
    /**
577
     * Determines whether or not the provided object is undefined
578 1374 Luisehahne
    * @method isUndefined
579
    * @param {any} o The object being testing
580
    * @return {boolean} the result
581 601 doc
     */
582
    isUndefined: function(o) {
583
        return typeof o === 'undefined';
584
    },
585
586
587
    /**
588
     * IE will not enumerate native functions in a derived object even if the
589
     * function was overridden.  This is a workaround for specific functions
590
     * we care about on the Object prototype.
591 1374 Luisehahne
    * @property _IEEnumFix
592
    * @param {Function} r  the object to receive the augmentation
593
    * @param {Function} s  the object that supplies the properties to augment
594
    * @static
595
    * @private
596 601 doc
     */
597 1263 Luisehahne
    _IEEnumFix: (YAHOO.env.ua.ie) ? function(r, s) {
598
            var i, fname, f;
599
            for (i=0;i<ADD.length;i=i+1) {
600
601
                fname = ADD[i];
602
                f = s[fname];
603
604
                if (L.isFunction(f) && f!=OP[fname]) {
605 601 doc
                    r[fname]=f;
606
                }
607
            }
608 1263 Luisehahne
    } : function(){},
609 601 doc
610
    /**
611
     * Utility to set up the prototype, constructor and superclass properties to
612
     * support an inheritance strategy that can chain constructors and methods.
613
     * Static members will not be inherited.
614
     *
615 1374 Luisehahne
    * @method extend
616
    * @static
617
    * @param {Function} subc   the object to modify
618
    * @param {Function} superc the object to inherit
619
    * @param {Object} overrides  additional properties/methods to add to the
620 601 doc
     *                              subclass prototype.  These will override the
621
     *                              matching items obtained from the superclass
622
     *                              if present.
623
     */
624
    extend: function(subc, superc, overrides) {
625
        if (!superc||!subc) {
626 1263 Luisehahne
            throw new Error("extend failed, please check that " +
627 601 doc
                            "all dependencies are included.");
628
        }
629 1263 Luisehahne
        var F = function() {}, i;
630 601 doc
        F.prototype=superc.prototype;
631
        subc.prototype=new F();
632
        subc.prototype.constructor=subc;
633
        subc.superclass=superc.prototype;
634 1263 Luisehahne
        if (superc.prototype.constructor == OP.constructor) {
635 601 doc
            superc.prototype.constructor=superc;
636
        }
637
638
        if (overrides) {
639 1263 Luisehahne
            for (i in overrides) {
640
                if (L.hasOwnProperty(overrides, i)) {
641
                    subc.prototype[i]=overrides[i];
642
                }
643 601 doc
            }
644
645 1263 Luisehahne
            L._IEEnumFix(subc.prototype, overrides);
646 601 doc
        }
647
    },
648
649
    /**
650
     * Applies all properties in the supplier to the receiver if the
651
     * receiver does not have these properties yet.  Optionally, one or
652
     * more methods/properties can be specified (as additional
653
     * parameters).  This option will overwrite the property if receiver
654
     * has it already.  If true is passed as the third parameter, all
655
     * properties will be applied and _will_ overwrite properties in
656
     * the receiver.
657
     *
658 1374 Luisehahne
    * @method augmentObject
659
    * @static
660
    * @since 2.3.0
661
    * @param {Function} r  the object to receive the augmentation
662
    * @param {Function} s  the object that supplies the properties to augment
663
    * @param {String*|boolean}  arguments zero or more properties methods
664 601 doc
     *        to augment the receiver with.  If none specified, everything
665
     *        in the supplier will be used unless it would
666
     *        overwrite an existing property in the receiver. If true
667
     *        is specified as the third parameter, all properties will
668
     *        be applied and will overwrite an existing property in
669
     *        the receiver
670
     */
671
    augmentObject: function(r, s) {
672
        if (!s||!r) {
673
            throw new Error("Absorb failed, verify dependencies.");
674
        }
675 1263 Luisehahne
        var a=arguments, i, p, overrideList=a[2];
676
        if (overrideList && overrideList!==true) { // only absorb the specified properties
677 601 doc
            for (i=2; i<a.length; i=i+1) {
678
                r[a[i]] = s[a[i]];
679
            }
680
        } else { // take everything, overwriting only if the third parameter is true
681
            for (p in s) {
682 1263 Luisehahne
                if (overrideList || !(p in r)) {
683 601 doc
                    r[p] = s[p];
684
                }
685
            }
686
687 1263 Luisehahne
            L._IEEnumFix(r, s);
688 601 doc
        }
689
    },
690
691
    /**
692
     * Same as YAHOO.lang.augmentObject, except it only applies prototype properties
693 1374 Luisehahne
    * @see YAHOO.lang.augmentObject
694
    * @method augmentProto
695
    * @static
696
    * @param {Function} r  the object to receive the augmentation
697
    * @param {Function} s  the object that supplies the properties to augment
698
    * @param {String*|boolean}  arguments zero or more properties methods
699 601 doc
     *        to augment the receiver with.  If none specified, everything
700
     *        in the supplier will be used unless it would overwrite an existing
701
     *        property in the receiver.  if true is specified as the third
702
     *        parameter, all properties will be applied and will overwrite an
703
     *        existing property in the receiver
704
     */
705
    augmentProto: function(r, s) {
706
        if (!s||!r) {
707
            throw new Error("Augment failed, verify dependencies.");
708
        }
709
        //var a=[].concat(arguments);
710 1263 Luisehahne
        var a=[r.prototype,s.prototype], i;
711
        for (i=2;i<arguments.length;i=i+1) {
712 601 doc
            a.push(arguments[i]);
713
        }
714 1263 Luisehahne
        L.augmentObject.apply(this, a);
715 601 doc
    },
716
717
718
    /**
719
     * Returns a simple string representation of the object or array.
720
     * Other types of objects will be returned unprocessed.  Arrays
721
     * are expected to be indexed.  Use object notation for
722
     * associative arrays.
723 1374 Luisehahne
    * @method dump
724
    * @since 2.3.0
725
    * @param o {Object} The object to dump
726
    * @param d {int} How deep to recurse child objects, default 3
727
    * @return {String} the dump result
728 601 doc
     */
729
    dump: function(o, d) {
730 1263 Luisehahne
        var i,len,s=[],OBJ="{...}",FUN="f(){...}",
731 601 doc
            COMMA=', ', ARROW=' => ';
732
733
        // Cast non-objects to string
734
        // Skip dates because the std toString is what we want
735
        // Skip HTMLElement-like objects because trying to dump
736
        // an element will cause an unhandled exception in FF 2.x
737 1263 Luisehahne
        if (!L.isObject(o)) {
738 601 doc
            return o + "";
739
        } else if (o instanceof Date || ("nodeType" in o && "tagName" in o)) {
740
            return o;
741 1263 Luisehahne
        } else if  (L.isFunction(o)) {
742 601 doc
            return FUN;
743
        }
744
745
        // dig into child objects the depth specifed. Default 3
746 1263 Luisehahne
        d = (L.isNumber(d)) ? d : 3;
747 601 doc
748
        // arrays [1, 2, 3]
749 1263 Luisehahne
        if (L.isArray(o)) {
750 601 doc
            s.push("[");
751
            for (i=0,len=o.length;i<len;i=i+1) {
752 1263 Luisehahne
                if (L.isObject(o[i])) {
753
                    s.push((d > 0) ? L.dump(o[i], d-1) : OBJ);
754 601 doc
                } else {
755
                    s.push(o[i]);
756
                }
757
                s.push(COMMA);
758
            }
759
            if (s.length > 1) {
760
                s.pop();
761
            }
762
            s.push("]");
763
        // objects {k1 => v1, k2 => v2}
764
        } else {
765
            s.push("{");
766
            for (i in o) {
767 1263 Luisehahne
                if (L.hasOwnProperty(o, i)) {
768 601 doc
                    s.push(i + ARROW);
769 1263 Luisehahne
                    if (L.isObject(o[i])) {
770
                        s.push((d > 0) ? L.dump(o[i], d-1) : OBJ);
771 601 doc
                    } else {
772
                        s.push(o[i]);
773
                    }
774
                    s.push(COMMA);
775
                }
776
            }
777
            if (s.length > 1) {
778
                s.pop();
779
            }
780
            s.push("}");
781
        }
782
783
        return s.join("");
784
    },
785
786
    /**
787
     * Does variable substitution on a string. It scans through the string
788
     * looking for expressions enclosed in { } braces. If an expression
789
     * is found, it is used a key on the object.  If there is a space in
790
     * the key, the first word is used for the key and the rest is provided
791
     * to an optional function to be used to programatically determine the
792
     * value (the extra information might be used for this decision). If
793
     * the value for the key in the object, or what is returned from the
794
     * function has a string value, number value, or object value, it is
795
     * substituted for the bracket expression and it repeats.  If this
796
     * value is an object, it uses the Object's toString() if this has
797
     * been overridden, otherwise it does a shallow dump of the key/value
798
     * pairs.
799 1374 Luisehahne
    * @method substitute
800
    * @since 2.3.0
801
    * @param s {String} The string that will be modified.
802
    * @param o {Object} An object containing the replacement values
803
    * @param f {Function} An optional function that can be used to
804 601 doc
     *                     process each match.  It receives the key,
805
     *                     value, and any extra metadata included with
806
     *                     the key inside of the braces.
807 1374 Luisehahne
    * @return {String} the substituted string
808 601 doc
     */
809
    substitute: function (s, o, f) {
810 1263 Luisehahne
        var i, j, k, key, v, meta, saved=[], token,
811
            DUMP='dump', SPACE=' ', LBRACE='{', RBRACE='}',
812
            dump, objstr;
813 601 doc
814
815
        for (;;) {
816
            i = s.lastIndexOf(LBRACE);
817
            if (i < 0) {
818
                break;
819
            }
820
            j = s.indexOf(RBRACE, i);
821
            if (i + 1 >= j) {
822
                break;
823
            }
824
825
            //Extract key and meta info
826
            token = s.substring(i + 1, j);
827
            key = token;
828
            meta = null;
829
            k = key.indexOf(SPACE);
830
            if (k > -1) {
831
                meta = key.substring(k + 1);
832
                key = key.substring(0, k);
833
            }
834
835
            // lookup the value
836
            v = o[key];
837
838
            // if a substitution function was provided, execute it
839
            if (f) {
840
                v = f(key, v, meta);
841
            }
842
843 1263 Luisehahne
            if (L.isObject(v)) {
844
                if (L.isArray(v)) {
845
                    v = L.dump(v, parseInt(meta, 10));
846 601 doc
                } else {
847
                    meta = meta || "";
848
849
                    // look for the keyword 'dump', if found force obj dump
850 1263 Luisehahne
                    dump = meta.indexOf(DUMP);
851 601 doc
                    if (dump > -1) {
852
                        meta = meta.substring(4);
853
                    }
854
855 1263 Luisehahne
                    objstr = v.toString();
856
857 601 doc
                    // use the toString if it is not the Object toString
858
                    // and the 'dump' meta info was not found
859 1263 Luisehahne
                    if (objstr === OBJECT_TOSTRING || dump > -1) {
860
                        v = L.dump(v, parseInt(meta, 10));
861 601 doc
                    } else {
862 1263 Luisehahne
                        v = objstr;
863 601 doc
                    }
864
                }
865 1263 Luisehahne
            } else if (!L.isString(v) && !L.isNumber(v)) {
866 601 doc
                // This {block} has no replace string. Save it for later.
867
                v = "~-" + saved.length + "-~";
868
                saved[saved.length] = token;
869
870
                // break;
871
            }
872
873
            s = s.substring(0, i) + v + s.substring(j + 1);
874
875
876
        }
877
878
        // restore saved {block}s
879
        for (i=saved.length-1; i>=0; i=i-1) {
880
            s = s.replace(new RegExp("~-" + i + "-~"), "{"  + saved[i] + "}", "g");
881
        }
882
883
        return s;
884
    },
885
886
887
    /**
888
     * Returns a string without any leading or trailing whitespace.  If
889
     * the input is not a string, the input will be returned untouched.
890 1374 Luisehahne
    * @method trim
891
    * @since 2.3.0
892
    * @param s {string} the string to trim
893
    * @return {string} the trimmed string
894 601 doc
     */
895
    trim: function(s){
896
        try {
897
            return s.replace(/^\s+|\s+$/g, "");
898
        } catch(e) {
899
            return s;
900
        }
901
    },
902
903
    /**
904
     * Returns a new object containing all of the properties of
905
     * all the supplied objects.  The properties from later objects
906
     * will overwrite those in earlier objects.
907 1374 Luisehahne
    * @method merge
908
    * @since 2.3.0
909
    * @param arguments {Object*} the objects to merge
910
    * @return the new merged object
911 601 doc
     */
912
    merge: function() {
913 1263 Luisehahne
        var o={}, a=arguments, l=a.length, i;
914
        for (i=0; i<l; i=i+1) {
915
            L.augmentObject(o, a[i], true);
916 601 doc
        }
917
        return o;
918
    },
919
920
    /**
921 1263 Luisehahne
     * Executes the supplied function in the context of the supplied
922 601 doc
     * object 'when' milliseconds later.  Executes the function a
923
     * single time unless periodic is set to true.
924 1374 Luisehahne
    * @method later
925
    * @since 2.4.0
926
    * @param when {int} the number of milliseconds to wait until the fn
927 601 doc
     * is executed
928 1374 Luisehahne
    * @param o the context object
929
    * @param fn {Function|String} the function to execute or the name of
930 601 doc
     * the method in the 'o' object to execute
931 1374 Luisehahne
    * @param data [Array] data that is provided to the function.  This accepts
932 601 doc
     * either a single item or an array.  If an array is provided, the
933
     * function is executed with one parameter for each array item.  If
934
     * you need to pass a single array parameter, it needs to be wrapped in
935
     * an array [myarray]
936 1374 Luisehahne
    * @param periodic {boolean} if true, executes continuously at supplied
937 601 doc
     * interval until canceled
938 1374 Luisehahne
    * @return a timer object. Call the cancel() method on this object to
939 601 doc
     * stop the timer.
940
     */
941
    later: function(when, o, fn, data, periodic) {
942
        when = when || 0;
943
        o = o || {};
944
        var m=fn, d=data, f, r;
945
946 1263 Luisehahne
        if (L.isString(fn)) {
947 601 doc
            m = o[fn];
948
        }
949
950
        if (!m) {
951
            throw new TypeError("method undefined");
952
        }
953
954 1263 Luisehahne
        if (d && !L.isArray(d)) {
955 601 doc
            d = [data];
956
        }
957
958
        f = function() {
959 1263 Luisehahne
            m.apply(o, d || NOTHING);
960 601 doc
        };
961
962
        r = (periodic) ? setInterval(f, when) : setTimeout(f, when);
963
964
        return {
965
            interval: periodic,
966
            cancel: function() {
967
                if (this.interval) {
968
                    clearInterval(r);
969
                } else {
970
                    clearTimeout(r);
971
                }
972
            }
973
        };
974
    },
975 1263 Luisehahne
976 601 doc
    /**
977
     * A convenience method for detecting a legitimate non-null value.
978
     * Returns false for null/undefined/NaN, true for other values,
979
     * including 0/false/''
980 1374 Luisehahne
    * @method isValue
981
    * @since 2.3.0
982
    * @param o {any} the item to test
983
    * @return {boolean} true if it is not null/undefined/NaN || false
984 601 doc
     */
985
    isValue: function(o) {
986
        // return (o || o === false || o === 0 || o === ''); // Infinity fails
987 1263 Luisehahne
return (L.isObject(o) || L.isString(o) || L.isNumber(o) || L.isBoolean(o));
988 601 doc
    }
989
990
};
991
992 1263 Luisehahne
/**
993
 * Determines whether or not the property was added
994
 * to the object instance.  Returns false if the property is not present
995
 * in the object, or was inherited from the prototype.
996
 * This abstraction is provided to enable hasOwnProperty for Safari 1.3.x.
997
 * There is a discrepancy between YAHOO.lang.hasOwnProperty and
998
 * Object.prototype.hasOwnProperty when the property is a primitive added to
999
 * both the instance AND prototype with the same value:
1000
 * <pre>
1001
 * var A = function() {};
1002
 * A.prototype.foo = 'foo';
1003
 * var a = new A();
1004
 * a.foo = 'foo';
1005
 * alert(a.hasOwnProperty('foo')); // true
1006
 * alert(YAHOO.lang.hasOwnProperty(a, 'foo')); // false when using fallback
1007
 * </pre>
1008
 * @method hasOwnProperty
1009
 * @param {any} o The object being testing
1010
 * @param prop {string} the name of the property to test
1011
 * @return {boolean} the result
1012
 */
1013
L.hasOwnProperty = (OP.hasOwnProperty) ?
1014
    function(o, prop) {
1015
        return o && o.hasOwnProperty(prop);
1016
    } : function(o, prop) {
1017
        return !L.isUndefined(o[prop]) &&
1018
                o.constructor.prototype[prop] !== o[prop];
1019
    };
1020
1021
// new lang wins
1022
OB.augmentObject(L, OB, true);
1023
1024 601 doc
/*
1025
 * An alias for <a href="YAHOO.lang.html">YAHOO.lang</a>
1026
 * @class YAHOO.util.Lang
1027
 */
1028 1263 Luisehahne
YAHOO.util.Lang = L;
1029 601 doc
1030
/**
1031
 * Same as YAHOO.lang.augmentObject, except it only applies prototype
1032
 * properties.  This is an alias for augmentProto.
1033
 * @see YAHOO.lang.augmentObject
1034
 * @method augment
1035
 * @static
1036
 * @param {Function} r  the object to receive the augmentation
1037
 * @param {Function} s  the object that supplies the properties to augment
1038
 * @param {String*|boolean}  arguments zero or more properties methods to
1039
 *        augment the receiver with.  If none specified, everything
1040
 *        in the supplier will be used unless it would
1041
 *        overwrite an existing property in the receiver.  if true
1042
 *        is specified as the third parameter, all properties will
1043
 *        be applied and will overwrite an existing property in
1044
 *        the receiver
1045
 */
1046 1263 Luisehahne
L.augment = L.augmentProto;
1047 601 doc
1048
/**
1049
 * An alias for <a href="YAHOO.lang.html#augment">YAHOO.lang.augment</a>
1050
 * @for YAHOO
1051
 * @method augment
1052
 * @static
1053
 * @param {Function} r  the object to receive the augmentation
1054
 * @param {Function} s  the object that supplies the properties to augment
1055
 * @param {String*}  arguments zero or more properties methods to
1056
 *        augment the receiver with.  If none specified, everything
1057
 *        in the supplier will be used unless it would
1058
 *        overwrite an existing property in the receiver
1059
 */
1060 1263 Luisehahne
YAHOO.augment = L.augmentProto;
1061 601 doc
1062
/**
1063
 * An alias for <a href="YAHOO.lang.html#extend">YAHOO.lang.extend</a>
1064
 * @method extend
1065
 * @static
1066
 * @param {Function} subc   the object to modify
1067
 * @param {Function} superc the object to inherit
1068
 * @param {Object} overrides  additional properties/methods to add to the
1069
 *        subclass prototype.  These will override the
1070
 *        matching items obtained from the superclass if present.
1071
 */
1072 1263 Luisehahne
YAHOO.extend = L.extend;
1073 601 doc
1074 1263 Luisehahne
})();
1075
YAHOO.register("yahoo", YAHOO, {version: "2.8.0r4", build: "2449"});