~andreserl/maas/packaging_precise_rebase

« back to all changes in this revision

Viewing changes to debian/extras/jslibs/yui/yui-core/yui-core.js

  • Committer: Andres Rodriguez
  • Date: 2013-03-20 18:12:30 UTC
  • mfrom: (145.2.22 precise.sru)
  • Revision ID: andreserl@ubuntu.com-20130320181230-6l5guc0nhlv2z4p7
Re-base againts latest quantal released branch towards SRU

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
YUI 3.5.1 (build 22)
 
3
Copyright 2012 Yahoo! Inc. All rights reserved.
 
4
Licensed under the BSD License.
 
5
http://yuilibrary.com/license/
 
6
*/
 
7
/**
 
8
 * The YUI module contains the components required for building the YUI seed
 
9
 * file.  This includes the script loading mechanism, a simple queue, and
 
10
 * the core utilities for the library.
 
11
 * @module yui
 
12
 * @submodule yui-base
 
13
 */
 
14
 
 
15
if (typeof YUI != 'undefined') {
 
16
    YUI._YUI = YUI;
 
17
}
 
18
 
 
19
/**
 
20
The YUI global namespace object.  If YUI is already defined, the
 
21
existing YUI object will not be overwritten so that defined
 
22
namespaces are preserved.  It is the constructor for the object
 
23
the end user interacts with.  As indicated below, each instance
 
24
has full custom event support, but only if the event system
 
25
is available.  This is a self-instantiable factory function.  You
 
26
can invoke it directly like this:
 
27
 
 
28
     YUI().use('*', function(Y) {
 
29
         // ready
 
30
     });
 
31
 
 
32
But it also works like this:
 
33
 
 
34
     var Y = YUI();
 
35
 
 
36
Configuring the YUI object:
 
37
 
 
38
    YUI({
 
39
        debug: true,
 
40
        combine: false
 
41
    }).use('node', function(Y) {
 
42
        //Node is ready to use
 
43
    });
 
44
 
 
45
See the API docs for the <a href="config.html">Config</a> class
 
46
for the complete list of supported configuration properties accepted
 
47
by the YUI constuctor.
 
48
 
 
49
@class YUI
 
50
@constructor
 
51
@global
 
52
@uses EventTarget
 
53
@param [o]* {Object} 0..n optional configuration objects.  these values
 
54
are store in Y.config.  See <a href="config.html">Config</a> for the list of supported
 
55
properties.
 
56
*/
 
57
    /*global YUI*/
 
58
    /*global YUI_config*/
 
59
    var YUI = function() {
 
60
        var i = 0,
 
61
            Y = this,
 
62
            args = arguments,
 
63
            l = args.length,
 
64
            instanceOf = function(o, type) {
 
65
                return (o && o.hasOwnProperty && (o instanceof type));
 
66
            },
 
67
            gconf = (typeof YUI_config !== 'undefined') && YUI_config;
 
68
 
 
69
        if (!(instanceOf(Y, YUI))) {
 
70
            Y = new YUI();
 
71
        } else {
 
72
            // set up the core environment
 
73
            Y._init();
 
74
 
 
75
            /**
 
76
                YUI.GlobalConfig is a master configuration that might span
 
77
                multiple contexts in a non-browser environment.  It is applied
 
78
                first to all instances in all contexts.
 
79
                @property GlobalConfig
 
80
                @type {Object}
 
81
                @global
 
82
                @static
 
83
                @example
 
84
 
 
85
 
 
86
                    YUI.GlobalConfig = {
 
87
                        filter: 'debug'
 
88
                    };
 
89
 
 
90
                    YUI().use('node', function(Y) {
 
91
                        //debug files used here
 
92
                    });
 
93
 
 
94
                    YUI({
 
95
                        filter: 'min'
 
96
                    }).use('node', function(Y) {
 
97
                        //min files used here
 
98
                    });
 
99
 
 
100
            */
 
101
            if (YUI.GlobalConfig) {
 
102
                Y.applyConfig(YUI.GlobalConfig);
 
103
            }
 
104
 
 
105
            /**
 
106
                YUI_config is a page-level config.  It is applied to all
 
107
                instances created on the page.  This is applied after
 
108
                YUI.GlobalConfig, and before the instance level configuration
 
109
                objects.
 
110
                @global
 
111
                @property YUI_config
 
112
                @type {Object}
 
113
                @example
 
114
 
 
115
 
 
116
                    //Single global var to include before YUI seed file
 
117
                    YUI_config = {
 
118
                        filter: 'debug'
 
119
                    };
 
120
 
 
121
                    YUI().use('node', function(Y) {
 
122
                        //debug files used here
 
123
                    });
 
124
 
 
125
                    YUI({
 
126
                        filter: 'min'
 
127
                    }).use('node', function(Y) {
 
128
                        //min files used here
 
129
                    });
 
130
            */
 
131
            if (gconf) {
 
132
                Y.applyConfig(gconf);
 
133
            }
 
134
 
 
135
            // bind the specified additional modules for this instance
 
136
            if (!l) {
 
137
                Y._setup();
 
138
            }
 
139
        }
 
140
 
 
141
        if (l) {
 
142
            // Each instance can accept one or more configuration objects.
 
143
            // These are applied after YUI.GlobalConfig and YUI_Config,
 
144
            // overriding values set in those config files if there is a '
 
145
            // matching property.
 
146
            for (; i < l; i++) {
 
147
                Y.applyConfig(args[i]);
 
148
            }
 
149
 
 
150
            Y._setup();
 
151
        }
 
152
 
 
153
        Y.instanceOf = instanceOf;
 
154
 
 
155
        return Y;
 
156
    };
 
157
 
 
158
(function() {
 
159
 
 
160
    var proto, prop,
 
161
        VERSION = '3.5.1',
 
162
        PERIOD = '.',
 
163
        BASE = 'http://yui.yahooapis.com/',
 
164
        DOC_LABEL = 'yui3-js-enabled',
 
165
        CSS_STAMP_EL = 'yui3-css-stamp',
 
166
        NOOP = function() {},
 
167
        SLICE = Array.prototype.slice,
 
168
        APPLY_TO_AUTH = { 'io.xdrReady': 1,   // the functions applyTo
 
169
                          'io.xdrResponse': 1,   // can call. this should
 
170
                          'SWF.eventHandler': 1 }, // be done at build time
 
171
        hasWin = (typeof window != 'undefined'),
 
172
        win = (hasWin) ? window : null,
 
173
        doc = (hasWin) ? win.document : null,
 
174
        docEl = doc && doc.documentElement,
 
175
        docClass = docEl && docEl.className,
 
176
        instances = {},
 
177
        time = new Date().getTime(),
 
178
        add = function(el, type, fn, capture) {
 
179
            if (el && el.addEventListener) {
 
180
                el.addEventListener(type, fn, capture);
 
181
            } else if (el && el.attachEvent) {
 
182
                el.attachEvent('on' + type, fn);
 
183
            }
 
184
        },
 
185
        remove = function(el, type, fn, capture) {
 
186
            if (el && el.removeEventListener) {
 
187
                // this can throw an uncaught exception in FF
 
188
                try {
 
189
                    el.removeEventListener(type, fn, capture);
 
190
                } catch (ex) {}
 
191
            } else if (el && el.detachEvent) {
 
192
                el.detachEvent('on' + type, fn);
 
193
            }
 
194
        },
 
195
        handleLoad = function() {
 
196
            YUI.Env.windowLoaded = true;
 
197
            YUI.Env.DOMReady = true;
 
198
            if (hasWin) {
 
199
                remove(window, 'load', handleLoad);
 
200
            }
 
201
        },
 
202
        getLoader = function(Y, o) {
 
203
            var loader = Y.Env._loader;
 
204
            if (loader) {
 
205
                //loader._config(Y.config);
 
206
                loader.ignoreRegistered = false;
 
207
                loader.onEnd = null;
 
208
                loader.data = null;
 
209
                loader.required = [];
 
210
                loader.loadType = null;
 
211
            } else {
 
212
                loader = new Y.Loader(Y.config);
 
213
                Y.Env._loader = loader;
 
214
            }
 
215
            YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, [ 'loader-base', 'loader-rollup', 'loader-yui3' ]));
 
216
 
 
217
            return loader;
 
218
        },
 
219
 
 
220
        clobber = function(r, s) {
 
221
            for (var i in s) {
 
222
                if (s.hasOwnProperty(i)) {
 
223
                    r[i] = s[i];
 
224
                }
 
225
            }
 
226
        },
 
227
 
 
228
        ALREADY_DONE = { success: true };
 
229
 
 
230
//  Stamp the documentElement (HTML) with a class of "yui-loaded" to
 
231
//  enable styles that need to key off of JS being enabled.
 
232
if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
 
233
    if (docClass) {
 
234
        docClass += ' ';
 
235
    }
 
236
    docClass += DOC_LABEL;
 
237
    docEl.className = docClass;
 
238
}
 
239
 
 
240
if (VERSION.indexOf('@') > -1) {
 
241
    VERSION = '3.3.0'; // dev time hack for cdn test
 
242
}
 
243
 
 
244
proto = {
 
245
    /**
 
246
     * Applies a new configuration object to the YUI instance config.
 
247
     * This will merge new group/module definitions, and will also
 
248
     * update the loader cache if necessary.  Updating Y.config directly
 
249
     * will not update the cache.
 
250
     * @method applyConfig
 
251
     * @param {Object} o the configuration object.
 
252
     * @since 3.2.0
 
253
     */
 
254
    applyConfig: function(o) {
 
255
 
 
256
        o = o || NOOP;
 
257
 
 
258
        var attr,
 
259
            name,
 
260
            // detail,
 
261
            config = this.config,
 
262
            mods = config.modules,
 
263
            groups = config.groups,
 
264
            aliases = config.aliases,
 
265
            loader = this.Env._loader;
 
266
 
 
267
        for (name in o) {
 
268
            if (o.hasOwnProperty(name)) {
 
269
                attr = o[name];
 
270
                if (mods && name == 'modules') {
 
271
                    clobber(mods, attr);
 
272
                } else if (aliases && name == 'aliases') {
 
273
                    clobber(aliases, attr);
 
274
                } else if (groups && name == 'groups') {
 
275
                    clobber(groups, attr);
 
276
                } else if (name == 'win') {
 
277
                    config[name] = (attr && attr.contentWindow) || attr;
 
278
                    config.doc = config[name] ? config[name].document : null;
 
279
                } else if (name == '_yuid') {
 
280
                    // preserve the guid
 
281
                } else {
 
282
                    config[name] = attr;
 
283
                }
 
284
            }
 
285
        }
 
286
 
 
287
        if (loader) {
 
288
            loader._config(o);
 
289
        }
 
290
 
 
291
    },
 
292
    /**
 
293
    * Old way to apply a config to the instance (calls `applyConfig` under the hood)
 
294
    * @private
 
295
    * @method _config
 
296
    * @param {Object} o The config to apply
 
297
    */
 
298
    _config: function(o) {
 
299
        this.applyConfig(o);
 
300
    },
 
301
 
 
302
    /**
 
303
     * Initialize this YUI instance
 
304
     * @private
 
305
     * @method _init
 
306
     */
 
307
    _init: function() {
 
308
        var filter, el,
 
309
            Y = this,
 
310
            G_ENV = YUI.Env,
 
311
            Env = Y.Env,
 
312
            prop;
 
313
 
 
314
        /**
 
315
         * The version number of the YUI instance.
 
316
         * @property version
 
317
         * @type string
 
318
         */
 
319
        Y.version = VERSION;
 
320
 
 
321
        if (!Env) {
 
322
            Y.Env = {
 
323
                core: ['get','intl-base'],
 
324
                mods: {}, // flat module map
 
325
                versions: {}, // version module map
 
326
                base: BASE,
 
327
                cdn: BASE + VERSION + '/build/',
 
328
                // bootstrapped: false,
 
329
                _idx: 0,
 
330
                _used: {},
 
331
                _attached: {},
 
332
                _missed: [],
 
333
                _yidx: 0,
 
334
                _uidx: 0,
 
335
                _guidp: 'y',
 
336
                _loaded: {},
 
337
                // serviced: {},
 
338
                // Regex in English:
 
339
                // I'll start at the \b(simpleyui).
 
340
                // 1. Look in the test string for "simpleyui" or "yui" or
 
341
                //    "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break.  That is, it
 
342
                //    can't match "foyui" or "i_heart_simpleyui". This can be anywhere in the string.
 
343
                // 2. After #1 must come a forward slash followed by the string matched in #1, so
 
344
                //    "yui-base/yui-base" or "simpleyui/simpleyui" or "yui-pants/yui-pants".
 
345
                // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
 
346
                //    so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
 
347
                // 4. This is followed by ".js", so "yui/yui.js", "simpleyui/simpleyui-min.js"
 
348
                // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
 
349
                //    then capture the junk between the LAST "&" and the string in 1-4.  So
 
350
                //    "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js"
 
351
                //    will capture "3.3.0/build/"
 
352
                //
 
353
                // Regex Exploded:
 
354
                // (?:\?             Find a ?
 
355
                //   (?:[^&]*&)      followed by 0..n characters followed by an &
 
356
                //   *               in fact, find as many sets of characters followed by a & as you can
 
357
                //   ([^&]*)         capture the stuff after the last & in \1
 
358
                // )?                but it's ok if all this ?junk&more_junk stuff isn't even there
 
359
                // \b(simpleyui|     after a word break find either the string "simpleyui" or
 
360
                //    yui(?:-\w+)?   the string "yui" optionally followed by a -, then more characters
 
361
                // )                 and store the simpleyui or yui-* string in \2
 
362
                // \/\2              then comes a / followed by the simpleyui or yui-* string in \2
 
363
                // (?:-(min|debug))? optionally followed by "-min" or "-debug"
 
364
                // .js               and ending in ".js"
 
365
                _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(simpleyui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
 
366
                parseBasePath: function(src, pattern) {
 
367
                    var match = src.match(pattern),
 
368
                        path, filter;
 
369
 
 
370
                    if (match) {
 
371
                        path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
 
372
 
 
373
                        // this is to set up the path to the loader.  The file
 
374
                        // filter for loader should match the yui include.
 
375
                        filter = match[3];
 
376
 
 
377
                        // extract correct path for mixed combo urls
 
378
                        // http://yuilibrary.com/projects/yui3/ticket/2528423
 
379
                        if (match[1]) {
 
380
                            path += '?' + match[1];
 
381
                        }
 
382
                        path = {
 
383
                            filter: filter,
 
384
                            path: path
 
385
                        }
 
386
                    }
 
387
                    return path;
 
388
                },
 
389
                getBase: G_ENV && G_ENV.getBase ||
 
390
                        function(pattern) {
 
391
                            var nodes = (doc && doc.getElementsByTagName('script')) || [],
 
392
                                path = Env.cdn, parsed,
 
393
                                i, len, src;
 
394
 
 
395
                            for (i = 0, len = nodes.length; i < len; ++i) {
 
396
                                src = nodes[i].src;
 
397
                                if (src) {
 
398
                                    parsed = Y.Env.parseBasePath(src, pattern);
 
399
                                    if (parsed) {
 
400
                                        filter = parsed.filter;
 
401
                                        path = parsed.path;
 
402
                                        break;
 
403
                                    }
 
404
                                }
 
405
                            }
 
406
 
 
407
                            // use CDN default
 
408
                            return path;
 
409
                        }
 
410
 
 
411
            };
 
412
 
 
413
            Env = Y.Env;
 
414
 
 
415
            Env._loaded[VERSION] = {};
 
416
 
 
417
            if (G_ENV && Y !== YUI) {
 
418
                Env._yidx = ++G_ENV._yidx;
 
419
                Env._guidp = ('yui_' + VERSION + '_' +
 
420
                             Env._yidx + '_' + time).replace(/\./g, '_');
 
421
            } else if (YUI._YUI) {
 
422
 
 
423
                G_ENV = YUI._YUI.Env;
 
424
                Env._yidx += G_ENV._yidx;
 
425
                Env._uidx += G_ENV._uidx;
 
426
 
 
427
                for (prop in G_ENV) {
 
428
                    if (!(prop in Env)) {
 
429
                        Env[prop] = G_ENV[prop];
 
430
                    }
 
431
                }
 
432
 
 
433
                delete YUI._YUI;
 
434
            }
 
435
 
 
436
            Y.id = Y.stamp(Y);
 
437
            instances[Y.id] = Y;
 
438
 
 
439
        }
 
440
 
 
441
        Y.constructor = YUI;
 
442
 
 
443
        // configuration defaults
 
444
        Y.config = Y.config || {
 
445
            bootstrap: true,
 
446
            cacheUse: true,
 
447
            debug: true,
 
448
            doc: doc,
 
449
            fetchCSS: true,
 
450
            throwFail: true,
 
451
            useBrowserConsole: true,
 
452
            useNativeES5: true,
 
453
            win: win
 
454
        };
 
455
 
 
456
        //Register the CSS stamp element
 
457
        if (doc && !doc.getElementById(CSS_STAMP_EL)) {
 
458
            el = doc.createElement('div');
 
459
            el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>';
 
460
            YUI.Env.cssStampEl = el.firstChild;
 
461
            docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild);
 
462
        }
 
463
 
 
464
        Y.config.lang = Y.config.lang || 'en-US';
 
465
 
 
466
        Y.config.base = YUI.config.base || Y.Env.getBase(Y.Env._BASE_RE);
 
467
 
 
468
        if (!filter || (!('mindebug').indexOf(filter))) {
 
469
            filter = 'min';
 
470
        }
 
471
        filter = (filter) ? '-' + filter : filter;
 
472
        Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
 
473
 
 
474
    },
 
475
 
 
476
    /**
 
477
     * Finishes the instance setup. Attaches whatever modules were defined
 
478
     * when the yui modules was registered.
 
479
     * @method _setup
 
480
     * @private
 
481
     */
 
482
    _setup: function(o) {
 
483
        var i, Y = this,
 
484
            core = [],
 
485
            mods = YUI.Env.mods,
 
486
            //extras = Y.config.core || ['get','intl-base'];
 
487
            extras = Y.config.core || [].concat(YUI.Env.core); //Clone it..
 
488
 
 
489
        for (i = 0; i < extras.length; i++) {
 
490
            if (mods[extras[i]]) {
 
491
                core.push(extras[i]);
 
492
            }
 
493
        }
 
494
 
 
495
        Y._attach(['yui-base']);
 
496
        Y._attach(core);
 
497
 
 
498
        if (Y.Loader) {
 
499
            getLoader(Y);
 
500
        }
 
501
 
 
502
    },
 
503
 
 
504
    /**
 
505
     * Executes a method on a YUI instance with
 
506
     * the specified id if the specified method is whitelisted.
 
507
     * @method applyTo
 
508
     * @param id {String} the YUI instance id.
 
509
     * @param method {String} the name of the method to exectute.
 
510
     * Ex: 'Object.keys'.
 
511
     * @param args {Array} the arguments to apply to the method.
 
512
     * @return {Object} the return value from the applied method or null.
 
513
     */
 
514
    applyTo: function(id, method, args) {
 
515
        if (!(method in APPLY_TO_AUTH)) {
 
516
            this.log(method + ': applyTo not allowed', 'warn', 'yui');
 
517
            return null;
 
518
        }
 
519
 
 
520
        var instance = instances[id], nest, m, i;
 
521
        if (instance) {
 
522
            nest = method.split('.');
 
523
            m = instance;
 
524
            for (i = 0; i < nest.length; i = i + 1) {
 
525
                m = m[nest[i]];
 
526
                if (!m) {
 
527
                    this.log('applyTo not found: ' + method, 'warn', 'yui');
 
528
                }
 
529
            }
 
530
            return m && m.apply(instance, args);
 
531
        }
 
532
 
 
533
        return null;
 
534
    },
 
535
 
 
536
/**
 
537
Registers a module with the YUI global.  The easiest way to create a
 
538
first-class YUI module is to use the YUI component build tool.
 
539
 
 
540
http://yuilibrary.com/projects/builder
 
541
 
 
542
The build system will produce the `YUI.add` wrapper for you module, along
 
543
with any configuration info required for the module.
 
544
@method add
 
545
@param name {String} module name.
 
546
@param fn {Function} entry point into the module that is used to bind module to the YUI instance.
 
547
@param {YUI} fn.Y The YUI instance this module is executed in.
 
548
@param {String} fn.name The name of the module
 
549
@param version {String} version string.
 
550
@param details {Object} optional config data:
 
551
@param details.requires {Array} features that must be present before this module can be attached.
 
552
@param details.optional {Array} optional features that should be present if loadOptional
 
553
 is defined.  Note: modules are not often loaded this way in YUI 3,
 
554
 but this field is still useful to inform the user that certain
 
555
 features in the component will require additional dependencies.
 
556
@param details.use {Array} features that are included within this module which need to
 
557
 be attached automatically when this module is attached.  This
 
558
 supports the YUI 3 rollup system -- a module with submodules
 
559
 defined will need to have the submodules listed in the 'use'
 
560
 config.  The YUI component build tool does this for you.
 
561
@return {YUI} the YUI instance.
 
562
@example
 
563
 
 
564
    YUI.add('davglass', function(Y, name) {
 
565
        Y.davglass = function() {
 
566
            alert('Dav was here!');
 
567
        };
 
568
    }, '3.4.0', { requires: ['yui-base', 'harley-davidson', 'mt-dew'] });
 
569
 
 
570
*/
 
571
    add: function(name, fn, version, details) {
 
572
        details = details || {};
 
573
        var env = YUI.Env,
 
574
            mod = {
 
575
                name: name,
 
576
                fn: fn,
 
577
                version: version,
 
578
                details: details
 
579
            },
 
580
            loader,
 
581
            i, versions = env.versions;
 
582
 
 
583
        env.mods[name] = mod;
 
584
        versions[version] = versions[version] || {};
 
585
        versions[version][name] = mod;
 
586
 
 
587
        for (i in instances) {
 
588
            if (instances.hasOwnProperty(i)) {
 
589
                loader = instances[i].Env._loader;
 
590
                if (loader) {
 
591
                    if (!loader.moduleInfo[name] || loader.moduleInfo[name].temp) {
 
592
                        loader.addModule(details, name);
 
593
                    }
 
594
                }
 
595
            }
 
596
        }
 
597
 
 
598
        return this;
 
599
    },
 
600
 
 
601
    /**
 
602
     * Executes the function associated with each required
 
603
     * module, binding the module to the YUI instance.
 
604
     * @param {Array} r The array of modules to attach
 
605
     * @param {Boolean} [moot=false] Don't throw a warning if the module is not attached
 
606
     * @method _attach
 
607
     * @private
 
608
     */
 
609
    _attach: function(r, moot) {
 
610
        var i, name, mod, details, req, use, after,
 
611
            mods = YUI.Env.mods,
 
612
            aliases = YUI.Env.aliases,
 
613
            Y = this, j,
 
614
            loader = Y.Env._loader,
 
615
            done = Y.Env._attached,
 
616
            len = r.length, loader,
 
617
            c = [];
 
618
 
 
619
        //Check for conditional modules (in a second+ instance) and add their requirements
 
620
        //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
 
621
        for (i = 0; i < len; i++) {
 
622
            name = r[i];
 
623
            mod = mods[name];
 
624
            c.push(name);
 
625
            if (loader && loader.conditions[name]) {
 
626
                Y.Object.each(loader.conditions[name], function(def) {
 
627
                    var go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
 
628
                    if (go) {
 
629
                        c.push(def.name);
 
630
                    }
 
631
                });
 
632
            }
 
633
        }
 
634
        r = c;
 
635
        len = r.length;
 
636
 
 
637
        for (i = 0; i < len; i++) {
 
638
            if (!done[r[i]]) {
 
639
                name = r[i];
 
640
                mod = mods[name];
 
641
 
 
642
                if (aliases && aliases[name]) {
 
643
                    Y._attach(aliases[name]);
 
644
                    continue;
 
645
                }
 
646
                if (!mod) {
 
647
                    if (loader && loader.moduleInfo[name]) {
 
648
                        mod = loader.moduleInfo[name];
 
649
                        moot = true;
 
650
                    }
 
651
 
 
652
 
 
653
                    //if (!loader || !loader.moduleInfo[name]) {
 
654
                    //if ((!loader || !loader.moduleInfo[name]) && !moot) {
 
655
                    if (!moot && name) {
 
656
                        if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
 
657
                            Y.Env._missed.push(name);
 
658
                            Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
 
659
                            Y.message('NOT loaded: ' + name, 'warn', 'yui');
 
660
                        }
 
661
                    }
 
662
                } else {
 
663
                    done[name] = true;
 
664
                    //Don't like this, but in case a mod was asked for once, then we fetch it
 
665
                    //We need to remove it from the missed list ^davglass
 
666
                    for (j = 0; j < Y.Env._missed.length; j++) {
 
667
                        if (Y.Env._missed[j] === name) {
 
668
                            Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
 
669
                            Y.Env._missed.splice(j, 1);
 
670
                        }
 
671
                    }
 
672
                    details = mod.details;
 
673
                    req = details.requires;
 
674
                    use = details.use;
 
675
                    after = details.after;
 
676
 
 
677
                    if (req) {
 
678
                        for (j = 0; j < req.length; j++) {
 
679
                            if (!done[req[j]]) {
 
680
                                if (!Y._attach(req)) {
 
681
                                    return false;
 
682
                                }
 
683
                                break;
 
684
                            }
 
685
                        }
 
686
                    }
 
687
 
 
688
                    if (after) {
 
689
                        for (j = 0; j < after.length; j++) {
 
690
                            if (!done[after[j]]) {
 
691
                                if (!Y._attach(after, true)) {
 
692
                                    return false;
 
693
                                }
 
694
                                break;
 
695
                            }
 
696
                        }
 
697
                    }
 
698
 
 
699
                    if (mod.fn) {
 
700
                        try {
 
701
                            mod.fn(Y, name);
 
702
                        } catch (e) {
 
703
                            Y.error('Attach error: ' + name, e, name);
 
704
                            return false;
 
705
                        }
 
706
                    }
 
707
 
 
708
                    if (use) {
 
709
                        for (j = 0; j < use.length; j++) {
 
710
                            if (!done[use[j]]) {
 
711
                                if (!Y._attach(use)) {
 
712
                                    return false;
 
713
                                }
 
714
                                break;
 
715
                            }
 
716
                        }
 
717
                    }
 
718
 
 
719
 
 
720
 
 
721
                }
 
722
            }
 
723
        }
 
724
 
 
725
        return true;
 
726
    },
 
727
 
 
728
    /**
 
729
     * Attaches one or more modules to the YUI instance.  When this
 
730
     * is executed, the requirements are analyzed, and one of
 
731
     * several things can happen:
 
732
     *
 
733
     *  * All requirements are available on the page --  The modules
 
734
     *   are attached to the instance.  If supplied, the use callback
 
735
     *   is executed synchronously.
 
736
     *
 
737
     *  * Modules are missing, the Get utility is not available OR
 
738
     *   the 'bootstrap' config is false -- A warning is issued about
 
739
     *   the missing modules and all available modules are attached.
 
740
     *
 
741
     *  * Modules are missing, the Loader is not available but the Get
 
742
     *   utility is and boostrap is not false -- The loader is bootstrapped
 
743
     *   before doing the following....
 
744
     *
 
745
     *  * Modules are missing and the Loader is available -- The loader
 
746
     *   expands the dependency tree and fetches missing modules.  When
 
747
     *   the loader is finshed the callback supplied to use is executed
 
748
     *   asynchronously.
 
749
     *
 
750
     * @method use
 
751
     * @param modules* {String|Array} 1-n modules to bind (uses arguments array).
 
752
     * @param [callback] {Function} callback function executed when
 
753
     * the instance has the required functionality.  If included, it
 
754
     * must be the last parameter.
 
755
     * @param callback.Y {YUI} The `YUI` instance created for this sandbox
 
756
     * @param callback.data {Object} Object data returned from `Loader`.
 
757
     *
 
758
     * @example
 
759
     *      // loads and attaches dd and its dependencies
 
760
     *      YUI().use('dd', function(Y) {});
 
761
     *
 
762
     *      // loads and attaches dd and node as well as all of their dependencies (since 3.4.0)
 
763
     *      YUI().use(['dd', 'node'], function(Y) {});
 
764
     *
 
765
     *      // attaches all modules that are available on the page
 
766
     *      YUI().use('*', function(Y) {});
 
767
     *
 
768
     *      // intrinsic YUI gallery support (since 3.1.0)
 
769
     *      YUI().use('gallery-yql', function(Y) {});
 
770
     *
 
771
     *      // intrinsic YUI 2in3 support (since 3.1.0)
 
772
     *      YUI().use('yui2-datatable', function(Y) {});
 
773
     *
 
774
     * @return {YUI} the YUI instance.
 
775
     */
 
776
    use: function() {
 
777
        var args = SLICE.call(arguments, 0),
 
778
            callback = args[args.length - 1],
 
779
            Y = this,
 
780
            i = 0,
 
781
            a = [],
 
782
            name,
 
783
            Env = Y.Env,
 
784
            provisioned = true;
 
785
 
 
786
        // The last argument supplied to use can be a load complete callback
 
787
        if (Y.Lang.isFunction(callback)) {
 
788
            args.pop();
 
789
        } else {
 
790
            callback = null;
 
791
        }
 
792
        if (Y.Lang.isArray(args[0])) {
 
793
            args = args[0];
 
794
        }
 
795
 
 
796
        if (Y.config.cacheUse) {
 
797
            while ((name = args[i++])) {
 
798
                if (!Env._attached[name]) {
 
799
                    provisioned = false;
 
800
                    break;
 
801
                }
 
802
            }
 
803
 
 
804
            if (provisioned) {
 
805
                if (args.length) {
 
806
                }
 
807
                Y._notify(callback, ALREADY_DONE, args);
 
808
                return Y;
 
809
            }
 
810
        }
 
811
 
 
812
        if (Y._loading) {
 
813
            Y._useQueue = Y._useQueue || new Y.Queue();
 
814
            Y._useQueue.add([args, callback]);
 
815
        } else {
 
816
            Y._use(args, function(Y, response) {
 
817
                Y._notify(callback, response, args);
 
818
            });
 
819
        }
 
820
 
 
821
        return Y;
 
822
    },
 
823
    /**
 
824
    * Notify handler from Loader for attachment/load errors
 
825
    * @method _notify
 
826
    * @param callback {Function} The callback to pass to the `Y.config.loadErrorFn`
 
827
    * @param response {Object} The response returned from Loader
 
828
    * @param args {Array} The aruments passed from Loader
 
829
    * @private
 
830
    */
 
831
    _notify: function(callback, response, args) {
 
832
        if (!response.success && this.config.loadErrorFn) {
 
833
            this.config.loadErrorFn.call(this, this, callback, response, args);
 
834
        } else if (callback) {
 
835
            try {
 
836
                callback(this, response);
 
837
            } catch (e) {
 
838
                this.error('use callback error', e, args);
 
839
            }
 
840
        }
 
841
    },
 
842
 
 
843
    /**
 
844
    * This private method is called from the `use` method queue. To ensure that only one set of loading
 
845
    * logic is performed at a time.
 
846
    * @method _use
 
847
    * @private
 
848
    * @param args* {String} 1-n modules to bind (uses arguments array).
 
849
    * @param *callback {Function} callback function executed when
 
850
    * the instance has the required functionality.  If included, it
 
851
    * must be the last parameter.
 
852
    */
 
853
    _use: function(args, callback) {
 
854
 
 
855
        if (!this.Array) {
 
856
            this._attach(['yui-base']);
 
857
        }
 
858
 
 
859
        var len, loader, handleBoot, handleRLS,
 
860
            Y = this,
 
861
            G_ENV = YUI.Env,
 
862
            mods = G_ENV.mods,
 
863
            Env = Y.Env,
 
864
            used = Env._used,
 
865
            aliases = G_ENV.aliases,
 
866
            queue = G_ENV._loaderQueue,
 
867
            firstArg = args[0],
 
868
            YArray = Y.Array,
 
869
            config = Y.config,
 
870
            boot = config.bootstrap,
 
871
            missing = [],
 
872
            r = [],
 
873
            ret = true,
 
874
            fetchCSS = config.fetchCSS,
 
875
            process = function(names, skip) {
 
876
 
 
877
                var i = 0, a = [];
 
878
 
 
879
                if (!names.length) {
 
880
                    return;
 
881
                }
 
882
 
 
883
                if (aliases) {
 
884
                    for (i = 0; i < names.length; i++) {
 
885
                        if (aliases[names[i]]) {
 
886
                            a = [].concat(a, aliases[names[i]]);
 
887
                        } else {
 
888
                            a.push(names[i]);
 
889
                        }
 
890
                    }
 
891
                    names = a;
 
892
                }
 
893
 
 
894
                YArray.each(names, function(name) {
 
895
 
 
896
                    // add this module to full list of things to attach
 
897
                    if (!skip) {
 
898
                        r.push(name);
 
899
                    }
 
900
 
 
901
                    // only attach a module once
 
902
                    if (used[name]) {
 
903
                        return;
 
904
                    }
 
905
 
 
906
                    var m = mods[name], req, use;
 
907
 
 
908
                    if (m) {
 
909
                        used[name] = true;
 
910
                        req = m.details.requires;
 
911
                        use = m.details.use;
 
912
                    } else {
 
913
                        // CSS files don't register themselves, see if it has
 
914
                        // been loaded
 
915
                        if (!G_ENV._loaded[VERSION][name]) {
 
916
                            missing.push(name);
 
917
                        } else {
 
918
                            used[name] = true; // probably css
 
919
                        }
 
920
                    }
 
921
 
 
922
                    // make sure requirements are attached
 
923
                    if (req && req.length) {
 
924
                        process(req);
 
925
                    }
 
926
 
 
927
                    // make sure we grab the submodule dependencies too
 
928
                    if (use && use.length) {
 
929
                        process(use, 1);
 
930
                    }
 
931
                });
 
932
            },
 
933
 
 
934
            handleLoader = function(fromLoader) {
 
935
                var response = fromLoader || {
 
936
                        success: true,
 
937
                        msg: 'not dynamic'
 
938
                    },
 
939
                    redo, origMissing,
 
940
                    ret = true,
 
941
                    data = response.data;
 
942
 
 
943
                Y._loading = false;
 
944
 
 
945
                if (data) {
 
946
                    origMissing = missing;
 
947
                    missing = [];
 
948
                    r = [];
 
949
                    process(data);
 
950
                    redo = missing.length;
 
951
                    if (redo) {
 
952
                        if (missing.sort().join() ==
 
953
                                origMissing.sort().join()) {
 
954
                            redo = false;
 
955
                        }
 
956
                    }
 
957
                }
 
958
 
 
959
                if (redo && data) {
 
960
                    Y._loading = true;
 
961
                    Y._use(missing, function() {
 
962
                        if (Y._attach(data)) {
 
963
                            Y._notify(callback, response, data);
 
964
                        }
 
965
                    });
 
966
                } else {
 
967
                    if (data) {
 
968
                        ret = Y._attach(data);
 
969
                    }
 
970
                    if (ret) {
 
971
                        Y._notify(callback, response, args);
 
972
                    }
 
973
                }
 
974
 
 
975
                if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
 
976
                    Y._use.apply(Y, Y._useQueue.next());
 
977
                }
 
978
 
 
979
            };
 
980
 
 
981
 
 
982
        // YUI().use('*'); // bind everything available
 
983
        if (firstArg === '*') {
 
984
            ret = Y._attach(Y.Object.keys(mods));
 
985
            if (ret) {
 
986
                handleLoader();
 
987
            }
 
988
            return Y;
 
989
        }
 
990
 
 
991
        if (mods['loader'] && !Y.Loader) {
 
992
            Y._attach(['loader']);
 
993
        }
 
994
 
 
995
 
 
996
        // use loader to expand dependencies and sort the
 
997
        // requirements if it is available.
 
998
        if (boot && Y.Loader && args.length) {
 
999
            loader = getLoader(Y);
 
1000
            loader.require(args);
 
1001
            loader.ignoreRegistered = true;
 
1002
            loader._boot = true;
 
1003
            loader.calculate(null, (fetchCSS) ? null : 'js');
 
1004
            args = loader.sorted;
 
1005
            loader._boot = false;
 
1006
        }
 
1007
 
 
1008
        // process each requirement and any additional requirements
 
1009
        // the module metadata specifies
 
1010
        process(args);
 
1011
 
 
1012
        len = missing.length;
 
1013
 
 
1014
        if (len) {
 
1015
            missing = Y.Object.keys(YArray.hash(missing));
 
1016
            len = missing.length;
 
1017
        }
 
1018
 
 
1019
 
 
1020
        // dynamic load
 
1021
        if (boot && len && Y.Loader) {
 
1022
            Y._loading = true;
 
1023
            loader = getLoader(Y);
 
1024
            loader.onEnd = handleLoader;
 
1025
            loader.context = Y;
 
1026
            loader.data = args;
 
1027
            loader.ignoreRegistered = false;
 
1028
            loader.require(args);
 
1029
            loader.insert(null, (fetchCSS) ? null : 'js');
 
1030
 
 
1031
        } else if (boot && len && Y.Get && !Env.bootstrapped) {
 
1032
 
 
1033
            Y._loading = true;
 
1034
 
 
1035
            handleBoot = function() {
 
1036
                Y._loading = false;
 
1037
                queue.running = false;
 
1038
                Env.bootstrapped = true;
 
1039
                G_ENV._bootstrapping = false;
 
1040
                if (Y._attach(['loader'])) {
 
1041
                    Y._use(args, callback);
 
1042
                }
 
1043
            };
 
1044
 
 
1045
            if (G_ENV._bootstrapping) {
 
1046
                queue.add(handleBoot);
 
1047
            } else {
 
1048
                G_ENV._bootstrapping = true;
 
1049
                Y.Get.script(config.base + config.loaderPath, {
 
1050
                    onEnd: handleBoot
 
1051
                });
 
1052
            }
 
1053
 
 
1054
        } else {
 
1055
            ret = Y._attach(args);
 
1056
            if (ret) {
 
1057
                handleLoader();
 
1058
            }
 
1059
        }
 
1060
 
 
1061
        return Y;
 
1062
    },
 
1063
 
 
1064
 
 
1065
    /**
 
1066
    Adds a namespace object onto the YUI global if called statically.
 
1067
 
 
1068
        // creates YUI.your.namespace.here as nested objects
 
1069
        YUI.namespace("your.namespace.here");
 
1070
 
 
1071
    If called as a method on a YUI <em>instance</em>, it creates the
 
1072
    namespace on the instance.
 
1073
 
 
1074
         // creates Y.property.package
 
1075
         Y.namespace("property.package");
 
1076
 
 
1077
    Dots in the input string cause `namespace` to create nested objects for
 
1078
    each token. If any part of the requested namespace already exists, the
 
1079
    current object will be left in place.  This allows multiple calls to
 
1080
    `namespace` to preserve existing namespaced properties.
 
1081
 
 
1082
    If the first token in the namespace string is "YAHOO", the token is
 
1083
    discarded.
 
1084
 
 
1085
    Be careful with namespace tokens. Reserved words may work in some browsers
 
1086
    and not others. For instance, the following will fail in some browsers
 
1087
    because the supported version of JavaScript reserves the word "long":
 
1088
 
 
1089
         Y.namespace("really.long.nested.namespace");
 
1090
 
 
1091
    <em>Note: If you pass multiple arguments to create multiple namespaces, only
 
1092
    the last one created is returned from this function.</em>
 
1093
 
 
1094
    @method namespace
 
1095
    @param  {String} namespace* namespaces to create.
 
1096
    @return {Object}  A reference to the last namespace object created.
 
1097
    **/
 
1098
    namespace: function() {
 
1099
        var a = arguments, o, i = 0, j, d, arg;
 
1100
 
 
1101
        for (; i < a.length; i++) {
 
1102
            o = this; //Reset base object per argument or it will get reused from the last
 
1103
            arg = a[i];
 
1104
            if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
 
1105
                d = arg.split(PERIOD);
 
1106
                for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
 
1107
                    o[d[j]] = o[d[j]] || {};
 
1108
                    o = o[d[j]];
 
1109
                }
 
1110
            } else {
 
1111
                o[arg] = o[arg] || {};
 
1112
                o = o[arg]; //Reset base object to the new object so it's returned
 
1113
            }
 
1114
        }
 
1115
        return o;
 
1116
    },
 
1117
 
 
1118
    // this is replaced if the log module is included
 
1119
    log: NOOP,
 
1120
    message: NOOP,
 
1121
    // this is replaced if the dump module is included
 
1122
    dump: function (o) { return ''+o; },
 
1123
 
 
1124
    /**
 
1125
     * Report an error.  The reporting mechanism is controlled by
 
1126
     * the `throwFail` configuration attribute.  If throwFail is
 
1127
     * not specified, the message is written to the Logger, otherwise
 
1128
     * a JS error is thrown. If an `errorFn` is specified in the config
 
1129
     * it must return `true` to keep the error from being thrown.
 
1130
     * @method error
 
1131
     * @param msg {String} the error message.
 
1132
     * @param e {Error|String} Optional JS error that was caught, or an error string.
 
1133
     * @param src Optional additional info (passed to `Y.config.errorFn` and `Y.message`)
 
1134
     * and `throwFail` is specified, this error will be re-thrown.
 
1135
     * @return {YUI} this YUI instance.
 
1136
     */
 
1137
    error: function(msg, e, src) {
 
1138
        //TODO Add check for window.onerror here
 
1139
 
 
1140
        var Y = this, ret;
 
1141
 
 
1142
        if (Y.config.errorFn) {
 
1143
            ret = Y.config.errorFn.apply(Y, arguments);
 
1144
        }
 
1145
 
 
1146
        if (Y.config.throwFail && !ret) {
 
1147
            throw (e || new Error(msg));
 
1148
        } else {
 
1149
            Y.message(msg, 'error', ''+src); // don't scrub this one
 
1150
        }
 
1151
 
 
1152
        return Y;
 
1153
    },
 
1154
 
 
1155
    /**
 
1156
     * Generate an id that is unique among all YUI instances
 
1157
     * @method guid
 
1158
     * @param pre {String} optional guid prefix.
 
1159
     * @return {String} the guid.
 
1160
     */
 
1161
    guid: function(pre) {
 
1162
        var id = this.Env._guidp + '_' + (++this.Env._uidx);
 
1163
        return (pre) ? (pre + id) : id;
 
1164
    },
 
1165
 
 
1166
    /**
 
1167
     * Returns a `guid` associated with an object.  If the object
 
1168
     * does not have one, a new one is created unless `readOnly`
 
1169
     * is specified.
 
1170
     * @method stamp
 
1171
     * @param o {Object} The object to stamp.
 
1172
     * @param readOnly {Boolean} if `true`, a valid guid will only
 
1173
     * be returned if the object has one assigned to it.
 
1174
     * @return {String} The object's guid or null.
 
1175
     */
 
1176
    stamp: function(o, readOnly) {
 
1177
        var uid;
 
1178
        if (!o) {
 
1179
            return o;
 
1180
        }
 
1181
 
 
1182
        // IE generates its own unique ID for dom nodes
 
1183
        // The uniqueID property of a document node returns a new ID
 
1184
        if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
 
1185
            uid = o.uniqueID;
 
1186
        } else {
 
1187
            uid = (typeof o === 'string') ? o : o._yuid;
 
1188
        }
 
1189
 
 
1190
        if (!uid) {
 
1191
            uid = this.guid();
 
1192
            if (!readOnly) {
 
1193
                try {
 
1194
                    o._yuid = uid;
 
1195
                } catch (e) {
 
1196
                    uid = null;
 
1197
                }
 
1198
            }
 
1199
        }
 
1200
        return uid;
 
1201
    },
 
1202
 
 
1203
    /**
 
1204
     * Destroys the YUI instance
 
1205
     * @method destroy
 
1206
     * @since 3.3.0
 
1207
     */
 
1208
    destroy: function() {
 
1209
        var Y = this;
 
1210
        if (Y.Event) {
 
1211
            Y.Event._unload();
 
1212
        }
 
1213
        delete instances[Y.id];
 
1214
        delete Y.Env;
 
1215
        delete Y.config;
 
1216
    }
 
1217
 
 
1218
    /**
 
1219
     * instanceof check for objects that works around
 
1220
     * memory leak in IE when the item tested is
 
1221
     * window/document
 
1222
     * @method instanceOf
 
1223
     * @param o {Object} The object to check.
 
1224
     * @param type {Object} The class to check against.
 
1225
     * @since 3.3.0
 
1226
     */
 
1227
};
 
1228
 
 
1229
    YUI.prototype = proto;
 
1230
 
 
1231
    // inheritance utilities are not available yet
 
1232
    for (prop in proto) {
 
1233
        if (proto.hasOwnProperty(prop)) {
 
1234
            YUI[prop] = proto[prop];
 
1235
        }
 
1236
    }
 
1237
 
 
1238
    /**
 
1239
Static method on the Global YUI object to apply a config to all YUI instances.
 
1240
It's main use case is "mashups" where several third party scripts are trying to write to
 
1241
a global YUI config at the same time. This way they can all call `YUI.applyConfig({})` instead of
 
1242
overwriting other scripts configs.
 
1243
@static
 
1244
@since 3.5.0
 
1245
@method applyConfig
 
1246
@param {Object} o the configuration object.
 
1247
@example
 
1248
 
 
1249
    YUI.applyConfig({
 
1250
        modules: {
 
1251
            davglass: {
 
1252
                fullpath: './davglass.js'
 
1253
            }
 
1254
        }
 
1255
    });
 
1256
 
 
1257
    YUI.applyConfig({
 
1258
        modules: {
 
1259
            foo: {
 
1260
                fullpath: './foo.js'
 
1261
            }
 
1262
        }
 
1263
    });
 
1264
 
 
1265
    YUI().use('davglass', function(Y) {
 
1266
        //Module davglass will be available here..
 
1267
    });
 
1268
 
 
1269
    */
 
1270
    YUI.applyConfig = function(o) {
 
1271
        if (!o) {
 
1272
            return;
 
1273
        }
 
1274
        //If there is a GlobalConfig, apply it first to set the defaults
 
1275
        if (YUI.GlobalConfig) {
 
1276
            this.prototype.applyConfig.call(this, YUI.GlobalConfig);
 
1277
        }
 
1278
        //Apply this config to it
 
1279
        this.prototype.applyConfig.call(this, o);
 
1280
        //Reset GlobalConfig to the combined config
 
1281
        YUI.GlobalConfig = this.config;
 
1282
    };
 
1283
 
 
1284
    // set up the environment
 
1285
    YUI._init();
 
1286
 
 
1287
    if (hasWin) {
 
1288
        // add a window load event at load time so we can capture
 
1289
        // the case where it fires before dynamic loading is
 
1290
        // complete.
 
1291
        add(window, 'load', handleLoad);
 
1292
    } else {
 
1293
        handleLoad();
 
1294
    }
 
1295
 
 
1296
    YUI.Env.add = add;
 
1297
    YUI.Env.remove = remove;
 
1298
 
 
1299
    /*global exports*/
 
1300
    // Support the CommonJS method for exporting our single global
 
1301
    if (typeof exports == 'object') {
 
1302
        exports.YUI = YUI;
 
1303
    }
 
1304
 
 
1305
}());
 
1306
 
 
1307
 
 
1308
/**
 
1309
 * The config object contains all of the configuration options for
 
1310
 * the `YUI` instance.  This object is supplied by the implementer
 
1311
 * when instantiating a `YUI` instance.  Some properties have default
 
1312
 * values if they are not supplied by the implementer.  This should
 
1313
 * not be updated directly because some values are cached.  Use
 
1314
 * `applyConfig()` to update the config object on a YUI instance that
 
1315
 * has already been configured.
 
1316
 *
 
1317
 * @class config
 
1318
 * @static
 
1319
 */
 
1320
 
 
1321
/**
 
1322
 * Allows the YUI seed file to fetch the loader component and library
 
1323
 * metadata to dynamically load additional dependencies.
 
1324
 *
 
1325
 * @property bootstrap
 
1326
 * @type boolean
 
1327
 * @default true
 
1328
 */
 
1329
 
 
1330
/**
 
1331
 * Turns on writing Ylog messages to the browser console.
 
1332
 *
 
1333
 * @property debug
 
1334
 * @type boolean
 
1335
 * @default true
 
1336
 */
 
1337
 
 
1338
/**
 
1339
 * Log to the browser console if debug is on and the browser has a
 
1340
 * supported console.
 
1341
 *
 
1342
 * @property useBrowserConsole
 
1343
 * @type boolean
 
1344
 * @default true
 
1345
 */
 
1346
 
 
1347
/**
 
1348
 * A hash of log sources that should be logged.  If specified, only
 
1349
 * log messages from these sources will be logged.
 
1350
 *
 
1351
 * @property logInclude
 
1352
 * @type object
 
1353
 */
 
1354
 
 
1355
/**
 
1356
 * A hash of log sources that should be not be logged.  If specified,
 
1357
 * all sources are logged if not on this list.
 
1358
 *
 
1359
 * @property logExclude
 
1360
 * @type object
 
1361
 */
 
1362
 
 
1363
/**
 
1364
 * Set to true if the yui seed file was dynamically loaded in
 
1365
 * order to bootstrap components relying on the window load event
 
1366
 * and the `domready` custom event.
 
1367
 *
 
1368
 * @property injected
 
1369
 * @type boolean
 
1370
 * @default false
 
1371
 */
 
1372
 
 
1373
/**
 
1374
 * If `throwFail` is set, `Y.error` will generate or re-throw a JS Error.
 
1375
 * Otherwise the failure is logged.
 
1376
 *
 
1377
 * @property throwFail
 
1378
 * @type boolean
 
1379
 * @default true
 
1380
 */
 
1381
 
 
1382
/**
 
1383
 * The window/frame that this instance should operate in.
 
1384
 *
 
1385
 * @property win
 
1386
 * @type Window
 
1387
 * @default the window hosting YUI
 
1388
 */
 
1389
 
 
1390
/**
 
1391
 * The document associated with the 'win' configuration.
 
1392
 *
 
1393
 * @property doc
 
1394
 * @type Document
 
1395
 * @default the document hosting YUI
 
1396
 */
 
1397
 
 
1398
/**
 
1399
 * A list of modules that defines the YUI core (overrides the default list).
 
1400
 *
 
1401
 * @property core
 
1402
 * @type Array
 
1403
 * @default [ get,features,intl-base,yui-log,yui-later,loader-base, loader-rollup, loader-yui3 ]
 
1404
 */
 
1405
 
 
1406
/**
 
1407
 * A list of languages in order of preference. This list is matched against
 
1408
 * the list of available languages in modules that the YUI instance uses to
 
1409
 * determine the best possible localization of language sensitive modules.
 
1410
 * Languages are represented using BCP 47 language tags, such as "en-GB" for
 
1411
 * English as used in the United Kingdom, or "zh-Hans-CN" for simplified
 
1412
 * Chinese as used in China. The list can be provided as a comma-separated
 
1413
 * list or as an array.
 
1414
 *
 
1415
 * @property lang
 
1416
 * @type string|string[]
 
1417
 */
 
1418
 
 
1419
/**
 
1420
 * The default date format
 
1421
 * @property dateFormat
 
1422
 * @type string
 
1423
 * @deprecated use configuration in `DataType.Date.format()` instead.
 
1424
 */
 
1425
 
 
1426
/**
 
1427
 * The default locale
 
1428
 * @property locale
 
1429
 * @type string
 
1430
 * @deprecated use `config.lang` instead.
 
1431
 */
 
1432
 
 
1433
/**
 
1434
 * The default interval when polling in milliseconds.
 
1435
 * @property pollInterval
 
1436
 * @type int
 
1437
 * @default 20
 
1438
 */
 
1439
 
 
1440
/**
 
1441
 * The number of dynamic nodes to insert by default before
 
1442
 * automatically removing them.  This applies to script nodes
 
1443
 * because removing the node will not make the evaluated script
 
1444
 * unavailable.  Dynamic CSS is not auto purged, because removing
 
1445
 * a linked style sheet will also remove the style definitions.
 
1446
 * @property purgethreshold
 
1447
 * @type int
 
1448
 * @default 20
 
1449
 */
 
1450
 
 
1451
/**
 
1452
 * The default interval when polling in milliseconds.
 
1453
 * @property windowResizeDelay
 
1454
 * @type int
 
1455
 * @default 40
 
1456
 */
 
1457
 
 
1458
/**
 
1459
 * Base directory for dynamic loading
 
1460
 * @property base
 
1461
 * @type string
 
1462
 */
 
1463
 
 
1464
/*
 
1465
 * The secure base dir (not implemented)
 
1466
 * For dynamic loading.
 
1467
 * @property secureBase
 
1468
 * @type string
 
1469
 */
 
1470
 
 
1471
/**
 
1472
 * The YUI combo service base dir. Ex: `http://yui.yahooapis.com/combo?`
 
1473
 * For dynamic loading.
 
1474
 * @property comboBase
 
1475
 * @type string
 
1476
 */
 
1477
 
 
1478
/**
 
1479
 * The root path to prepend to module path for the combo service.
 
1480
 * Ex: 3.0.0b1/build/
 
1481
 * For dynamic loading.
 
1482
 * @property root
 
1483
 * @type string
 
1484
 */
 
1485
 
 
1486
/**
 
1487
 * A filter to apply to result urls.  This filter will modify the default
 
1488
 * path for all modules.  The default path for the YUI library is the
 
1489
 * minified version of the files (e.g., event-min.js).  The filter property
 
1490
 * can be a predefined filter or a custom filter.  The valid predefined
 
1491
 * filters are:
 
1492
 * <dl>
 
1493
 *  <dt>DEBUG</dt>
 
1494
 *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
 
1495
 *      This option will automatically include the Logger widget</dd>
 
1496
 *  <dt>RAW</dt>
 
1497
 *  <dd>Selects the non-minified version of the library (e.g., event.js).</dd>
 
1498
 * </dl>
 
1499
 * You can also define a custom filter, which must be an object literal
 
1500
 * containing a search expression and a replace string:
 
1501
 *
 
1502
 *      myFilter: {
 
1503
 *          'searchExp': "-min\\.js",
 
1504
 *          'replaceStr': "-debug.js"
 
1505
 *      }
 
1506
 *
 
1507
 * For dynamic loading.
 
1508
 *
 
1509
 * @property filter
 
1510
 * @type string|object
 
1511
 */
 
1512
 
 
1513
/**
 
1514
 * The `skin` config let's you configure application level skin
 
1515
 * customizations.  It contains the following attributes which
 
1516
 * can be specified to override the defaults:
 
1517
 *
 
1518
 *      // The default skin, which is automatically applied if not
 
1519
 *      // overriden by a component-specific skin definition.
 
1520
 *      // Change this in to apply a different skin globally
 
1521
 *      defaultSkin: 'sam',
 
1522
 *
 
1523
 *      // This is combined with the loader base property to get
 
1524
 *      // the default root directory for a skin.
 
1525
 *      base: 'assets/skins/',
 
1526
 *
 
1527
 *      // Any component-specific overrides can be specified here,
 
1528
 *      // making it possible to load different skins for different
 
1529
 *      // components.  It is possible to load more than one skin
 
1530
 *      // for a given component as well.
 
1531
 *      overrides: {
 
1532
 *          slider: ['capsule', 'round']
 
1533
 *      }
 
1534
 *
 
1535
 * For dynamic loading.
 
1536
 *
 
1537
 *  @property skin
 
1538
 */
 
1539
 
 
1540
/**
 
1541
 * Hash of per-component filter specification.  If specified for a given
 
1542
 * component, this overrides the filter config.
 
1543
 *
 
1544
 * For dynamic loading.
 
1545
 *
 
1546
 * @property filters
 
1547
 */
 
1548
 
 
1549
/**
 
1550
 * Use the YUI combo service to reduce the number of http connections
 
1551
 * required to load your dependencies.  Turning this off will
 
1552
 * disable combo handling for YUI and all module groups configured
 
1553
 * with a combo service.
 
1554
 *
 
1555
 * For dynamic loading.
 
1556
 *
 
1557
 * @property combine
 
1558
 * @type boolean
 
1559
 * @default true if 'base' is not supplied, false if it is.
 
1560
 */
 
1561
 
 
1562
/**
 
1563
 * A list of modules that should never be dynamically loaded
 
1564
 *
 
1565
 * @property ignore
 
1566
 * @type string[]
 
1567
 */
 
1568
 
 
1569
/**
 
1570
 * A list of modules that should always be loaded when required, even if already
 
1571
 * present on the page.
 
1572
 *
 
1573
 * @property force
 
1574
 * @type string[]
 
1575
 */
 
1576
 
 
1577
/**
 
1578
 * Node or id for a node that should be used as the insertion point for new
 
1579
 * nodes.  For dynamic loading.
 
1580
 *
 
1581
 * @property insertBefore
 
1582
 * @type string
 
1583
 */
 
1584
 
 
1585
/**
 
1586
 * Object literal containing attributes to add to dynamically loaded script
 
1587
 * nodes.
 
1588
 * @property jsAttributes
 
1589
 * @type string
 
1590
 */
 
1591
 
 
1592
/**
 
1593
 * Object literal containing attributes to add to dynamically loaded link
 
1594
 * nodes.
 
1595
 * @property cssAttributes
 
1596
 * @type string
 
1597
 */
 
1598
 
 
1599
/**
 
1600
 * Number of milliseconds before a timeout occurs when dynamically
 
1601
 * loading nodes. If not set, there is no timeout.
 
1602
 * @property timeout
 
1603
 * @type int
 
1604
 */
 
1605
 
 
1606
/**
 
1607
 * Callback for the 'CSSComplete' event.  When dynamically loading YUI
 
1608
 * components with CSS, this property fires when the CSS is finished
 
1609
 * loading but script loading is still ongoing.  This provides an
 
1610
 * opportunity to enhance the presentation of a loading page a little
 
1611
 * bit before the entire loading process is done.
 
1612
 *
 
1613
 * @property onCSS
 
1614
 * @type function
 
1615
 */
 
1616
 
 
1617
/**
 
1618
 * A hash of module definitions to add to the list of YUI components.
 
1619
 * These components can then be dynamically loaded side by side with
 
1620
 * YUI via the `use()` method. This is a hash, the key is the module
 
1621
 * name, and the value is an object literal specifying the metdata
 
1622
 * for the module.  See `Loader.addModule` for the supported module
 
1623
 * metadata fields.  Also see groups, which provides a way to
 
1624
 * configure the base and combo spec for a set of modules.
 
1625
 *
 
1626
 *      modules: {
 
1627
 *          mymod1: {
 
1628
 *              requires: ['node'],
 
1629
 *              fullpath: '/mymod1/mymod1.js'
 
1630
 *          },
 
1631
 *          mymod2: {
 
1632
 *              requires: ['mymod1'],
 
1633
 *              fullpath: '/mymod2/mymod2.js'
 
1634
 *          },
 
1635
 *          mymod3: '/js/mymod3.js',
 
1636
 *          mycssmod: '/css/mycssmod.css'
 
1637
 *      }
 
1638
 *
 
1639
 *
 
1640
 * @property modules
 
1641
 * @type object
 
1642
 */
 
1643
 
 
1644
/**
 
1645
 * Aliases are dynamic groups of modules that can be used as
 
1646
 * shortcuts.
 
1647
 *
 
1648
 *      YUI({
 
1649
 *          aliases: {
 
1650
 *              davglass: [ 'node', 'yql', 'dd' ],
 
1651
 *              mine: [ 'davglass', 'autocomplete']
 
1652
 *          }
 
1653
 *      }).use('mine', function(Y) {
 
1654
 *          //Node, YQL, DD &amp; AutoComplete available here..
 
1655
 *      });
 
1656
 *
 
1657
 * @property aliases
 
1658
 * @type object
 
1659
 */
 
1660
 
 
1661
/**
 
1662
 * A hash of module group definitions.  It for each group you
 
1663
 * can specify a list of modules and the base path and
 
1664
 * combo spec to use when dynamically loading the modules.
 
1665
 *
 
1666
 *      groups: {
 
1667
 *          yui2: {
 
1668
 *              // specify whether or not this group has a combo service
 
1669
 *              combine: true,
 
1670
 *
 
1671
 *              // The comboSeperator to use with this group's combo handler
 
1672
 *              comboSep: ';',
 
1673
 *
 
1674
 *              // The maxURLLength for this server
 
1675
 *              maxURLLength: 500,
 
1676
 *
 
1677
 *              // the base path for non-combo paths
 
1678
 *              base: 'http://yui.yahooapis.com/2.8.0r4/build/',
 
1679
 *
 
1680
 *              // the path to the combo service
 
1681
 *              comboBase: 'http://yui.yahooapis.com/combo?',
 
1682
 *
 
1683
 *              // a fragment to prepend to the path attribute when
 
1684
 *              // when building combo urls
 
1685
 *              root: '2.8.0r4/build/',
 
1686
 *
 
1687
 *              // the module definitions
 
1688
 *              modules:  {
 
1689
 *                  yui2_yde: {
 
1690
 *                      path: "yahoo-dom-event/yahoo-dom-event.js"
 
1691
 *                  },
 
1692
 *                  yui2_anim: {
 
1693
 *                      path: "animation/animation.js",
 
1694
 *                      requires: ['yui2_yde']
 
1695
 *                  }
 
1696
 *              }
 
1697
 *          }
 
1698
 *      }
 
1699
 *
 
1700
 * @property groups
 
1701
 * @type object
 
1702
 */
 
1703
 
 
1704
/**
 
1705
 * The loader 'path' attribute to the loader itself.  This is combined
 
1706
 * with the 'base' attribute to dynamically load the loader component
 
1707
 * when boostrapping with the get utility alone.
 
1708
 *
 
1709
 * @property loaderPath
 
1710
 * @type string
 
1711
 * @default loader/loader-min.js
 
1712
 */
 
1713
 
 
1714
/**
 
1715
 * Specifies whether or not YUI().use(...) will attempt to load CSS
 
1716
 * resources at all.  Any truthy value will cause CSS dependencies
 
1717
 * to load when fetching script.  The special value 'force' will
 
1718
 * cause CSS dependencies to be loaded even if no script is needed.
 
1719
 *
 
1720
 * @property fetchCSS
 
1721
 * @type boolean|string
 
1722
 * @default true
 
1723
 */
 
1724
 
 
1725
/**
 
1726
 * The default gallery version to build gallery module urls
 
1727
 * @property gallery
 
1728
 * @type string
 
1729
 * @since 3.1.0
 
1730
 */
 
1731
 
 
1732
/**
 
1733
 * The default YUI 2 version to build yui2 module urls.  This is for
 
1734
 * intrinsic YUI 2 support via the 2in3 project.  Also see the '2in3'
 
1735
 * config for pulling different revisions of the wrapped YUI 2
 
1736
 * modules.
 
1737
 * @since 3.1.0
 
1738
 * @property yui2
 
1739
 * @type string
 
1740
 * @default 2.9.0
 
1741
 */
 
1742
 
 
1743
/**
 
1744
 * The 2in3 project is a deployment of the various versions of YUI 2
 
1745
 * deployed as first-class YUI 3 modules.  Eventually, the wrapper
 
1746
 * for the modules will change (but the underlying YUI 2 code will
 
1747
 * be the same), and you can select a particular version of
 
1748
 * the wrapper modules via this config.
 
1749
 * @since 3.1.0
 
1750
 * @property 2in3
 
1751
 * @type string
 
1752
 * @default 4
 
1753
 */
 
1754
 
 
1755
/**
 
1756
 * Alternative console log function for use in environments without
 
1757
 * a supported native console.  The function is executed in the
 
1758
 * YUI instance context.
 
1759
 * @since 3.1.0
 
1760
 * @property logFn
 
1761
 * @type Function
 
1762
 */
 
1763
 
 
1764
/**
 
1765
 * A callback to execute when Y.error is called.  It receives the
 
1766
 * error message and an javascript error object if Y.error was
 
1767
 * executed because a javascript error was caught.  The function
 
1768
 * is executed in the YUI instance context. Returning `true` from this
 
1769
 * function will stop the Error from being thrown.
 
1770
 *
 
1771
 * @since 3.2.0
 
1772
 * @property errorFn
 
1773
 * @type Function
 
1774
 */
 
1775
 
 
1776
/**
 
1777
 * A callback to execute when the loader fails to load one or
 
1778
 * more resource.  This could be because of a script load
 
1779
 * failure.  It can also fail if a javascript module fails
 
1780
 * to register itself, but only when the 'requireRegistration'
 
1781
 * is true.  If this function is defined, the use() callback will
 
1782
 * only be called when the loader succeeds, otherwise it always
 
1783
 * executes unless there was a javascript error when attaching
 
1784
 * a module.
 
1785
 *
 
1786
 * @since 3.3.0
 
1787
 * @property loadErrorFn
 
1788
 * @type Function
 
1789
 */
 
1790
 
 
1791
/**
 
1792
 * When set to true, the YUI loader will expect that all modules
 
1793
 * it is responsible for loading will be first-class YUI modules
 
1794
 * that register themselves with the YUI global.  If this is
 
1795
 * set to true, loader will fail if the module registration fails
 
1796
 * to happen after the script is loaded.
 
1797
 *
 
1798
 * @since 3.3.0
 
1799
 * @property requireRegistration
 
1800
 * @type boolean
 
1801
 * @default false
 
1802
 */
 
1803
 
 
1804
/**
 
1805
 * Cache serviced use() requests.
 
1806
 * @since 3.3.0
 
1807
 * @property cacheUse
 
1808
 * @type boolean
 
1809
 * @default true
 
1810
 * @deprecated no longer used
 
1811
 */
 
1812
 
 
1813
/**
 
1814
 * Whether or not YUI should use native ES5 functionality when available for
 
1815
 * features like `Y.Array.each()`, `Y.Object()`, etc. When `false`, YUI will
 
1816
 * always use its own fallback implementations instead of relying on ES5
 
1817
 * functionality, even when it's available.
 
1818
 *
 
1819
 * @method useNativeES5
 
1820
 * @type Boolean
 
1821
 * @default true
 
1822
 * @since 3.5.0
 
1823
 */
 
1824
YUI.add('yui-base', function(Y) {
 
1825
 
 
1826
/*
 
1827
 * YUI stub
 
1828
 * @module yui
 
1829
 * @submodule yui-base
 
1830
 */
 
1831
/**
 
1832
 * The YUI module contains the components required for building the YUI
 
1833
 * seed file.  This includes the script loading mechanism, a simple queue,
 
1834
 * and the core utilities for the library.
 
1835
 * @module yui
 
1836
 * @submodule yui-base
 
1837
 */
 
1838
 
 
1839
/**
 
1840
 * Provides core language utilites and extensions used throughout YUI.
 
1841
 *
 
1842
 * @class Lang
 
1843
 * @static
 
1844
 */
 
1845
 
 
1846
var L = Y.Lang || (Y.Lang = {}),
 
1847
 
 
1848
STRING_PROTO = String.prototype,
 
1849
TOSTRING     = Object.prototype.toString,
 
1850
 
 
1851
TYPES = {
 
1852
    'undefined'        : 'undefined',
 
1853
    'number'           : 'number',
 
1854
    'boolean'          : 'boolean',
 
1855
    'string'           : 'string',
 
1856
    '[object Function]': 'function',
 
1857
    '[object RegExp]'  : 'regexp',
 
1858
    '[object Array]'   : 'array',
 
1859
    '[object Date]'    : 'date',
 
1860
    '[object Error]'   : 'error'
 
1861
},
 
1862
 
 
1863
SUBREGEX        = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
 
1864
TRIMREGEX       = /^\s+|\s+$/g,
 
1865
NATIVE_FN_REGEX = /\{\s*\[(?:native code|function)\]\s*\}/i;
 
1866
 
 
1867
// -- Protected Methods --------------------------------------------------------
 
1868
 
 
1869
/**
 
1870
Returns `true` if the given function appears to be implemented in native code,
 
1871
`false` otherwise. Will always return `false` -- even in ES5-capable browsers --
 
1872
if the `useNativeES5` YUI config option is set to `false`.
 
1873
 
 
1874
This isn't guaranteed to be 100% accurate and won't work for anything other than
 
1875
functions, but it can be useful for determining whether a function like
 
1876
`Array.prototype.forEach` is native or a JS shim provided by another library.
 
1877
 
 
1878
There's a great article by @kangax discussing certain flaws with this technique:
 
1879
<http://perfectionkills.com/detecting-built-in-host-methods/>
 
1880
 
 
1881
While his points are valid, it's still possible to benefit from this function
 
1882
as long as it's used carefully and sparingly, and in such a way that false
 
1883
negatives have minimal consequences. It's used internally to avoid using
 
1884
potentially broken non-native ES5 shims that have been added to the page by
 
1885
other libraries.
 
1886
 
 
1887
@method _isNative
 
1888
@param {Function} fn Function to test.
 
1889
@return {Boolean} `true` if _fn_ appears to be native, `false` otherwise.
 
1890
@static
 
1891
@protected
 
1892
@since 3.5.0
 
1893
**/
 
1894
L._isNative = function (fn) {
 
1895
    return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn));
 
1896
};
 
1897
 
 
1898
// -- Public Methods -----------------------------------------------------------
 
1899
 
 
1900
/**
 
1901
 * Determines whether or not the provided item is an array.
 
1902
 *
 
1903
 * Returns `false` for array-like collections such as the function `arguments`
 
1904
 * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
 
1905
 * test for an array-like collection.
 
1906
 *
 
1907
 * @method isArray
 
1908
 * @param o The object to test.
 
1909
 * @return {boolean} true if o is an array.
 
1910
 * @static
 
1911
 */
 
1912
L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) {
 
1913
    return L.type(o) === 'array';
 
1914
};
 
1915
 
 
1916
/**
 
1917
 * Determines whether or not the provided item is a boolean.
 
1918
 * @method isBoolean
 
1919
 * @static
 
1920
 * @param o The object to test.
 
1921
 * @return {boolean} true if o is a boolean.
 
1922
 */
 
1923
L.isBoolean = function(o) {
 
1924
    return typeof o === 'boolean';
 
1925
};
 
1926
 
 
1927
/**
 
1928
 * Determines whether or not the supplied item is a date instance.
 
1929
 * @method isDate
 
1930
 * @static
 
1931
 * @param o The object to test.
 
1932
 * @return {boolean} true if o is a date.
 
1933
 */
 
1934
L.isDate = function(o) {
 
1935
    return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
 
1936
};
 
1937
 
 
1938
/**
 
1939
 * <p>
 
1940
 * Determines whether or not the provided item is a function.
 
1941
 * Note: Internet Explorer thinks certain functions are objects:
 
1942
 * </p>
 
1943
 *
 
1944
 * <pre>
 
1945
 * var obj = document.createElement("object");
 
1946
 * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
 
1947
 * &nbsp;
 
1948
 * var input = document.createElement("input"); // append to body
 
1949
 * Y.Lang.isFunction(input.focus) // reports false in IE
 
1950
 * </pre>
 
1951
 *
 
1952
 * <p>
 
1953
 * You will have to implement additional tests if these functions
 
1954
 * matter to you.
 
1955
 * </p>
 
1956
 *
 
1957
 * @method isFunction
 
1958
 * @static
 
1959
 * @param o The object to test.
 
1960
 * @return {boolean} true if o is a function.
 
1961
 */
 
1962
L.isFunction = function(o) {
 
1963
    return L.type(o) === 'function';
 
1964
};
 
1965
 
 
1966
/**
 
1967
 * Determines whether or not the provided item is null.
 
1968
 * @method isNull
 
1969
 * @static
 
1970
 * @param o The object to test.
 
1971
 * @return {boolean} true if o is null.
 
1972
 */
 
1973
L.isNull = function(o) {
 
1974
    return o === null;
 
1975
};
 
1976
 
 
1977
/**
 
1978
 * Determines whether or not the provided item is a legal number.
 
1979
 * @method isNumber
 
1980
 * @static
 
1981
 * @param o The object to test.
 
1982
 * @return {boolean} true if o is a number.
 
1983
 */
 
1984
L.isNumber = function(o) {
 
1985
    return typeof o === 'number' && isFinite(o);
 
1986
};
 
1987
 
 
1988
/**
 
1989
 * Determines whether or not the provided item is of type object
 
1990
 * or function. Note that arrays are also objects, so
 
1991
 * <code>Y.Lang.isObject([]) === true</code>.
 
1992
 * @method isObject
 
1993
 * @static
 
1994
 * @param o The object to test.
 
1995
 * @param failfn {boolean} fail if the input is a function.
 
1996
 * @return {boolean} true if o is an object.
 
1997
 * @see isPlainObject
 
1998
 */
 
1999
L.isObject = function(o, failfn) {
 
2000
    var t = typeof o;
 
2001
    return (o && (t === 'object' ||
 
2002
        (!failfn && (t === 'function' || L.isFunction(o))))) || false;
 
2003
};
 
2004
 
 
2005
/**
 
2006
 * Determines whether or not the provided item is a string.
 
2007
 * @method isString
 
2008
 * @static
 
2009
 * @param o The object to test.
 
2010
 * @return {boolean} true if o is a string.
 
2011
 */
 
2012
L.isString = function(o) {
 
2013
    return typeof o === 'string';
 
2014
};
 
2015
 
 
2016
/**
 
2017
 * Determines whether or not the provided item is undefined.
 
2018
 * @method isUndefined
 
2019
 * @static
 
2020
 * @param o The object to test.
 
2021
 * @return {boolean} true if o is undefined.
 
2022
 */
 
2023
L.isUndefined = function(o) {
 
2024
    return typeof o === 'undefined';
 
2025
};
 
2026
 
 
2027
/**
 
2028
 * A convenience method for detecting a legitimate non-null value.
 
2029
 * Returns false for null/undefined/NaN, true for other values,
 
2030
 * including 0/false/''
 
2031
 * @method isValue
 
2032
 * @static
 
2033
 * @param o The item to test.
 
2034
 * @return {boolean} true if it is not null/undefined/NaN || false.
 
2035
 */
 
2036
L.isValue = function(o) {
 
2037
    var t = L.type(o);
 
2038
 
 
2039
    switch (t) {
 
2040
        case 'number':
 
2041
            return isFinite(o);
 
2042
 
 
2043
        case 'null': // fallthru
 
2044
        case 'undefined':
 
2045
            return false;
 
2046
 
 
2047
        default:
 
2048
            return !!t;
 
2049
    }
 
2050
};
 
2051
 
 
2052
/**
 
2053
 * Returns the current time in milliseconds.
 
2054
 *
 
2055
 * @method now
 
2056
 * @return {Number} Current time in milliseconds.
 
2057
 * @static
 
2058
 * @since 3.3.0
 
2059
 */
 
2060
L.now = Date.now || function () {
 
2061
    return new Date().getTime();
 
2062
};
 
2063
 
 
2064
/**
 
2065
 * Lightweight version of <code>Y.substitute</code>. Uses the same template
 
2066
 * structure as <code>Y.substitute</code>, but doesn't support recursion,
 
2067
 * auto-object coersion, or formats.
 
2068
 * @method sub
 
2069
 * @param {string} s String to be modified.
 
2070
 * @param {object} o Object containing replacement values.
 
2071
 * @return {string} the substitute result.
 
2072
 * @static
 
2073
 * @since 3.2.0
 
2074
 */
 
2075
L.sub = function(s, o) {
 
2076
    return s.replace ? s.replace(SUBREGEX, function (match, key) {
 
2077
        return L.isUndefined(o[key]) ? match : o[key];
 
2078
    }) : s;
 
2079
};
 
2080
 
 
2081
/**
 
2082
 * Returns a string without any leading or trailing whitespace.  If
 
2083
 * the input is not a string, the input will be returned untouched.
 
2084
 * @method trim
 
2085
 * @static
 
2086
 * @param s {string} the string to trim.
 
2087
 * @return {string} the trimmed string.
 
2088
 */
 
2089
L.trim = STRING_PROTO.trim ? function(s) {
 
2090
    return s && s.trim ? s.trim() : s;
 
2091
} : function (s) {
 
2092
    try {
 
2093
        return s.replace(TRIMREGEX, '');
 
2094
    } catch (e) {
 
2095
        return s;
 
2096
    }
 
2097
};
 
2098
 
 
2099
/**
 
2100
 * Returns a string without any leading whitespace.
 
2101
 * @method trimLeft
 
2102
 * @static
 
2103
 * @param s {string} the string to trim.
 
2104
 * @return {string} the trimmed string.
 
2105
 */
 
2106
L.trimLeft = STRING_PROTO.trimLeft ? function (s) {
 
2107
    return s.trimLeft();
 
2108
} : function (s) {
 
2109
    return s.replace(/^\s+/, '');
 
2110
};
 
2111
 
 
2112
/**
 
2113
 * Returns a string without any trailing whitespace.
 
2114
 * @method trimRight
 
2115
 * @static
 
2116
 * @param s {string} the string to trim.
 
2117
 * @return {string} the trimmed string.
 
2118
 */
 
2119
L.trimRight = STRING_PROTO.trimRight ? function (s) {
 
2120
    return s.trimRight();
 
2121
} : function (s) {
 
2122
    return s.replace(/\s+$/, '');
 
2123
};
 
2124
 
 
2125
/**
 
2126
Returns one of the following strings, representing the type of the item passed
 
2127
in:
 
2128
 
 
2129
 * "array"
 
2130
 * "boolean"
 
2131
 * "date"
 
2132
 * "error"
 
2133
 * "function"
 
2134
 * "null"
 
2135
 * "number"
 
2136
 * "object"
 
2137
 * "regexp"
 
2138
 * "string"
 
2139
 * "undefined"
 
2140
 
 
2141
Known issues:
 
2142
 
 
2143
 * `typeof HTMLElementCollection` returns function in Safari, but
 
2144
    `Y.Lang.type()` reports "object", which could be a good thing --
 
2145
    but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
 
2146
 
 
2147
@method type
 
2148
@param o the item to test.
 
2149
@return {string} the detected type.
 
2150
@static
 
2151
**/
 
2152
L.type = function(o) {
 
2153
    return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
 
2154
};
 
2155
/**
 
2156
@module yui
 
2157
@submodule yui-base
 
2158
*/
 
2159
 
 
2160
var Lang   = Y.Lang,
 
2161
    Native = Array.prototype,
 
2162
 
 
2163
    hasOwn = Object.prototype.hasOwnProperty;
 
2164
 
 
2165
/**
 
2166
Provides utility methods for working with arrays. Additional array helpers can
 
2167
be found in the `collection` and `array-extras` modules.
 
2168
 
 
2169
`Y.Array(thing)` returns a native array created from _thing_. Depending on
 
2170
_thing_'s type, one of the following will happen:
 
2171
 
 
2172
  * Arrays are returned unmodified unless a non-zero _startIndex_ is
 
2173
    specified.
 
2174
  * Array-like collections (see `Array.test()`) are converted to arrays.
 
2175
  * For everything else, a new array is created with _thing_ as the sole
 
2176
    item.
 
2177
 
 
2178
Note: elements that are also collections, such as `<form>` and `<select>`
 
2179
elements, are not automatically converted to arrays. To force a conversion,
 
2180
pass `true` as the value of the _force_ parameter.
 
2181
 
 
2182
@class Array
 
2183
@constructor
 
2184
@param {Any} thing The thing to arrayify.
 
2185
@param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
 
2186
  collection, a subset of items starting at the specified index will be
 
2187
  returned.
 
2188
@param {Boolean} [force=false] If `true`, _thing_ will be treated as an
 
2189
  array-like collection no matter what.
 
2190
@return {Array} A native array created from _thing_, according to the rules
 
2191
  described above.
 
2192
**/
 
2193
function YArray(thing, startIndex, force) {
 
2194
    var len, result;
 
2195
 
 
2196
    startIndex || (startIndex = 0);
 
2197
 
 
2198
    if (force || YArray.test(thing)) {
 
2199
        // IE throws when trying to slice HTMLElement collections.
 
2200
        try {
 
2201
            return Native.slice.call(thing, startIndex);
 
2202
        } catch (ex) {
 
2203
            result = [];
 
2204
 
 
2205
            for (len = thing.length; startIndex < len; ++startIndex) {
 
2206
                result.push(thing[startIndex]);
 
2207
            }
 
2208
 
 
2209
            return result;
 
2210
        }
 
2211
    }
 
2212
 
 
2213
    return [thing];
 
2214
}
 
2215
 
 
2216
Y.Array = YArray;
 
2217
 
 
2218
/**
 
2219
Dedupes an array of strings, returning an array that's guaranteed to contain
 
2220
only one copy of a given string.
 
2221
 
 
2222
This method differs from `Array.unique()` in that it's optimized for use only
 
2223
with strings, whereas `unique` may be used with other types (but is slower).
 
2224
Using `dedupe()` with non-string values may result in unexpected behavior.
 
2225
 
 
2226
@method dedupe
 
2227
@param {String[]} array Array of strings to dedupe.
 
2228
@return {Array} Deduped copy of _array_.
 
2229
@static
 
2230
@since 3.4.0
 
2231
**/
 
2232
YArray.dedupe = function (array) {
 
2233
    var hash    = {},
 
2234
        results = [],
 
2235
        i, item, len;
 
2236
 
 
2237
    for (i = 0, len = array.length; i < len; ++i) {
 
2238
        item = array[i];
 
2239
 
 
2240
        if (!hasOwn.call(hash, item)) {
 
2241
            hash[item] = 1;
 
2242
            results.push(item);
 
2243
        }
 
2244
    }
 
2245
 
 
2246
    return results;
 
2247
};
 
2248
 
 
2249
/**
 
2250
Executes the supplied function on each item in the array. This method wraps
 
2251
the native ES5 `Array.forEach()` method if available.
 
2252
 
 
2253
@method each
 
2254
@param {Array} array Array to iterate.
 
2255
@param {Function} fn Function to execute on each item in the array. The function
 
2256
  will receive the following arguments:
 
2257
    @param {Any} fn.item Current array item.
 
2258
    @param {Number} fn.index Current array index.
 
2259
    @param {Array} fn.array Array being iterated.
 
2260
@param {Object} [thisObj] `this` object to use when calling _fn_.
 
2261
@return {YUI} The YUI instance.
 
2262
@static
 
2263
**/
 
2264
YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) {
 
2265
    Native.forEach.call(array || [], fn, thisObj || Y);
 
2266
    return Y;
 
2267
} : function (array, fn, thisObj) {
 
2268
    for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
 
2269
        if (i in array) {
 
2270
            fn.call(thisObj || Y, array[i], i, array);
 
2271
        }
 
2272
    }
 
2273
 
 
2274
    return Y;
 
2275
};
 
2276
 
 
2277
/**
 
2278
Alias for `each()`.
 
2279
 
 
2280
@method forEach
 
2281
@static
 
2282
**/
 
2283
 
 
2284
/**
 
2285
Returns an object using the first array as keys and the second as values. If
 
2286
the second array is not provided, or if it doesn't contain the same number of
 
2287
values as the first array, then `true` will be used in place of the missing
 
2288
values.
 
2289
 
 
2290
@example
 
2291
 
 
2292
    Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
 
2293
    // => {a: 'foo', b: 'bar', c: true}
 
2294
 
 
2295
@method hash
 
2296
@param {String[]} keys Array of strings to use as keys.
 
2297
@param {Array} [values] Array to use as values.
 
2298
@return {Object} Hash using the first array as keys and the second as values.
 
2299
@static
 
2300
**/
 
2301
YArray.hash = function (keys, values) {
 
2302
    var hash = {},
 
2303
        vlen = (values && values.length) || 0,
 
2304
        i, len;
 
2305
 
 
2306
    for (i = 0, len = keys.length; i < len; ++i) {
 
2307
        if (i in keys) {
 
2308
            hash[keys[i]] = vlen > i && i in values ? values[i] : true;
 
2309
        }
 
2310
    }
 
2311
 
 
2312
    return hash;
 
2313
};
 
2314
 
 
2315
/**
 
2316
Returns the index of the first item in the array that's equal (using a strict
 
2317
equality check) to the specified _value_, or `-1` if the value isn't found.
 
2318
 
 
2319
This method wraps the native ES5 `Array.indexOf()` method if available.
 
2320
 
 
2321
@method indexOf
 
2322
@param {Array} array Array to search.
 
2323
@param {Any} value Value to search for.
 
2324
@param {Number} [from=0] The index at which to begin the search.
 
2325
@return {Number} Index of the item strictly equal to _value_, or `-1` if not
 
2326
    found.
 
2327
@static
 
2328
**/
 
2329
YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) {
 
2330
    return Native.indexOf.call(array, value, from);
 
2331
} : function (array, value, from) {
 
2332
    // http://es5.github.com/#x15.4.4.14
 
2333
    var len = array.length;
 
2334
 
 
2335
    from = +from || 0;
 
2336
    from = (from > 0 || -1) * Math.floor(Math.abs(from));
 
2337
 
 
2338
    if (from < 0) {
 
2339
        from += len;
 
2340
 
 
2341
        if (from < 0) {
 
2342
            from = 0;
 
2343
        }
 
2344
    }
 
2345
 
 
2346
    for (; from < len; ++from) {
 
2347
        if (from in array && array[from] === value) {
 
2348
            return from;
 
2349
        }
 
2350
    }
 
2351
 
 
2352
    return -1;
 
2353
};
 
2354
 
 
2355
/**
 
2356
Numeric sort convenience function.
 
2357
 
 
2358
The native `Array.prototype.sort()` function converts values to strings and
 
2359
sorts them in lexicographic order, which is unsuitable for sorting numeric
 
2360
values. Provide `Array.numericSort` as a custom sort function when you want
 
2361
to sort values in numeric order.
 
2362
 
 
2363
@example
 
2364
 
 
2365
    [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
 
2366
    // => [4, 8, 15, 16, 23, 42]
 
2367
 
 
2368
@method numericSort
 
2369
@param {Number} a First value to compare.
 
2370
@param {Number} b Second value to compare.
 
2371
@return {Number} Difference between _a_ and _b_.
 
2372
@static
 
2373
**/
 
2374
YArray.numericSort = function (a, b) {
 
2375
    return a - b;
 
2376
};
 
2377
 
 
2378
/**
 
2379
Executes the supplied function on each item in the array. Returning a truthy
 
2380
value from the function will stop the processing of remaining items.
 
2381
 
 
2382
@method some
 
2383
@param {Array} array Array to iterate over.
 
2384
@param {Function} fn Function to execute on each item. The function will receive
 
2385
  the following arguments:
 
2386
    @param {Any} fn.value Current array item.
 
2387
    @param {Number} fn.index Current array index.
 
2388
    @param {Array} fn.array Array being iterated over.
 
2389
@param {Object} [thisObj] `this` object to use when calling _fn_.
 
2390
@return {Boolean} `true` if the function returns a truthy value on any of the
 
2391
  items in the array; `false` otherwise.
 
2392
@static
 
2393
**/
 
2394
YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) {
 
2395
    return Native.some.call(array, fn, thisObj);
 
2396
} : function (array, fn, thisObj) {
 
2397
    for (var i = 0, len = array.length; i < len; ++i) {
 
2398
        if (i in array && fn.call(thisObj, array[i], i, array)) {
 
2399
            return true;
 
2400
        }
 
2401
    }
 
2402
 
 
2403
    return false;
 
2404
};
 
2405
 
 
2406
/**
 
2407
Evaluates _obj_ to determine if it's an array, an array-like collection, or
 
2408
something else. This is useful when working with the function `arguments`
 
2409
collection and `HTMLElement` collections.
 
2410
 
 
2411
Note: This implementation doesn't consider elements that are also
 
2412
collections, such as `<form>` and `<select>`, to be array-like.
 
2413
 
 
2414
@method test
 
2415
@param {Object} obj Object to test.
 
2416
@return {Number} A number indicating the results of the test:
 
2417
 
 
2418
  * 0: Neither an array nor an array-like collection.
 
2419
  * 1: Real array.
 
2420
  * 2: Array-like collection.
 
2421
 
 
2422
@static
 
2423
**/
 
2424
YArray.test = function (obj) {
 
2425
    var result = 0;
 
2426
 
 
2427
    if (Lang.isArray(obj)) {
 
2428
        result = 1;
 
2429
    } else if (Lang.isObject(obj)) {
 
2430
        try {
 
2431
            // indexed, but no tagName (element) or alert (window),
 
2432
            // or functions without apply/call (Safari
 
2433
            // HTMLElementCollection bug).
 
2434
            if ('length' in obj && !obj.tagName && !obj.alert && !obj.apply) {
 
2435
                result = 2;
 
2436
            }
 
2437
        } catch (ex) {}
 
2438
    }
 
2439
 
 
2440
    return result;
 
2441
};
 
2442
/**
 
2443
 * The YUI module contains the components required for building the YUI
 
2444
 * seed file.  This includes the script loading mechanism, a simple queue,
 
2445
 * and the core utilities for the library.
 
2446
 * @module yui
 
2447
 * @submodule yui-base
 
2448
 */
 
2449
 
 
2450
/**
 
2451
 * A simple FIFO queue.  Items are added to the Queue with add(1..n items) and
 
2452
 * removed using next().
 
2453
 *
 
2454
 * @class Queue
 
2455
 * @constructor
 
2456
 * @param {MIXED} item* 0..n items to seed the queue.
 
2457
 */
 
2458
function Queue() {
 
2459
    this._init();
 
2460
    this.add.apply(this, arguments);
 
2461
}
 
2462
 
 
2463
Queue.prototype = {
 
2464
    /**
 
2465
     * Initialize the queue
 
2466
     *
 
2467
     * @method _init
 
2468
     * @protected
 
2469
     */
 
2470
    _init: function() {
 
2471
        /**
 
2472
         * The collection of enqueued items
 
2473
         *
 
2474
         * @property _q
 
2475
         * @type Array
 
2476
         * @protected
 
2477
         */
 
2478
        this._q = [];
 
2479
    },
 
2480
 
 
2481
    /**
 
2482
     * Get the next item in the queue. FIFO support
 
2483
     *
 
2484
     * @method next
 
2485
     * @return {MIXED} the next item in the queue.
 
2486
     */
 
2487
    next: function() {
 
2488
        return this._q.shift();
 
2489
    },
 
2490
 
 
2491
    /**
 
2492
     * Get the last in the queue. LIFO support.
 
2493
     *
 
2494
     * @method last
 
2495
     * @return {MIXED} the last item in the queue.
 
2496
     */
 
2497
    last: function() {
 
2498
        return this._q.pop();
 
2499
    },
 
2500
 
 
2501
    /**
 
2502
     * Add 0..n items to the end of the queue.
 
2503
     *
 
2504
     * @method add
 
2505
     * @param {MIXED} item* 0..n items.
 
2506
     * @return {object} this queue.
 
2507
     */
 
2508
    add: function() {
 
2509
        this._q.push.apply(this._q, arguments);
 
2510
 
 
2511
        return this;
 
2512
    },
 
2513
 
 
2514
    /**
 
2515
     * Returns the current number of queued items.
 
2516
     *
 
2517
     * @method size
 
2518
     * @return {Number} The size.
 
2519
     */
 
2520
    size: function() {
 
2521
        return this._q.length;
 
2522
    }
 
2523
};
 
2524
 
 
2525
Y.Queue = Queue;
 
2526
 
 
2527
YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
 
2528
 
 
2529
/**
 
2530
The YUI module contains the components required for building the YUI seed file.
 
2531
This includes the script loading mechanism, a simple queue, and the core
 
2532
utilities for the library.
 
2533
 
 
2534
@module yui
 
2535
@submodule yui-base
 
2536
**/
 
2537
 
 
2538
var CACHED_DELIMITER = '__',
 
2539
 
 
2540
    hasOwn   = Object.prototype.hasOwnProperty,
 
2541
    isObject = Y.Lang.isObject;
 
2542
 
 
2543
/**
 
2544
Returns a wrapper for a function which caches the return value of that function,
 
2545
keyed off of the combined string representation of the argument values provided
 
2546
when the wrapper is called.
 
2547
 
 
2548
Calling this function again with the same arguments will return the cached value
 
2549
rather than executing the wrapped function.
 
2550
 
 
2551
Note that since the cache is keyed off of the string representation of arguments
 
2552
passed to the wrapper function, arguments that aren't strings and don't provide
 
2553
a meaningful `toString()` method may result in unexpected caching behavior. For
 
2554
example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
 
2555
string `[object Object]` when used as a cache key.
 
2556
 
 
2557
@method cached
 
2558
@param {Function} source The function to memoize.
 
2559
@param {Object} [cache={}] Object in which to store cached values. You may seed
 
2560
  this object with pre-existing cached values if desired.
 
2561
@param {any} [refetch] If supplied, this value is compared with the cached value
 
2562
  using a `==` comparison. If the values are equal, the wrapped function is
 
2563
  executed again even though a cached value exists.
 
2564
@return {Function} Wrapped function.
 
2565
@for YUI
 
2566
**/
 
2567
Y.cached = function (source, cache, refetch) {
 
2568
    cache || (cache = {});
 
2569
 
 
2570
    return function (arg) {
 
2571
        var key = arguments.length > 1 ?
 
2572
                Array.prototype.join.call(arguments, CACHED_DELIMITER) :
 
2573
                String(arg);
 
2574
 
 
2575
        if (!(key in cache) || (refetch && cache[key] == refetch)) {
 
2576
            cache[key] = source.apply(source, arguments);
 
2577
        }
 
2578
 
 
2579
        return cache[key];
 
2580
    };
 
2581
};
 
2582
 
 
2583
/**
 
2584
Returns the `location` object from the window/frame in which this YUI instance
 
2585
operates, or `undefined` when executing in a non-browser environment
 
2586
(e.g. Node.js).
 
2587
 
 
2588
It is _not_ recommended to hold references to the `window.location` object
 
2589
outside of the scope of a function in which its properties are being accessed or
 
2590
its methods are being called. This is because of a nasty bug/issue that exists
 
2591
in both Safari and MobileSafari browsers:
 
2592
[WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679).
 
2593
 
 
2594
@method getLocation
 
2595
@return {location} The `location` object from the window/frame in which this YUI
 
2596
    instance operates.
 
2597
@since 3.5.0
 
2598
**/
 
2599
Y.getLocation = function () {
 
2600
    // It is safer to look this up every time because yui-base is attached to a
 
2601
    // YUI instance before a user's config is applied; i.e. `Y.config.win` does
 
2602
    // not point the correct window object when this file is loaded.
 
2603
    var win = Y.config.win;
 
2604
 
 
2605
    // It is not safe to hold a reference to the `location` object outside the
 
2606
    // scope in which it is being used. The WebKit engine used in Safari and
 
2607
    // MobileSafari will "disconnect" the `location` object from the `window`
 
2608
    // when a page is restored from back/forward history cache.
 
2609
    return win && win.location;
 
2610
};
 
2611
 
 
2612
/**
 
2613
Returns a new object containing all of the properties of all the supplied
 
2614
objects. The properties from later objects will overwrite those in earlier
 
2615
objects.
 
2616
 
 
2617
Passing in a single object will create a shallow copy of it. For a deep copy,
 
2618
use `clone()`.
 
2619
 
 
2620
@method merge
 
2621
@param {Object} objects* One or more objects to merge.
 
2622
@return {Object} A new merged object.
 
2623
**/
 
2624
Y.merge = function () {
 
2625
    var args   = arguments,
 
2626
        i      = 0,
 
2627
        len    = args.length,
 
2628
        result = {};
 
2629
 
 
2630
    for (; i < len; ++i) {
 
2631
        Y.mix(result, args[i], true);
 
2632
    }
 
2633
 
 
2634
    return result;
 
2635
};
 
2636
 
 
2637
/**
 
2638
Mixes _supplier_'s properties into _receiver_.
 
2639
 
 
2640
Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
 
2641
shadowed unless the _overwrite_ parameter is `true`, and will not be merged
 
2642
unless the _merge_ parameter is `true`.
 
2643
 
 
2644
In the default mode (0), only properties the supplier owns are copied (prototype
 
2645
properties are not copied). The following copying modes are available:
 
2646
 
 
2647
  * `0`: _Default_. Object to object.
 
2648
  * `1`: Prototype to prototype.
 
2649
  * `2`: Prototype to prototype and object to object.
 
2650
  * `3`: Prototype to object.
 
2651
  * `4`: Object to prototype.
 
2652
 
 
2653
@method mix
 
2654
@param {Function|Object} receiver The object or function to receive the mixed
 
2655
  properties.
 
2656
@param {Function|Object} supplier The object or function supplying the
 
2657
  properties to be mixed.
 
2658
@param {Boolean} [overwrite=false] If `true`, properties that already exist
 
2659
  on the receiver will be overwritten with properties from the supplier.
 
2660
@param {String[]} [whitelist] An array of property names to copy. If
 
2661
  specified, only the whitelisted properties will be copied, and all others
 
2662
  will be ignored.
 
2663
@param {Number} [mode=0] Mix mode to use. See above for available modes.
 
2664
@param {Boolean} [merge=false] If `true`, objects and arrays that already
 
2665
  exist on the receiver will have the corresponding object/array from the
 
2666
  supplier merged into them, rather than being skipped or overwritten. When
 
2667
  both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
 
2668
@return {Function|Object|YUI} The receiver, or the YUI instance if the
 
2669
  specified receiver is falsy.
 
2670
**/
 
2671
Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
 
2672
    var alwaysOverwrite, exists, from, i, key, len, to;
 
2673
 
 
2674
    // If no supplier is given, we return the receiver. If no receiver is given,
 
2675
    // we return Y. Returning Y doesn't make much sense to me, but it's
 
2676
    // grandfathered in for backcompat reasons.
 
2677
    if (!receiver || !supplier) {
 
2678
        return receiver || Y;
 
2679
    }
 
2680
 
 
2681
    if (mode) {
 
2682
        // In mode 2 (prototype to prototype and object to object), we recurse
 
2683
        // once to do the proto to proto mix. The object to object mix will be
 
2684
        // handled later on.
 
2685
        if (mode === 2) {
 
2686
            Y.mix(receiver.prototype, supplier.prototype, overwrite,
 
2687
                    whitelist, 0, merge);
 
2688
        }
 
2689
 
 
2690
        // Depending on which mode is specified, we may be copying from or to
 
2691
        // the prototypes of the supplier and receiver.
 
2692
        from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
 
2693
        to   = mode === 1 || mode === 4 ? receiver.prototype : receiver;
 
2694
 
 
2695
        // If either the supplier or receiver doesn't actually have a
 
2696
        // prototype property, then we could end up with an undefined `from`
 
2697
        // or `to`. If that happens, we abort and return the receiver.
 
2698
        if (!from || !to) {
 
2699
            return receiver;
 
2700
        }
 
2701
    } else {
 
2702
        from = supplier;
 
2703
        to   = receiver;
 
2704
    }
 
2705
 
 
2706
    // If `overwrite` is truthy and `merge` is falsy, then we can skip a
 
2707
    // property existence check on each iteration and save some time.
 
2708
    alwaysOverwrite = overwrite && !merge;
 
2709
 
 
2710
    if (whitelist) {
 
2711
        for (i = 0, len = whitelist.length; i < len; ++i) {
 
2712
            key = whitelist[i];
 
2713
 
 
2714
            // We call `Object.prototype.hasOwnProperty` instead of calling
 
2715
            // `hasOwnProperty` on the object itself, since the object's
 
2716
            // `hasOwnProperty` method may have been overridden or removed.
 
2717
            // Also, some native objects don't implement a `hasOwnProperty`
 
2718
            // method.
 
2719
            if (!hasOwn.call(from, key)) {
 
2720
                continue;
 
2721
            }
 
2722
 
 
2723
            // The `key in to` check here is (sadly) intentional for backwards
 
2724
            // compatibility reasons. It prevents undesired shadowing of
 
2725
            // prototype members on `to`.
 
2726
            exists = alwaysOverwrite ? false : key in to;
 
2727
 
 
2728
            if (merge && exists && isObject(to[key], true)
 
2729
                    && isObject(from[key], true)) {
 
2730
                // If we're in merge mode, and the key is present on both
 
2731
                // objects, and the value on both objects is either an object or
 
2732
                // an array (but not a function), then we recurse to merge the
 
2733
                // `from` value into the `to` value instead of overwriting it.
 
2734
                //
 
2735
                // Note: It's intentional that the whitelist isn't passed to the
 
2736
                // recursive call here. This is legacy behavior that lots of
 
2737
                // code still depends on.
 
2738
                Y.mix(to[key], from[key], overwrite, null, 0, merge);
 
2739
            } else if (overwrite || !exists) {
 
2740
                // We're not in merge mode, so we'll only copy the `from` value
 
2741
                // to the `to` value if we're in overwrite mode or if the
 
2742
                // current key doesn't exist on the `to` object.
 
2743
                to[key] = from[key];
 
2744
            }
 
2745
        }
 
2746
    } else {
 
2747
        for (key in from) {
 
2748
            // The code duplication here is for runtime performance reasons.
 
2749
            // Combining whitelist and non-whitelist operations into a single
 
2750
            // loop or breaking the shared logic out into a function both result
 
2751
            // in worse performance, and Y.mix is critical enough that the byte
 
2752
            // tradeoff is worth it.
 
2753
            if (!hasOwn.call(from, key)) {
 
2754
                continue;
 
2755
            }
 
2756
 
 
2757
            // The `key in to` check here is (sadly) intentional for backwards
 
2758
            // compatibility reasons. It prevents undesired shadowing of
 
2759
            // prototype members on `to`.
 
2760
            exists = alwaysOverwrite ? false : key in to;
 
2761
 
 
2762
            if (merge && exists && isObject(to[key], true)
 
2763
                    && isObject(from[key], true)) {
 
2764
                Y.mix(to[key], from[key], overwrite, null, 0, merge);
 
2765
            } else if (overwrite || !exists) {
 
2766
                to[key] = from[key];
 
2767
            }
 
2768
        }
 
2769
 
 
2770
        // If this is an IE browser with the JScript enumeration bug, force
 
2771
        // enumeration of the buggy properties by making a recursive call with
 
2772
        // the buggy properties as the whitelist.
 
2773
        if (Y.Object._hasEnumBug) {
 
2774
            Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
 
2775
        }
 
2776
    }
 
2777
 
 
2778
    return receiver;
 
2779
};
 
2780
/**
 
2781
 * The YUI module contains the components required for building the YUI
 
2782
 * seed file.  This includes the script loading mechanism, a simple queue,
 
2783
 * and the core utilities for the library.
 
2784
 * @module yui
 
2785
 * @submodule yui-base
 
2786
 */
 
2787
 
 
2788
/**
 
2789
 * Adds utilities to the YUI instance for working with objects.
 
2790
 *
 
2791
 * @class Object
 
2792
 */
 
2793
 
 
2794
var Lang   = Y.Lang,
 
2795
    hasOwn = Object.prototype.hasOwnProperty,
 
2796
 
 
2797
    UNDEFINED, // <-- Note the comma. We're still declaring vars.
 
2798
 
 
2799
/**
 
2800
 * Returns a new object that uses _obj_ as its prototype. This method wraps the
 
2801
 * native ES5 `Object.create()` method if available, but doesn't currently
 
2802
 * pass through `Object.create()`'s second argument (properties) in order to
 
2803
 * ensure compatibility with older browsers.
 
2804
 *
 
2805
 * @method ()
 
2806
 * @param {Object} obj Prototype object.
 
2807
 * @return {Object} New object using _obj_ as its prototype.
 
2808
 * @static
 
2809
 */
 
2810
O = Y.Object = Lang._isNative(Object.create) ? function (obj) {
 
2811
    // We currently wrap the native Object.create instead of simply aliasing it
 
2812
    // to ensure consistency with our fallback shim, which currently doesn't
 
2813
    // support Object.create()'s second argument (properties). Once we have a
 
2814
    // safe fallback for the properties arg, we can stop wrapping
 
2815
    // Object.create().
 
2816
    return Object.create(obj);
 
2817
} : (function () {
 
2818
    // Reusable constructor function for the Object.create() shim.
 
2819
    function F() {}
 
2820
 
 
2821
    // The actual shim.
 
2822
    return function (obj) {
 
2823
        F.prototype = obj;
 
2824
        return new F();
 
2825
    };
 
2826
}()),
 
2827
 
 
2828
/**
 
2829
 * Property names that IE doesn't enumerate in for..in loops, even when they
 
2830
 * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
 
2831
 * manually enumerate these properties.
 
2832
 *
 
2833
 * @property _forceEnum
 
2834
 * @type String[]
 
2835
 * @protected
 
2836
 * @static
 
2837
 */
 
2838
forceEnum = O._forceEnum = [
 
2839
    'hasOwnProperty',
 
2840
    'isPrototypeOf',
 
2841
    'propertyIsEnumerable',
 
2842
    'toString',
 
2843
    'toLocaleString',
 
2844
    'valueOf'
 
2845
],
 
2846
 
 
2847
/**
 
2848
 * `true` if this browser has the JScript enumeration bug that prevents
 
2849
 * enumeration of the properties named in the `_forceEnum` array, `false`
 
2850
 * otherwise.
 
2851
 *
 
2852
 * See:
 
2853
 *   - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
 
2854
 *   - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
 
2855
 *
 
2856
 * @property _hasEnumBug
 
2857
 * @type Boolean
 
2858
 * @protected
 
2859
 * @static
 
2860
 */
 
2861
hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
 
2862
 
 
2863
/**
 
2864
 * `true` if this browser incorrectly considers the `prototype` property of
 
2865
 * functions to be enumerable. Currently known to affect Opera 11.50.
 
2866
 *
 
2867
 * @property _hasProtoEnumBug
 
2868
 * @type Boolean
 
2869
 * @protected
 
2870
 * @static
 
2871
 */
 
2872
hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
 
2873
 
 
2874
/**
 
2875
 * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
 
2876
 * exists only on _obj_'s prototype. This is essentially a safer version of
 
2877
 * `obj.hasOwnProperty()`.
 
2878
 *
 
2879
 * @method owns
 
2880
 * @param {Object} obj Object to test.
 
2881
 * @param {String} key Property name to look for.
 
2882
 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
 
2883
 * @static
 
2884
 */
 
2885
owns = O.owns = function (obj, key) {
 
2886
    return !!obj && hasOwn.call(obj, key);
 
2887
}; // <-- End of var declarations.
 
2888
 
 
2889
/**
 
2890
 * Alias for `owns()`.
 
2891
 *
 
2892
 * @method hasKey
 
2893
 * @param {Object} obj Object to test.
 
2894
 * @param {String} key Property name to look for.
 
2895
 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
 
2896
 * @static
 
2897
 */
 
2898
O.hasKey = owns;
 
2899
 
 
2900
/**
 
2901
 * Returns an array containing the object's enumerable keys. Does not include
 
2902
 * prototype keys or non-enumerable keys.
 
2903
 *
 
2904
 * Note that keys are returned in enumeration order (that is, in the same order
 
2905
 * that they would be enumerated by a `for-in` loop), which may not be the same
 
2906
 * as the order in which they were defined.
 
2907
 *
 
2908
 * This method is an alias for the native ES5 `Object.keys()` method if
 
2909
 * available.
 
2910
 *
 
2911
 * @example
 
2912
 *
 
2913
 *     Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
 
2914
 *     // => ['a', 'b', 'c']
 
2915
 *
 
2916
 * @method keys
 
2917
 * @param {Object} obj An object.
 
2918
 * @return {String[]} Array of keys.
 
2919
 * @static
 
2920
 */
 
2921
O.keys = Lang._isNative(Object.keys) ? Object.keys : function (obj) {
 
2922
    if (!Lang.isObject(obj)) {
 
2923
        throw new TypeError('Object.keys called on a non-object');
 
2924
    }
 
2925
 
 
2926
    var keys = [],
 
2927
        i, key, len;
 
2928
 
 
2929
    if (hasProtoEnumBug && typeof obj === 'function') {
 
2930
        for (key in obj) {
 
2931
            if (owns(obj, key) && key !== 'prototype') {
 
2932
                keys.push(key);
 
2933
            }
 
2934
        }
 
2935
    } else {
 
2936
        for (key in obj) {
 
2937
            if (owns(obj, key)) {
 
2938
                keys.push(key);
 
2939
            }
 
2940
        }
 
2941
    }
 
2942
 
 
2943
    if (hasEnumBug) {
 
2944
        for (i = 0, len = forceEnum.length; i < len; ++i) {
 
2945
            key = forceEnum[i];
 
2946
 
 
2947
            if (owns(obj, key)) {
 
2948
                keys.push(key);
 
2949
            }
 
2950
        }
 
2951
    }
 
2952
 
 
2953
    return keys;
 
2954
};
 
2955
 
 
2956
/**
 
2957
 * Returns an array containing the values of the object's enumerable keys.
 
2958
 *
 
2959
 * Note that values are returned in enumeration order (that is, in the same
 
2960
 * order that they would be enumerated by a `for-in` loop), which may not be the
 
2961
 * same as the order in which they were defined.
 
2962
 *
 
2963
 * @example
 
2964
 *
 
2965
 *     Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
 
2966
 *     // => ['foo', 'bar', 'baz']
 
2967
 *
 
2968
 * @method values
 
2969
 * @param {Object} obj An object.
 
2970
 * @return {Array} Array of values.
 
2971
 * @static
 
2972
 */
 
2973
O.values = function (obj) {
 
2974
    var keys   = O.keys(obj),
 
2975
        i      = 0,
 
2976
        len    = keys.length,
 
2977
        values = [];
 
2978
 
 
2979
    for (; i < len; ++i) {
 
2980
        values.push(obj[keys[i]]);
 
2981
    }
 
2982
 
 
2983
    return values;
 
2984
};
 
2985
 
 
2986
/**
 
2987
 * Returns the number of enumerable keys owned by an object.
 
2988
 *
 
2989
 * @method size
 
2990
 * @param {Object} obj An object.
 
2991
 * @return {Number} The object's size.
 
2992
 * @static
 
2993
 */
 
2994
O.size = function (obj) {
 
2995
    try {
 
2996
        return O.keys(obj).length;
 
2997
    } catch (ex) {
 
2998
        return 0; // Legacy behavior for non-objects.
 
2999
    }
 
3000
};
 
3001
 
 
3002
/**
 
3003
 * Returns `true` if the object owns an enumerable property with the specified
 
3004
 * value.
 
3005
 *
 
3006
 * @method hasValue
 
3007
 * @param {Object} obj An object.
 
3008
 * @param {any} value The value to search for.
 
3009
 * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
 
3010
 * @static
 
3011
 */
 
3012
O.hasValue = function (obj, value) {
 
3013
    return Y.Array.indexOf(O.values(obj), value) > -1;
 
3014
};
 
3015
 
 
3016
/**
 
3017
 * Executes a function on each enumerable property in _obj_. The function
 
3018
 * receives the value, the key, and the object itself as parameters (in that
 
3019
 * order).
 
3020
 *
 
3021
 * By default, only properties owned by _obj_ are enumerated. To include
 
3022
 * prototype properties, set the _proto_ parameter to `true`.
 
3023
 *
 
3024
 * @method each
 
3025
 * @param {Object} obj Object to enumerate.
 
3026
 * @param {Function} fn Function to execute on each enumerable property.
 
3027
 *   @param {mixed} fn.value Value of the current property.
 
3028
 *   @param {String} fn.key Key of the current property.
 
3029
 *   @param {Object} fn.obj Object being enumerated.
 
3030
 * @param {Object} [thisObj] `this` object to use when calling _fn_.
 
3031
 * @param {Boolean} [proto=false] Include prototype properties.
 
3032
 * @return {YUI} the YUI instance.
 
3033
 * @chainable
 
3034
 * @static
 
3035
 */
 
3036
O.each = function (obj, fn, thisObj, proto) {
 
3037
    var key;
 
3038
 
 
3039
    for (key in obj) {
 
3040
        if (proto || owns(obj, key)) {
 
3041
            fn.call(thisObj || Y, obj[key], key, obj);
 
3042
        }
 
3043
    }
 
3044
 
 
3045
    return Y;
 
3046
};
 
3047
 
 
3048
/**
 
3049
 * Executes a function on each enumerable property in _obj_, but halts if the
 
3050
 * function returns a truthy value. The function receives the value, the key,
 
3051
 * and the object itself as paramters (in that order).
 
3052
 *
 
3053
 * By default, only properties owned by _obj_ are enumerated. To include
 
3054
 * prototype properties, set the _proto_ parameter to `true`.
 
3055
 *
 
3056
 * @method some
 
3057
 * @param {Object} obj Object to enumerate.
 
3058
 * @param {Function} fn Function to execute on each enumerable property.
 
3059
 *   @param {mixed} fn.value Value of the current property.
 
3060
 *   @param {String} fn.key Key of the current property.
 
3061
 *   @param {Object} fn.obj Object being enumerated.
 
3062
 * @param {Object} [thisObj] `this` object to use when calling _fn_.
 
3063
 * @param {Boolean} [proto=false] Include prototype properties.
 
3064
 * @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
 
3065
 *   `false` otherwise.
 
3066
 * @static
 
3067
 */
 
3068
O.some = function (obj, fn, thisObj, proto) {
 
3069
    var key;
 
3070
 
 
3071
    for (key in obj) {
 
3072
        if (proto || owns(obj, key)) {
 
3073
            if (fn.call(thisObj || Y, obj[key], key, obj)) {
 
3074
                return true;
 
3075
            }
 
3076
        }
 
3077
    }
 
3078
 
 
3079
    return false;
 
3080
};
 
3081
 
 
3082
/**
 
3083
 * Retrieves the sub value at the provided path,
 
3084
 * from the value object provided.
 
3085
 *
 
3086
 * @method getValue
 
3087
 * @static
 
3088
 * @param o The object from which to extract the property value.
 
3089
 * @param path {Array} A path array, specifying the object traversal path
 
3090
 * from which to obtain the sub value.
 
3091
 * @return {Any} The value stored in the path, undefined if not found,
 
3092
 * undefined if the source is not an object.  Returns the source object
 
3093
 * if an empty path is provided.
 
3094
 */
 
3095
O.getValue = function(o, path) {
 
3096
    if (!Lang.isObject(o)) {
 
3097
        return UNDEFINED;
 
3098
    }
 
3099
 
 
3100
    var i,
 
3101
        p = Y.Array(path),
 
3102
        l = p.length;
 
3103
 
 
3104
    for (i = 0; o !== UNDEFINED && i < l; i++) {
 
3105
        o = o[p[i]];
 
3106
    }
 
3107
 
 
3108
    return o;
 
3109
};
 
3110
 
 
3111
/**
 
3112
 * Sets the sub-attribute value at the provided path on the
 
3113
 * value object.  Returns the modified value object, or
 
3114
 * undefined if the path is invalid.
 
3115
 *
 
3116
 * @method setValue
 
3117
 * @static
 
3118
 * @param o             The object on which to set the sub value.
 
3119
 * @param path {Array}  A path array, specifying the object traversal path
 
3120
 *                      at which to set the sub value.
 
3121
 * @param val {Any}     The new value for the sub-attribute.
 
3122
 * @return {Object}     The modified object, with the new sub value set, or
 
3123
 *                      undefined, if the path was invalid.
 
3124
 */
 
3125
O.setValue = function(o, path, val) {
 
3126
    var i,
 
3127
        p = Y.Array(path),
 
3128
        leafIdx = p.length - 1,
 
3129
        ref = o;
 
3130
 
 
3131
    if (leafIdx >= 0) {
 
3132
        for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
 
3133
            ref = ref[p[i]];
 
3134
        }
 
3135
 
 
3136
        if (ref !== UNDEFINED) {
 
3137
            ref[p[i]] = val;
 
3138
        } else {
 
3139
            return UNDEFINED;
 
3140
        }
 
3141
    }
 
3142
 
 
3143
    return o;
 
3144
};
 
3145
 
 
3146
/**
 
3147
 * Returns `true` if the object has no enumerable properties of its own.
 
3148
 *
 
3149
 * @method isEmpty
 
3150
 * @param {Object} obj An object.
 
3151
 * @return {Boolean} `true` if the object is empty.
 
3152
 * @static
 
3153
 * @since 3.2.0
 
3154
 */
 
3155
O.isEmpty = function (obj) {
 
3156
    return !O.keys(Object(obj)).length;
 
3157
};
 
3158
/**
 
3159
 * The YUI module contains the components required for building the YUI seed
 
3160
 * file.  This includes the script loading mechanism, a simple queue, and the
 
3161
 * core utilities for the library.
 
3162
 * @module yui
 
3163
 * @submodule yui-base
 
3164
 */
 
3165
 
 
3166
/**
 
3167
 * YUI user agent detection.
 
3168
 * Do not fork for a browser if it can be avoided.  Use feature detection when
 
3169
 * you can.  Use the user agent as a last resort.  For all fields listed
 
3170
 * as @type float, UA stores a version number for the browser engine,
 
3171
 * 0 otherwise.  This value may or may not map to the version number of
 
3172
 * the browser using the engine.  The value is presented as a float so
 
3173
 * that it can easily be used for boolean evaluation as well as for
 
3174
 * looking for a particular range of versions.  Because of this,
 
3175
 * some of the granularity of the version info may be lost.  The fields that
 
3176
 * are @type string default to null.  The API docs list the values that
 
3177
 * these fields can have.
 
3178
 * @class UA
 
3179
 * @static
 
3180
 */
 
3181
 
 
3182
/**
 
3183
* Static method on `YUI.Env` for parsing a UA string.  Called at instantiation
 
3184
* to populate `Y.UA`.
 
3185
*
 
3186
* @static
 
3187
* @method parseUA
 
3188
* @param {String} [subUA=navigator.userAgent] UA string to parse
 
3189
* @return {Object} The Y.UA object
 
3190
*/
 
3191
YUI.Env.parseUA = function(subUA) {
 
3192
 
 
3193
    var numberify = function(s) {
 
3194
            var c = 0;
 
3195
            return parseFloat(s.replace(/\./g, function() {
 
3196
                return (c++ == 1) ? '' : '.';
 
3197
            }));
 
3198
        },
 
3199
 
 
3200
        win = Y.config.win,
 
3201
 
 
3202
        nav = win && win.navigator,
 
3203
 
 
3204
        o = {
 
3205
 
 
3206
        /**
 
3207
         * Internet Explorer version number or 0.  Example: 6
 
3208
         * @property ie
 
3209
         * @type float
 
3210
         * @static
 
3211
         */
 
3212
        ie: 0,
 
3213
 
 
3214
        /**
 
3215
         * Opera version number or 0.  Example: 9.2
 
3216
         * @property opera
 
3217
         * @type float
 
3218
         * @static
 
3219
         */
 
3220
        opera: 0,
 
3221
 
 
3222
        /**
 
3223
         * Gecko engine revision number.  Will evaluate to 1 if Gecko
 
3224
         * is detected but the revision could not be found. Other browsers
 
3225
         * will be 0.  Example: 1.8
 
3226
         * <pre>
 
3227
         * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
 
3228
         * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
 
3229
         * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
 
3230
         * Firefox 3.0   <-- 1.9
 
3231
         * Firefox 3.5   <-- 1.91
 
3232
         * </pre>
 
3233
         * @property gecko
 
3234
         * @type float
 
3235
         * @static
 
3236
         */
 
3237
        gecko: 0,
 
3238
 
 
3239
        /**
 
3240
         * AppleWebKit version.  KHTML browsers that are not WebKit browsers
 
3241
         * will evaluate to 1, other browsers 0.  Example: 418.9
 
3242
         * <pre>
 
3243
         * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
 
3244
         *                                   latest available for Mac OSX 10.3.
 
3245
         * Safari 2.0.2:         416     <-- hasOwnProperty introduced
 
3246
         * Safari 2.0.4:         418     <-- preventDefault fixed
 
3247
         * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
 
3248
         *                                   different versions of webkit
 
3249
         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
 
3250
         *                                   updated, but not updated
 
3251
         *                                   to the latest patch.
 
3252
         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native
 
3253
         * SVG and many major issues fixed).
 
3254
         * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic
 
3255
         * update from 2.x via the 10.4.11 OS patch.
 
3256
         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
 
3257
         *                                   yahoo.com user agent hack removed.
 
3258
         * </pre>
 
3259
         * http://en.wikipedia.org/wiki/Safari_version_history
 
3260
         * @property webkit
 
3261
         * @type float
 
3262
         * @static
 
3263
         */
 
3264
        webkit: 0,
 
3265
 
 
3266
        /**
 
3267
         * Safari will be detected as webkit, but this property will also
 
3268
         * be populated with the Safari version number
 
3269
         * @property safari
 
3270
         * @type float
 
3271
         * @static
 
3272
         */
 
3273
        safari: 0,
 
3274
 
 
3275
        /**
 
3276
         * Chrome will be detected as webkit, but this property will also
 
3277
         * be populated with the Chrome version number
 
3278
         * @property chrome
 
3279
         * @type float
 
3280
         * @static
 
3281
         */
 
3282
        chrome: 0,
 
3283
 
 
3284
        /**
 
3285
         * The mobile property will be set to a string containing any relevant
 
3286
         * user agent information when a modern mobile browser is detected.
 
3287
         * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
 
3288
         * devices with the WebKit-based browser, and Opera Mini.
 
3289
         * @property mobile
 
3290
         * @type string
 
3291
         * @default null
 
3292
         * @static
 
3293
         */
 
3294
        mobile: null,
 
3295
 
 
3296
        /**
 
3297
         * Adobe AIR version number or 0.  Only populated if webkit is detected.
 
3298
         * Example: 1.0
 
3299
         * @property air
 
3300
         * @type float
 
3301
         */
 
3302
        air: 0,
 
3303
        /**
 
3304
         * Detects Apple iPad's OS version
 
3305
         * @property ipad
 
3306
         * @type float
 
3307
         * @static
 
3308
         */
 
3309
        ipad: 0,
 
3310
        /**
 
3311
         * Detects Apple iPhone's OS version
 
3312
         * @property iphone
 
3313
         * @type float
 
3314
         * @static
 
3315
         */
 
3316
        iphone: 0,
 
3317
        /**
 
3318
         * Detects Apples iPod's OS version
 
3319
         * @property ipod
 
3320
         * @type float
 
3321
         * @static
 
3322
         */
 
3323
        ipod: 0,
 
3324
        /**
 
3325
         * General truthy check for iPad, iPhone or iPod
 
3326
         * @property ios
 
3327
         * @type float
 
3328
         * @default null
 
3329
         * @static
 
3330
         */
 
3331
        ios: null,
 
3332
        /**
 
3333
         * Detects Googles Android OS version
 
3334
         * @property android
 
3335
         * @type float
 
3336
         * @static
 
3337
         */
 
3338
        android: 0,
 
3339
        /**
 
3340
         * Detects Kindle Silk
 
3341
         * @property silk
 
3342
         * @type float
 
3343
         * @static
 
3344
         */
 
3345
        silk: 0,
 
3346
        /**
 
3347
         * Detects Kindle Silk Acceleration
 
3348
         * @property accel
 
3349
         * @type Boolean
 
3350
         * @static
 
3351
         */
 
3352
        accel: false,
 
3353
        /**
 
3354
         * Detects Palms WebOS version
 
3355
         * @property webos
 
3356
         * @type float
 
3357
         * @static
 
3358
         */
 
3359
        webos: 0,
 
3360
 
 
3361
        /**
 
3362
         * Google Caja version number or 0.
 
3363
         * @property caja
 
3364
         * @type float
 
3365
         */
 
3366
        caja: nav && nav.cajaVersion,
 
3367
 
 
3368
        /**
 
3369
         * Set to true if the page appears to be in SSL
 
3370
         * @property secure
 
3371
         * @type boolean
 
3372
         * @static
 
3373
         */
 
3374
        secure: false,
 
3375
 
 
3376
        /**
 
3377
         * The operating system.  Currently only detecting windows or macintosh
 
3378
         * @property os
 
3379
         * @type string
 
3380
         * @default null
 
3381
         * @static
 
3382
         */
 
3383
        os: null,
 
3384
 
 
3385
        /**
 
3386
         * The Nodejs Version
 
3387
         * @property nodejs
 
3388
         * @type float
 
3389
         * @default 0
 
3390
         * @static
 
3391
         */
 
3392
        nodejs: 0
 
3393
    },
 
3394
 
 
3395
    ua = subUA || nav && nav.userAgent,
 
3396
 
 
3397
    loc = win && win.location,
 
3398
 
 
3399
    href = loc && loc.href,
 
3400
 
 
3401
    m;
 
3402
 
 
3403
    /**
 
3404
    * The User Agent string that was parsed
 
3405
    * @property userAgent
 
3406
    * @type String
 
3407
    * @static
 
3408
    */
 
3409
    o.userAgent = ua;
 
3410
 
 
3411
 
 
3412
    o.secure = href && (href.toLowerCase().indexOf('https') === 0);
 
3413
 
 
3414
    if (ua) {
 
3415
 
 
3416
        if ((/windows|win32/i).test(ua)) {
 
3417
            o.os = 'windows';
 
3418
        } else if ((/macintosh|mac_powerpc/i).test(ua)) {
 
3419
            o.os = 'macintosh';
 
3420
        } else if ((/android/i).test(ua)) {
 
3421
            o.os = 'android';
 
3422
        } else if ((/symbos/i).test(ua)) {
 
3423
            o.os = 'symbos';
 
3424
        } else if ((/linux/i).test(ua)) {
 
3425
            o.os = 'linux';
 
3426
        } else if ((/rhino/i).test(ua)) {
 
3427
            o.os = 'rhino';
 
3428
        }
 
3429
 
 
3430
        // Modern KHTML browsers should qualify as Safari X-Grade
 
3431
        if ((/KHTML/).test(ua)) {
 
3432
            o.webkit = 1;
 
3433
        }
 
3434
        if ((/IEMobile|XBLWP7/).test(ua)) {
 
3435
            o.mobile = 'windows';
 
3436
        }
 
3437
        if ((/Fennec/).test(ua)) {
 
3438
            o.mobile = 'gecko';
 
3439
        }
 
3440
        // Modern WebKit browsers are at least X-Grade
 
3441
        m = ua.match(/AppleWebKit\/([^\s]*)/);
 
3442
        if (m && m[1]) {
 
3443
            o.webkit = numberify(m[1]);
 
3444
            o.safari = o.webkit;
 
3445
 
 
3446
            // Mobile browser check
 
3447
            if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {
 
3448
                o.mobile = 'Apple'; // iPhone or iPod Touch
 
3449
 
 
3450
                m = ua.match(/OS ([^\s]*)/);
 
3451
                if (m && m[1]) {
 
3452
                    m = numberify(m[1].replace('_', '.'));
 
3453
                }
 
3454
                o.ios = m;
 
3455
                o.os = 'ios';
 
3456
                o.ipad = o.ipod = o.iphone = 0;
 
3457
 
 
3458
                m = ua.match(/iPad|iPod|iPhone/);
 
3459
                if (m && m[0]) {
 
3460
                    o[m[0].toLowerCase()] = o.ios;
 
3461
                }
 
3462
            } else {
 
3463
                m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
 
3464
                if (m) {
 
3465
                    // Nokia N-series, webOS, ex: NokiaN95
 
3466
                    o.mobile = m[0];
 
3467
                }
 
3468
                if (/webOS/.test(ua)) {
 
3469
                    o.mobile = 'WebOS';
 
3470
                    m = ua.match(/webOS\/([^\s]*);/);
 
3471
                    if (m && m[1]) {
 
3472
                        o.webos = numberify(m[1]);
 
3473
                    }
 
3474
                }
 
3475
                if (/ Android/.test(ua)) {
 
3476
                    if (/Mobile/.test(ua)) {
 
3477
                        o.mobile = 'Android';
 
3478
                    }
 
3479
                    m = ua.match(/Android ([^\s]*);/);
 
3480
                    if (m && m[1]) {
 
3481
                        o.android = numberify(m[1]);
 
3482
                    }
 
3483
 
 
3484
                }
 
3485
                if (/Silk/.test(ua)) {
 
3486
                    m = ua.match(/Silk\/([^\s]*)\)/);
 
3487
                    if (m && m[1]) {
 
3488
                        o.silk = numberify(m[1]);
 
3489
                    }
 
3490
                    if (!o.android) {
 
3491
                        o.android = 2.34; //Hack for desktop mode in Kindle
 
3492
                        o.os = 'Android';
 
3493
                    }
 
3494
                    if (/Accelerated=true/.test(ua)) {
 
3495
                        o.accel = true;
 
3496
                    }
 
3497
                }
 
3498
            }
 
3499
 
 
3500
            m = ua.match(/(Chrome|CrMo)\/([^\s]*)/);
 
3501
            if (m && m[1] && m[2]) {
 
3502
                o.chrome = numberify(m[2]); // Chrome
 
3503
                o.safari = 0; //Reset safari back to 0
 
3504
                if (m[1] === 'CrMo') {
 
3505
                    o.mobile = 'chrome';
 
3506
                }
 
3507
            } else {
 
3508
                m = ua.match(/AdobeAIR\/([^\s]*)/);
 
3509
                if (m) {
 
3510
                    o.air = m[0]; // Adobe AIR 1.0 or better
 
3511
                }
 
3512
            }
 
3513
        }
 
3514
 
 
3515
        if (!o.webkit) { // not webkit
 
3516
// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
 
3517
            if (/Opera/.test(ua)) {
 
3518
                m = ua.match(/Opera[\s\/]([^\s]*)/);
 
3519
                if (m && m[1]) {
 
3520
                    o.opera = numberify(m[1]);
 
3521
                }
 
3522
                m = ua.match(/Version\/([^\s]*)/);
 
3523
                if (m && m[1]) {
 
3524
                    o.opera = numberify(m[1]); // opera 10+
 
3525
                }
 
3526
 
 
3527
                if (/Opera Mobi/.test(ua)) {
 
3528
                    o.mobile = 'opera';
 
3529
                    m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);
 
3530
                    if (m && m[1]) {
 
3531
                        o.opera = numberify(m[1]);
 
3532
                    }
 
3533
                }
 
3534
                m = ua.match(/Opera Mini[^;]*/);
 
3535
 
 
3536
                if (m) {
 
3537
                    o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
 
3538
                }
 
3539
            } else { // not opera or webkit
 
3540
                m = ua.match(/MSIE\s([^;]*)/);
 
3541
                if (m && m[1]) {
 
3542
                    o.ie = numberify(m[1]);
 
3543
                } else { // not opera, webkit, or ie
 
3544
                    m = ua.match(/Gecko\/([^\s]*)/);
 
3545
                    if (m) {
 
3546
                        o.gecko = 1; // Gecko detected, look for revision
 
3547
                        m = ua.match(/rv:([^\s\)]*)/);
 
3548
                        if (m && m[1]) {
 
3549
                            o.gecko = numberify(m[1]);
 
3550
                        }
 
3551
                    }
 
3552
                }
 
3553
            }
 
3554
        }
 
3555
    }
 
3556
 
 
3557
    //It was a parsed UA, do not assign the global value.
 
3558
    if (!subUA) {
 
3559
 
 
3560
        if (typeof process == 'object') {
 
3561
 
 
3562
            if (process.versions && process.versions.node) {
 
3563
                //NodeJS
 
3564
                o.os = process.platform;
 
3565
                o.nodejs = process.versions.node;
 
3566
            }
 
3567
        }
 
3568
 
 
3569
        YUI.Env.UA = o;
 
3570
 
 
3571
    }
 
3572
 
 
3573
    return o;
 
3574
};
 
3575
 
 
3576
 
 
3577
Y.UA = YUI.Env.UA || YUI.Env.parseUA();
 
3578
 
 
3579
/**
 
3580
Performs a simple comparison between two version numbers, accounting for
 
3581
standard versioning logic such as the fact that "535.8" is a lower version than
 
3582
"535.24", even though a simple numerical comparison would indicate that it's
 
3583
greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are
 
3584
considered equivalent.
 
3585
 
 
3586
Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent,
 
3587
1 if _a_ is higher than _b_.
 
3588
 
 
3589
Versions may be numbers or strings containing numbers and dots. For example,
 
3590
both `535` and `"535.8.10"` are acceptable. A version string containing
 
3591
non-numeric characters, like `"535.8.beta"`, may produce unexpected results.
 
3592
 
 
3593
@method compareVersions
 
3594
@param {Number|String} a First version number to compare.
 
3595
@param {Number|String} b Second version number to compare.
 
3596
@return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is
 
3597
    higher than _b_.
 
3598
**/
 
3599
Y.UA.compareVersions = function (a, b) {
 
3600
    var aPart, aParts, bPart, bParts, i, len;
 
3601
 
 
3602
    if (a === b) {
 
3603
        return 0;
 
3604
    }
 
3605
 
 
3606
    aParts = (a + '').split('.');
 
3607
    bParts = (b + '').split('.');
 
3608
 
 
3609
    for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {
 
3610
        aPart = parseInt(aParts[i], 10);
 
3611
        bPart = parseInt(bParts[i], 10);
 
3612
 
 
3613
        isNaN(aPart) && (aPart = 0);
 
3614
        isNaN(bPart) && (bPart = 0);
 
3615
 
 
3616
        if (aPart < bPart) {
 
3617
            return -1;
 
3618
        }
 
3619
 
 
3620
        if (aPart > bPart) {
 
3621
            return 1;
 
3622
        }
 
3623
    }
 
3624
 
 
3625
    return 0;
 
3626
};
 
3627
YUI.Env.aliases = {
 
3628
    "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
 
3629
    "app": ["app-base","app-transitions","model","model-list","router","view"],
 
3630
    "attribute": ["attribute-base","attribute-complex"],
 
3631
    "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
 
3632
    "base": ["base-base","base-pluginhost","base-build"],
 
3633
    "cache": ["cache-base","cache-offline","cache-plugin"],
 
3634
    "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
 
3635
    "controller": ["router"],
 
3636
    "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
 
3637
    "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
 
3638
    "datatable": ["datatable-core","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"],
 
3639
    "datatable-deprecated": ["datatable-base-deprecated","datatable-datasource-deprecated","datatable-sort-deprecated","datatable-scroll-deprecated"],
 
3640
    "datatype": ["datatype-number","datatype-date","datatype-xml"],
 
3641
    "datatype-date": ["datatype-date-parse","datatype-date-format"],
 
3642
    "datatype-number": ["datatype-number-parse","datatype-number-format"],
 
3643
    "datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
 
3644
    "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
 
3645
    "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
 
3646
    "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
 
3647
    "event": ["event-base","event-delegate","event-synthetic","event-mousewheel","event-mouseenter","event-key","event-focus","event-resize","event-hover","event-outside","event-touch","event-move","event-flick","event-valuechange"],
 
3648
    "event-custom": ["event-custom-base","event-custom-complex"],
 
3649
    "event-gestures": ["event-flick","event-move"],
 
3650
    "handlebars": ["handlebars-compiler"],
 
3651
    "highlight": ["highlight-base","highlight-accentfold"],
 
3652
    "history": ["history-base","history-hash","history-hash-ie","history-html5"],
 
3653
    "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
 
3654
    "json": ["json-parse","json-stringify"],
 
3655
    "loader": ["loader-base","loader-rollup","loader-yui3"],
 
3656
    "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
 
3657
    "pluginhost": ["pluginhost-base","pluginhost-config"],
 
3658
    "querystring": ["querystring-parse","querystring-stringify"],
 
3659
    "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
 
3660
    "resize": ["resize-base","resize-proxy","resize-constrain"],
 
3661
    "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
 
3662
    "text": ["text-accentfold","text-wordbreak"],
 
3663
    "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"]
 
3664
};
 
3665
 
 
3666
 
 
3667
}, '3.5.1' );