~ubuntu-branches/ubuntu/utopic/moodle/utopic

« back to all changes in this revision

Viewing changes to lib/yuilib/3.9.1/build/yui-base/yui-base.js

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2014-05-12 16:10:38 UTC
  • mfrom: (36.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20140512161038-puyqf65k4e0s8ytz
Tags: 2.6.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* YUI 3.9.1 (build 5852) Copyright 2013 Yahoo! Inc. http://yuilibrary.com/license/ */
2
 
/**
3
 
The YUI module contains the components required for building the YUI seed file.
4
 
This includes the script loading mechanism, a simple queue, and the core
5
 
utilities for the library.
6
 
 
7
 
@module yui
8
 
@main yui
9
 
@submodule yui-base
10
 
**/
11
 
 
12
 
/*jshint eqeqeq: false*/
13
 
if (typeof YUI != 'undefined') {
14
 
    YUI._YUI = YUI;
15
 
}
16
 
 
17
 
/**
18
 
The YUI global namespace object. This is the constructor for all YUI instances.
19
 
 
20
 
This is a self-instantiable factory function, meaning you don't need to precede
21
 
it with the `new` operator. You can invoke it directly like this:
22
 
 
23
 
    YUI().use('*', function (Y) {
24
 
        // Y is a new YUI instance.
25
 
    });
26
 
 
27
 
But it also works like this:
28
 
 
29
 
    var Y = YUI();
30
 
 
31
 
The `YUI` constructor accepts an optional config object, like this:
32
 
 
33
 
    YUI({
34
 
        debug: true,
35
 
        combine: false
36
 
    }).use('node', function (Y) {
37
 
        // Y.Node is ready to use.
38
 
    });
39
 
 
40
 
See the API docs for the <a href="config.html">Config</a> class for the complete
41
 
list of supported configuration properties accepted by the YUI constuctor.
42
 
 
43
 
If a global `YUI` object is already defined, the existing YUI object will not be
44
 
overwritten, to ensure that defined namespaces are preserved.
45
 
 
46
 
Each YUI instance has full custom event support, but only if the event system is
47
 
available.
48
 
 
49
 
@class YUI
50
 
@uses EventTarget
51
 
@constructor
52
 
@global
53
 
@param {Object} [config]* Zero or more optional configuration objects. Config
54
 
    values are stored in the `Y.config` property. See the
55
 
    <a href="config.html">Config</a> docs for the list of supported properties.
56
 
**/
57
 
 
58
 
    /*global YUI*/
59
 
    /*global YUI_config*/
60
 
    var YUI = function() {
61
 
        var i = 0,
62
 
            Y = this,
63
 
            args = arguments,
64
 
            l = args.length,
65
 
            instanceOf = function(o, type) {
66
 
                return (o && o.hasOwnProperty && (o instanceof type));
67
 
            },
68
 
            gconf = (typeof YUI_config !== 'undefined') && YUI_config;
69
 
 
70
 
        if (!(instanceOf(Y, YUI))) {
71
 
            Y = new YUI();
72
 
        } else {
73
 
            // set up the core environment
74
 
            Y._init();
75
 
 
76
 
            /**
77
 
            Master configuration that might span multiple contexts in a non-
78
 
            browser environment. It is applied first to all instances in all
79
 
            contexts.
80
 
 
81
 
            @example
82
 
 
83
 
                YUI.GlobalConfig = {
84
 
                    filter: 'debug'
85
 
                };
86
 
 
87
 
                YUI().use('node', function (Y) {
88
 
                    // debug files used here
89
 
                });
90
 
 
91
 
                YUI({
92
 
                    filter: 'min'
93
 
                }).use('node', function (Y) {
94
 
                    // min files used here
95
 
                });
96
 
 
97
 
            @property {Object} GlobalConfig
98
 
            @global
99
 
            @static
100
 
            **/
101
 
            if (YUI.GlobalConfig) {
102
 
                Y.applyConfig(YUI.GlobalConfig);
103
 
            }
104
 
 
105
 
            /**
106
 
            Page-level config applied to all YUI instances created on the
107
 
            current page. This is applied after `YUI.GlobalConfig` and before
108
 
            any instance-level configuration.
109
 
 
110
 
            @example
111
 
 
112
 
                // Single global var to include before YUI seed file
113
 
                YUI_config = {
114
 
                    filter: 'debug'
115
 
                };
116
 
 
117
 
                YUI().use('node', function (Y) {
118
 
                    // debug files used here
119
 
                });
120
 
 
121
 
                YUI({
122
 
                    filter: 'min'
123
 
                }).use('node', function (Y) {
124
 
                    // min files used here
125
 
                });
126
 
 
127
 
            @property {Object} YUI_config
128
 
            @global
129
 
            **/
130
 
            if (gconf) {
131
 
                Y.applyConfig(gconf);
132
 
            }
133
 
 
134
 
            // bind the specified additional modules for this instance
135
 
            if (!l) {
136
 
                Y._setup();
137
 
            }
138
 
        }
139
 
 
140
 
        if (l) {
141
 
            // Each instance can accept one or more configuration objects.
142
 
            // These are applied after YUI.GlobalConfig and YUI_Config,
143
 
            // overriding values set in those config files if there is a
144
 
            // matching property.
145
 
            for (; i < l; i++) {
146
 
                Y.applyConfig(args[i]);
147
 
            }
148
 
 
149
 
            Y._setup();
150
 
        }
151
 
 
152
 
        Y.instanceOf = instanceOf;
153
 
 
154
 
        return Y;
155
 
    };
156
 
 
157
 
(function() {
158
 
 
159
 
    var proto, prop,
160
 
        VERSION = '3.9.1',
161
 
        PERIOD = '.',
162
 
        BASE = 'http://yui.yahooapis.com/',
163
 
        /*
164
 
            These CSS class names can't be generated by
165
 
            getClassName since it is not available at the
166
 
            time they are being used.
167
 
        */
168
 
        DOC_LABEL = 'yui3-js-enabled',
169
 
        CSS_STAMP_EL = 'yui3-css-stamp',
170
 
        NOOP = function() {},
171
 
        SLICE = Array.prototype.slice,
172
 
        APPLY_TO_AUTH = { 'io.xdrReady': 1,   // the functions applyTo
173
 
                          'io.xdrResponse': 1,   // can call. this should
174
 
                          'SWF.eventHandler': 1 }, // be done at build time
175
 
        hasWin = (typeof window != 'undefined'),
176
 
        win = (hasWin) ? window : null,
177
 
        doc = (hasWin) ? win.document : null,
178
 
        docEl = doc && doc.documentElement,
179
 
        docClass = docEl && docEl.className,
180
 
        instances = {},
181
 
        time = new Date().getTime(),
182
 
        add = function(el, type, fn, capture) {
183
 
            if (el && el.addEventListener) {
184
 
                el.addEventListener(type, fn, capture);
185
 
            } else if (el && el.attachEvent) {
186
 
                el.attachEvent('on' + type, fn);
187
 
            }
188
 
        },
189
 
        remove = function(el, type, fn, capture) {
190
 
            if (el && el.removeEventListener) {
191
 
                // this can throw an uncaught exception in FF
192
 
                try {
193
 
                    el.removeEventListener(type, fn, capture);
194
 
                } catch (ex) {}
195
 
            } else if (el && el.detachEvent) {
196
 
                el.detachEvent('on' + type, fn);
197
 
            }
198
 
        },
199
 
        handleLoad = function() {
200
 
            YUI.Env.windowLoaded = true;
201
 
            YUI.Env.DOMReady = true;
202
 
            if (hasWin) {
203
 
                remove(window, 'load', handleLoad);
204
 
            }
205
 
        },
206
 
        getLoader = function(Y, o) {
207
 
            var loader = Y.Env._loader,
208
 
                lCore = [ 'loader-base' ],
209
 
                G_ENV = YUI.Env,
210
 
                mods = G_ENV.mods;
211
 
 
212
 
            if (loader) {
213
 
                //loader._config(Y.config);
214
 
                loader.ignoreRegistered = false;
215
 
                loader.onEnd = null;
216
 
                loader.data = null;
217
 
                loader.required = [];
218
 
                loader.loadType = null;
219
 
            } else {
220
 
                loader = new Y.Loader(Y.config);
221
 
                Y.Env._loader = loader;
222
 
            }
223
 
            if (mods && mods.loader) {
224
 
                lCore = [].concat(lCore, YUI.Env.loaderExtras);
225
 
            }
226
 
            YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore));
227
 
 
228
 
            return loader;
229
 
        },
230
 
 
231
 
        clobber = function(r, s) {
232
 
            for (var i in s) {
233
 
                if (s.hasOwnProperty(i)) {
234
 
                    r[i] = s[i];
235
 
                }
236
 
            }
237
 
        },
238
 
 
239
 
        ALREADY_DONE = { success: true };
240
 
 
241
 
//  Stamp the documentElement (HTML) with a class of "yui-loaded" to
242
 
//  enable styles that need to key off of JS being enabled.
243
 
if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
244
 
    if (docClass) {
245
 
        docClass += ' ';
246
 
    }
247
 
    docClass += DOC_LABEL;
248
 
    docEl.className = docClass;
249
 
}
250
 
 
251
 
if (VERSION.indexOf('@') > -1) {
252
 
    VERSION = '3.5.0'; // dev time hack for cdn test
253
 
}
254
 
 
255
 
proto = {
256
 
    /**
257
 
    Applies a new configuration object to the config of this YUI instance. This
258
 
    will merge new group/module definitions, and will also update the loader
259
 
    cache if necessary. Updating `Y.config` directly will not update the cache.
260
 
 
261
 
    @method applyConfig
262
 
    @param {Object} o the configuration object.
263
 
    @since 3.2.0
264
 
    **/
265
 
    applyConfig: function(o) {
266
 
 
267
 
        o = o || NOOP;
268
 
 
269
 
        var attr,
270
 
            name,
271
 
            // detail,
272
 
            config = this.config,
273
 
            mods = config.modules,
274
 
            groups = config.groups,
275
 
            aliases = config.aliases,
276
 
            loader = this.Env._loader;
277
 
 
278
 
        for (name in o) {
279
 
            if (o.hasOwnProperty(name)) {
280
 
                attr = o[name];
281
 
                if (mods && name == 'modules') {
282
 
                    clobber(mods, attr);
283
 
                } else if (aliases && name == 'aliases') {
284
 
                    clobber(aliases, attr);
285
 
                } else if (groups && name == 'groups') {
286
 
                    clobber(groups, attr);
287
 
                } else if (name == 'win') {
288
 
                    config[name] = (attr && attr.contentWindow) || attr;
289
 
                    config.doc = config[name] ? config[name].document : null;
290
 
                } else if (name == '_yuid') {
291
 
                    // preserve the guid
292
 
                } else {
293
 
                    config[name] = attr;
294
 
                }
295
 
            }
296
 
        }
297
 
 
298
 
        if (loader) {
299
 
            loader._config(o);
300
 
        }
301
 
 
302
 
    },
303
 
 
304
 
    /**
305
 
    Old way to apply a config to this instance (calls `applyConfig` under the
306
 
    hood).
307
 
 
308
 
    @private
309
 
    @method _config
310
 
    @param {Object} o The config to apply
311
 
    **/
312
 
    _config: function(o) {
313
 
        this.applyConfig(o);
314
 
    },
315
 
 
316
 
    /**
317
 
    Initializes this YUI instance.
318
 
 
319
 
    @private
320
 
    @method _init
321
 
    **/
322
 
    _init: function() {
323
 
        var filter, el,
324
 
            Y = this,
325
 
            G_ENV = YUI.Env,
326
 
            Env = Y.Env,
327
 
            prop;
328
 
 
329
 
        /**
330
 
        The version number of this YUI instance.
331
 
 
332
 
        This value is typically updated by a script when a YUI release is built,
333
 
        so it may not reflect the correct version number when YUI is run from
334
 
        the development source tree.
335
 
 
336
 
        @property {String} version
337
 
        **/
338
 
        Y.version = VERSION;
339
 
 
340
 
        if (!Env) {
341
 
            Y.Env = {
342
 
                core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later'],
343
 
                loaderExtras: ['loader-rollup', 'loader-yui3'],
344
 
                mods: {}, // flat module map
345
 
                versions: {}, // version module map
346
 
                base: BASE,
347
 
                cdn: BASE + VERSION + '/build/',
348
 
                // bootstrapped: false,
349
 
                _idx: 0,
350
 
                _used: {},
351
 
                _attached: {},
352
 
                _missed: [],
353
 
                _yidx: 0,
354
 
                _uidx: 0,
355
 
                _guidp: 'y',
356
 
                _loaded: {},
357
 
                // serviced: {},
358
 
                // Regex in English:
359
 
                // I'll start at the \b(simpleyui).
360
 
                // 1. Look in the test string for "simpleyui" or "yui" or
361
 
                //    "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break.  That is, it
362
 
                //    can't match "foyui" or "i_heart_simpleyui". This can be anywhere in the string.
363
 
                // 2. After #1 must come a forward slash followed by the string matched in #1, so
364
 
                //    "yui-base/yui-base" or "simpleyui/simpleyui" or "yui-pants/yui-pants".
365
 
                // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
366
 
                //    so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
367
 
                // 4. This is followed by ".js", so "yui/yui.js", "simpleyui/simpleyui-min.js"
368
 
                // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
369
 
                //    then capture the junk between the LAST "&" and the string in 1-4.  So
370
 
                //    "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js"
371
 
                //    will capture "3.3.0/build/"
372
 
                //
373
 
                // Regex Exploded:
374
 
                // (?:\?             Find a ?
375
 
                //   (?:[^&]*&)      followed by 0..n characters followed by an &
376
 
                //   *               in fact, find as many sets of characters followed by a & as you can
377
 
                //   ([^&]*)         capture the stuff after the last & in \1
378
 
                // )?                but it's ok if all this ?junk&more_junk stuff isn't even there
379
 
                // \b(simpleyui|     after a word break find either the string "simpleyui" or
380
 
                //    yui(?:-\w+)?   the string "yui" optionally followed by a -, then more characters
381
 
                // )                 and store the simpleyui or yui-* string in \2
382
 
                // \/\2              then comes a / followed by the simpleyui or yui-* string in \2
383
 
                // (?:-(min|debug))? optionally followed by "-min" or "-debug"
384
 
                // .js               and ending in ".js"
385
 
                _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(simpleyui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
386
 
                parseBasePath: function(src, pattern) {
387
 
                    var match = src.match(pattern),
388
 
                        path, filter;
389
 
 
390
 
                    if (match) {
391
 
                        path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
392
 
 
393
 
                        // this is to set up the path to the loader.  The file
394
 
                        // filter for loader should match the yui include.
395
 
                        filter = match[3];
396
 
 
397
 
                        // extract correct path for mixed combo urls
398
 
                        // http://yuilibrary.com/projects/yui3/ticket/2528423
399
 
                        if (match[1]) {
400
 
                            path += '?' + match[1];
401
 
                        }
402
 
                        path = {
403
 
                            filter: filter,
404
 
                            path: path
405
 
                        };
406
 
                    }
407
 
                    return path;
408
 
                },
409
 
                getBase: G_ENV && G_ENV.getBase ||
410
 
                        function(pattern) {
411
 
                            var nodes = (doc && doc.getElementsByTagName('script')) || [],
412
 
                                path = Env.cdn, parsed,
413
 
                                i, len, src;
414
 
 
415
 
                            for (i = 0, len = nodes.length; i < len; ++i) {
416
 
                                src = nodes[i].src;
417
 
                                if (src) {
418
 
                                    parsed = Y.Env.parseBasePath(src, pattern);
419
 
                                    if (parsed) {
420
 
                                        filter = parsed.filter;
421
 
                                        path = parsed.path;
422
 
                                        break;
423
 
                                    }
424
 
                                }
425
 
                            }
426
 
 
427
 
                            // use CDN default
428
 
                            return path;
429
 
                        }
430
 
 
431
 
            };
432
 
 
433
 
            Env = Y.Env;
434
 
 
435
 
            Env._loaded[VERSION] = {};
436
 
 
437
 
            if (G_ENV && Y !== YUI) {
438
 
                Env._yidx = ++G_ENV._yidx;
439
 
                Env._guidp = ('yui_' + VERSION + '_' +
440
 
                             Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_');
441
 
            } else if (YUI._YUI) {
442
 
 
443
 
                G_ENV = YUI._YUI.Env;
444
 
                Env._yidx += G_ENV._yidx;
445
 
                Env._uidx += G_ENV._uidx;
446
 
 
447
 
                for (prop in G_ENV) {
448
 
                    if (!(prop in Env)) {
449
 
                        Env[prop] = G_ENV[prop];
450
 
                    }
451
 
                }
452
 
 
453
 
                delete YUI._YUI;
454
 
            }
455
 
 
456
 
            Y.id = Y.stamp(Y);
457
 
            instances[Y.id] = Y;
458
 
 
459
 
        }
460
 
 
461
 
        Y.constructor = YUI;
462
 
 
463
 
        // configuration defaults
464
 
        Y.config = Y.config || {
465
 
            bootstrap: true,
466
 
            cacheUse: true,
467
 
            debug: true,
468
 
            doc: doc,
469
 
            fetchCSS: true,
470
 
            throwFail: true,
471
 
            useBrowserConsole: true,
472
 
            useNativeES5: true,
473
 
            win: win,
474
 
            global: Function('return this')()
475
 
        };
476
 
 
477
 
        //Register the CSS stamp element
478
 
        if (doc && !doc.getElementById(CSS_STAMP_EL)) {
479
 
            el = doc.createElement('div');
480
 
            el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>';
481
 
            YUI.Env.cssStampEl = el.firstChild;
482
 
            if (doc.body) {
483
 
                doc.body.appendChild(YUI.Env.cssStampEl);
484
 
            } else {
485
 
                docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild);
486
 
            }
487
 
        } else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) {
488
 
            YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL);
489
 
        }
490
 
 
491
 
        Y.config.lang = Y.config.lang || 'en-US';
492
 
 
493
 
        Y.config.base = YUI.config.base || Y.Env.getBase(Y.Env._BASE_RE);
494
 
 
495
 
        if (!filter || (!('mindebug').indexOf(filter))) {
496
 
            filter = 'min';
497
 
        }
498
 
        filter = (filter) ? '-' + filter : filter;
499
 
        Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
500
 
 
501
 
    },
502
 
 
503
 
    /**
504
 
    Finishes the instance setup. Attaches whatever YUI modules were defined
505
 
    at the time that this instance was created.
506
 
 
507
 
    @method _setup
508
 
    @private
509
 
    **/
510
 
    _setup: function() {
511
 
        var i, Y = this,
512
 
            core = [],
513
 
            mods = YUI.Env.mods,
514
 
            extras = Y.config.core || [].concat(YUI.Env.core); //Clone it..
515
 
 
516
 
        for (i = 0; i < extras.length; i++) {
517
 
            if (mods[extras[i]]) {
518
 
                core.push(extras[i]);
519
 
            }
520
 
        }
521
 
 
522
 
        Y._attach(['yui-base']);
523
 
        Y._attach(core);
524
 
 
525
 
        if (Y.Loader) {
526
 
            getLoader(Y);
527
 
        }
528
 
 
529
 
    },
530
 
 
531
 
    /**
532
 
    Executes the named method on the specified YUI instance if that method is
533
 
    whitelisted.
534
 
 
535
 
    @method applyTo
536
 
    @param {String} id YUI instance id.
537
 
    @param {String} method Name of the method to execute. For example:
538
 
        'Object.keys'.
539
 
    @param {Array} args Arguments to apply to the method.
540
 
    @return {Mixed} Return value from the applied method, or `null` if the
541
 
        specified instance was not found or the method was not whitelisted.
542
 
    **/
543
 
    applyTo: function(id, method, args) {
544
 
        if (!(method in APPLY_TO_AUTH)) {
545
 
            this.log(method + ': applyTo not allowed', 'warn', 'yui');
546
 
            return null;
547
 
        }
548
 
 
549
 
        var instance = instances[id], nest, m, i;
550
 
        if (instance) {
551
 
            nest = method.split('.');
552
 
            m = instance;
553
 
            for (i = 0; i < nest.length; i = i + 1) {
554
 
                m = m[nest[i]];
555
 
                if (!m) {
556
 
                    this.log('applyTo not found: ' + method, 'warn', 'yui');
557
 
                }
558
 
            }
559
 
            return m && m.apply(instance, args);
560
 
        }
561
 
 
562
 
        return null;
563
 
    },
564
 
 
565
 
/**
566
 
Registers a YUI module and makes it available for use in a `YUI().use()` call or
567
 
as a dependency for other modules.
568
 
 
569
 
The easiest way to create a first-class YUI module is to use
570
 
<a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build
571
 
tool.
572
 
 
573
 
Shifter will automatically wrap your module code in a `YUI.add()` call along
574
 
with any configuration info required for the module.
575
 
 
576
 
@example
577
 
 
578
 
    YUI.add('davglass', function (Y) {
579
 
        Y.davglass = function () {
580
 
        };
581
 
    }, '3.4.0', {
582
 
        requires: ['harley-davidson', 'mt-dew']
583
 
    });
584
 
 
585
 
@method add
586
 
@param {String} name Module name.
587
 
@param {Function} fn Function containing module code. This function will be
588
 
    executed whenever the module is attached to a specific YUI instance.
589
 
 
590
 
    @param {YUI} fn.Y The YUI instance to which this module is attached.
591
 
    @param {String} fn.name Name of the module
592
 
 
593
 
@param {String} version Module version number. This is currently used only for
594
 
    informational purposes, and is not used internally by YUI.
595
 
 
596
 
@param {Object} [config] Module config.
597
 
    @param {Array} [config.requires] Array of other module names that must be
598
 
        attached before this module can be attached.
599
 
    @param {Array} [config.optional] Array of optional module names that should
600
 
        be attached before this module is attached if they've already been
601
 
        loaded. If the `loadOptional` YUI option is `true`, optional modules
602
 
        that have not yet been loaded will be loaded just as if they were hard
603
 
        requirements.
604
 
    @param {Array} [config.use] Array of module names that are included within
605
 
        or otherwise provided by this module, and which should be attached
606
 
        automatically when this module is attached. This makes it possible to
607
 
        create "virtual rollup" modules that simply attach a collection of other
608
 
        modules or submodules.
609
 
 
610
 
@return {YUI} This YUI instance.
611
 
**/
612
 
    add: function(name, fn, version, details) {
613
 
        details = details || {};
614
 
        var env = YUI.Env,
615
 
            mod = {
616
 
                name: name,
617
 
                fn: fn,
618
 
                version: version,
619
 
                details: details
620
 
            },
621
 
            //Instance hash so we don't apply it to the same instance twice
622
 
            applied = {},
623
 
            loader, inst,
624
 
            i, versions = env.versions;
625
 
 
626
 
        env.mods[name] = mod;
627
 
        versions[version] = versions[version] || {};
628
 
        versions[version][name] = mod;
629
 
 
630
 
        for (i in instances) {
631
 
            if (instances.hasOwnProperty(i)) {
632
 
                inst = instances[i];
633
 
                if (!applied[inst.id]) {
634
 
                    applied[inst.id] = true;
635
 
                    loader = inst.Env._loader;
636
 
                    if (loader) {
637
 
                        if (!loader.moduleInfo[name] || loader.moduleInfo[name].temp) {
638
 
                            loader.addModule(details, name);
639
 
                        }
640
 
                    }
641
 
                }
642
 
            }
643
 
        }
644
 
 
645
 
        return this;
646
 
    },
647
 
 
648
 
    /**
649
 
    Executes the callback function associated with each required module,
650
 
    attaching the module to this YUI instance.
651
 
 
652
 
    @method _attach
653
 
    @param {Array} r The array of modules to attach
654
 
    @param {Boolean} [moot=false] If `true`, don't throw a warning if the module
655
 
        is not attached.
656
 
    @private
657
 
    **/
658
 
    _attach: function(r, moot) {
659
 
        var i, name, mod, details, req, use, after,
660
 
            mods = YUI.Env.mods,
661
 
            aliases = YUI.Env.aliases,
662
 
            Y = this, j,
663
 
            cache = YUI.Env._renderedMods,
664
 
            loader = Y.Env._loader,
665
 
            done = Y.Env._attached,
666
 
            len = r.length, loader, def, go,
667
 
            c = [];
668
 
 
669
 
        //Check for conditional modules (in a second+ instance) and add their requirements
670
 
        //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
671
 
        for (i = 0; i < len; i++) {
672
 
            name = r[i];
673
 
            mod = mods[name];
674
 
            c.push(name);
675
 
            if (loader && loader.conditions[name]) {
676
 
                for (j in loader.conditions[name]) {
677
 
                    if (loader.conditions[name].hasOwnProperty(j)) {
678
 
                        def = loader.conditions[name][j];
679
 
                        go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
680
 
                        if (go) {
681
 
                            c.push(def.name);
682
 
                        }
683
 
                    }
684
 
                }
685
 
            }
686
 
        }
687
 
        r = c;
688
 
        len = r.length;
689
 
 
690
 
        for (i = 0; i < len; i++) {
691
 
            if (!done[r[i]]) {
692
 
                name = r[i];
693
 
                mod = mods[name];
694
 
 
695
 
                if (aliases && aliases[name] && !mod) {
696
 
                    Y._attach(aliases[name]);
697
 
                    continue;
698
 
                }
699
 
                if (!mod) {
700
 
                    if (loader && loader.moduleInfo[name]) {
701
 
                        mod = loader.moduleInfo[name];
702
 
                        moot = true;
703
 
                    }
704
 
 
705
 
 
706
 
                    //if (!loader || !loader.moduleInfo[name]) {
707
 
                    //if ((!loader || !loader.moduleInfo[name]) && !moot) {
708
 
                    if (!moot && name) {
709
 
                        if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
710
 
                            Y.Env._missed.push(name);
711
 
                            Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
712
 
                            Y.message('NOT loaded: ' + name, 'warn', 'yui');
713
 
                        }
714
 
                    }
715
 
                } else {
716
 
                    done[name] = true;
717
 
                    //Don't like this, but in case a mod was asked for once, then we fetch it
718
 
                    //We need to remove it from the missed list ^davglass
719
 
                    for (j = 0; j < Y.Env._missed.length; j++) {
720
 
                        if (Y.Env._missed[j] === name) {
721
 
                            Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
722
 
                            Y.Env._missed.splice(j, 1);
723
 
                        }
724
 
                    }
725
 
                    /*
726
 
                        If it's a temp module, we need to redo it's requirements if it's already loaded
727
 
                        since it may have been loaded by another instance and it's dependencies might
728
 
                        have been redefined inside the fetched file.
729
 
                    */
730
 
                    if (loader && cache && cache[name] && cache[name].temp) {
731
 
                        loader.getRequires(cache[name]);
732
 
                        req = [];
733
 
                        for (j in loader.moduleInfo[name].expanded_map) {
734
 
                            if (loader.moduleInfo[name].expanded_map.hasOwnProperty(j)) {
735
 
                                req.push(j);
736
 
                            }
737
 
                        }
738
 
                        Y._attach(req);
739
 
                    }
740
 
 
741
 
                    details = mod.details;
742
 
                    req = details.requires;
743
 
                    use = details.use;
744
 
                    after = details.after;
745
 
                    //Force Intl load if there is a language (Loader logic) @todo fix this shit
746
 
                    if (details.lang) {
747
 
                        req = req || [];
748
 
                        req.unshift('intl');
749
 
                    }
750
 
 
751
 
                    if (req) {
752
 
                        for (j = 0; j < req.length; j++) {
753
 
                            if (!done[req[j]]) {
754
 
                                if (!Y._attach(req)) {
755
 
                                    return false;
756
 
                                }
757
 
                                break;
758
 
                            }
759
 
                        }
760
 
                    }
761
 
 
762
 
                    if (after) {
763
 
                        for (j = 0; j < after.length; j++) {
764
 
                            if (!done[after[j]]) {
765
 
                                if (!Y._attach(after, true)) {
766
 
                                    return false;
767
 
                                }
768
 
                                break;
769
 
                            }
770
 
                        }
771
 
                    }
772
 
 
773
 
                    if (mod.fn) {
774
 
                            if (Y.config.throwFail) {
775
 
                                mod.fn(Y, name);
776
 
                            } else {
777
 
                                try {
778
 
                                    mod.fn(Y, name);
779
 
                                } catch (e) {
780
 
                                    Y.error('Attach error: ' + name, e, name);
781
 
                                return false;
782
 
                            }
783
 
                        }
784
 
                    }
785
 
 
786
 
                    if (use) {
787
 
                        for (j = 0; j < use.length; j++) {
788
 
                            if (!done[use[j]]) {
789
 
                                if (!Y._attach(use)) {
790
 
                                    return false;
791
 
                                }
792
 
                                break;
793
 
                            }
794
 
                        }
795
 
                    }
796
 
 
797
 
 
798
 
 
799
 
                }
800
 
            }
801
 
        }
802
 
 
803
 
        return true;
804
 
    },
805
 
 
806
 
    /**
807
 
    Delays the `use` callback until another event has taken place such as
808
 
    `window.onload`, `domready`, `contentready`, or `available`.
809
 
 
810
 
    @private
811
 
    @method _delayCallback
812
 
    @param {Function} cb The original `use` callback.
813
 
    @param {String|Object} until Either an event name ('load', 'domready', etc.)
814
 
        or an object containing event/args keys for contentready/available.
815
 
    @return {Function}
816
 
    **/
817
 
    _delayCallback: function(cb, until) {
818
 
 
819
 
        var Y = this,
820
 
            mod = ['event-base'];
821
 
 
822
 
        until = (Y.Lang.isObject(until) ? until : { event: until });
823
 
 
824
 
        if (until.event === 'load') {
825
 
            mod.push('event-synthetic');
826
 
        }
827
 
 
828
 
        return function() {
829
 
            var args = arguments;
830
 
            Y._use(mod, function() {
831
 
                Y.on(until.event, function() {
832
 
                    args[1].delayUntil = until.event;
833
 
                    cb.apply(Y, args);
834
 
                }, until.args);
835
 
            });
836
 
        };
837
 
    },
838
 
 
839
 
    /**
840
 
    Attaches one or more modules to this YUI instance. When this is executed,
841
 
    the requirements of the desired modules are analyzed, and one of several
842
 
    things can happen:
843
 
 
844
 
 
845
 
      * All required modules have already been loaded, and just need to be
846
 
        attached to this YUI instance. In this case, the `use()` callback will
847
 
        be executed synchronously after the modules are attached.
848
 
 
849
 
      * One or more modules have not yet been loaded, or the Get utility is not
850
 
        available, or the `bootstrap` config option is `false`. In this case,
851
 
        a warning is issued indicating that modules are missing, but all
852
 
        available modules will still be attached and the `use()` callback will
853
 
        be executed synchronously.
854
 
 
855
 
      * One or more modules are missing and the Loader is not available but the
856
 
        Get utility is, and `bootstrap` is not `false`. In this case, the Get
857
 
        utility will be used to load the Loader, and we will then proceed to
858
 
        the following state:
859
 
 
860
 
      * One or more modules are missing and the Loader is available. In this
861
 
        case, the Loader will be used to resolve the dependency tree for the
862
 
        missing modules and load them and their dependencies. When the Loader is
863
 
        finished loading modules, the `use()` callback will be executed
864
 
        asynchronously.
865
 
 
866
 
    @example
867
 
 
868
 
        // Loads and attaches dd and its dependencies.
869
 
        YUI().use('dd', function (Y) {
870
 
            // ...
871
 
        });
872
 
 
873
 
        // Loads and attaches dd and node as well as all of their dependencies.
874
 
        YUI().use(['dd', 'node'], function (Y) {
875
 
            // ...
876
 
        });
877
 
 
878
 
        // Attaches all modules that have already been loaded.
879
 
        YUI().use('*', function (Y) {
880
 
            // ...
881
 
        });
882
 
 
883
 
        // Attaches a gallery module.
884
 
        YUI().use('gallery-yql', function (Y) {
885
 
            // ...
886
 
        });
887
 
 
888
 
        // Attaches a YUI 2in3 module.
889
 
        YUI().use('yui2-datatable', function (Y) {
890
 
            // ...
891
 
        });
892
 
 
893
 
    @method use
894
 
    @param {String|Array} modules* One or more module names to attach.
895
 
    @param {Function} [callback] Callback function to be executed once all
896
 
        specified modules and their dependencies have been attached.
897
 
    @param {YUI} callback.Y The YUI instance created for this sandbox.
898
 
    @param {Object} callback.status Object containing `success`, `msg` and
899
 
        `data` properties.
900
 
    @chainable
901
 
    **/
902
 
    use: function() {
903
 
        var args = SLICE.call(arguments, 0),
904
 
            callback = args[args.length - 1],
905
 
            Y = this,
906
 
            i = 0,
907
 
            name,
908
 
            Env = Y.Env,
909
 
            provisioned = true;
910
 
 
911
 
        // The last argument supplied to use can be a load complete callback
912
 
        if (Y.Lang.isFunction(callback)) {
913
 
            args.pop();
914
 
            if (Y.config.delayUntil) {
915
 
                callback = Y._delayCallback(callback, Y.config.delayUntil);
916
 
            }
917
 
        } else {
918
 
            callback = null;
919
 
        }
920
 
        if (Y.Lang.isArray(args[0])) {
921
 
            args = args[0];
922
 
        }
923
 
 
924
 
        if (Y.config.cacheUse) {
925
 
            while ((name = args[i++])) {
926
 
                if (!Env._attached[name]) {
927
 
                    provisioned = false;
928
 
                    break;
929
 
                }
930
 
            }
931
 
 
932
 
            if (provisioned) {
933
 
                if (args.length) {
934
 
                }
935
 
                Y._notify(callback, ALREADY_DONE, args);
936
 
                return Y;
937
 
            }
938
 
        }
939
 
 
940
 
        if (Y._loading) {
941
 
            Y._useQueue = Y._useQueue || new Y.Queue();
942
 
            Y._useQueue.add([args, callback]);
943
 
        } else {
944
 
            Y._use(args, function(Y, response) {
945
 
                Y._notify(callback, response, args);
946
 
            });
947
 
        }
948
 
 
949
 
        return Y;
950
 
    },
951
 
 
952
 
    /**
953
 
    Handles Loader notifications about attachment/load errors.
954
 
 
955
 
    @method _notify
956
 
    @param {Function} callback Callback to pass to `Y.config.loadErrorFn`.
957
 
    @param {Object} response Response returned from Loader.
958
 
    @param {Array} args Arguments passed from Loader.
959
 
    @private
960
 
    **/
961
 
    _notify: function(callback, response, args) {
962
 
        if (!response.success && this.config.loadErrorFn) {
963
 
            this.config.loadErrorFn.call(this, this, callback, response, args);
964
 
        } else if (callback) {
965
 
            if (this.Env._missed && this.Env._missed.length) {
966
 
                response.msg = 'Missing modules: ' + this.Env._missed.join();
967
 
                response.success = false;
968
 
            }
969
 
            if (this.config.throwFail) {
970
 
                callback(this, response);
971
 
            } else {
972
 
                try {
973
 
                    callback(this, response);
974
 
                } catch (e) {
975
 
                    this.error('use callback error', e, args);
976
 
                }
977
 
            }
978
 
        }
979
 
    },
980
 
 
981
 
    /**
982
 
    Called from the `use` method queue to ensure that only one set of loading
983
 
    logic is performed at a time.
984
 
 
985
 
    @method _use
986
 
    @param {String} args* One or more modules to attach.
987
 
    @param {Function} [callback] Function to call once all required modules have
988
 
        been attached.
989
 
    @private
990
 
    **/
991
 
    _use: function(args, callback) {
992
 
 
993
 
        if (!this.Array) {
994
 
            this._attach(['yui-base']);
995
 
        }
996
 
 
997
 
        var len, loader, handleBoot,
998
 
            Y = this,
999
 
            G_ENV = YUI.Env,
1000
 
            mods = G_ENV.mods,
1001
 
            Env = Y.Env,
1002
 
            used = Env._used,
1003
 
            aliases = G_ENV.aliases,
1004
 
            queue = G_ENV._loaderQueue,
1005
 
            firstArg = args[0],
1006
 
            YArray = Y.Array,
1007
 
            config = Y.config,
1008
 
            boot = config.bootstrap,
1009
 
            missing = [],
1010
 
            i,
1011
 
            r = [],
1012
 
            ret = true,
1013
 
            fetchCSS = config.fetchCSS,
1014
 
            process = function(names, skip) {
1015
 
 
1016
 
                var i = 0, a = [], name, len, m, req, use;
1017
 
 
1018
 
                if (!names.length) {
1019
 
                    return;
1020
 
                }
1021
 
 
1022
 
                if (aliases) {
1023
 
                    len = names.length;
1024
 
                    for (i = 0; i < len; i++) {
1025
 
                        if (aliases[names[i]] && !mods[names[i]]) {
1026
 
                            a = [].concat(a, aliases[names[i]]);
1027
 
                        } else {
1028
 
                            a.push(names[i]);
1029
 
                        }
1030
 
                    }
1031
 
                    names = a;
1032
 
                }
1033
 
 
1034
 
                len = names.length;
1035
 
 
1036
 
                for (i = 0; i < len; i++) {
1037
 
                    name = names[i];
1038
 
                    if (!skip) {
1039
 
                        r.push(name);
1040
 
                    }
1041
 
 
1042
 
                    // only attach a module once
1043
 
                    if (used[name]) {
1044
 
                        continue;
1045
 
                    }
1046
 
 
1047
 
                    m = mods[name];
1048
 
                    req = null;
1049
 
                    use = null;
1050
 
 
1051
 
                    if (m) {
1052
 
                        used[name] = true;
1053
 
                        req = m.details.requires;
1054
 
                        use = m.details.use;
1055
 
                    } else {
1056
 
                        // CSS files don't register themselves, see if it has
1057
 
                        // been loaded
1058
 
                        if (!G_ENV._loaded[VERSION][name]) {
1059
 
                            missing.push(name);
1060
 
                        } else {
1061
 
                            used[name] = true; // probably css
1062
 
                        }
1063
 
                    }
1064
 
 
1065
 
                    // make sure requirements are attached
1066
 
                    if (req && req.length) {
1067
 
                        process(req);
1068
 
                    }
1069
 
 
1070
 
                    // make sure we grab the submodule dependencies too
1071
 
                    if (use && use.length) {
1072
 
                        process(use, 1);
1073
 
                    }
1074
 
                }
1075
 
 
1076
 
            },
1077
 
 
1078
 
            handleLoader = function(fromLoader) {
1079
 
                var response = fromLoader || {
1080
 
                        success: true,
1081
 
                        msg: 'not dynamic'
1082
 
                    },
1083
 
                    redo, origMissing,
1084
 
                    ret = true,
1085
 
                    data = response.data;
1086
 
 
1087
 
                Y._loading = false;
1088
 
 
1089
 
                if (data) {
1090
 
                    origMissing = missing;
1091
 
                    missing = [];
1092
 
                    r = [];
1093
 
                    process(data);
1094
 
                    redo = missing.length;
1095
 
                    if (redo) {
1096
 
                        if ([].concat(missing).sort().join() ==
1097
 
                                origMissing.sort().join()) {
1098
 
                            redo = false;
1099
 
                        }
1100
 
                    }
1101
 
                }
1102
 
 
1103
 
                if (redo && data) {
1104
 
                    Y._loading = true;
1105
 
                    Y._use(missing, function() {
1106
 
                        if (Y._attach(data)) {
1107
 
                            Y._notify(callback, response, data);
1108
 
                        }
1109
 
                    });
1110
 
                } else {
1111
 
                    if (data) {
1112
 
                        ret = Y._attach(data);
1113
 
                    }
1114
 
                    if (ret) {
1115
 
                        Y._notify(callback, response, args);
1116
 
                    }
1117
 
                }
1118
 
 
1119
 
                if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
1120
 
                    Y._use.apply(Y, Y._useQueue.next());
1121
 
                }
1122
 
 
1123
 
            };
1124
 
 
1125
 
 
1126
 
        // YUI().use('*'); // bind everything available
1127
 
        if (firstArg === '*') {
1128
 
            args = [];
1129
 
            for (i in mods) {
1130
 
                if (mods.hasOwnProperty(i)) {
1131
 
                    args.push(i);
1132
 
                }
1133
 
            }
1134
 
            ret = Y._attach(args);
1135
 
            if (ret) {
1136
 
                handleLoader();
1137
 
            }
1138
 
            return Y;
1139
 
        }
1140
 
 
1141
 
        if ((mods.loader || mods['loader-base']) && !Y.Loader) {
1142
 
            Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]);
1143
 
        }
1144
 
 
1145
 
 
1146
 
        // use loader to expand dependencies and sort the
1147
 
        // requirements if it is available.
1148
 
        if (boot && Y.Loader && args.length) {
1149
 
            loader = getLoader(Y);
1150
 
            loader.require(args);
1151
 
            loader.ignoreRegistered = true;
1152
 
            loader._boot = true;
1153
 
            loader.calculate(null, (fetchCSS) ? null : 'js');
1154
 
            args = loader.sorted;
1155
 
            loader._boot = false;
1156
 
        }
1157
 
 
1158
 
        process(args);
1159
 
 
1160
 
        len = missing.length;
1161
 
 
1162
 
 
1163
 
        if (len) {
1164
 
            missing = YArray.dedupe(missing);
1165
 
            len = missing.length;
1166
 
        }
1167
 
 
1168
 
 
1169
 
        // dynamic load
1170
 
        if (boot && len && Y.Loader) {
1171
 
            Y._loading = true;
1172
 
            loader = getLoader(Y);
1173
 
            loader.onEnd = handleLoader;
1174
 
            loader.context = Y;
1175
 
            loader.data = args;
1176
 
            loader.ignoreRegistered = false;
1177
 
            loader.require(missing);
1178
 
            loader.insert(null, (fetchCSS) ? null : 'js');
1179
 
 
1180
 
        } else if (boot && len && Y.Get && !Env.bootstrapped) {
1181
 
 
1182
 
            Y._loading = true;
1183
 
 
1184
 
            handleBoot = function() {
1185
 
                Y._loading = false;
1186
 
                queue.running = false;
1187
 
                Env.bootstrapped = true;
1188
 
                G_ENV._bootstrapping = false;
1189
 
                if (Y._attach(['loader'])) {
1190
 
                    Y._use(args, callback);
1191
 
                }
1192
 
            };
1193
 
 
1194
 
            if (G_ENV._bootstrapping) {
1195
 
                queue.add(handleBoot);
1196
 
            } else {
1197
 
                G_ENV._bootstrapping = true;
1198
 
                Y.Get.script(config.base + config.loaderPath, {
1199
 
                    onEnd: handleBoot
1200
 
                });
1201
 
            }
1202
 
 
1203
 
        } else {
1204
 
            ret = Y._attach(args);
1205
 
            if (ret) {
1206
 
                handleLoader();
1207
 
            }
1208
 
        }
1209
 
 
1210
 
        return Y;
1211
 
    },
1212
 
 
1213
 
 
1214
 
    /**
1215
 
    Utility method for safely creating namespaces if they don't already exist.
1216
 
    May be called statically on the YUI global object or as a method on a YUI
1217
 
    instance.
1218
 
 
1219
 
    When called statically, a namespace will be created on the YUI global
1220
 
    object:
1221
 
 
1222
 
        // Create `YUI.your.namespace.here` as nested objects, preserving any
1223
 
        // objects that already exist instead of overwriting them.
1224
 
        YUI.namespace('your.namespace.here');
1225
 
 
1226
 
    When called as a method on a YUI instance, a namespace will be created on
1227
 
    that instance:
1228
 
 
1229
 
        // Creates `Y.property.package`.
1230
 
        Y.namespace('property.package');
1231
 
 
1232
 
    Dots in the input string cause `namespace` to create nested objects for each
1233
 
    token. If any part of the requested namespace already exists, the current
1234
 
    object will be left in place and will not be overwritten. This allows
1235
 
    multiple calls to `namespace` to preserve existing namespaced properties.
1236
 
 
1237
 
    If the first token in the namespace string is "YAHOO", that token is
1238
 
    discarded. This is legacy behavior for backwards compatibility with YUI 2.
1239
 
 
1240
 
    Be careful with namespace tokens. Reserved words may work in some browsers
1241
 
    and not others. For instance, the following will fail in some browsers
1242
 
    because the supported version of JavaScript reserves the word "long":
1243
 
 
1244
 
        Y.namespace('really.long.nested.namespace');
1245
 
 
1246
 
    Note: If you pass multiple arguments to create multiple namespaces, only the
1247
 
    last one created is returned from this function.
1248
 
 
1249
 
    @method namespace
1250
 
    @param {String} namespace* One or more namespaces to create.
1251
 
    @return {Object} Reference to the last namespace object created.
1252
 
    **/
1253
 
    namespace: function() {
1254
 
        var a = arguments, o, i = 0, j, d, arg;
1255
 
 
1256
 
        for (; i < a.length; i++) {
1257
 
            o = this; //Reset base object per argument or it will get reused from the last
1258
 
            arg = a[i];
1259
 
            if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
1260
 
                d = arg.split(PERIOD);
1261
 
                for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
1262
 
                    o[d[j]] = o[d[j]] || {};
1263
 
                    o = o[d[j]];
1264
 
                }
1265
 
            } else {
1266
 
                o[arg] = o[arg] || {};
1267
 
                o = o[arg]; //Reset base object to the new object so it's returned
1268
 
            }
1269
 
        }
1270
 
        return o;
1271
 
    },
1272
 
 
1273
 
    // this is replaced if the log module is included
1274
 
    log: NOOP,
1275
 
    message: NOOP,
1276
 
    // this is replaced if the dump module is included
1277
 
    dump: function (o) { return ''+o; },
1278
 
 
1279
 
    /**
1280
 
    Reports an error.
1281
 
 
1282
 
    The reporting mechanism is controlled by the `throwFail` configuration
1283
 
    attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is
1284
 
    truthy, a JS exception is thrown.
1285
 
 
1286
 
    If an `errorFn` is specified in the config it must return `true` to indicate
1287
 
    that the exception was handled and keep it from being thrown.
1288
 
 
1289
 
    @method error
1290
 
    @param {String} msg Error message.
1291
 
    @param {Error|String} [e] JavaScript error object or an error string.
1292
 
    @param {String} [src] Source of the error (such as the name of the module in
1293
 
        which the error occurred).
1294
 
    @chainable
1295
 
    **/
1296
 
    error: function(msg, e, src) {
1297
 
        //TODO Add check for window.onerror here
1298
 
 
1299
 
        var Y = this, ret;
1300
 
 
1301
 
        if (Y.config.errorFn) {
1302
 
            ret = Y.config.errorFn.apply(Y, arguments);
1303
 
        }
1304
 
 
1305
 
        if (!ret) {
1306
 
            throw (e || new Error(msg));
1307
 
        } else {
1308
 
            Y.message(msg, 'error', ''+src); // don't scrub this one
1309
 
        }
1310
 
 
1311
 
        return Y;
1312
 
    },
1313
 
 
1314
 
    /**
1315
 
    Generates an id string that is unique among all YUI instances in this
1316
 
    execution context.
1317
 
 
1318
 
    @method guid
1319
 
    @param {String} [pre] Prefix.
1320
 
    @return {String} Unique id.
1321
 
    **/
1322
 
    guid: function(pre) {
1323
 
        var id = this.Env._guidp + '_' + (++this.Env._uidx);
1324
 
        return (pre) ? (pre + id) : id;
1325
 
    },
1326
 
 
1327
 
    /**
1328
 
    Returns a unique id associated with the given object and (if *readOnly* is
1329
 
    falsy) stamps the object with that id so it can be identified in the future.
1330
 
 
1331
 
    Stamping an object involves adding a `_yuid` property to it that contains
1332
 
    the object's id. One exception to this is that in Internet Explorer, DOM
1333
 
    nodes have a `uniqueID` property that contains a browser-generated unique
1334
 
    id, which will be used instead of a YUI-generated id when available.
1335
 
 
1336
 
    @method stamp
1337
 
    @param {Object} o Object to stamp.
1338
 
    @param {Boolean} readOnly If truthy and the given object has not already
1339
 
        been stamped, the object will not be modified and `null` will be
1340
 
        returned.
1341
 
    @return {String} Object's unique id, or `null` if *readOnly* was truthy and
1342
 
        the given object was not already stamped.
1343
 
    **/
1344
 
    stamp: function(o, readOnly) {
1345
 
        var uid;
1346
 
        if (!o) {
1347
 
            return o;
1348
 
        }
1349
 
 
1350
 
        // IE generates its own unique ID for dom nodes
1351
 
        // The uniqueID property of a document node returns a new ID
1352
 
        if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
1353
 
            uid = o.uniqueID;
1354
 
        } else {
1355
 
            uid = (typeof o === 'string') ? o : o._yuid;
1356
 
        }
1357
 
 
1358
 
        if (!uid) {
1359
 
            uid = this.guid();
1360
 
            if (!readOnly) {
1361
 
                try {
1362
 
                    o._yuid = uid;
1363
 
                } catch (e) {
1364
 
                    uid = null;
1365
 
                }
1366
 
            }
1367
 
        }
1368
 
        return uid;
1369
 
    },
1370
 
 
1371
 
    /**
1372
 
    Destroys this YUI instance.
1373
 
 
1374
 
    @method destroy
1375
 
    @since 3.3.0
1376
 
    **/
1377
 
    destroy: function() {
1378
 
        var Y = this;
1379
 
        if (Y.Event) {
1380
 
            Y.Event._unload();
1381
 
        }
1382
 
        delete instances[Y.id];
1383
 
        delete Y.Env;
1384
 
        delete Y.config;
1385
 
    }
1386
 
 
1387
 
    /**
1388
 
    Safe `instanceof` wrapper that works around a memory leak in IE when the
1389
 
    object being tested is `window` or `document`.
1390
 
 
1391
 
    Unless you are testing objects that may be `window` or `document`, you
1392
 
    should use the native `instanceof` operator instead of this method.
1393
 
 
1394
 
    @method instanceOf
1395
 
    @param {Object} o Object to check.
1396
 
    @param {Object} type Class to check against.
1397
 
    @since 3.3.0
1398
 
    **/
1399
 
};
1400
 
 
1401
 
    YUI.prototype = proto;
1402
 
 
1403
 
    // inheritance utilities are not available yet
1404
 
    for (prop in proto) {
1405
 
        if (proto.hasOwnProperty(prop)) {
1406
 
            YUI[prop] = proto[prop];
1407
 
        }
1408
 
    }
1409
 
 
1410
 
    /**
1411
 
    Applies a configuration to all YUI instances in this execution context.
1412
 
 
1413
 
    The main use case for this method is in "mashups" where several third-party
1414
 
    scripts need to write to a global YUI config, but cannot share a single
1415
 
    centrally-managed config object. This way they can all call
1416
 
    `YUI.applyConfig({})` instead of overwriting the single global config.
1417
 
 
1418
 
    @example
1419
 
 
1420
 
        YUI.applyConfig({
1421
 
            modules: {
1422
 
                davglass: {
1423
 
                    fullpath: './davglass.js'
1424
 
                }
1425
 
            }
1426
 
        });
1427
 
 
1428
 
        YUI.applyConfig({
1429
 
            modules: {
1430
 
                foo: {
1431
 
                    fullpath: './foo.js'
1432
 
                }
1433
 
            }
1434
 
        });
1435
 
 
1436
 
        YUI().use('davglass', function (Y) {
1437
 
            // Module davglass will be available here.
1438
 
        });
1439
 
 
1440
 
    @method applyConfig
1441
 
    @param {Object} o Configuration object to apply.
1442
 
    @static
1443
 
    @since 3.5.0
1444
 
    **/
1445
 
    YUI.applyConfig = function(o) {
1446
 
        if (!o) {
1447
 
            return;
1448
 
        }
1449
 
        //If there is a GlobalConfig, apply it first to set the defaults
1450
 
        if (YUI.GlobalConfig) {
1451
 
            this.prototype.applyConfig.call(this, YUI.GlobalConfig);
1452
 
        }
1453
 
        //Apply this config to it
1454
 
        this.prototype.applyConfig.call(this, o);
1455
 
        //Reset GlobalConfig to the combined config
1456
 
        YUI.GlobalConfig = this.config;
1457
 
    };
1458
 
 
1459
 
    // set up the environment
1460
 
    YUI._init();
1461
 
 
1462
 
    if (hasWin) {
1463
 
        // add a window load event at load time so we can capture
1464
 
        // the case where it fires before dynamic loading is
1465
 
        // complete.
1466
 
        add(window, 'load', handleLoad);
1467
 
    } else {
1468
 
        handleLoad();
1469
 
    }
1470
 
 
1471
 
    YUI.Env.add = add;
1472
 
    YUI.Env.remove = remove;
1473
 
 
1474
 
    /*global exports*/
1475
 
    // Support the CommonJS method for exporting our single global
1476
 
    if (typeof exports == 'object') {
1477
 
        exports.YUI = YUI;
1478
 
        /**
1479
 
        * Set a method to be called when `Get.script` is called in Node.js
1480
 
        * `Get` will open the file, then pass it's content and it's path
1481
 
        * to this method before attaching it. Commonly used for code coverage
1482
 
        * instrumentation. <strong>Calling this multiple times will only
1483
 
        * attach the last hook method</strong>. This method is only
1484
 
        * available in Node.js.
1485
 
        * @method setLoadHook
1486
 
        * @static
1487
 
        * @param {Function} fn The function to set
1488
 
        * @param {String} fn.data The content of the file
1489
 
        * @param {String} fn.path The file path of the file
1490
 
        */
1491
 
        YUI.setLoadHook = function(fn) {
1492
 
            YUI._getLoadHook = fn;
1493
 
        };
1494
 
        /**
1495
 
        * Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook`
1496
 
        * @method _getLoadHook
1497
 
        * @private
1498
 
        * @param {String} data The content of the file
1499
 
        * @param {String} path The file path of the file
1500
 
        */
1501
 
        YUI._getLoadHook = null;
1502
 
    }
1503
 
 
1504
 
}());
1505
 
 
1506
 
 
1507
 
/**
1508
 
Config object that contains all of the configuration options for
1509
 
this `YUI` instance.
1510
 
 
1511
 
This object is supplied by the implementer when instantiating YUI. Some
1512
 
properties have default values if they are not supplied by the implementer.
1513
 
 
1514
 
This object should not be updated directly because some values are cached. Use
1515
 
`applyConfig()` to update the config object on a YUI instance that has already
1516
 
been configured.
1517
 
 
1518
 
@class config
1519
 
@static
1520
 
**/
1521
 
 
1522
 
/**
1523
 
If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata
1524
 
if they're needed to load additional dependencies and aren't already available.
1525
 
 
1526
 
Setting this to `false` will prevent YUI from automatically loading the Loader
1527
 
and module metadata, so you will need to manually ensure that they're available
1528
 
or handle dependency resolution yourself.
1529
 
 
1530
 
@property {Boolean} bootstrap
1531
 
@default true
1532
 
**/
1533
 
 
1534
 
/**
1535
 
 
1536
 
@property {Object} aliases
1537
 
**/
1538
 
 
1539
 
/**
1540
 
A hash of module group definitions.
1541
 
 
1542
 
For each group you can specify a list of modules and the base path and
1543
 
combo spec to use when dynamically loading the modules.
1544
 
 
1545
 
@example
1546
 
 
1547
 
    groups: {
1548
 
        yui2: {
1549
 
            // specify whether or not this group has a combo service
1550
 
            combine: true,
1551
 
 
1552
 
            // The comboSeperator to use with this group's combo handler
1553
 
            comboSep: ';',
1554
 
 
1555
 
            // The maxURLLength for this server
1556
 
            maxURLLength: 500,
1557
 
 
1558
 
            // the base path for non-combo paths
1559
 
            base: 'http://yui.yahooapis.com/2.8.0r4/build/',
1560
 
 
1561
 
            // the path to the combo service
1562
 
            comboBase: 'http://yui.yahooapis.com/combo?',
1563
 
 
1564
 
            // a fragment to prepend to the path attribute when
1565
 
            // when building combo urls
1566
 
            root: '2.8.0r4/build/',
1567
 
 
1568
 
            // the module definitions
1569
 
            modules:  {
1570
 
                yui2_yde: {
1571
 
                    path: "yahoo-dom-event/yahoo-dom-event.js"
1572
 
                },
1573
 
                yui2_anim: {
1574
 
                    path: "animation/animation.js",
1575
 
                    requires: ['yui2_yde']
1576
 
                }
1577
 
            }
1578
 
        }
1579
 
    }
1580
 
 
1581
 
@property {Object} groups
1582
 
**/
1583
 
 
1584
 
/**
1585
 
Path to the Loader JS file, relative to the `base` path.
1586
 
 
1587
 
This is used to dynamically bootstrap the Loader when it's needed and isn't yet
1588
 
available.
1589
 
 
1590
 
@property {String} loaderPath
1591
 
@default "loader/loader-min.js"
1592
 
**/
1593
 
 
1594
 
/**
1595
 
If `true`, YUI will attempt to load CSS dependencies and skins. Set this to
1596
 
`false` to prevent YUI from loading any CSS, or set it to the string `"force"`
1597
 
to force CSS dependencies to be loaded even if their associated JS modules are
1598
 
already loaded.
1599
 
 
1600
 
@property {Boolean|String} fetchCSS
1601
 
@default true
1602
 
**/
1603
 
 
1604
 
/**
1605
 
Default gallery version used to build gallery module urls.
1606
 
 
1607
 
@property {String} gallery
1608
 
@since 3.1.0
1609
 
**/
1610
 
 
1611
 
/**
1612
 
Default YUI 2 version used to build YUI 2 module urls.
1613
 
 
1614
 
This is used for intrinsic YUI 2 support via the 2in3 project. Also see the
1615
 
`2in3` config for pulling different revisions of the wrapped YUI 2 modules.
1616
 
 
1617
 
@property {String} yui2
1618
 
@default "2.9.0"
1619
 
@since 3.1.0
1620
 
**/
1621
 
 
1622
 
/**
1623
 
Revision number of YUI 2in3 modules that should be used when loading YUI 2in3.
1624
 
 
1625
 
@property {String} 2in3
1626
 
@default "4"
1627
 
@since 3.1.0
1628
 
**/
1629
 
 
1630
 
/**
1631
 
Alternate console log function that should be used in environments without a
1632
 
supported native console. This function is executed with the YUI instance as its
1633
 
`this` object.
1634
 
 
1635
 
@property {Function} logFn
1636
 
@since 3.1.0
1637
 
**/
1638
 
 
1639
 
/**
1640
 
Callback to execute when `Y.error()` is called. It receives the error message
1641
 
and a JavaScript error object if one was provided.
1642
 
 
1643
 
This function is executed with the YUI instance as its `this` object.
1644
 
 
1645
 
Returning `true` from this function will prevent an exception from being thrown.
1646
 
 
1647
 
@property {Function} errorFn
1648
 
@param {String} errorFn.msg Error message
1649
 
@param {Object} [errorFn.err] Error object (if one was provided).
1650
 
@since 3.2.0
1651
 
**/
1652
 
 
1653
 
/**
1654
 
A callback to execute when Loader fails to load one or more resources.
1655
 
 
1656
 
This could be because of a script load failure. It could also be because a
1657
 
module fails to register itself when the `requireRegistration` config is `true`.
1658
 
 
1659
 
If this function is defined, the `use()` callback will only be called when the
1660
 
loader succeeds. Otherwise, `use()` will always executes unless there was a
1661
 
JavaScript error when attaching a module.
1662
 
 
1663
 
@property {Function} loadErrorFn
1664
 
@since 3.3.0
1665
 
**/
1666
 
 
1667
 
/**
1668
 
If `true`, Loader will expect all loaded scripts to be first-class YUI modules
1669
 
that register themselves with the YUI global, and will trigger a failure if a
1670
 
loaded script does not register a YUI module.
1671
 
 
1672
 
@property {Boolean} requireRegistration
1673
 
@default false
1674
 
@since 3.3.0
1675
 
**/
1676
 
 
1677
 
/**
1678
 
Cache serviced use() requests.
1679
 
 
1680
 
@property {Boolean} cacheUse
1681
 
@default true
1682
 
@since 3.3.0
1683
 
@deprecated No longer used.
1684
 
**/
1685
 
 
1686
 
/**
1687
 
Whether or not YUI should use native ES5 functionality when available for
1688
 
features like `Y.Array.each()`, `Y.Object()`, etc.
1689
 
 
1690
 
When `false`, YUI will always use its own fallback implementations instead of
1691
 
relying on ES5 functionality, even when ES5 functionality is available.
1692
 
 
1693
 
@property {Boolean} useNativeES5
1694
 
@default true
1695
 
@since 3.5.0
1696
 
**/
1697
 
 
1698
 
/**
1699
 
 * Leverage native JSON stringify if the browser has a native
1700
 
 * implementation.  In general, this is a good idea.  See the Known Issues
1701
 
 * section in the JSON user guide for caveats.  The default value is true
1702
 
 * for browsers with native JSON support.
1703
 
 *
1704
 
 * @property useNativeJSONStringify
1705
 
 * @type Boolean
1706
 
 * @default true
1707
 
 * @since 3.8.0
1708
 
 */
1709
 
 
1710
 
 /**
1711
 
 * Leverage native JSON parse if the browser has a native implementation.
1712
 
 * In general, this is a good idea.  See the Known Issues section in the
1713
 
 * JSON user guide for caveats.  The default value is true for browsers with
1714
 
 * native JSON support.
1715
 
 *
1716
 
 * @property useNativeJSONParse
1717
 
 * @type Boolean
1718
 
 * @default true
1719
 
 * @since 3.8.0
1720
 
 */
1721
 
 
1722
 
/**
1723
 
Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`)
1724
 
@property delayUntil
1725
 
@type String|Object
1726
 
@since 3.6.0
1727
 
@example
1728
 
 
1729
 
You can use `load` or `domready` strings by default:
1730
 
 
1731
 
    YUI({
1732
 
        delayUntil: 'domready'
1733
 
    }, function (Y) {
1734
 
        // This will not execute until 'domeready' occurs.
1735
 
    });
1736
 
 
1737
 
Or you can delay until a node is available (with `available` or `contentready`):
1738
 
 
1739
 
    YUI({
1740
 
        delayUntil: {
1741
 
            event: 'available',
1742
 
            args : '#foo'
1743
 
        }
1744
 
    }, function (Y) {
1745
 
        // This will not execute until a node matching the selector "#foo" is
1746
 
        // available in the DOM.
1747
 
    });
1748
 
 
1749
 
@property {Object|String} delayUntil
1750
 
@since 3.6.0
1751
 
**/
1752
 
YUI.add('yui-base', function (Y, NAME) {
1753
 
 
1754
 
/*
1755
 
 * YUI stub
1756
 
 * @module yui
1757
 
 * @submodule yui-base
1758
 
 */
1759
 
/**
1760
 
 * The YUI module contains the components required for building the YUI
1761
 
 * seed file.  This includes the script loading mechanism, a simple queue,
1762
 
 * and the core utilities for the library.
1763
 
 * @module yui
1764
 
 * @submodule yui-base
1765
 
 */
1766
 
 
1767
 
/**
1768
 
 * Provides core language utilites and extensions used throughout YUI.
1769
 
 *
1770
 
 * @class Lang
1771
 
 * @static
1772
 
 */
1773
 
 
1774
 
var L = Y.Lang || (Y.Lang = {}),
1775
 
 
1776
 
STRING_PROTO = String.prototype,
1777
 
TOSTRING     = Object.prototype.toString,
1778
 
 
1779
 
TYPES = {
1780
 
    'undefined'        : 'undefined',
1781
 
    'number'           : 'number',
1782
 
    'boolean'          : 'boolean',
1783
 
    'string'           : 'string',
1784
 
    '[object Function]': 'function',
1785
 
    '[object RegExp]'  : 'regexp',
1786
 
    '[object Array]'   : 'array',
1787
 
    '[object Date]'    : 'date',
1788
 
    '[object Error]'   : 'error'
1789
 
},
1790
 
 
1791
 
SUBREGEX        = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
1792
 
TRIMREGEX       = /^\s+|\s+$/g,
1793
 
NATIVE_FN_REGEX = /\{\s*\[(?:native code|function)\]\s*\}/i;
1794
 
 
1795
 
// -- Protected Methods --------------------------------------------------------
1796
 
 
1797
 
/**
1798
 
Returns `true` if the given function appears to be implemented in native code,
1799
 
`false` otherwise. Will always return `false` -- even in ES5-capable browsers --
1800
 
if the `useNativeES5` YUI config option is set to `false`.
1801
 
 
1802
 
This isn't guaranteed to be 100% accurate and won't work for anything other than
1803
 
functions, but it can be useful for determining whether a function like
1804
 
`Array.prototype.forEach` is native or a JS shim provided by another library.
1805
 
 
1806
 
There's a great article by @kangax discussing certain flaws with this technique:
1807
 
<http://perfectionkills.com/detecting-built-in-host-methods/>
1808
 
 
1809
 
While his points are valid, it's still possible to benefit from this function
1810
 
as long as it's used carefully and sparingly, and in such a way that false
1811
 
negatives have minimal consequences. It's used internally to avoid using
1812
 
potentially broken non-native ES5 shims that have been added to the page by
1813
 
other libraries.
1814
 
 
1815
 
@method _isNative
1816
 
@param {Function} fn Function to test.
1817
 
@return {Boolean} `true` if _fn_ appears to be native, `false` otherwise.
1818
 
@static
1819
 
@protected
1820
 
@since 3.5.0
1821
 
**/
1822
 
L._isNative = function (fn) {
1823
 
    return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn));
1824
 
};
1825
 
 
1826
 
// -- Public Methods -----------------------------------------------------------
1827
 
 
1828
 
/**
1829
 
 * Determines whether or not the provided item is an array.
1830
 
 *
1831
 
 * Returns `false` for array-like collections such as the function `arguments`
1832
 
 * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
1833
 
 * test for an array-like collection.
1834
 
 *
1835
 
 * @method isArray
1836
 
 * @param o The object to test.
1837
 
 * @return {boolean} true if o is an array.
1838
 
 * @static
1839
 
 */
1840
 
L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) {
1841
 
    return L.type(o) === 'array';
1842
 
};
1843
 
 
1844
 
/**
1845
 
 * Determines whether or not the provided item is a boolean.
1846
 
 * @method isBoolean
1847
 
 * @static
1848
 
 * @param o The object to test.
1849
 
 * @return {boolean} true if o is a boolean.
1850
 
 */
1851
 
L.isBoolean = function(o) {
1852
 
    return typeof o === 'boolean';
1853
 
};
1854
 
 
1855
 
/**
1856
 
 * Determines whether or not the supplied item is a date instance.
1857
 
 * @method isDate
1858
 
 * @static
1859
 
 * @param o The object to test.
1860
 
 * @return {boolean} true if o is a date.
1861
 
 */
1862
 
L.isDate = function(o) {
1863
 
    return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
1864
 
};
1865
 
 
1866
 
/**
1867
 
 * <p>
1868
 
 * Determines whether or not the provided item is a function.
1869
 
 * Note: Internet Explorer thinks certain functions are objects:
1870
 
 * </p>
1871
 
 *
1872
 
 * <pre>
1873
 
 * var obj = document.createElement("object");
1874
 
 * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
1875
 
 * &nbsp;
1876
 
 * var input = document.createElement("input"); // append to body
1877
 
 * Y.Lang.isFunction(input.focus) // reports false in IE
1878
 
 * </pre>
1879
 
 *
1880
 
 * <p>
1881
 
 * You will have to implement additional tests if these functions
1882
 
 * matter to you.
1883
 
 * </p>
1884
 
 *
1885
 
 * @method isFunction
1886
 
 * @static
1887
 
 * @param o The object to test.
1888
 
 * @return {boolean} true if o is a function.
1889
 
 */
1890
 
L.isFunction = function(o) {
1891
 
    return L.type(o) === 'function';
1892
 
};
1893
 
 
1894
 
/**
1895
 
 * Determines whether or not the provided item is null.
1896
 
 * @method isNull
1897
 
 * @static
1898
 
 * @param o The object to test.
1899
 
 * @return {boolean} true if o is null.
1900
 
 */
1901
 
L.isNull = function(o) {
1902
 
    return o === null;
1903
 
};
1904
 
 
1905
 
/**
1906
 
 * Determines whether or not the provided item is a legal number.
1907
 
 * @method isNumber
1908
 
 * @static
1909
 
 * @param o The object to test.
1910
 
 * @return {boolean} true if o is a number.
1911
 
 */
1912
 
L.isNumber = function(o) {
1913
 
    return typeof o === 'number' && isFinite(o);
1914
 
};
1915
 
 
1916
 
/**
1917
 
 * Determines whether or not the provided item is of type object
1918
 
 * or function. Note that arrays are also objects, so
1919
 
 * <code>Y.Lang.isObject([]) === true</code>.
1920
 
 * @method isObject
1921
 
 * @static
1922
 
 * @param o The object to test.
1923
 
 * @param failfn {boolean} fail if the input is a function.
1924
 
 * @return {boolean} true if o is an object.
1925
 
 * @see isPlainObject
1926
 
 */
1927
 
L.isObject = function(o, failfn) {
1928
 
    var t = typeof o;
1929
 
    return (o && (t === 'object' ||
1930
 
        (!failfn && (t === 'function' || L.isFunction(o))))) || false;
1931
 
};
1932
 
 
1933
 
/**
1934
 
 * Determines whether or not the provided item is a string.
1935
 
 * @method isString
1936
 
 * @static
1937
 
 * @param o The object to test.
1938
 
 * @return {boolean} true if o is a string.
1939
 
 */
1940
 
L.isString = function(o) {
1941
 
    return typeof o === 'string';
1942
 
};
1943
 
 
1944
 
/**
1945
 
 * Determines whether or not the provided item is undefined.
1946
 
 * @method isUndefined
1947
 
 * @static
1948
 
 * @param o The object to test.
1949
 
 * @return {boolean} true if o is undefined.
1950
 
 */
1951
 
L.isUndefined = function(o) {
1952
 
    return typeof o === 'undefined';
1953
 
};
1954
 
 
1955
 
/**
1956
 
 * A convenience method for detecting a legitimate non-null value.
1957
 
 * Returns false for null/undefined/NaN, true for other values,
1958
 
 * including 0/false/''
1959
 
 * @method isValue
1960
 
 * @static
1961
 
 * @param o The item to test.
1962
 
 * @return {boolean} true if it is not null/undefined/NaN || false.
1963
 
 */
1964
 
L.isValue = function(o) {
1965
 
    var t = L.type(o);
1966
 
 
1967
 
    switch (t) {
1968
 
        case 'number':
1969
 
            return isFinite(o);
1970
 
 
1971
 
        case 'null': // fallthru
1972
 
        case 'undefined':
1973
 
            return false;
1974
 
 
1975
 
        default:
1976
 
            return !!t;
1977
 
    }
1978
 
};
1979
 
 
1980
 
/**
1981
 
 * Returns the current time in milliseconds.
1982
 
 *
1983
 
 * @method now
1984
 
 * @return {Number} Current time in milliseconds.
1985
 
 * @static
1986
 
 * @since 3.3.0
1987
 
 */
1988
 
L.now = Date.now || function () {
1989
 
    return new Date().getTime();
1990
 
};
1991
 
 
1992
 
/**
1993
 
 * Lightweight version of <code>Y.substitute</code>. Uses the same template
1994
 
 * structure as <code>Y.substitute</code>, but doesn't support recursion,
1995
 
 * auto-object coersion, or formats.
1996
 
 * @method sub
1997
 
 * @param {string} s String to be modified.
1998
 
 * @param {object} o Object containing replacement values.
1999
 
 * @return {string} the substitute result.
2000
 
 * @static
2001
 
 * @since 3.2.0
2002
 
 */
2003
 
L.sub = function(s, o) {
2004
 
    return s.replace ? s.replace(SUBREGEX, function (match, key) {
2005
 
        return L.isUndefined(o[key]) ? match : o[key];
2006
 
    }) : s;
2007
 
};
2008
 
 
2009
 
/**
2010
 
 * Returns a string without any leading or trailing whitespace.  If
2011
 
 * the input is not a string, the input will be returned untouched.
2012
 
 * @method trim
2013
 
 * @static
2014
 
 * @param s {string} the string to trim.
2015
 
 * @return {string} the trimmed string.
2016
 
 */
2017
 
L.trim = STRING_PROTO.trim ? function(s) {
2018
 
    return s && s.trim ? s.trim() : s;
2019
 
} : function (s) {
2020
 
    try {
2021
 
        return s.replace(TRIMREGEX, '');
2022
 
    } catch (e) {
2023
 
        return s;
2024
 
    }
2025
 
};
2026
 
 
2027
 
/**
2028
 
 * Returns a string without any leading whitespace.
2029
 
 * @method trimLeft
2030
 
 * @static
2031
 
 * @param s {string} the string to trim.
2032
 
 * @return {string} the trimmed string.
2033
 
 */
2034
 
L.trimLeft = STRING_PROTO.trimLeft ? function (s) {
2035
 
    return s.trimLeft();
2036
 
} : function (s) {
2037
 
    return s.replace(/^\s+/, '');
2038
 
};
2039
 
 
2040
 
/**
2041
 
 * Returns a string without any trailing whitespace.
2042
 
 * @method trimRight
2043
 
 * @static
2044
 
 * @param s {string} the string to trim.
2045
 
 * @return {string} the trimmed string.
2046
 
 */
2047
 
L.trimRight = STRING_PROTO.trimRight ? function (s) {
2048
 
    return s.trimRight();
2049
 
} : function (s) {
2050
 
    return s.replace(/\s+$/, '');
2051
 
};
2052
 
 
2053
 
/**
2054
 
Returns one of the following strings, representing the type of the item passed
2055
 
in:
2056
 
 
2057
 
 * "array"
2058
 
 * "boolean"
2059
 
 * "date"
2060
 
 * "error"
2061
 
 * "function"
2062
 
 * "null"
2063
 
 * "number"
2064
 
 * "object"
2065
 
 * "regexp"
2066
 
 * "string"
2067
 
 * "undefined"
2068
 
 
2069
 
Known issues:
2070
 
 
2071
 
 * `typeof HTMLElementCollection` returns function in Safari, but
2072
 
    `Y.Lang.type()` reports "object", which could be a good thing --
2073
 
    but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
2074
 
 
2075
 
@method type
2076
 
@param o the item to test.
2077
 
@return {string} the detected type.
2078
 
@static
2079
 
**/
2080
 
L.type = function(o) {
2081
 
    return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
2082
 
};
2083
 
/**
2084
 
@module yui
2085
 
@submodule yui-base
2086
 
*/
2087
 
 
2088
 
var Lang   = Y.Lang,
2089
 
    Native = Array.prototype,
2090
 
 
2091
 
    hasOwn = Object.prototype.hasOwnProperty;
2092
 
 
2093
 
/**
2094
 
Provides utility methods for working with arrays. Additional array helpers can
2095
 
be found in the `collection` and `array-extras` modules.
2096
 
 
2097
 
`Y.Array(thing)` returns a native array created from _thing_. Depending on
2098
 
_thing_'s type, one of the following will happen:
2099
 
 
2100
 
  * Arrays are returned unmodified unless a non-zero _startIndex_ is
2101
 
    specified.
2102
 
  * Array-like collections (see `Array.test()`) are converted to arrays.
2103
 
  * For everything else, a new array is created with _thing_ as the sole
2104
 
    item.
2105
 
 
2106
 
Note: elements that are also collections, such as `<form>` and `<select>`
2107
 
elements, are not automatically converted to arrays. To force a conversion,
2108
 
pass `true` as the value of the _force_ parameter.
2109
 
 
2110
 
@class Array
2111
 
@constructor
2112
 
@param {Any} thing The thing to arrayify.
2113
 
@param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
2114
 
  collection, a subset of items starting at the specified index will be
2115
 
  returned.
2116
 
@param {Boolean} [force=false] If `true`, _thing_ will be treated as an
2117
 
  array-like collection no matter what.
2118
 
@return {Array} A native array created from _thing_, according to the rules
2119
 
  described above.
2120
 
**/
2121
 
function YArray(thing, startIndex, force) {
2122
 
    var len, result;
2123
 
 
2124
 
    /*jshint expr: true*/
2125
 
    startIndex || (startIndex = 0);
2126
 
 
2127
 
    if (force || YArray.test(thing)) {
2128
 
        // IE throws when trying to slice HTMLElement collections.
2129
 
        try {
2130
 
            return Native.slice.call(thing, startIndex);
2131
 
        } catch (ex) {
2132
 
            result = [];
2133
 
 
2134
 
            for (len = thing.length; startIndex < len; ++startIndex) {
2135
 
                result.push(thing[startIndex]);
2136
 
            }
2137
 
 
2138
 
            return result;
2139
 
        }
2140
 
    }
2141
 
 
2142
 
    return [thing];
2143
 
}
2144
 
 
2145
 
Y.Array = YArray;
2146
 
 
2147
 
/**
2148
 
Dedupes an array of strings, returning an array that's guaranteed to contain
2149
 
only one copy of a given string.
2150
 
 
2151
 
This method differs from `Array.unique()` in that it's optimized for use only
2152
 
with strings, whereas `unique` may be used with other types (but is slower).
2153
 
Using `dedupe()` with non-string values may result in unexpected behavior.
2154
 
 
2155
 
@method dedupe
2156
 
@param {String[]} array Array of strings to dedupe.
2157
 
@return {Array} Deduped copy of _array_.
2158
 
@static
2159
 
@since 3.4.0
2160
 
**/
2161
 
YArray.dedupe = function (array) {
2162
 
    var hash    = {},
2163
 
        results = [],
2164
 
        i, item, len;
2165
 
 
2166
 
    for (i = 0, len = array.length; i < len; ++i) {
2167
 
        item = array[i];
2168
 
 
2169
 
        if (!hasOwn.call(hash, item)) {
2170
 
            hash[item] = 1;
2171
 
            results.push(item);
2172
 
        }
2173
 
    }
2174
 
 
2175
 
    return results;
2176
 
};
2177
 
 
2178
 
/**
2179
 
Executes the supplied function on each item in the array. This method wraps
2180
 
the native ES5 `Array.forEach()` method if available.
2181
 
 
2182
 
@method each
2183
 
@param {Array} array Array to iterate.
2184
 
@param {Function} fn Function to execute on each item in the array. The function
2185
 
  will receive the following arguments:
2186
 
    @param {Any} fn.item Current array item.
2187
 
    @param {Number} fn.index Current array index.
2188
 
    @param {Array} fn.array Array being iterated.
2189
 
@param {Object} [thisObj] `this` object to use when calling _fn_.
2190
 
@return {YUI} The YUI instance.
2191
 
@static
2192
 
**/
2193
 
YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) {
2194
 
    Native.forEach.call(array || [], fn, thisObj || Y);
2195
 
    return Y;
2196
 
} : function (array, fn, thisObj) {
2197
 
    for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
2198
 
        if (i in array) {
2199
 
            fn.call(thisObj || Y, array[i], i, array);
2200
 
        }
2201
 
    }
2202
 
 
2203
 
    return Y;
2204
 
};
2205
 
 
2206
 
/**
2207
 
Alias for `each()`.
2208
 
 
2209
 
@method forEach
2210
 
@static
2211
 
**/
2212
 
 
2213
 
/**
2214
 
Returns an object using the first array as keys and the second as values. If
2215
 
the second array is not provided, or if it doesn't contain the same number of
2216
 
values as the first array, then `true` will be used in place of the missing
2217
 
values.
2218
 
 
2219
 
@example
2220
 
 
2221
 
    Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
2222
 
    // => {a: 'foo', b: 'bar', c: true}
2223
 
 
2224
 
@method hash
2225
 
@param {String[]} keys Array of strings to use as keys.
2226
 
@param {Array} [values] Array to use as values.
2227
 
@return {Object} Hash using the first array as keys and the second as values.
2228
 
@static
2229
 
**/
2230
 
YArray.hash = function (keys, values) {
2231
 
    var hash = {},
2232
 
        vlen = (values && values.length) || 0,
2233
 
        i, len;
2234
 
 
2235
 
    for (i = 0, len = keys.length; i < len; ++i) {
2236
 
        if (i in keys) {
2237
 
            hash[keys[i]] = vlen > i && i in values ? values[i] : true;
2238
 
        }
2239
 
    }
2240
 
 
2241
 
    return hash;
2242
 
};
2243
 
 
2244
 
/**
2245
 
Returns the index of the first item in the array that's equal (using a strict
2246
 
equality check) to the specified _value_, or `-1` if the value isn't found.
2247
 
 
2248
 
This method wraps the native ES5 `Array.indexOf()` method if available.
2249
 
 
2250
 
@method indexOf
2251
 
@param {Array} array Array to search.
2252
 
@param {Any} value Value to search for.
2253
 
@param {Number} [from=0] The index at which to begin the search.
2254
 
@return {Number} Index of the item strictly equal to _value_, or `-1` if not
2255
 
    found.
2256
 
@static
2257
 
**/
2258
 
YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) {
2259
 
    return Native.indexOf.call(array, value, from);
2260
 
} : function (array, value, from) {
2261
 
    // http://es5.github.com/#x15.4.4.14
2262
 
    var len = array.length;
2263
 
 
2264
 
    from = +from || 0;
2265
 
    from = (from > 0 || -1) * Math.floor(Math.abs(from));
2266
 
 
2267
 
    if (from < 0) {
2268
 
        from += len;
2269
 
 
2270
 
        if (from < 0) {
2271
 
            from = 0;
2272
 
        }
2273
 
    }
2274
 
 
2275
 
    for (; from < len; ++from) {
2276
 
        if (from in array && array[from] === value) {
2277
 
            return from;
2278
 
        }
2279
 
    }
2280
 
 
2281
 
    return -1;
2282
 
};
2283
 
 
2284
 
/**
2285
 
Numeric sort convenience function.
2286
 
 
2287
 
The native `Array.prototype.sort()` function converts values to strings and
2288
 
sorts them in lexicographic order, which is unsuitable for sorting numeric
2289
 
values. Provide `Array.numericSort` as a custom sort function when you want
2290
 
to sort values in numeric order.
2291
 
 
2292
 
@example
2293
 
 
2294
 
    [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
2295
 
    // => [4, 8, 15, 16, 23, 42]
2296
 
 
2297
 
@method numericSort
2298
 
@param {Number} a First value to compare.
2299
 
@param {Number} b Second value to compare.
2300
 
@return {Number} Difference between _a_ and _b_.
2301
 
@static
2302
 
**/
2303
 
YArray.numericSort = function (a, b) {
2304
 
    return a - b;
2305
 
};
2306
 
 
2307
 
/**
2308
 
Executes the supplied function on each item in the array. Returning a truthy
2309
 
value from the function will stop the processing of remaining items.
2310
 
 
2311
 
@method some
2312
 
@param {Array} array Array to iterate over.
2313
 
@param {Function} fn Function to execute on each item. The function will receive
2314
 
  the following arguments:
2315
 
    @param {Any} fn.value Current array item.
2316
 
    @param {Number} fn.index Current array index.
2317
 
    @param {Array} fn.array Array being iterated over.
2318
 
@param {Object} [thisObj] `this` object to use when calling _fn_.
2319
 
@return {Boolean} `true` if the function returns a truthy value on any of the
2320
 
  items in the array; `false` otherwise.
2321
 
@static
2322
 
**/
2323
 
YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) {
2324
 
    return Native.some.call(array, fn, thisObj);
2325
 
} : function (array, fn, thisObj) {
2326
 
    for (var i = 0, len = array.length; i < len; ++i) {
2327
 
        if (i in array && fn.call(thisObj, array[i], i, array)) {
2328
 
            return true;
2329
 
        }
2330
 
    }
2331
 
 
2332
 
    return false;
2333
 
};
2334
 
 
2335
 
/**
2336
 
Evaluates _obj_ to determine if it's an array, an array-like collection, or
2337
 
something else. This is useful when working with the function `arguments`
2338
 
collection and `HTMLElement` collections.
2339
 
 
2340
 
Note: This implementation doesn't consider elements that are also
2341
 
collections, such as `<form>` and `<select>`, to be array-like.
2342
 
 
2343
 
@method test
2344
 
@param {Object} obj Object to test.
2345
 
@return {Number} A number indicating the results of the test:
2346
 
 
2347
 
  * 0: Neither an array nor an array-like collection.
2348
 
  * 1: Real array.
2349
 
  * 2: Array-like collection.
2350
 
 
2351
 
@static
2352
 
**/
2353
 
YArray.test = function (obj) {
2354
 
    var result = 0;
2355
 
 
2356
 
    if (Lang.isArray(obj)) {
2357
 
        result = 1;
2358
 
    } else if (Lang.isObject(obj)) {
2359
 
        try {
2360
 
            // indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here),
2361
 
            // or functions without apply/call (Safari
2362
 
            // HTMLElementCollection bug).
2363
 
            if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) {
2364
 
                result = 2;
2365
 
            }
2366
 
        } catch (ex) {}
2367
 
    }
2368
 
 
2369
 
    return result;
2370
 
};
2371
 
/**
2372
 
 * The YUI module contains the components required for building the YUI
2373
 
 * seed file.  This includes the script loading mechanism, a simple queue,
2374
 
 * and the core utilities for the library.
2375
 
 * @module yui
2376
 
 * @submodule yui-base
2377
 
 */
2378
 
 
2379
 
/**
2380
 
 * A simple FIFO queue.  Items are added to the Queue with add(1..n items) and
2381
 
 * removed using next().
2382
 
 *
2383
 
 * @class Queue
2384
 
 * @constructor
2385
 
 * @param {MIXED} item* 0..n items to seed the queue.
2386
 
 */
2387
 
function Queue() {
2388
 
    this._init();
2389
 
    this.add.apply(this, arguments);
2390
 
}
2391
 
 
2392
 
Queue.prototype = {
2393
 
    /**
2394
 
     * Initialize the queue
2395
 
     *
2396
 
     * @method _init
2397
 
     * @protected
2398
 
     */
2399
 
    _init: function() {
2400
 
        /**
2401
 
         * The collection of enqueued items
2402
 
         *
2403
 
         * @property _q
2404
 
         * @type Array
2405
 
         * @protected
2406
 
         */
2407
 
        this._q = [];
2408
 
    },
2409
 
 
2410
 
    /**
2411
 
     * Get the next item in the queue. FIFO support
2412
 
     *
2413
 
     * @method next
2414
 
     * @return {MIXED} the next item in the queue.
2415
 
     */
2416
 
    next: function() {
2417
 
        return this._q.shift();
2418
 
    },
2419
 
 
2420
 
    /**
2421
 
     * Get the last in the queue. LIFO support.
2422
 
     *
2423
 
     * @method last
2424
 
     * @return {MIXED} the last item in the queue.
2425
 
     */
2426
 
    last: function() {
2427
 
        return this._q.pop();
2428
 
    },
2429
 
 
2430
 
    /**
2431
 
     * Add 0..n items to the end of the queue.
2432
 
     *
2433
 
     * @method add
2434
 
     * @param {MIXED} item* 0..n items.
2435
 
     * @return {object} this queue.
2436
 
     */
2437
 
    add: function() {
2438
 
        this._q.push.apply(this._q, arguments);
2439
 
 
2440
 
        return this;
2441
 
    },
2442
 
 
2443
 
    /**
2444
 
     * Returns the current number of queued items.
2445
 
     *
2446
 
     * @method size
2447
 
     * @return {Number} The size.
2448
 
     */
2449
 
    size: function() {
2450
 
        return this._q.length;
2451
 
    }
2452
 
};
2453
 
 
2454
 
Y.Queue = Queue;
2455
 
 
2456
 
YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
2457
 
 
2458
 
/**
2459
 
The YUI module contains the components required for building the YUI seed file.
2460
 
This includes the script loading mechanism, a simple queue, and the core
2461
 
utilities for the library.
2462
 
 
2463
 
@module yui
2464
 
@submodule yui-base
2465
 
**/
2466
 
 
2467
 
var CACHED_DELIMITER = '__',
2468
 
 
2469
 
    hasOwn   = Object.prototype.hasOwnProperty,
2470
 
    isObject = Y.Lang.isObject;
2471
 
 
2472
 
/**
2473
 
Returns a wrapper for a function which caches the return value of that function,
2474
 
keyed off of the combined string representation of the argument values provided
2475
 
when the wrapper is called.
2476
 
 
2477
 
Calling this function again with the same arguments will return the cached value
2478
 
rather than executing the wrapped function.
2479
 
 
2480
 
Note that since the cache is keyed off of the string representation of arguments
2481
 
passed to the wrapper function, arguments that aren't strings and don't provide
2482
 
a meaningful `toString()` method may result in unexpected caching behavior. For
2483
 
example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
2484
 
string `[object Object]` when used as a cache key.
2485
 
 
2486
 
@method cached
2487
 
@param {Function} source The function to memoize.
2488
 
@param {Object} [cache={}] Object in which to store cached values. You may seed
2489
 
  this object with pre-existing cached values if desired.
2490
 
@param {any} [refetch] If supplied, this value is compared with the cached value
2491
 
  using a `==` comparison. If the values are equal, the wrapped function is
2492
 
  executed again even though a cached value exists.
2493
 
@return {Function} Wrapped function.
2494
 
@for YUI
2495
 
**/
2496
 
Y.cached = function (source, cache, refetch) {
2497
 
    /*jshint expr: true*/
2498
 
    cache || (cache = {});
2499
 
 
2500
 
    return function (arg) {
2501
 
        var key = arguments.length > 1 ?
2502
 
                Array.prototype.join.call(arguments, CACHED_DELIMITER) :
2503
 
                String(arg);
2504
 
        
2505
 
        /*jshint eqeqeq: false*/
2506
 
        if (!(key in cache) || (refetch && cache[key] == refetch)) {
2507
 
            cache[key] = source.apply(source, arguments);
2508
 
        }
2509
 
 
2510
 
        return cache[key];
2511
 
    };
2512
 
};
2513
 
 
2514
 
/**
2515
 
Returns the `location` object from the window/frame in which this YUI instance
2516
 
operates, or `undefined` when executing in a non-browser environment
2517
 
(e.g. Node.js).
2518
 
 
2519
 
It is _not_ recommended to hold references to the `window.location` object
2520
 
outside of the scope of a function in which its properties are being accessed or
2521
 
its methods are being called. This is because of a nasty bug/issue that exists
2522
 
in both Safari and MobileSafari browsers:
2523
 
[WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679).
2524
 
 
2525
 
@method getLocation
2526
 
@return {location} The `location` object from the window/frame in which this YUI
2527
 
    instance operates.
2528
 
@since 3.5.0
2529
 
**/
2530
 
Y.getLocation = function () {
2531
 
    // It is safer to look this up every time because yui-base is attached to a
2532
 
    // YUI instance before a user's config is applied; i.e. `Y.config.win` does
2533
 
    // not point the correct window object when this file is loaded.
2534
 
    var win = Y.config.win;
2535
 
 
2536
 
    // It is not safe to hold a reference to the `location` object outside the
2537
 
    // scope in which it is being used. The WebKit engine used in Safari and
2538
 
    // MobileSafari will "disconnect" the `location` object from the `window`
2539
 
    // when a page is restored from back/forward history cache.
2540
 
    return win && win.location;
2541
 
};
2542
 
 
2543
 
/**
2544
 
Returns a new object containing all of the properties of all the supplied
2545
 
objects. The properties from later objects will overwrite those in earlier
2546
 
objects.
2547
 
 
2548
 
Passing in a single object will create a shallow copy of it. For a deep copy,
2549
 
use `clone()`.
2550
 
 
2551
 
@method merge
2552
 
@param {Object} objects* One or more objects to merge.
2553
 
@return {Object} A new merged object.
2554
 
**/
2555
 
Y.merge = function () {
2556
 
    var i      = 0,
2557
 
        len    = arguments.length,
2558
 
        result = {},
2559
 
        key,
2560
 
        obj;
2561
 
 
2562
 
    for (; i < len; ++i) {
2563
 
        obj = arguments[i];
2564
 
 
2565
 
        for (key in obj) {
2566
 
            if (hasOwn.call(obj, key)) {
2567
 
                result[key] = obj[key];
2568
 
            }
2569
 
        }
2570
 
    }
2571
 
 
2572
 
    return result;
2573
 
};
2574
 
 
2575
 
/**
2576
 
Mixes _supplier_'s properties into _receiver_.
2577
 
 
2578
 
Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
2579
 
shadowed unless the _overwrite_ parameter is `true`, and will not be merged
2580
 
unless the _merge_ parameter is `true`.
2581
 
 
2582
 
In the default mode (0), only properties the supplier owns are copied (prototype
2583
 
properties are not copied). The following copying modes are available:
2584
 
 
2585
 
  * `0`: _Default_. Object to object.
2586
 
  * `1`: Prototype to prototype.
2587
 
  * `2`: Prototype to prototype and object to object.
2588
 
  * `3`: Prototype to object.
2589
 
  * `4`: Object to prototype.
2590
 
 
2591
 
@method mix
2592
 
@param {Function|Object} receiver The object or function to receive the mixed
2593
 
  properties.
2594
 
@param {Function|Object} supplier The object or function supplying the
2595
 
  properties to be mixed.
2596
 
@param {Boolean} [overwrite=false] If `true`, properties that already exist
2597
 
  on the receiver will be overwritten with properties from the supplier.
2598
 
@param {String[]} [whitelist] An array of property names to copy. If
2599
 
  specified, only the whitelisted properties will be copied, and all others
2600
 
  will be ignored.
2601
 
@param {Number} [mode=0] Mix mode to use. See above for available modes.
2602
 
@param {Boolean} [merge=false] If `true`, objects and arrays that already
2603
 
  exist on the receiver will have the corresponding object/array from the
2604
 
  supplier merged into them, rather than being skipped or overwritten. When
2605
 
  both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
2606
 
@return {Function|Object|YUI} The receiver, or the YUI instance if the
2607
 
  specified receiver is falsy.
2608
 
**/
2609
 
Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
2610
 
    var alwaysOverwrite, exists, from, i, key, len, to;
2611
 
 
2612
 
    // If no supplier is given, we return the receiver. If no receiver is given,
2613
 
    // we return Y. Returning Y doesn't make much sense to me, but it's
2614
 
    // grandfathered in for backcompat reasons.
2615
 
    if (!receiver || !supplier) {
2616
 
        return receiver || Y;
2617
 
    }
2618
 
 
2619
 
    if (mode) {
2620
 
        // In mode 2 (prototype to prototype and object to object), we recurse
2621
 
        // once to do the proto to proto mix. The object to object mix will be
2622
 
        // handled later on.
2623
 
        if (mode === 2) {
2624
 
            Y.mix(receiver.prototype, supplier.prototype, overwrite,
2625
 
                    whitelist, 0, merge);
2626
 
        }
2627
 
 
2628
 
        // Depending on which mode is specified, we may be copying from or to
2629
 
        // the prototypes of the supplier and receiver.
2630
 
        from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
2631
 
        to   = mode === 1 || mode === 4 ? receiver.prototype : receiver;
2632
 
 
2633
 
        // If either the supplier or receiver doesn't actually have a
2634
 
        // prototype property, then we could end up with an undefined `from`
2635
 
        // or `to`. If that happens, we abort and return the receiver.
2636
 
        if (!from || !to) {
2637
 
            return receiver;
2638
 
        }
2639
 
    } else {
2640
 
        from = supplier;
2641
 
        to   = receiver;
2642
 
    }
2643
 
 
2644
 
    // If `overwrite` is truthy and `merge` is falsy, then we can skip a
2645
 
    // property existence check on each iteration and save some time.
2646
 
    alwaysOverwrite = overwrite && !merge;
2647
 
 
2648
 
    if (whitelist) {
2649
 
        for (i = 0, len = whitelist.length; i < len; ++i) {
2650
 
            key = whitelist[i];
2651
 
 
2652
 
            // We call `Object.prototype.hasOwnProperty` instead of calling
2653
 
            // `hasOwnProperty` on the object itself, since the object's
2654
 
            // `hasOwnProperty` method may have been overridden or removed.
2655
 
            // Also, some native objects don't implement a `hasOwnProperty`
2656
 
            // method.
2657
 
            if (!hasOwn.call(from, key)) {
2658
 
                continue;
2659
 
            }
2660
 
 
2661
 
            // The `key in to` check here is (sadly) intentional for backwards
2662
 
            // compatibility reasons. It prevents undesired shadowing of
2663
 
            // prototype members on `to`.
2664
 
            exists = alwaysOverwrite ? false : key in to;
2665
 
 
2666
 
            if (merge && exists && isObject(to[key], true)
2667
 
                    && isObject(from[key], true)) {
2668
 
                // If we're in merge mode, and the key is present on both
2669
 
                // objects, and the value on both objects is either an object or
2670
 
                // an array (but not a function), then we recurse to merge the
2671
 
                // `from` value into the `to` value instead of overwriting it.
2672
 
                //
2673
 
                // Note: It's intentional that the whitelist isn't passed to the
2674
 
                // recursive call here. This is legacy behavior that lots of
2675
 
                // code still depends on.
2676
 
                Y.mix(to[key], from[key], overwrite, null, 0, merge);
2677
 
            } else if (overwrite || !exists) {
2678
 
                // We're not in merge mode, so we'll only copy the `from` value
2679
 
                // to the `to` value if we're in overwrite mode or if the
2680
 
                // current key doesn't exist on the `to` object.
2681
 
                to[key] = from[key];
2682
 
            }
2683
 
        }
2684
 
    } else {
2685
 
        for (key in from) {
2686
 
            // The code duplication here is for runtime performance reasons.
2687
 
            // Combining whitelist and non-whitelist operations into a single
2688
 
            // loop or breaking the shared logic out into a function both result
2689
 
            // in worse performance, and Y.mix is critical enough that the byte
2690
 
            // tradeoff is worth it.
2691
 
            if (!hasOwn.call(from, key)) {
2692
 
                continue;
2693
 
            }
2694
 
 
2695
 
            // The `key in to` check here is (sadly) intentional for backwards
2696
 
            // compatibility reasons. It prevents undesired shadowing of
2697
 
            // prototype members on `to`.
2698
 
            exists = alwaysOverwrite ? false : key in to;
2699
 
 
2700
 
            if (merge && exists && isObject(to[key], true)
2701
 
                    && isObject(from[key], true)) {
2702
 
                Y.mix(to[key], from[key], overwrite, null, 0, merge);
2703
 
            } else if (overwrite || !exists) {
2704
 
                to[key] = from[key];
2705
 
            }
2706
 
        }
2707
 
 
2708
 
        // If this is an IE browser with the JScript enumeration bug, force
2709
 
        // enumeration of the buggy properties by making a recursive call with
2710
 
        // the buggy properties as the whitelist.
2711
 
        if (Y.Object._hasEnumBug) {
2712
 
            Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
2713
 
        }
2714
 
    }
2715
 
 
2716
 
    return receiver;
2717
 
};
2718
 
/**
2719
 
 * The YUI module contains the components required for building the YUI
2720
 
 * seed file.  This includes the script loading mechanism, a simple queue,
2721
 
 * and the core utilities for the library.
2722
 
 * @module yui
2723
 
 * @submodule yui-base
2724
 
 */
2725
 
 
2726
 
/**
2727
 
 * Adds utilities to the YUI instance for working with objects.
2728
 
 *
2729
 
 * @class Object
2730
 
 */
2731
 
 
2732
 
var Lang   = Y.Lang,
2733
 
    hasOwn = Object.prototype.hasOwnProperty,
2734
 
 
2735
 
    UNDEFINED, // <-- Note the comma. We're still declaring vars.
2736
 
 
2737
 
/**
2738
 
 * Returns a new object that uses _obj_ as its prototype. This method wraps the
2739
 
 * native ES5 `Object.create()` method if available, but doesn't currently
2740
 
 * pass through `Object.create()`'s second argument (properties) in order to
2741
 
 * ensure compatibility with older browsers.
2742
 
 *
2743
 
 * @method ()
2744
 
 * @param {Object} obj Prototype object.
2745
 
 * @return {Object} New object using _obj_ as its prototype.
2746
 
 * @static
2747
 
 */
2748
 
O = Y.Object = Lang._isNative(Object.create) ? function (obj) {
2749
 
    // We currently wrap the native Object.create instead of simply aliasing it
2750
 
    // to ensure consistency with our fallback shim, which currently doesn't
2751
 
    // support Object.create()'s second argument (properties). Once we have a
2752
 
    // safe fallback for the properties arg, we can stop wrapping
2753
 
    // Object.create().
2754
 
    return Object.create(obj);
2755
 
} : (function () {
2756
 
    // Reusable constructor function for the Object.create() shim.
2757
 
    function F() {}
2758
 
 
2759
 
    // The actual shim.
2760
 
    return function (obj) {
2761
 
        F.prototype = obj;
2762
 
        return new F();
2763
 
    };
2764
 
}()),
2765
 
 
2766
 
/**
2767
 
 * Property names that IE doesn't enumerate in for..in loops, even when they
2768
 
 * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
2769
 
 * manually enumerate these properties.
2770
 
 *
2771
 
 * @property _forceEnum
2772
 
 * @type String[]
2773
 
 * @protected
2774
 
 * @static
2775
 
 */
2776
 
forceEnum = O._forceEnum = [
2777
 
    'hasOwnProperty',
2778
 
    'isPrototypeOf',
2779
 
    'propertyIsEnumerable',
2780
 
    'toString',
2781
 
    'toLocaleString',
2782
 
    'valueOf'
2783
 
],
2784
 
 
2785
 
/**
2786
 
 * `true` if this browser has the JScript enumeration bug that prevents
2787
 
 * enumeration of the properties named in the `_forceEnum` array, `false`
2788
 
 * otherwise.
2789
 
 *
2790
 
 * See:
2791
 
 *   - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
2792
 
 *   - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
2793
 
 *
2794
 
 * @property _hasEnumBug
2795
 
 * @type Boolean
2796
 
 * @protected
2797
 
 * @static
2798
 
 */
2799
 
hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
2800
 
 
2801
 
/**
2802
 
 * `true` if this browser incorrectly considers the `prototype` property of
2803
 
 * functions to be enumerable. Currently known to affect Opera 11.50.
2804
 
 *
2805
 
 * @property _hasProtoEnumBug
2806
 
 * @type Boolean
2807
 
 * @protected
2808
 
 * @static
2809
 
 */
2810
 
hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
2811
 
 
2812
 
/**
2813
 
 * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
2814
 
 * exists only on _obj_'s prototype. This is essentially a safer version of
2815
 
 * `obj.hasOwnProperty()`.
2816
 
 *
2817
 
 * @method owns
2818
 
 * @param {Object} obj Object to test.
2819
 
 * @param {String} key Property name to look for.
2820
 
 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
2821
 
 * @static
2822
 
 */
2823
 
owns = O.owns = function (obj, key) {
2824
 
    return !!obj && hasOwn.call(obj, key);
2825
 
}; // <-- End of var declarations.
2826
 
 
2827
 
/**
2828
 
 * Alias for `owns()`.
2829
 
 *
2830
 
 * @method hasKey
2831
 
 * @param {Object} obj Object to test.
2832
 
 * @param {String} key Property name to look for.
2833
 
 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
2834
 
 * @static
2835
 
 */
2836
 
O.hasKey = owns;
2837
 
 
2838
 
/**
2839
 
 * Returns an array containing the object's enumerable keys. Does not include
2840
 
 * prototype keys or non-enumerable keys.
2841
 
 *
2842
 
 * Note that keys are returned in enumeration order (that is, in the same order
2843
 
 * that they would be enumerated by a `for-in` loop), which may not be the same
2844
 
 * as the order in which they were defined.
2845
 
 *
2846
 
 * This method is an alias for the native ES5 `Object.keys()` method if
2847
 
 * available.
2848
 
 *
2849
 
 * @example
2850
 
 *
2851
 
 *     Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
2852
 
 *     // => ['a', 'b', 'c']
2853
 
 *
2854
 
 * @method keys
2855
 
 * @param {Object} obj An object.
2856
 
 * @return {String[]} Array of keys.
2857
 
 * @static
2858
 
 */
2859
 
O.keys = Lang._isNative(Object.keys) ? Object.keys : function (obj) {
2860
 
    if (!Lang.isObject(obj)) {
2861
 
        throw new TypeError('Object.keys called on a non-object');
2862
 
    }
2863
 
 
2864
 
    var keys = [],
2865
 
        i, key, len;
2866
 
 
2867
 
    if (hasProtoEnumBug && typeof obj === 'function') {
2868
 
        for (key in obj) {
2869
 
            if (owns(obj, key) && key !== 'prototype') {
2870
 
                keys.push(key);
2871
 
            }
2872
 
        }
2873
 
    } else {
2874
 
        for (key in obj) {
2875
 
            if (owns(obj, key)) {
2876
 
                keys.push(key);
2877
 
            }
2878
 
        }
2879
 
    }
2880
 
 
2881
 
    if (hasEnumBug) {
2882
 
        for (i = 0, len = forceEnum.length; i < len; ++i) {
2883
 
            key = forceEnum[i];
2884
 
 
2885
 
            if (owns(obj, key)) {
2886
 
                keys.push(key);
2887
 
            }
2888
 
        }
2889
 
    }
2890
 
 
2891
 
    return keys;
2892
 
};
2893
 
 
2894
 
/**
2895
 
 * Returns an array containing the values of the object's enumerable keys.
2896
 
 *
2897
 
 * Note that values are returned in enumeration order (that is, in the same
2898
 
 * order that they would be enumerated by a `for-in` loop), which may not be the
2899
 
 * same as the order in which they were defined.
2900
 
 *
2901
 
 * @example
2902
 
 *
2903
 
 *     Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
2904
 
 *     // => ['foo', 'bar', 'baz']
2905
 
 *
2906
 
 * @method values
2907
 
 * @param {Object} obj An object.
2908
 
 * @return {Array} Array of values.
2909
 
 * @static
2910
 
 */
2911
 
O.values = function (obj) {
2912
 
    var keys   = O.keys(obj),
2913
 
        i      = 0,
2914
 
        len    = keys.length,
2915
 
        values = [];
2916
 
 
2917
 
    for (; i < len; ++i) {
2918
 
        values.push(obj[keys[i]]);
2919
 
    }
2920
 
 
2921
 
    return values;
2922
 
};
2923
 
 
2924
 
/**
2925
 
 * Returns the number of enumerable keys owned by an object.
2926
 
 *
2927
 
 * @method size
2928
 
 * @param {Object} obj An object.
2929
 
 * @return {Number} The object's size.
2930
 
 * @static
2931
 
 */
2932
 
O.size = function (obj) {
2933
 
    try {
2934
 
        return O.keys(obj).length;
2935
 
    } catch (ex) {
2936
 
        return 0; // Legacy behavior for non-objects.
2937
 
    }
2938
 
};
2939
 
 
2940
 
/**
2941
 
 * Returns `true` if the object owns an enumerable property with the specified
2942
 
 * value.
2943
 
 *
2944
 
 * @method hasValue
2945
 
 * @param {Object} obj An object.
2946
 
 * @param {any} value The value to search for.
2947
 
 * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
2948
 
 * @static
2949
 
 */
2950
 
O.hasValue = function (obj, value) {
2951
 
    return Y.Array.indexOf(O.values(obj), value) > -1;
2952
 
};
2953
 
 
2954
 
/**
2955
 
 * Executes a function on each enumerable property in _obj_. The function
2956
 
 * receives the value, the key, and the object itself as parameters (in that
2957
 
 * order).
2958
 
 *
2959
 
 * By default, only properties owned by _obj_ are enumerated. To include
2960
 
 * prototype properties, set the _proto_ parameter to `true`.
2961
 
 *
2962
 
 * @method each
2963
 
 * @param {Object} obj Object to enumerate.
2964
 
 * @param {Function} fn Function to execute on each enumerable property.
2965
 
 *   @param {mixed} fn.value Value of the current property.
2966
 
 *   @param {String} fn.key Key of the current property.
2967
 
 *   @param {Object} fn.obj Object being enumerated.
2968
 
 * @param {Object} [thisObj] `this` object to use when calling _fn_.
2969
 
 * @param {Boolean} [proto=false] Include prototype properties.
2970
 
 * @return {YUI} the YUI instance.
2971
 
 * @chainable
2972
 
 * @static
2973
 
 */
2974
 
O.each = function (obj, fn, thisObj, proto) {
2975
 
    var key;
2976
 
 
2977
 
    for (key in obj) {
2978
 
        if (proto || owns(obj, key)) {
2979
 
            fn.call(thisObj || Y, obj[key], key, obj);
2980
 
        }
2981
 
    }
2982
 
 
2983
 
    return Y;
2984
 
};
2985
 
 
2986
 
/**
2987
 
 * Executes a function on each enumerable property in _obj_, but halts if the
2988
 
 * function returns a truthy value. The function receives the value, the key,
2989
 
 * and the object itself as paramters (in that order).
2990
 
 *
2991
 
 * By default, only properties owned by _obj_ are enumerated. To include
2992
 
 * prototype properties, set the _proto_ parameter to `true`.
2993
 
 *
2994
 
 * @method some
2995
 
 * @param {Object} obj Object to enumerate.
2996
 
 * @param {Function} fn Function to execute on each enumerable property.
2997
 
 *   @param {mixed} fn.value Value of the current property.
2998
 
 *   @param {String} fn.key Key of the current property.
2999
 
 *   @param {Object} fn.obj Object being enumerated.
3000
 
 * @param {Object} [thisObj] `this` object to use when calling _fn_.
3001
 
 * @param {Boolean} [proto=false] Include prototype properties.
3002
 
 * @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
3003
 
 *   `false` otherwise.
3004
 
 * @static
3005
 
 */
3006
 
O.some = function (obj, fn, thisObj, proto) {
3007
 
    var key;
3008
 
 
3009
 
    for (key in obj) {
3010
 
        if (proto || owns(obj, key)) {
3011
 
            if (fn.call(thisObj || Y, obj[key], key, obj)) {
3012
 
                return true;
3013
 
            }
3014
 
        }
3015
 
    }
3016
 
 
3017
 
    return false;
3018
 
};
3019
 
 
3020
 
/**
3021
 
 * Retrieves the sub value at the provided path,
3022
 
 * from the value object provided.
3023
 
 *
3024
 
 * @method getValue
3025
 
 * @static
3026
 
 * @param o The object from which to extract the property value.
3027
 
 * @param path {Array} A path array, specifying the object traversal path
3028
 
 * from which to obtain the sub value.
3029
 
 * @return {Any} The value stored in the path, undefined if not found,
3030
 
 * undefined if the source is not an object.  Returns the source object
3031
 
 * if an empty path is provided.
3032
 
 */
3033
 
O.getValue = function(o, path) {
3034
 
    if (!Lang.isObject(o)) {
3035
 
        return UNDEFINED;
3036
 
    }
3037
 
 
3038
 
    var i,
3039
 
        p = Y.Array(path),
3040
 
        l = p.length;
3041
 
 
3042
 
    for (i = 0; o !== UNDEFINED && i < l; i++) {
3043
 
        o = o[p[i]];
3044
 
    }
3045
 
 
3046
 
    return o;
3047
 
};
3048
 
 
3049
 
/**
3050
 
 * Sets the sub-attribute value at the provided path on the
3051
 
 * value object.  Returns the modified value object, or
3052
 
 * undefined if the path is invalid.
3053
 
 *
3054
 
 * @method setValue
3055
 
 * @static
3056
 
 * @param o             The object on which to set the sub value.
3057
 
 * @param path {Array}  A path array, specifying the object traversal path
3058
 
 *                      at which to set the sub value.
3059
 
 * @param val {Any}     The new value for the sub-attribute.
3060
 
 * @return {Object}     The modified object, with the new sub value set, or
3061
 
 *                      undefined, if the path was invalid.
3062
 
 */
3063
 
O.setValue = function(o, path, val) {
3064
 
    var i,
3065
 
        p = Y.Array(path),
3066
 
        leafIdx = p.length - 1,
3067
 
        ref = o;
3068
 
 
3069
 
    if (leafIdx >= 0) {
3070
 
        for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
3071
 
            ref = ref[p[i]];
3072
 
        }
3073
 
 
3074
 
        if (ref !== UNDEFINED) {
3075
 
            ref[p[i]] = val;
3076
 
        } else {
3077
 
            return UNDEFINED;
3078
 
        }
3079
 
    }
3080
 
 
3081
 
    return o;
3082
 
};
3083
 
 
3084
 
/**
3085
 
 * Returns `true` if the object has no enumerable properties of its own.
3086
 
 *
3087
 
 * @method isEmpty
3088
 
 * @param {Object} obj An object.
3089
 
 * @return {Boolean} `true` if the object is empty.
3090
 
 * @static
3091
 
 * @since 3.2.0
3092
 
 */
3093
 
O.isEmpty = function (obj) {
3094
 
    return !O.keys(Object(obj)).length;
3095
 
};
3096
 
/**
3097
 
 * The YUI module contains the components required for building the YUI seed
3098
 
 * file.  This includes the script loading mechanism, a simple queue, and the
3099
 
 * core utilities for the library.
3100
 
 * @module yui
3101
 
 * @submodule yui-base
3102
 
 */
3103
 
 
3104
 
/**
3105
 
 * YUI user agent detection.
3106
 
 * Do not fork for a browser if it can be avoided.  Use feature detection when
3107
 
 * you can.  Use the user agent as a last resort.  For all fields listed
3108
 
 * as @type float, UA stores a version number for the browser engine,
3109
 
 * 0 otherwise.  This value may or may not map to the version number of
3110
 
 * the browser using the engine.  The value is presented as a float so
3111
 
 * that it can easily be used for boolean evaluation as well as for
3112
 
 * looking for a particular range of versions.  Because of this,
3113
 
 * some of the granularity of the version info may be lost.  The fields that
3114
 
 * are @type string default to null.  The API docs list the values that
3115
 
 * these fields can have.
3116
 
 * @class UA
3117
 
 * @static
3118
 
 */
3119
 
 
3120
 
/**
3121
 
* Static method on `YUI.Env` for parsing a UA string.  Called at instantiation
3122
 
* to populate `Y.UA`.
3123
 
*
3124
 
* @static
3125
 
* @method parseUA
3126
 
* @param {String} [subUA=navigator.userAgent] UA string to parse
3127
 
* @return {Object} The Y.UA object
3128
 
*/
3129
 
YUI.Env.parseUA = function(subUA) {
3130
 
 
3131
 
    var numberify = function(s) {
3132
 
            var c = 0;
3133
 
            return parseFloat(s.replace(/\./g, function() {
3134
 
                return (c++ === 1) ? '' : '.';
3135
 
            }));
3136
 
        },
3137
 
 
3138
 
        win = Y.config.win,
3139
 
 
3140
 
        nav = win && win.navigator,
3141
 
 
3142
 
        o = {
3143
 
 
3144
 
        /**
3145
 
         * Internet Explorer version number or 0.  Example: 6
3146
 
         * @property ie
3147
 
         * @type float
3148
 
         * @static
3149
 
         */
3150
 
        ie: 0,
3151
 
 
3152
 
        /**
3153
 
         * Opera version number or 0.  Example: 9.2
3154
 
         * @property opera
3155
 
         * @type float
3156
 
         * @static
3157
 
         */
3158
 
        opera: 0,
3159
 
 
3160
 
        /**
3161
 
         * Gecko engine revision number.  Will evaluate to 1 if Gecko
3162
 
         * is detected but the revision could not be found. Other browsers
3163
 
         * will be 0.  Example: 1.8
3164
 
         * <pre>
3165
 
         * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
3166
 
         * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
3167
 
         * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
3168
 
         * Firefox 3.0   <-- 1.9
3169
 
         * Firefox 3.5   <-- 1.91
3170
 
         * </pre>
3171
 
         * @property gecko
3172
 
         * @type float
3173
 
         * @static
3174
 
         */
3175
 
        gecko: 0,
3176
 
 
3177
 
        /**
3178
 
         * AppleWebKit version.  KHTML browsers that are not WebKit browsers
3179
 
         * will evaluate to 1, other browsers 0.  Example: 418.9
3180
 
         * <pre>
3181
 
         * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
3182
 
         *                                   latest available for Mac OSX 10.3.
3183
 
         * Safari 2.0.2:         416     <-- hasOwnProperty introduced
3184
 
         * Safari 2.0.4:         418     <-- preventDefault fixed
3185
 
         * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
3186
 
         *                                   different versions of webkit
3187
 
         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
3188
 
         *                                   updated, but not updated
3189
 
         *                                   to the latest patch.
3190
 
         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native
3191
 
         * SVG and many major issues fixed).
3192
 
         * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic
3193
 
         * update from 2.x via the 10.4.11 OS patch.
3194
 
         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
3195
 
         *                                   yahoo.com user agent hack removed.
3196
 
         * </pre>
3197
 
         * http://en.wikipedia.org/wiki/Safari_version_history
3198
 
         * @property webkit
3199
 
         * @type float
3200
 
         * @static
3201
 
         */
3202
 
        webkit: 0,
3203
 
 
3204
 
        /**
3205
 
         * Safari will be detected as webkit, but this property will also
3206
 
         * be populated with the Safari version number
3207
 
         * @property safari
3208
 
         * @type float
3209
 
         * @static
3210
 
         */
3211
 
        safari: 0,
3212
 
 
3213
 
        /**
3214
 
         * Chrome will be detected as webkit, but this property will also
3215
 
         * be populated with the Chrome version number
3216
 
         * @property chrome
3217
 
         * @type float
3218
 
         * @static
3219
 
         */
3220
 
        chrome: 0,
3221
 
 
3222
 
        /**
3223
 
         * The mobile property will be set to a string containing any relevant
3224
 
         * user agent information when a modern mobile browser is detected.
3225
 
         * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
3226
 
         * devices with the WebKit-based browser, and Opera Mini.
3227
 
         * @property mobile
3228
 
         * @type string
3229
 
         * @default null
3230
 
         * @static
3231
 
         */
3232
 
        mobile: null,
3233
 
 
3234
 
        /**
3235
 
         * Adobe AIR version number or 0.  Only populated if webkit is detected.
3236
 
         * Example: 1.0
3237
 
         * @property air
3238
 
         * @type float
3239
 
         */
3240
 
        air: 0,
3241
 
        /**
3242
 
         * PhantomJS version number or 0.  Only populated if webkit is detected.
3243
 
         * Example: 1.0
3244
 
         * @property phantomjs
3245
 
         * @type float
3246
 
         */
3247
 
        phantomjs: 0,
3248
 
        /**
3249
 
         * Detects Apple iPad's OS version
3250
 
         * @property ipad
3251
 
         * @type float
3252
 
         * @static
3253
 
         */
3254
 
        ipad: 0,
3255
 
        /**
3256
 
         * Detects Apple iPhone's OS version
3257
 
         * @property iphone
3258
 
         * @type float
3259
 
         * @static
3260
 
         */
3261
 
        iphone: 0,
3262
 
        /**
3263
 
         * Detects Apples iPod's OS version
3264
 
         * @property ipod
3265
 
         * @type float
3266
 
         * @static
3267
 
         */
3268
 
        ipod: 0,
3269
 
        /**
3270
 
         * General truthy check for iPad, iPhone or iPod
3271
 
         * @property ios
3272
 
         * @type Boolean
3273
 
         * @default null
3274
 
         * @static
3275
 
         */
3276
 
        ios: null,
3277
 
        /**
3278
 
         * Detects Googles Android OS version
3279
 
         * @property android
3280
 
         * @type float
3281
 
         * @static
3282
 
         */
3283
 
        android: 0,
3284
 
        /**
3285
 
         * Detects Kindle Silk
3286
 
         * @property silk
3287
 
         * @type float
3288
 
         * @static
3289
 
         */
3290
 
        silk: 0,
3291
 
        /**
3292
 
         * Detects Kindle Silk Acceleration
3293
 
         * @property accel
3294
 
         * @type Boolean
3295
 
         * @static
3296
 
         */
3297
 
        accel: false,
3298
 
        /**
3299
 
         * Detects Palms WebOS version
3300
 
         * @property webos
3301
 
         * @type float
3302
 
         * @static
3303
 
         */
3304
 
        webos: 0,
3305
 
 
3306
 
        /**
3307
 
         * Google Caja version number or 0.
3308
 
         * @property caja
3309
 
         * @type float
3310
 
         */
3311
 
        caja: nav && nav.cajaVersion,
3312
 
 
3313
 
        /**
3314
 
         * Set to true if the page appears to be in SSL
3315
 
         * @property secure
3316
 
         * @type boolean
3317
 
         * @static
3318
 
         */
3319
 
        secure: false,
3320
 
 
3321
 
        /**
3322
 
         * The operating system.  Currently only detecting windows or macintosh
3323
 
         * @property os
3324
 
         * @type string
3325
 
         * @default null
3326
 
         * @static
3327
 
         */
3328
 
        os: null,
3329
 
 
3330
 
        /**
3331
 
         * The Nodejs Version
3332
 
         * @property nodejs
3333
 
         * @type float
3334
 
         * @default 0
3335
 
         * @static
3336
 
         */
3337
 
        nodejs: 0,
3338
 
        /**
3339
 
        * Window8/IE10 Application host environment
3340
 
        * @property winjs
3341
 
        * @type Boolean
3342
 
        * @static
3343
 
        */
3344
 
        winjs: !!((typeof Windows !== "undefined") && Windows.System),
3345
 
        /**
3346
 
        * Are touch/msPointer events available on this device
3347
 
        * @property touchEnabled
3348
 
        * @type Boolean
3349
 
        * @static
3350
 
        */
3351
 
        touchEnabled: false
3352
 
    },
3353
 
 
3354
 
    ua = subUA || nav && nav.userAgent,
3355
 
 
3356
 
    loc = win && win.location,
3357
 
 
3358
 
    href = loc && loc.href,
3359
 
 
3360
 
    m;
3361
 
 
3362
 
    /**
3363
 
    * The User Agent string that was parsed
3364
 
    * @property userAgent
3365
 
    * @type String
3366
 
    * @static
3367
 
    */
3368
 
    o.userAgent = ua;
3369
 
 
3370
 
 
3371
 
    o.secure = href && (href.toLowerCase().indexOf('https') === 0);
3372
 
 
3373
 
    if (ua) {
3374
 
 
3375
 
        if ((/windows|win32/i).test(ua)) {
3376
 
            o.os = 'windows';
3377
 
        } else if ((/macintosh|mac_powerpc/i).test(ua)) {
3378
 
            o.os = 'macintosh';
3379
 
        } else if ((/android/i).test(ua)) {
3380
 
            o.os = 'android';
3381
 
        } else if ((/symbos/i).test(ua)) {
3382
 
            o.os = 'symbos';
3383
 
        } else if ((/linux/i).test(ua)) {
3384
 
            o.os = 'linux';
3385
 
        } else if ((/rhino/i).test(ua)) {
3386
 
            o.os = 'rhino';
3387
 
        }
3388
 
 
3389
 
        // Modern KHTML browsers should qualify as Safari X-Grade
3390
 
        if ((/KHTML/).test(ua)) {
3391
 
            o.webkit = 1;
3392
 
        }
3393
 
        if ((/IEMobile|XBLWP7/).test(ua)) {
3394
 
            o.mobile = 'windows';
3395
 
        }
3396
 
        if ((/Fennec/).test(ua)) {
3397
 
            o.mobile = 'gecko';
3398
 
        }
3399
 
        // Modern WebKit browsers are at least X-Grade
3400
 
        m = ua.match(/AppleWebKit\/([^\s]*)/);
3401
 
        if (m && m[1]) {
3402
 
            o.webkit = numberify(m[1]);
3403
 
            o.safari = o.webkit;
3404
 
 
3405
 
            if (/PhantomJS/.test(ua)) {
3406
 
                m = ua.match(/PhantomJS\/([^\s]*)/);
3407
 
                if (m && m[1]) {
3408
 
                    o.phantomjs = numberify(m[1]);
3409
 
                }
3410
 
            }
3411
 
 
3412
 
            // Mobile browser check
3413
 
            if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {
3414
 
                o.mobile = 'Apple'; // iPhone or iPod Touch
3415
 
 
3416
 
                m = ua.match(/OS ([^\s]*)/);
3417
 
                if (m && m[1]) {
3418
 
                    m = numberify(m[1].replace('_', '.'));
3419
 
                }
3420
 
                o.ios = m;
3421
 
                o.os = 'ios';
3422
 
                o.ipad = o.ipod = o.iphone = 0;
3423
 
 
3424
 
                m = ua.match(/iPad|iPod|iPhone/);
3425
 
                if (m && m[0]) {
3426
 
                    o[m[0].toLowerCase()] = o.ios;
3427
 
                }
3428
 
            } else {
3429
 
                m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
3430
 
                if (m) {
3431
 
                    // Nokia N-series, webOS, ex: NokiaN95
3432
 
                    o.mobile = m[0];
3433
 
                }
3434
 
                if (/webOS/.test(ua)) {
3435
 
                    o.mobile = 'WebOS';
3436
 
                    m = ua.match(/webOS\/([^\s]*);/);
3437
 
                    if (m && m[1]) {
3438
 
                        o.webos = numberify(m[1]);
3439
 
                    }
3440
 
                }
3441
 
                if (/ Android/.test(ua)) {
3442
 
                    if (/Mobile/.test(ua)) {
3443
 
                        o.mobile = 'Android';
3444
 
                    }
3445
 
                    m = ua.match(/Android ([^\s]*);/);
3446
 
                    if (m && m[1]) {
3447
 
                        o.android = numberify(m[1]);
3448
 
                    }
3449
 
 
3450
 
                }
3451
 
                if (/Silk/.test(ua)) {
3452
 
                    m = ua.match(/Silk\/([^\s]*)\)/);
3453
 
                    if (m && m[1]) {
3454
 
                        o.silk = numberify(m[1]);
3455
 
                    }
3456
 
                    if (!o.android) {
3457
 
                        o.android = 2.34; //Hack for desktop mode in Kindle
3458
 
                        o.os = 'Android';
3459
 
                    }
3460
 
                    if (/Accelerated=true/.test(ua)) {
3461
 
                        o.accel = true;
3462
 
                    }
3463
 
                }
3464
 
            }
3465
 
 
3466
 
            m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/);
3467
 
            if (m && m[1] && m[2]) {
3468
 
                o.chrome = numberify(m[2]); // Chrome
3469
 
                o.safari = 0; //Reset safari back to 0
3470
 
                if (m[1] === 'CrMo') {
3471
 
                    o.mobile = 'chrome';
3472
 
                }
3473
 
            } else {
3474
 
                m = ua.match(/AdobeAIR\/([^\s]*)/);
3475
 
                if (m) {
3476
 
                    o.air = m[0]; // Adobe AIR 1.0 or better
3477
 
                }
3478
 
            }
3479
 
        }
3480
 
 
3481
 
        if (!o.webkit) { // not webkit
3482
 
// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
3483
 
            if (/Opera/.test(ua)) {
3484
 
                m = ua.match(/Opera[\s\/]([^\s]*)/);
3485
 
                if (m && m[1]) {
3486
 
                    o.opera = numberify(m[1]);
3487
 
                }
3488
 
                m = ua.match(/Version\/([^\s]*)/);
3489
 
                if (m && m[1]) {
3490
 
                    o.opera = numberify(m[1]); // opera 10+
3491
 
                }
3492
 
 
3493
 
                if (/Opera Mobi/.test(ua)) {
3494
 
                    o.mobile = 'opera';
3495
 
                    m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);
3496
 
                    if (m && m[1]) {
3497
 
                        o.opera = numberify(m[1]);
3498
 
                    }
3499
 
                }
3500
 
                m = ua.match(/Opera Mini[^;]*/);
3501
 
 
3502
 
                if (m) {
3503
 
                    o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
3504
 
                }
3505
 
            } else { // not opera or webkit
3506
 
                m = ua.match(/MSIE\s([^;]*)/);
3507
 
                if (m && m[1]) {
3508
 
                    o.ie = numberify(m[1]);
3509
 
                } else { // not opera, webkit, or ie
3510
 
                    m = ua.match(/Gecko\/([^\s]*)/);
3511
 
                    if (m) {
3512
 
                        o.gecko = 1; // Gecko detected, look for revision
3513
 
                        m = ua.match(/rv:([^\s\)]*)/);
3514
 
                        if (m && m[1]) {
3515
 
                            o.gecko = numberify(m[1]);
3516
 
                        }
3517
 
                    }
3518
 
                }
3519
 
            }
3520
 
        }
3521
 
    }
3522
 
 
3523
 
    //Check for known properties to tell if touch events are enabled on this device or if
3524
 
    //the number of MSPointer touchpoints on this device is greater than 0.
3525
 
    if (win && nav && !(o.chrome && o.chrome < 6)) {
3526
 
        o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0)));
3527
 
    }
3528
 
 
3529
 
    //It was a parsed UA, do not assign the global value.
3530
 
    if (!subUA) {
3531
 
 
3532
 
        if (typeof process === 'object') {
3533
 
 
3534
 
            if (process.versions && process.versions.node) {
3535
 
                //NodeJS
3536
 
                o.os = process.platform;
3537
 
                o.nodejs = numberify(process.versions.node);
3538
 
            }
3539
 
        }
3540
 
 
3541
 
        YUI.Env.UA = o;
3542
 
 
3543
 
    }
3544
 
 
3545
 
    return o;
3546
 
};
3547
 
 
3548
 
 
3549
 
Y.UA = YUI.Env.UA || YUI.Env.parseUA();
3550
 
 
3551
 
/**
3552
 
Performs a simple comparison between two version numbers, accounting for
3553
 
standard versioning logic such as the fact that "535.8" is a lower version than
3554
 
"535.24", even though a simple numerical comparison would indicate that it's
3555
 
greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are
3556
 
considered equivalent.
3557
 
 
3558
 
Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent,
3559
 
1 if _a_ is higher than _b_.
3560
 
 
3561
 
Versions may be numbers or strings containing numbers and dots. For example,
3562
 
both `535` and `"535.8.10"` are acceptable. A version string containing
3563
 
non-numeric characters, like `"535.8.beta"`, may produce unexpected results.
3564
 
 
3565
 
@method compareVersions
3566
 
@param {Number|String} a First version number to compare.
3567
 
@param {Number|String} b Second version number to compare.
3568
 
@return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is
3569
 
    higher than _b_.
3570
 
**/
3571
 
Y.UA.compareVersions = function (a, b) {
3572
 
    var aPart, aParts, bPart, bParts, i, len;
3573
 
 
3574
 
    if (a === b) {
3575
 
        return 0;
3576
 
    }
3577
 
 
3578
 
    aParts = (a + '').split('.');
3579
 
    bParts = (b + '').split('.');
3580
 
 
3581
 
    for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {
3582
 
        aPart = parseInt(aParts[i], 10);
3583
 
        bPart = parseInt(bParts[i], 10);
3584
 
 
3585
 
        /*jshint expr: true*/
3586
 
        isNaN(aPart) && (aPart = 0);
3587
 
        isNaN(bPart) && (bPart = 0);
3588
 
 
3589
 
        if (aPart < bPart) {
3590
 
            return -1;
3591
 
        }
3592
 
 
3593
 
        if (aPart > bPart) {
3594
 
            return 1;
3595
 
        }
3596
 
    }
3597
 
 
3598
 
    return 0;
3599
 
};
3600
 
YUI.Env.aliases = {
3601
 
    "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
3602
 
    "anim-shape-transform": ["anim-shape"],
3603
 
    "app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","router","view","view-node-map"],
3604
 
    "attribute": ["attribute-base","attribute-complex"],
3605
 
    "attribute-events": ["attribute-observable"],
3606
 
    "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
3607
 
    "axes": ["axis-numeric","axis-category","axis-time","axis-stacked"],
3608
 
    "axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"],
3609
 
    "base": ["base-base","base-pluginhost","base-build"],
3610
 
    "cache": ["cache-base","cache-offline","cache-plugin"],
3611
 
    "charts": ["charts-base"],
3612
 
    "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
3613
 
    "color": ["color-base","color-hsl","color-harmony"],
3614
 
    "controller": ["router"],
3615
 
    "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
3616
 
    "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
3617
 
    "datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"],
3618
 
    "datatype": ["datatype-date","datatype-number","datatype-xml"],
3619
 
    "datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"],
3620
 
    "datatype-number": ["datatype-number-parse","datatype-number-format"],
3621
 
    "datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
3622
 
    "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
3623
 
    "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
3624
 
    "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
3625
 
    "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","event-tap"],
3626
 
    "event-custom": ["event-custom-base","event-custom-complex"],
3627
 
    "event-gestures": ["event-flick","event-move"],
3628
 
    "handlebars": ["handlebars-compiler"],
3629
 
    "highlight": ["highlight-base","highlight-accentfold"],
3630
 
    "history": ["history-base","history-hash","history-hash-ie","history-html5"],
3631
 
    "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
3632
 
    "json": ["json-parse","json-stringify"],
3633
 
    "loader": ["loader-base","loader-rollup","loader-yui3"],
3634
 
    "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
3635
 
    "pluginhost": ["pluginhost-base","pluginhost-config"],
3636
 
    "querystring": ["querystring-parse","querystring-stringify"],
3637
 
    "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
3638
 
    "resize": ["resize-base","resize-proxy","resize-constrain"],
3639
 
    "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
3640
 
    "template": ["template-base","template-micro"],
3641
 
    "text": ["text-accentfold","text-wordbreak"],
3642
 
    "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"]
3643
 
};
3644
 
 
3645
 
 
3646
 
}, '3.9.1', {"use": ["get", "features", "intl-base", "yui-log", "yui-later"]});
3647
 
YUI.add('get', function (Y, NAME) {
3648
 
 
3649
 
/*jslint boss:true, expr:true, laxbreak: true */
3650
 
 
3651
 
/**
3652
 
Provides dynamic loading of remote JavaScript and CSS resources.
3653
 
 
3654
 
@module get
3655
 
@class Get
3656
 
@static
3657
 
**/
3658
 
 
3659
 
var Lang = Y.Lang,
3660
 
 
3661
 
    CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode()
3662
 
 
3663
 
    Get, Transaction;
3664
 
 
3665
 
Y.Get = Get = {
3666
 
    // -- Public Properties ----------------------------------------------------
3667
 
 
3668
 
    /**
3669
 
    Default options for CSS requests. Options specified here will override
3670
 
    global defaults for CSS requests.
3671
 
 
3672
 
    See the `options` property for all available options.
3673
 
 
3674
 
    @property cssOptions
3675
 
    @type Object
3676
 
    @static
3677
 
    @since 3.5.0
3678
 
    **/
3679
 
    cssOptions: {
3680
 
        attributes: {
3681
 
            rel: 'stylesheet'
3682
 
        },
3683
 
 
3684
 
        doc         : Y.config.linkDoc || Y.config.doc,
3685
 
        pollInterval: 50
3686
 
    },
3687
 
 
3688
 
    /**
3689
 
    Default options for JS requests. Options specified here will override global
3690
 
    defaults for JS requests.
3691
 
 
3692
 
    See the `options` property for all available options.
3693
 
 
3694
 
    @property jsOptions
3695
 
    @type Object
3696
 
    @static
3697
 
    @since 3.5.0
3698
 
    **/
3699
 
    jsOptions: {
3700
 
        autopurge: true,
3701
 
        doc      : Y.config.scriptDoc || Y.config.doc
3702
 
    },
3703
 
 
3704
 
    /**
3705
 
    Default options to use for all requests.
3706
 
 
3707
 
    Note that while all available options are documented here for ease of
3708
 
    discovery, some options (like callback functions) only make sense at the
3709
 
    transaction level.
3710
 
 
3711
 
    Callback functions specified via the options object or the `options`
3712
 
    parameter of the `css()`, `js()`, or `load()` methods will receive the
3713
 
    transaction object as a parameter. See `Y.Get.Transaction` for details on
3714
 
    the properties and methods available on transactions.
3715
 
 
3716
 
    @static
3717
 
    @since 3.5.0
3718
 
    @property {Object} options
3719
 
 
3720
 
    @property {Boolean} [options.async=false] Whether or not to load scripts
3721
 
        asynchronously, meaning they're requested in parallel and execution
3722
 
        order is not guaranteed. Has no effect on CSS, since CSS is always
3723
 
        loaded asynchronously.
3724
 
 
3725
 
    @property {Object} [options.attributes] HTML attribute name/value pairs that
3726
 
        should be added to inserted nodes. By default, the `charset` attribute
3727
 
        will be set to "utf-8" and nodes will be given an auto-generated `id`
3728
 
        attribute, but you can override these with your own values if desired.
3729
 
 
3730
 
    @property {Boolean} [options.autopurge] Whether or not to automatically
3731
 
        purge inserted nodes after the purge threshold is reached. This is
3732
 
        `true` by default for JavaScript, but `false` for CSS since purging a
3733
 
        CSS node will also remove any styling applied by the referenced file.
3734
 
 
3735
 
    @property {Object} [options.context] `this` object to use when calling
3736
 
        callback functions. Defaults to the transaction object.
3737
 
 
3738
 
    @property {Mixed} [options.data] Arbitrary data object to pass to "on*"
3739
 
        callbacks.
3740
 
 
3741
 
    @property {Document} [options.doc] Document into which nodes should be
3742
 
        inserted. By default, the current document is used.
3743
 
 
3744
 
    @property {HTMLElement|String} [options.insertBefore] HTML element or id
3745
 
        string of an element before which all generated nodes should be
3746
 
        inserted. If not specified, Get will automatically determine the best
3747
 
        place to insert nodes for maximum compatibility.
3748
 
 
3749
 
    @property {Function} [options.onEnd] Callback to execute after a transaction
3750
 
        is complete, regardless of whether it succeeded or failed.
3751
 
 
3752
 
    @property {Function} [options.onFailure] Callback to execute after a
3753
 
        transaction fails, times out, or is aborted.
3754
 
 
3755
 
    @property {Function} [options.onProgress] Callback to execute after each
3756
 
        individual request in a transaction either succeeds or fails.
3757
 
 
3758
 
    @property {Function} [options.onSuccess] Callback to execute after a
3759
 
        transaction completes successfully with no errors. Note that in browsers
3760
 
        that don't support the `error` event on CSS `<link>` nodes, a failed CSS
3761
 
        request may still be reported as a success because in these browsers
3762
 
        it can be difficult or impossible to distinguish between success and
3763
 
        failure for CSS resources.
3764
 
 
3765
 
    @property {Function} [options.onTimeout] Callback to execute after a
3766
 
        transaction times out.
3767
 
 
3768
 
    @property {Number} [options.pollInterval=50] Polling interval (in
3769
 
        milliseconds) for detecting CSS load completion in browsers that don't
3770
 
        support the `load` event on `<link>` nodes. This isn't used for
3771
 
        JavaScript.
3772
 
 
3773
 
    @property {Number} [options.purgethreshold=20] Number of nodes to insert
3774
 
        before triggering an automatic purge when `autopurge` is `true`.
3775
 
 
3776
 
    @property {Number} [options.timeout] Number of milliseconds to wait before
3777
 
        aborting a transaction. When a timeout occurs, the `onTimeout` callback
3778
 
        is called, followed by `onFailure` and finally `onEnd`. By default,
3779
 
        there is no timeout.
3780
 
 
3781
 
    @property {String} [options.type] Resource type ("css" or "js"). This option
3782
 
        is set automatically by the `css()` and `js()` functions and will be
3783
 
        ignored there, but may be useful when using the `load()` function. If
3784
 
        not specified, the type will be inferred from the URL, defaulting to
3785
 
        "js" if the URL doesn't contain a recognizable file extension.
3786
 
    **/
3787
 
    options: {
3788
 
        attributes: {
3789
 
            charset: 'utf-8'
3790
 
        },
3791
 
 
3792
 
        purgethreshold: 20
3793
 
    },
3794
 
 
3795
 
    // -- Protected Properties -------------------------------------------------
3796
 
 
3797
 
    /**
3798
 
    Regex that matches a CSS URL. Used to guess the file type when it's not
3799
 
    specified.
3800
 
 
3801
 
    @property REGEX_CSS
3802
 
    @type RegExp
3803
 
    @final
3804
 
    @protected
3805
 
    @static
3806
 
    @since 3.5.0
3807
 
    **/
3808
 
    REGEX_CSS: /\.css(?:[?;].*)?$/i,
3809
 
 
3810
 
    /**
3811
 
    Regex that matches a JS URL. Used to guess the file type when it's not
3812
 
    specified.
3813
 
 
3814
 
    @property REGEX_JS
3815
 
    @type RegExp
3816
 
    @final
3817
 
    @protected
3818
 
    @static
3819
 
    @since 3.5.0
3820
 
    **/
3821
 
    REGEX_JS : /\.js(?:[?;].*)?$/i,
3822
 
 
3823
 
    /**
3824
 
    Contains information about the current environment, such as what script and
3825
 
    link injection features it supports.
3826
 
 
3827
 
    This object is created and populated the first time the `_getEnv()` method
3828
 
    is called.
3829
 
 
3830
 
    @property _env
3831
 
    @type Object
3832
 
    @protected
3833
 
    @static
3834
 
    @since 3.5.0
3835
 
    **/
3836
 
 
3837
 
    /**
3838
 
    Mapping of document _yuid strings to <head> or <base> node references so we
3839
 
    don't have to look the node up each time we want to insert a request node.
3840
 
 
3841
 
    @property _insertCache
3842
 
    @type Object
3843
 
    @protected
3844
 
    @static
3845
 
    @since 3.5.0
3846
 
    **/
3847
 
    _insertCache: {},
3848
 
 
3849
 
    /**
3850
 
    Information about the currently pending transaction, if any.
3851
 
 
3852
 
    This is actually an object with two properties: `callback`, containing the
3853
 
    optional callback passed to `css()`, `load()`, or `js()`; and `transaction`,
3854
 
    containing the actual transaction instance.
3855
 
 
3856
 
    @property _pending
3857
 
    @type Object
3858
 
    @protected
3859
 
    @static
3860
 
    @since 3.5.0
3861
 
    **/
3862
 
    _pending: null,
3863
 
 
3864
 
    /**
3865
 
    HTML nodes eligible to be purged next time autopurge is triggered.
3866
 
 
3867
 
    @property _purgeNodes
3868
 
    @type HTMLElement[]
3869
 
    @protected
3870
 
    @static
3871
 
    @since 3.5.0
3872
 
    **/
3873
 
    _purgeNodes: [],
3874
 
 
3875
 
    /**
3876
 
    Queued transactions and associated callbacks.
3877
 
 
3878
 
    @property _queue
3879
 
    @type Object[]
3880
 
    @protected
3881
 
    @static
3882
 
    @since 3.5.0
3883
 
    **/
3884
 
    _queue: [],
3885
 
 
3886
 
    // -- Public Methods -------------------------------------------------------
3887
 
 
3888
 
    /**
3889
 
    Aborts the specified transaction.
3890
 
 
3891
 
    This will cause the transaction's `onFailure` callback to be called and
3892
 
    will prevent any new script and link nodes from being added to the document,
3893
 
    but any resources that have already been requested will continue loading
3894
 
    (there's no safe way to prevent this, unfortunately).
3895
 
 
3896
 
    *Note:* This method is deprecated as of 3.5.0, and will be removed in a
3897
 
    future version of YUI. Use the transaction-level `abort()` method instead.
3898
 
 
3899
 
    @method abort
3900
 
    @param {Get.Transaction} transaction Transaction to abort.
3901
 
    @deprecated Use the `abort()` method on the transaction instead.
3902
 
    @static
3903
 
    **/
3904
 
    abort: function (transaction) {
3905
 
        var i, id, item, len, pending;
3906
 
 
3907
 
 
3908
 
        if (!transaction.abort) {
3909
 
            id          = transaction;
3910
 
            pending     = this._pending;
3911
 
            transaction = null;
3912
 
 
3913
 
            if (pending && pending.transaction.id === id) {
3914
 
                transaction   = pending.transaction;
3915
 
                this._pending = null;
3916
 
            } else {
3917
 
                for (i = 0, len = this._queue.length; i < len; ++i) {
3918
 
                    item = this._queue[i].transaction;
3919
 
 
3920
 
                    if (item.id === id) {
3921
 
                        transaction = item;
3922
 
                        this._queue.splice(i, 1);
3923
 
                        break;
3924
 
                    }
3925
 
                }
3926
 
            }
3927
 
        }
3928
 
 
3929
 
        transaction && transaction.abort();
3930
 
    },
3931
 
 
3932
 
    /**
3933
 
    Loads one or more CSS files.
3934
 
 
3935
 
    The _urls_ parameter may be provided as a URL string, a request object,
3936
 
    or an array of URL strings and/or request objects.
3937
 
 
3938
 
    A request object is just an object that contains a `url` property and zero
3939
 
    or more options that should apply specifically to that request.
3940
 
    Request-specific options take priority over transaction-level options and
3941
 
    default options.
3942
 
 
3943
 
    URLs may be relative or absolute, and do not have to have the same origin
3944
 
    as the current page.
3945
 
 
3946
 
    The `options` parameter may be omitted completely and a callback passed in
3947
 
    its place, if desired.
3948
 
 
3949
 
    @example
3950
 
 
3951
 
        // Load a single CSS file and log a message on completion.
3952
 
        Y.Get.css('foo.css', function (err) {
3953
 
            if (err) {
3954
 
            } else {
3955
 
            }
3956
 
        });
3957
 
 
3958
 
        // Load multiple CSS files and log a message when all have finished
3959
 
        // loading.
3960
 
        var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css'];
3961
 
 
3962
 
        Y.Get.css(urls, function (err) {
3963
 
            if (err) {
3964
 
            } else {
3965
 
            }
3966
 
        });
3967
 
 
3968
 
        // Specify transaction-level options, which will apply to all requests
3969
 
        // within the transaction.
3970
 
        Y.Get.css(urls, {
3971
 
            attributes: {'class': 'my-css'},
3972
 
            timeout   : 5000
3973
 
        });
3974
 
 
3975
 
        // Specify per-request options, which override transaction-level and
3976
 
        // default options.
3977
 
        Y.Get.css([
3978
 
            {url: 'foo.css', attributes: {id: 'foo'}},
3979
 
            {url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}}
3980
 
        ]);
3981
 
 
3982
 
    @method css
3983
 
    @param {String|Object|Array} urls URL string, request object, or array
3984
 
        of URLs and/or request objects to load.
3985
 
    @param {Object} [options] Options for this transaction. See the
3986
 
        `Y.Get.options` property for a complete list of available options.
3987
 
    @param {Function} [callback] Callback function to be called on completion.
3988
 
        This is a general callback and will be called before any more granular
3989
 
        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
3990
 
        object.
3991
 
 
3992
 
        @param {Array|null} callback.err Array of errors that occurred during
3993
 
            the transaction, or `null` on success.
3994
 
        @param {Get.Transaction} callback.transaction Transaction object.
3995
 
 
3996
 
    @return {Get.Transaction} Transaction object.
3997
 
    @static
3998
 
    **/
3999
 
    css: function (urls, options, callback) {
4000
 
        return this._load('css', urls, options, callback);
4001
 
    },
4002
 
 
4003
 
    /**
4004
 
    Loads one or more JavaScript resources.
4005
 
 
4006
 
    The _urls_ parameter may be provided as a URL string, a request object,
4007
 
    or an array of URL strings and/or request objects.
4008
 
 
4009
 
    A request object is just an object that contains a `url` property and zero
4010
 
    or more options that should apply specifically to that request.
4011
 
    Request-specific options take priority over transaction-level options and
4012
 
    default options.
4013
 
 
4014
 
    URLs may be relative or absolute, and do not have to have the same origin
4015
 
    as the current page.
4016
 
 
4017
 
    The `options` parameter may be omitted completely and a callback passed in
4018
 
    its place, if desired.
4019
 
 
4020
 
    Scripts will be executed in the order they're specified unless the `async`
4021
 
    option is `true`, in which case they'll be loaded in parallel and executed
4022
 
    in whatever order they finish loading.
4023
 
 
4024
 
    @example
4025
 
 
4026
 
        // Load a single JS file and log a message on completion.
4027
 
        Y.Get.js('foo.js', function (err) {
4028
 
            if (err) {
4029
 
            } else {
4030
 
            }
4031
 
        });
4032
 
 
4033
 
        // Load multiple JS files, execute them in order, and log a message when
4034
 
        // all have finished loading.
4035
 
        var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js'];
4036
 
 
4037
 
        Y.Get.js(urls, function (err) {
4038
 
            if (err) {
4039
 
            } else {
4040
 
            }
4041
 
        });
4042
 
 
4043
 
        // Specify transaction-level options, which will apply to all requests
4044
 
        // within the transaction.
4045
 
        Y.Get.js(urls, {
4046
 
            attributes: {'class': 'my-js'},
4047
 
            timeout   : 5000
4048
 
        });
4049
 
 
4050
 
        // Specify per-request options, which override transaction-level and
4051
 
        // default options.
4052
 
        Y.Get.js([
4053
 
            {url: 'foo.js', attributes: {id: 'foo'}},
4054
 
            {url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4055
 
        ]);
4056
 
 
4057
 
    @method js
4058
 
    @param {String|Object|Array} urls URL string, request object, or array
4059
 
        of URLs and/or request objects to load.
4060
 
    @param {Object} [options] Options for this transaction. See the
4061
 
        `Y.Get.options` property for a complete list of available options.
4062
 
    @param {Function} [callback] Callback function to be called on completion.
4063
 
        This is a general callback and will be called before any more granular
4064
 
        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4065
 
        object.
4066
 
 
4067
 
        @param {Array|null} callback.err Array of errors that occurred during
4068
 
            the transaction, or `null` on success.
4069
 
        @param {Get.Transaction} callback.transaction Transaction object.
4070
 
 
4071
 
    @return {Get.Transaction} Transaction object.
4072
 
    @since 3.5.0
4073
 
    @static
4074
 
    **/
4075
 
    js: function (urls, options, callback) {
4076
 
        return this._load('js', urls, options, callback);
4077
 
    },
4078
 
 
4079
 
    /**
4080
 
    Loads one or more CSS and/or JavaScript resources in the same transaction.
4081
 
 
4082
 
    Use this method when you want to load both CSS and JavaScript in a single
4083
 
    transaction and be notified when all requested URLs have finished loading,
4084
 
    regardless of type.
4085
 
 
4086
 
    Behavior and options are the same as for the `css()` and `js()` methods. If
4087
 
    a resource type isn't specified in per-request options or transaction-level
4088
 
    options, Get will guess the file type based on the URL's extension (`.css`
4089
 
    or `.js`, with or without a following query string). If the file type can't
4090
 
    be guessed from the URL, a warning will be logged and Get will assume the
4091
 
    URL is a JavaScript resource.
4092
 
 
4093
 
    @example
4094
 
 
4095
 
        // Load both CSS and JS files in a single transaction, and log a message
4096
 
        // when all files have finished loading.
4097
 
        Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) {
4098
 
            if (err) {
4099
 
            } else {
4100
 
            }
4101
 
        });
4102
 
 
4103
 
    @method load
4104
 
    @param {String|Object|Array} urls URL string, request object, or array
4105
 
        of URLs and/or request objects to load.
4106
 
    @param {Object} [options] Options for this transaction. See the
4107
 
        `Y.Get.options` property for a complete list of available options.
4108
 
    @param {Function} [callback] Callback function to be called on completion.
4109
 
        This is a general callback and will be called before any more granular
4110
 
        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4111
 
        object.
4112
 
 
4113
 
        @param {Array|null} err Array of errors that occurred during the
4114
 
            transaction, or `null` on success.
4115
 
        @param {Get.Transaction} Transaction object.
4116
 
 
4117
 
    @return {Get.Transaction} Transaction object.
4118
 
    @since 3.5.0
4119
 
    @static
4120
 
    **/
4121
 
    load: function (urls, options, callback) {
4122
 
        return this._load(null, urls, options, callback);
4123
 
    },
4124
 
 
4125
 
    // -- Protected Methods ----------------------------------------------------
4126
 
 
4127
 
    /**
4128
 
    Triggers an automatic purge if the purge threshold has been reached.
4129
 
 
4130
 
    @method _autoPurge
4131
 
    @param {Number} threshold Purge threshold to use, in milliseconds.
4132
 
    @protected
4133
 
    @since 3.5.0
4134
 
    @static
4135
 
    **/
4136
 
    _autoPurge: function (threshold) {
4137
 
        if (threshold && this._purgeNodes.length >= threshold) {
4138
 
            this._purge(this._purgeNodes);
4139
 
        }
4140
 
    },
4141
 
 
4142
 
    /**
4143
 
    Populates the `_env` property with information about the current
4144
 
    environment.
4145
 
 
4146
 
    @method _getEnv
4147
 
    @return {Object} Environment information.
4148
 
    @protected
4149
 
    @since 3.5.0
4150
 
    @static
4151
 
    **/
4152
 
    _getEnv: function () {
4153
 
        var doc = Y.config.doc,
4154
 
            ua  = Y.UA;
4155
 
 
4156
 
        // Note: some of these checks require browser sniffs since it's not
4157
 
        // feasible to load test files on every pageview just to perform a
4158
 
        // feature test. I'm sorry if this makes you sad.
4159
 
        return (this._env = {
4160
 
 
4161
 
            // True if this is a browser that supports disabling async mode on
4162
 
            // dynamically created script nodes. See
4163
 
            // https://developer.mozilla.org/En/HTML/Element/Script#Attributes
4164
 
 
4165
 
            // IE10 doesn't return true for the MDN feature test, so setting it explicitly,
4166
 
            // because it is async by default, and allows you to disable async by setting it to false
4167
 
            async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10),
4168
 
 
4169
 
            // True if this browser fires an event when a dynamically injected
4170
 
            // link node fails to load. This is currently true for Firefox 9+
4171
 
            // and WebKit 535.24+
4172
 
            cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0,
4173
 
 
4174
 
            // True if this browser fires an event when a dynamically injected
4175
 
            // link node finishes loading. This is currently true for IE, Opera,
4176
 
            // Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the
4177
 
            // DOM 0 "onload" event, but not "load". All versions of IE fire
4178
 
            // "onload".
4179
 
            // davglass: Seems that Chrome on Android needs this to be false.
4180
 
            cssLoad: (
4181
 
                    (!ua.gecko && !ua.webkit) || ua.gecko >= 9 ||
4182
 
                    ua.compareVersions(ua.webkit, 535.24) >= 0
4183
 
                ) && !(ua.chrome && ua.chrome <= 18),
4184
 
 
4185
 
            // True if this browser preserves script execution order while
4186
 
            // loading scripts in parallel as long as the script node's `async`
4187
 
            // attribute is set to false to explicitly disable async execution.
4188
 
            preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10))
4189
 
        });
4190
 
    },
4191
 
 
4192
 
    _getTransaction: function (urls, options) {
4193
 
        var requests = [],
4194
 
            i, len, req, url;
4195
 
 
4196
 
        if (!Lang.isArray(urls)) {
4197
 
            urls = [urls];
4198
 
        }
4199
 
 
4200
 
        options = Y.merge(this.options, options);
4201
 
 
4202
 
        // Clone the attributes object so we don't end up modifying it by ref.
4203
 
        options.attributes = Y.merge(this.options.attributes,
4204
 
                options.attributes);
4205
 
 
4206
 
        for (i = 0, len = urls.length; i < len; ++i) {
4207
 
            url = urls[i];
4208
 
            req = {attributes: {}};
4209
 
 
4210
 
            // If `url` is a string, we create a URL object for it, then mix in
4211
 
            // global options and request-specific options. If it's an object
4212
 
            // with a "url" property, we assume it's a request object containing
4213
 
            // URL-specific options.
4214
 
            if (typeof url === 'string') {
4215
 
                req.url = url;
4216
 
            } else if (url.url) {
4217
 
                // URL-specific options override both global defaults and
4218
 
                // request-specific options.
4219
 
                Y.mix(req, url, false, null, 0, true);
4220
 
                url = url.url; // Make url a string so we can use it later.
4221
 
            } else {
4222
 
                continue;
4223
 
            }
4224
 
 
4225
 
            Y.mix(req, options, false, null, 0, true);
4226
 
 
4227
 
            // If we didn't get an explicit type for this URL either in the
4228
 
            // request options or the URL-specific options, try to determine
4229
 
            // one from the file extension.
4230
 
            if (!req.type) {
4231
 
                if (this.REGEX_CSS.test(url)) {
4232
 
                    req.type = 'css';
4233
 
                } else {
4234
 
                    if (!this.REGEX_JS.test(url)) {
4235
 
                    }
4236
 
 
4237
 
                    req.type = 'js';
4238
 
                }
4239
 
            }
4240
 
 
4241
 
            // Mix in type-specific default options, but don't overwrite any
4242
 
            // options that have already been set.
4243
 
            Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions,
4244
 
                false, null, 0, true);
4245
 
 
4246
 
            // Give the node an id attribute if it doesn't already have one.
4247
 
            req.attributes.id || (req.attributes.id = Y.guid());
4248
 
 
4249
 
            // Backcompat for <3.5.0 behavior.
4250
 
            if (req.win) {
4251
 
                req.doc = req.win.document;
4252
 
            } else {
4253
 
                req.win = req.doc.defaultView || req.doc.parentWindow;
4254
 
            }
4255
 
 
4256
 
            if (req.charset) {
4257
 
                req.attributes.charset = req.charset;
4258
 
            }
4259
 
 
4260
 
            requests.push(req);
4261
 
        }
4262
 
 
4263
 
        return new Transaction(requests, options);
4264
 
    },
4265
 
 
4266
 
    _load: function (type, urls, options, callback) {
4267
 
        var transaction;
4268
 
 
4269
 
        // Allow callback as third param.
4270
 
        if (typeof options === 'function') {
4271
 
            callback = options;
4272
 
            options  = {};
4273
 
        }
4274
 
 
4275
 
        options || (options = {});
4276
 
        options.type = type;
4277
 
 
4278
 
        options._onFinish = Get._onTransactionFinish;
4279
 
 
4280
 
        if (!this._env) {
4281
 
            this._getEnv();
4282
 
        }
4283
 
 
4284
 
        transaction = this._getTransaction(urls, options);
4285
 
 
4286
 
        this._queue.push({
4287
 
            callback   : callback,
4288
 
            transaction: transaction
4289
 
        });
4290
 
 
4291
 
        this._next();
4292
 
 
4293
 
        return transaction;
4294
 
    },
4295
 
 
4296
 
    _onTransactionFinish : function() {
4297
 
        Get._pending = null;
4298
 
        Get._next();
4299
 
    },
4300
 
 
4301
 
    _next: function () {
4302
 
        var item;
4303
 
 
4304
 
        if (this._pending) {
4305
 
            return;
4306
 
        }
4307
 
 
4308
 
        item = this._queue.shift();
4309
 
 
4310
 
        if (item) {
4311
 
            this._pending = item;
4312
 
            item.transaction.execute(item.callback);
4313
 
        }
4314
 
    },
4315
 
 
4316
 
    _purge: function (nodes) {
4317
 
        var purgeNodes    = this._purgeNodes,
4318
 
            isTransaction = nodes !== purgeNodes,
4319
 
            index, node;
4320
 
 
4321
 
        while (node = nodes.pop()) { // assignment
4322
 
            // Don't purge nodes that haven't finished loading (or errored out),
4323
 
            // since this can hang the transaction.
4324
 
            if (!node._yuiget_finished) {
4325
 
                continue;
4326
 
            }
4327
 
 
4328
 
            node.parentNode && node.parentNode.removeChild(node);
4329
 
 
4330
 
            // If this is a transaction-level purge and this node also exists in
4331
 
            // the Get-level _purgeNodes array, we need to remove it from
4332
 
            // _purgeNodes to avoid creating a memory leak. The indexOf lookup
4333
 
            // sucks, but until we get WeakMaps, this is the least troublesome
4334
 
            // way to do this (we can't just hold onto node ids because they may
4335
 
            // not be in the same document).
4336
 
            if (isTransaction) {
4337
 
                index = Y.Array.indexOf(purgeNodes, node);
4338
 
 
4339
 
                if (index > -1) {
4340
 
                    purgeNodes.splice(index, 1);
4341
 
                }
4342
 
            }
4343
 
        }
4344
 
    }
4345
 
};
4346
 
 
4347
 
/**
4348
 
Alias for `js()`.
4349
 
 
4350
 
@method script
4351
 
@static
4352
 
**/
4353
 
Get.script = Get.js;
4354
 
 
4355
 
/**
4356
 
Represents a Get transaction, which may contain requests for one or more JS or
4357
 
CSS files.
4358
 
 
4359
 
This class should not be instantiated manually. Instances will be created and
4360
 
returned as needed by Y.Get's `css()`, `js()`, and `load()` methods.
4361
 
 
4362
 
@class Get.Transaction
4363
 
@constructor
4364
 
@since 3.5.0
4365
 
**/
4366
 
Get.Transaction = Transaction = function (requests, options) {
4367
 
    var self = this;
4368
 
 
4369
 
    self.id       = Transaction._lastId += 1;
4370
 
    self.data     = options.data;
4371
 
    self.errors   = [];
4372
 
    self.nodes    = [];
4373
 
    self.options  = options;
4374
 
    self.requests = requests;
4375
 
 
4376
 
    self._callbacks = []; // callbacks to call after execution finishes
4377
 
    self._queue     = [];
4378
 
    self._reqsWaiting   = 0;
4379
 
 
4380
 
    // Deprecated pre-3.5.0 properties.
4381
 
    self.tId = self.id; // Use `id` instead.
4382
 
    self.win = options.win || Y.config.win;
4383
 
};
4384
 
 
4385
 
/**
4386
 
Arbitrary data object associated with this transaction.
4387
 
 
4388
 
This object comes from the options passed to `Get.css()`, `Get.js()`, or
4389
 
`Get.load()`, and will be `undefined` if no data object was specified.
4390
 
 
4391
 
@property {Object} data
4392
 
**/
4393
 
 
4394
 
/**
4395
 
Array of errors that have occurred during this transaction, if any.
4396
 
 
4397
 
@since 3.5.0
4398
 
@property {Object[]} errors
4399
 
@property {String} errors.error Error message.
4400
 
@property {Object} errors.request Request object related to the error.
4401
 
**/
4402
 
 
4403
 
/**
4404
 
Numeric id for this transaction, unique among all transactions within the same
4405
 
YUI sandbox in the current pageview.
4406
 
 
4407
 
@property {Number} id
4408
 
@since 3.5.0
4409
 
**/
4410
 
 
4411
 
/**
4412
 
HTMLElement nodes (native ones, not YUI Node instances) that have been inserted
4413
 
during the current transaction.
4414
 
 
4415
 
@property {HTMLElement[]} nodes
4416
 
**/
4417
 
 
4418
 
/**
4419
 
Options associated with this transaction.
4420
 
 
4421
 
See `Get.options` for the full list of available options.
4422
 
 
4423
 
@property {Object} options
4424
 
@since 3.5.0
4425
 
**/
4426
 
 
4427
 
/**
4428
 
Request objects contained in this transaction. Each request object represents
4429
 
one CSS or JS URL that will be (or has been) requested and loaded into the page.
4430
 
 
4431
 
@property {Object} requests
4432
 
@since 3.5.0
4433
 
**/
4434
 
 
4435
 
/**
4436
 
Id of the most recent transaction.
4437
 
 
4438
 
@property _lastId
4439
 
@type Number
4440
 
@protected
4441
 
@static
4442
 
**/
4443
 
Transaction._lastId = 0;
4444
 
 
4445
 
Transaction.prototype = {
4446
 
    // -- Public Properties ----------------------------------------------------
4447
 
 
4448
 
    /**
4449
 
    Current state of this transaction. One of "new", "executing", or "done".
4450
 
 
4451
 
    @property _state
4452
 
    @type String
4453
 
    @protected
4454
 
    **/
4455
 
    _state: 'new', // "new", "executing", or "done"
4456
 
 
4457
 
    // -- Public Methods -------------------------------------------------------
4458
 
 
4459
 
    /**
4460
 
    Aborts this transaction.
4461
 
 
4462
 
    This will cause the transaction's `onFailure` callback to be called and
4463
 
    will prevent any new script and link nodes from being added to the document,
4464
 
    but any resources that have already been requested will continue loading
4465
 
    (there's no safe way to prevent this, unfortunately).
4466
 
 
4467
 
    @method abort
4468
 
    @param {String} [msg="Aborted."] Optional message to use in the `errors`
4469
 
        array describing why the transaction was aborted.
4470
 
    **/
4471
 
    abort: function (msg) {
4472
 
        this._pending    = null;
4473
 
        this._pendingCSS = null;
4474
 
        this._pollTimer  = clearTimeout(this._pollTimer);
4475
 
        this._queue      = [];
4476
 
        this._reqsWaiting    = 0;
4477
 
 
4478
 
        this.errors.push({error: msg || 'Aborted'});
4479
 
        this._finish();
4480
 
    },
4481
 
 
4482
 
    /**
4483
 
    Begins execting the transaction.
4484
 
 
4485
 
    There's usually no reason to call this manually, since Get will call it
4486
 
    automatically when other pending transactions have finished. If you really
4487
 
    want to execute your transaction before Get does, you can, but be aware that
4488
 
    this transaction's scripts may end up executing before the scripts in other
4489
 
    pending transactions.
4490
 
 
4491
 
    If the transaction is already executing, the specified callback (if any)
4492
 
    will be queued and called after execution finishes. If the transaction has
4493
 
    already finished, the callback will be called immediately (the transaction
4494
 
    will not be executed again).
4495
 
 
4496
 
    @method execute
4497
 
    @param {Function} callback Callback function to execute after all requests
4498
 
        in the transaction are complete, or after the transaction is aborted.
4499
 
    **/
4500
 
    execute: function (callback) {
4501
 
        var self     = this,
4502
 
            requests = self.requests,
4503
 
            state    = self._state,
4504
 
            i, len, queue, req;
4505
 
 
4506
 
        if (state === 'done') {
4507
 
            callback && callback(self.errors.length ? self.errors : null, self);
4508
 
            return;
4509
 
        } else {
4510
 
            callback && self._callbacks.push(callback);
4511
 
 
4512
 
            if (state === 'executing') {
4513
 
                return;
4514
 
            }
4515
 
        }
4516
 
 
4517
 
        self._state = 'executing';
4518
 
        self._queue = queue = [];
4519
 
 
4520
 
        if (self.options.timeout) {
4521
 
            self._timeout = setTimeout(function () {
4522
 
                self.abort('Timeout');
4523
 
            }, self.options.timeout);
4524
 
        }
4525
 
 
4526
 
        self._reqsWaiting = requests.length;
4527
 
 
4528
 
        for (i = 0, len = requests.length; i < len; ++i) {
4529
 
            req = requests[i];
4530
 
 
4531
 
            if (req.async || req.type === 'css') {
4532
 
                // No need to queue CSS or fully async JS.
4533
 
                self._insert(req);
4534
 
            } else {
4535
 
                queue.push(req);
4536
 
            }
4537
 
        }
4538
 
 
4539
 
        self._next();
4540
 
    },
4541
 
 
4542
 
    /**
4543
 
    Manually purges any `<script>` or `<link>` nodes this transaction has
4544
 
    created.
4545
 
 
4546
 
    Be careful when purging a transaction that contains CSS requests, since
4547
 
    removing `<link>` nodes will also remove any styles they applied.
4548
 
 
4549
 
    @method purge
4550
 
    **/
4551
 
    purge: function () {
4552
 
        Get._purge(this.nodes);
4553
 
    },
4554
 
 
4555
 
    // -- Protected Methods ----------------------------------------------------
4556
 
    _createNode: function (name, attrs, doc) {
4557
 
        var node = doc.createElement(name),
4558
 
            attr, testEl;
4559
 
 
4560
 
        if (!CUSTOM_ATTRS) {
4561
 
            // IE6 and IE7 expect property names rather than attribute names for
4562
 
            // certain attributes. Rather than sniffing, we do a quick feature
4563
 
            // test the first time _createNode() runs to determine whether we
4564
 
            // need to provide a workaround.
4565
 
            testEl = doc.createElement('div');
4566
 
            testEl.setAttribute('class', 'a');
4567
 
 
4568
 
            CUSTOM_ATTRS = testEl.className === 'a' ? {} : {
4569
 
                'for'  : 'htmlFor',
4570
 
                'class': 'className'
4571
 
            };
4572
 
        }
4573
 
 
4574
 
        for (attr in attrs) {
4575
 
            if (attrs.hasOwnProperty(attr)) {
4576
 
                node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]);
4577
 
            }
4578
 
        }
4579
 
 
4580
 
        return node;
4581
 
    },
4582
 
 
4583
 
    _finish: function () {
4584
 
        var errors  = this.errors.length ? this.errors : null,
4585
 
            options = this.options,
4586
 
            thisObj = options.context || this,
4587
 
            data, i, len;
4588
 
 
4589
 
        if (this._state === 'done') {
4590
 
            return;
4591
 
        }
4592
 
 
4593
 
        this._state = 'done';
4594
 
 
4595
 
        for (i = 0, len = this._callbacks.length; i < len; ++i) {
4596
 
            this._callbacks[i].call(thisObj, errors, this);
4597
 
        }
4598
 
 
4599
 
        data = this._getEventData();
4600
 
 
4601
 
        if (errors) {
4602
 
            if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') {
4603
 
                options.onTimeout.call(thisObj, data);
4604
 
            }
4605
 
 
4606
 
            if (options.onFailure) {
4607
 
                options.onFailure.call(thisObj, data);
4608
 
            }
4609
 
        } else if (options.onSuccess) {
4610
 
            options.onSuccess.call(thisObj, data);
4611
 
        }
4612
 
 
4613
 
        if (options.onEnd) {
4614
 
            options.onEnd.call(thisObj, data);
4615
 
        }
4616
 
 
4617
 
        if (options._onFinish) {
4618
 
            options._onFinish();
4619
 
        }
4620
 
    },
4621
 
 
4622
 
    _getEventData: function (req) {
4623
 
        if (req) {
4624
 
            // This merge is necessary for backcompat. I hate it.
4625
 
            return Y.merge(this, {
4626
 
                abort  : this.abort, // have to copy these because the prototype isn't preserved
4627
 
                purge  : this.purge,
4628
 
                request: req,
4629
 
                url    : req.url,
4630
 
                win    : req.win
4631
 
            });
4632
 
        } else {
4633
 
            return this;
4634
 
        }
4635
 
    },
4636
 
 
4637
 
    _getInsertBefore: function (req) {
4638
 
        var doc = req.doc,
4639
 
            el  = req.insertBefore,
4640
 
            cache, docStamp;
4641
 
 
4642
 
        if (el) {
4643
 
            return typeof el === 'string' ? doc.getElementById(el) : el;
4644
 
        }
4645
 
 
4646
 
        cache    = Get._insertCache;
4647
 
        docStamp = Y.stamp(doc);
4648
 
 
4649
 
        if ((el = cache[docStamp])) { // assignment
4650
 
            return el;
4651
 
        }
4652
 
 
4653
 
        // Inserting before a <base> tag apparently works around an IE bug
4654
 
        // (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
4655
 
        // bug that is, exactly. Better safe than sorry?
4656
 
        if ((el = doc.getElementsByTagName('base')[0])) { // assignment
4657
 
            return (cache[docStamp] = el);
4658
 
        }
4659
 
 
4660
 
        // Look for a <head> element.
4661
 
        el = doc.head || doc.getElementsByTagName('head')[0];
4662
 
 
4663
 
        if (el) {
4664
 
            // Create a marker node at the end of <head> to use as an insertion
4665
 
            // point. Inserting before this node will ensure that all our CSS
4666
 
            // gets inserted in the correct order, to maintain style precedence.
4667
 
            el.appendChild(doc.createTextNode(''));
4668
 
            return (cache[docStamp] = el.lastChild);
4669
 
        }
4670
 
 
4671
 
        // If all else fails, just insert before the first script node on the
4672
 
        // page, which is virtually guaranteed to exist.
4673
 
        return (cache[docStamp] = doc.getElementsByTagName('script')[0]);
4674
 
    },
4675
 
 
4676
 
    _insert: function (req) {
4677
 
        var env          = Get._env,
4678
 
            insertBefore = this._getInsertBefore(req),
4679
 
            isScript     = req.type === 'js',
4680
 
            node         = req.node,
4681
 
            self         = this,
4682
 
            ua           = Y.UA,
4683
 
            cssTimeout, nodeType;
4684
 
 
4685
 
        if (!node) {
4686
 
            if (isScript) {
4687
 
                nodeType = 'script';
4688
 
            } else if (!env.cssLoad && ua.gecko) {
4689
 
                nodeType = 'style';
4690
 
            } else {
4691
 
                nodeType = 'link';
4692
 
            }
4693
 
 
4694
 
            node = req.node = this._createNode(nodeType, req.attributes,
4695
 
                req.doc);
4696
 
        }
4697
 
 
4698
 
        function onError() {
4699
 
            self._progress('Failed to load ' + req.url, req);
4700
 
        }
4701
 
 
4702
 
        function onLoad() {
4703
 
            if (cssTimeout) {
4704
 
                clearTimeout(cssTimeout);
4705
 
            }
4706
 
 
4707
 
            self._progress(null, req);
4708
 
        }
4709
 
 
4710
 
        // Deal with script asynchronicity.
4711
 
        if (isScript) {
4712
 
            node.setAttribute('src', req.url);
4713
 
 
4714
 
            if (req.async) {
4715
 
                // Explicitly indicate that we want the browser to execute this
4716
 
                // script asynchronously. This is necessary for older browsers
4717
 
                // like Firefox <4.
4718
 
                node.async = true;
4719
 
            } else {
4720
 
                if (env.async) {
4721
 
                    // This browser treats injected scripts as async by default
4722
 
                    // (standard HTML5 behavior) but asynchronous loading isn't
4723
 
                    // desired, so tell the browser not to mark this script as
4724
 
                    // async.
4725
 
                    node.async = false;
4726
 
                }
4727
 
 
4728
 
                // If this browser doesn't preserve script execution order based
4729
 
                // on insertion order, we'll need to avoid inserting other
4730
 
                // scripts until this one finishes loading.
4731
 
                if (!env.preservesScriptOrder) {
4732
 
                    this._pending = req;
4733
 
                }
4734
 
            }
4735
 
        } else {
4736
 
            if (!env.cssLoad && ua.gecko) {
4737
 
                // In Firefox <9, we can import the requested URL into a <style>
4738
 
                // node and poll for the existence of node.sheet.cssRules. This
4739
 
                // gives us a reliable way to determine CSS load completion that
4740
 
                // also works for cross-domain stylesheets.
4741
 
                //
4742
 
                // Props to Zach Leatherman for calling my attention to this
4743
 
                // technique.
4744
 
                node.innerHTML = (req.attributes.charset ?
4745
 
                    '@charset "' + req.attributes.charset + '";' : '') +
4746
 
                    '@import "' + req.url + '";';
4747
 
            } else {
4748
 
                node.setAttribute('href', req.url);
4749
 
            }
4750
 
        }
4751
 
 
4752
 
        // Inject the node.
4753
 
        if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) {
4754
 
            // Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode.
4755
 
            node.onreadystatechange = function () {
4756
 
                if (/loaded|complete/.test(node.readyState)) {
4757
 
                    node.onreadystatechange = null;
4758
 
                    onLoad();
4759
 
                }
4760
 
            };
4761
 
        } else if (!isScript && !env.cssLoad) {
4762
 
            // CSS on Firefox <9 or WebKit.
4763
 
            this._poll(req);
4764
 
        } else {
4765
 
            // Script or CSS on everything else. Using DOM 0 events because that
4766
 
            // evens the playing field with older IEs.
4767
 
 
4768
 
            if (ua.ie >= 10) {
4769
 
 
4770
 
                // We currently need to introduce a timeout for IE10, since it
4771
 
                // calls onerror/onload synchronously for 304s - messing up existing
4772
 
                // program flow.
4773
 
 
4774
 
                // Remove this block if the following bug gets fixed by GA
4775
 
                /*jshint maxlen: 1500 */
4776
 
                // https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload
4777
 
                node.onerror = function() { setTimeout(onError, 0); };
4778
 
                node.onload  = function() { setTimeout(onLoad, 0); };
4779
 
            } else {
4780
 
                node.onerror = onError;
4781
 
                node.onload  = onLoad;
4782
 
            }
4783
 
 
4784
 
            // If this browser doesn't fire an event when CSS fails to load,
4785
 
            // fail after a timeout to avoid blocking the transaction queue.
4786
 
            if (!env.cssFail && !isScript) {
4787
 
                cssTimeout = setTimeout(onError, req.timeout || 3000);
4788
 
            }
4789
 
        }
4790
 
 
4791
 
        this.nodes.push(node);
4792
 
        insertBefore.parentNode.insertBefore(node, insertBefore);
4793
 
    },
4794
 
 
4795
 
    _next: function () {
4796
 
        if (this._pending) {
4797
 
            return;
4798
 
        }
4799
 
 
4800
 
        // If there are requests in the queue, insert the next queued request.
4801
 
        // Otherwise, if we're waiting on already-inserted requests to finish,
4802
 
        // wait longer. If there are no queued requests and we're not waiting
4803
 
        // for anything to load, then we're done!
4804
 
        if (this._queue.length) {
4805
 
            this._insert(this._queue.shift());
4806
 
        } else if (!this._reqsWaiting) {
4807
 
            this._finish();
4808
 
        }
4809
 
    },
4810
 
 
4811
 
    _poll: function (newReq) {
4812
 
        var self       = this,
4813
 
            pendingCSS = self._pendingCSS,
4814
 
            isWebKit   = Y.UA.webkit,
4815
 
            i, hasRules, j, nodeHref, req, sheets;
4816
 
 
4817
 
        if (newReq) {
4818
 
            pendingCSS || (pendingCSS = self._pendingCSS = []);
4819
 
            pendingCSS.push(newReq);
4820
 
 
4821
 
            if (self._pollTimer) {
4822
 
                // A poll timeout is already pending, so no need to create a
4823
 
                // new one.
4824
 
                return;
4825
 
            }
4826
 
        }
4827
 
 
4828
 
        self._pollTimer = null;
4829
 
 
4830
 
        // Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s
4831
 
        // will still be treated as a success. There's no good workaround for
4832
 
        // this.
4833
 
 
4834
 
        for (i = 0; i < pendingCSS.length; ++i) {
4835
 
            req = pendingCSS[i];
4836
 
 
4837
 
            if (isWebKit) {
4838
 
                // Look for a stylesheet matching the pending URL.
4839
 
                sheets   = req.doc.styleSheets;
4840
 
                j        = sheets.length;
4841
 
                nodeHref = req.node.href;
4842
 
 
4843
 
                while (--j >= 0) {
4844
 
                    if (sheets[j].href === nodeHref) {
4845
 
                        pendingCSS.splice(i, 1);
4846
 
                        i -= 1;
4847
 
                        self._progress(null, req);
4848
 
                        break;
4849
 
                    }
4850
 
                }
4851
 
            } else {
4852
 
                // Many thanks to Zach Leatherman for calling my attention to
4853
 
                // the @import-based cross-domain technique used here, and to
4854
 
                // Oleg Slobodskoi for an earlier same-domain implementation.
4855
 
                //
4856
 
                // See Zach's blog for more details:
4857
 
                // http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
4858
 
                try {
4859
 
                    // We don't really need to store this value since we never
4860
 
                    // use it again, but if we don't store it, Closure Compiler
4861
 
                    // assumes the code is useless and removes it.
4862
 
                    hasRules = !!req.node.sheet.cssRules;
4863
 
 
4864
 
                    // If we get here, the stylesheet has loaded.
4865
 
                    pendingCSS.splice(i, 1);
4866
 
                    i -= 1;
4867
 
                    self._progress(null, req);
4868
 
                } catch (ex) {
4869
 
                    // An exception means the stylesheet is still loading.
4870
 
                }
4871
 
            }
4872
 
        }
4873
 
 
4874
 
        if (pendingCSS.length) {
4875
 
            self._pollTimer = setTimeout(function () {
4876
 
                self._poll.call(self);
4877
 
            }, self.options.pollInterval);
4878
 
        }
4879
 
    },
4880
 
 
4881
 
    _progress: function (err, req) {
4882
 
        var options = this.options;
4883
 
 
4884
 
        if (err) {
4885
 
            req.error = err;
4886
 
 
4887
 
            this.errors.push({
4888
 
                error  : err,
4889
 
                request: req
4890
 
            });
4891
 
 
4892
 
        }
4893
 
 
4894
 
        req.node._yuiget_finished = req.finished = true;
4895
 
 
4896
 
        if (options.onProgress) {
4897
 
            options.onProgress.call(options.context || this,
4898
 
                this._getEventData(req));
4899
 
        }
4900
 
 
4901
 
        if (req.autopurge) {
4902
 
            // Pre-3.5.0 Get always excludes the most recent node from an
4903
 
            // autopurge. I find this odd, but I'm keeping that behavior for
4904
 
            // the sake of backcompat.
4905
 
            Get._autoPurge(this.options.purgethreshold);
4906
 
            Get._purgeNodes.push(req.node);
4907
 
        }
4908
 
 
4909
 
        if (this._pending === req) {
4910
 
            this._pending = null;
4911
 
        }
4912
 
 
4913
 
        this._reqsWaiting -= 1;
4914
 
 
4915
 
        this._next();
4916
 
    }
4917
 
};
4918
 
 
4919
 
 
4920
 
}, '3.9.1', {"requires": ["yui-base"]});
4921
 
YUI.add('features', function (Y, NAME) {
4922
 
 
4923
 
var feature_tests = {};
4924
 
 
4925
 
/**
4926
 
Contains the core of YUI's feature test architecture.
4927
 
@module features
4928
 
*/
4929
 
 
4930
 
/**
4931
 
* Feature detection
4932
 
* @class Features
4933
 
* @static
4934
 
*/
4935
 
 
4936
 
Y.mix(Y.namespace('Features'), {
4937
 
 
4938
 
    /**
4939
 
    * Object hash of all registered feature tests
4940
 
    * @property tests
4941
 
    * @type Object
4942
 
    */
4943
 
    tests: feature_tests,
4944
 
 
4945
 
    /**
4946
 
    * Add a test to the system
4947
 
    *
4948
 
    *   ```
4949
 
    *   Y.Features.add("load", "1", {});
4950
 
    *   ```
4951
 
    *
4952
 
    * @method add
4953
 
    * @param {String} cat The category, right now only 'load' is supported
4954
 
    * @param {String} name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3
4955
 
    * @param {Object} o Object containing test properties
4956
 
    * @param {String} o.name The name of the test
4957
 
    * @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance
4958
 
    * @param {String} o.trigger The module that triggers this test.
4959
 
    */
4960
 
    add: function(cat, name, o) {
4961
 
        feature_tests[cat] = feature_tests[cat] || {};
4962
 
        feature_tests[cat][name] = o;
4963
 
    },
4964
 
    /**
4965
 
    * Execute all tests of a given category and return the serialized results
4966
 
    *
4967
 
    *   ```
4968
 
    *   caps=1:1;2:1;3:0
4969
 
    *   ```
4970
 
    * @method all
4971
 
    * @param {String} cat The category to execute
4972
 
    * @param {Array} args The arguments to pass to the test function
4973
 
    * @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0
4974
 
    */
4975
 
    all: function(cat, args) {
4976
 
        var cat_o = feature_tests[cat],
4977
 
            // results = {};
4978
 
            result = [];
4979
 
        if (cat_o) {
4980
 
            Y.Object.each(cat_o, function(v, k) {
4981
 
                result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0));
4982
 
            });
4983
 
        }
4984
 
 
4985
 
        return (result.length) ? result.join(';') : '';
4986
 
    },
4987
 
    /**
4988
 
    * Run a sepecific test and return a Boolean response.
4989
 
    *
4990
 
    *   ```
4991
 
    *   Y.Features.test("load", "1");
4992
 
    *   ```
4993
 
    *
4994
 
    * @method test
4995
 
    * @param {String} cat The category of the test to run
4996
 
    * @param {String} name The name of the test to run
4997
 
    * @param {Array} args The arguments to pass to the test function
4998
 
    * @return {Boolean} True or false if the test passed/failed.
4999
 
    */
5000
 
    test: function(cat, name, args) {
5001
 
        args = args || [];
5002
 
        var result, ua, test,
5003
 
            cat_o = feature_tests[cat],
5004
 
            feature = cat_o && cat_o[name];
5005
 
 
5006
 
        if (!feature) {
5007
 
        } else {
5008
 
 
5009
 
            result = feature.result;
5010
 
 
5011
 
            if (Y.Lang.isUndefined(result)) {
5012
 
 
5013
 
                ua = feature.ua;
5014
 
                if (ua) {
5015
 
                    result = (Y.UA[ua]);
5016
 
                }
5017
 
 
5018
 
                test = feature.test;
5019
 
                if (test && ((!ua) || result)) {
5020
 
                    result = test.apply(Y, args);
5021
 
                }
5022
 
 
5023
 
                feature.result = result;
5024
 
            }
5025
 
        }
5026
 
 
5027
 
        return result;
5028
 
    }
5029
 
});
5030
 
 
5031
 
// Y.Features.add("load", "1", {});
5032
 
// Y.Features.test("load", "1");
5033
 
// caps=1:1;2:0;3:1;
5034
 
 
5035
 
/* This file is auto-generated by (yogi loader --yes --mix --start ../) */
5036
 
/*jshint maxlen:900, eqeqeq: false */
5037
 
var add = Y.Features.add;
5038
 
// app-transitions-native
5039
 
add('load', '0', {
5040
 
    "name": "app-transitions-native",
5041
 
    "test": function (Y) {
5042
 
    var doc  = Y.config.doc,
5043
 
        node = doc ? doc.documentElement : null;
5044
 
 
5045
 
    if (node && node.style) {
5046
 
        return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5047
 
    }
5048
 
 
5049
 
    return false;
5050
 
},
5051
 
    "trigger": "app-transitions"
5052
 
});
5053
 
// autocomplete-list-keys
5054
 
add('load', '1', {
5055
 
    "name": "autocomplete-list-keys",
5056
 
    "test": function (Y) {
5057
 
    // Only add keyboard support to autocomplete-list if this doesn't appear to
5058
 
    // be an iOS or Android-based mobile device.
5059
 
    //
5060
 
    // There's currently no feasible way to actually detect whether a device has
5061
 
    // a hardware keyboard, so this sniff will have to do. It can easily be
5062
 
    // overridden by manually loading the autocomplete-list-keys module.
5063
 
    //
5064
 
    // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
5065
 
    // doesn't fire the keyboard events used by AutoCompleteList, so there's
5066
 
    // no point loading the -keys module even when a bluetooth keyboard may be
5067
 
    // available.
5068
 
    return !(Y.UA.ios || Y.UA.android);
5069
 
},
5070
 
    "trigger": "autocomplete-list"
5071
 
});
5072
 
// dd-gestures
5073
 
add('load', '2', {
5074
 
    "name": "dd-gestures",
5075
 
    "trigger": "dd-drag",
5076
 
    "ua": "touchEnabled"
5077
 
});
5078
 
// dom-style-ie
5079
 
add('load', '3', {
5080
 
    "name": "dom-style-ie",
5081
 
    "test": function (Y) {
5082
 
 
5083
 
    var testFeature = Y.Features.test,
5084
 
        addFeature = Y.Features.add,
5085
 
        WINDOW = Y.config.win,
5086
 
        DOCUMENT = Y.config.doc,
5087
 
        DOCUMENT_ELEMENT = 'documentElement',
5088
 
        ret = false;
5089
 
 
5090
 
    addFeature('style', 'computedStyle', {
5091
 
        test: function() {
5092
 
            return WINDOW && 'getComputedStyle' in WINDOW;
5093
 
        }
5094
 
    });
5095
 
 
5096
 
    addFeature('style', 'opacity', {
5097
 
        test: function() {
5098
 
            return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
5099
 
        }
5100
 
    });
5101
 
 
5102
 
    ret =  (!testFeature('style', 'opacity') &&
5103
 
            !testFeature('style', 'computedStyle'));
5104
 
 
5105
 
    return ret;
5106
 
},
5107
 
    "trigger": "dom-style"
5108
 
});
5109
 
// editor-para-ie
5110
 
add('load', '4', {
5111
 
    "name": "editor-para-ie",
5112
 
    "trigger": "editor-para",
5113
 
    "ua": "ie",
5114
 
    "when": "instead"
5115
 
});
5116
 
// event-base-ie
5117
 
add('load', '5', {
5118
 
    "name": "event-base-ie",
5119
 
    "test": function(Y) {
5120
 
    var imp = Y.config.doc && Y.config.doc.implementation;
5121
 
    return (imp && (!imp.hasFeature('Events', '2.0')));
5122
 
},
5123
 
    "trigger": "node-base"
5124
 
});
5125
 
// graphics-canvas
5126
 
add('load', '6', {
5127
 
    "name": "graphics-canvas",
5128
 
    "test": function(Y) {
5129
 
    var DOCUMENT = Y.config.doc,
5130
 
        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5131
 
                canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5132
 
        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5133
 
    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5134
 
},
5135
 
    "trigger": "graphics"
5136
 
});
5137
 
// graphics-canvas-default
5138
 
add('load', '7', {
5139
 
    "name": "graphics-canvas-default",
5140
 
    "test": function(Y) {
5141
 
    var DOCUMENT = Y.config.doc,
5142
 
        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5143
 
                canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5144
 
        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5145
 
    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5146
 
},
5147
 
    "trigger": "graphics"
5148
 
});
5149
 
// graphics-svg
5150
 
add('load', '8', {
5151
 
    "name": "graphics-svg",
5152
 
    "test": function(Y) {
5153
 
    var DOCUMENT = Y.config.doc,
5154
 
        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5155
 
                canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5156
 
        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5157
 
    
5158
 
    return svg && (useSVG || !canvas);
5159
 
},
5160
 
    "trigger": "graphics"
5161
 
});
5162
 
// graphics-svg-default
5163
 
add('load', '9', {
5164
 
    "name": "graphics-svg-default",
5165
 
    "test": function(Y) {
5166
 
    var DOCUMENT = Y.config.doc,
5167
 
        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5168
 
                canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5169
 
        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5170
 
    
5171
 
    return svg && (useSVG || !canvas);
5172
 
},
5173
 
    "trigger": "graphics"
5174
 
});
5175
 
// graphics-vml
5176
 
add('load', '10', {
5177
 
    "name": "graphics-vml",
5178
 
    "test": function(Y) {
5179
 
    var DOCUMENT = Y.config.doc,
5180
 
                canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5181
 
    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5182
 
},
5183
 
    "trigger": "graphics"
5184
 
});
5185
 
// graphics-vml-default
5186
 
add('load', '11', {
5187
 
    "name": "graphics-vml-default",
5188
 
    "test": function(Y) {
5189
 
    var DOCUMENT = Y.config.doc,
5190
 
                canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5191
 
    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5192
 
},
5193
 
    "trigger": "graphics"
5194
 
});
5195
 
// history-hash-ie
5196
 
add('load', '12', {
5197
 
    "name": "history-hash-ie",
5198
 
    "test": function (Y) {
5199
 
    var docMode = Y.config.doc && Y.config.doc.documentMode;
5200
 
 
5201
 
    return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
5202
 
            !docMode || docMode < 8);
5203
 
},
5204
 
    "trigger": "history-hash"
5205
 
});
5206
 
// io-nodejs
5207
 
add('load', '13', {
5208
 
    "name": "io-nodejs",
5209
 
    "trigger": "io-base",
5210
 
    "ua": "nodejs"
5211
 
});
5212
 
// json-parse-shim
5213
 
add('load', '14', {
5214
 
    "name": "json-parse-shim",
5215
 
    "test": function (Y) {
5216
 
    var _JSON = Y.config.global.JSON,
5217
 
        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5218
 
        nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
5219
 
 
5220
 
    function workingNative( k, v ) {
5221
 
        return k === "ok" ? true : v;
5222
 
    }
5223
 
    
5224
 
    // Double check basic functionality.  This is mainly to catch early broken
5225
 
    // implementations of the JSON API in Firefox 3.1 beta1 and beta2
5226
 
    if ( nativeSupport ) {
5227
 
        try {
5228
 
            nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
5229
 
        }
5230
 
        catch ( e ) {
5231
 
            nativeSupport = false;
5232
 
        }
5233
 
    }
5234
 
 
5235
 
    return !nativeSupport;
5236
 
},
5237
 
    "trigger": "json-parse"
5238
 
});
5239
 
// json-stringify-shim
5240
 
add('load', '15', {
5241
 
    "name": "json-stringify-shim",
5242
 
    "test": function (Y) {
5243
 
    var _JSON = Y.config.global.JSON,
5244
 
        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5245
 
        nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
5246
 
 
5247
 
    // Double check basic native functionality.  This is primarily to catch broken
5248
 
    // early JSON API implementations in Firefox 3.1 beta1 and beta2.
5249
 
    if ( nativeSupport ) {
5250
 
        try {
5251
 
            nativeSupport = ( '0' === Native.stringify(0) );
5252
 
        } catch ( e ) {
5253
 
            nativeSupport = false;
5254
 
        }
5255
 
    }
5256
 
 
5257
 
 
5258
 
    return !nativeSupport;
5259
 
},
5260
 
    "trigger": "json-stringify"
5261
 
});
5262
 
// scrollview-base-ie
5263
 
add('load', '16', {
5264
 
    "name": "scrollview-base-ie",
5265
 
    "trigger": "scrollview-base",
5266
 
    "ua": "ie"
5267
 
});
5268
 
// selector-css2
5269
 
add('load', '17', {
5270
 
    "name": "selector-css2",
5271
 
    "test": function (Y) {
5272
 
    var DOCUMENT = Y.config.doc,
5273
 
        ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
5274
 
 
5275
 
    return ret;
5276
 
},
5277
 
    "trigger": "selector"
5278
 
});
5279
 
// transition-timer
5280
 
add('load', '18', {
5281
 
    "name": "transition-timer",
5282
 
    "test": function (Y) {
5283
 
    var DOCUMENT = Y.config.doc,
5284
 
        node = (DOCUMENT) ? DOCUMENT.documentElement: null,
5285
 
        ret = true;
5286
 
 
5287
 
    if (node && node.style) {
5288
 
        ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5289
 
    }
5290
 
 
5291
 
    return ret;
5292
 
},
5293
 
    "trigger": "transition"
5294
 
});
5295
 
// widget-base-ie
5296
 
add('load', '19', {
5297
 
    "name": "widget-base-ie",
5298
 
    "trigger": "widget-base",
5299
 
    "ua": "ie"
5300
 
});
5301
 
// yql-jsonp
5302
 
add('load', '20', {
5303
 
    "name": "yql-jsonp",
5304
 
    "test": function (Y) {
5305
 
    /* Only load the JSONP module when not in nodejs or winjs
5306
 
    TODO Make the winjs module a CORS module
5307
 
    */
5308
 
    return (!Y.UA.nodejs && !Y.UA.winjs);
5309
 
},
5310
 
    "trigger": "yql",
5311
 
    "when": "after"
5312
 
});
5313
 
// yql-nodejs
5314
 
add('load', '21', {
5315
 
    "name": "yql-nodejs",
5316
 
    "trigger": "yql",
5317
 
    "ua": "nodejs",
5318
 
    "when": "after"
5319
 
});
5320
 
// yql-winjs
5321
 
add('load', '22', {
5322
 
    "name": "yql-winjs",
5323
 
    "trigger": "yql",
5324
 
    "ua": "winjs",
5325
 
    "when": "after"
5326
 
});
5327
 
 
5328
 
}, '3.9.1', {"requires": ["yui-base"]});
5329
 
YUI.add('intl-base', function (Y, NAME) {
5330
 
 
5331
 
/**
5332
 
 * The Intl utility provides a central location for managing sets of
5333
 
 * localized resources (strings and formatting patterns).
5334
 
 *
5335
 
 * @class Intl
5336
 
 * @uses EventTarget
5337
 
 * @static
5338
 
 */
5339
 
 
5340
 
var SPLIT_REGEX = /[, ]/;
5341
 
 
5342
 
Y.mix(Y.namespace('Intl'), {
5343
 
 
5344
 
 /**
5345
 
    * Returns the language among those available that
5346
 
    * best matches the preferred language list, using the Lookup
5347
 
    * algorithm of BCP 47.
5348
 
    * If none of the available languages meets the user's preferences,
5349
 
    * then "" is returned.
5350
 
    * Extended language ranges are not supported.
5351
 
    *
5352
 
    * @method lookupBestLang
5353
 
    * @param {String[] | String} preferredLanguages The list of preferred
5354
 
    * languages in descending preference order, represented as BCP 47
5355
 
    * language tags. A string array or a comma-separated list.
5356
 
    * @param {String[]} availableLanguages The list of languages
5357
 
    * that the application supports, represented as BCP 47 language
5358
 
    * tags.
5359
 
    *
5360
 
    * @return {String} The available language that best matches the
5361
 
    * preferred language list, or "".
5362
 
    * @since 3.1.0
5363
 
    */
5364
 
    lookupBestLang: function(preferredLanguages, availableLanguages) {
5365
 
 
5366
 
        var i, language, result, index;
5367
 
 
5368
 
        // check whether the list of available languages contains language;
5369
 
        // if so return it
5370
 
        function scan(language) {
5371
 
            var i;
5372
 
            for (i = 0; i < availableLanguages.length; i += 1) {
5373
 
                if (language.toLowerCase() ===
5374
 
                            availableLanguages[i].toLowerCase()) {
5375
 
                    return availableLanguages[i];
5376
 
                }
5377
 
            }
5378
 
        }
5379
 
 
5380
 
        if (Y.Lang.isString(preferredLanguages)) {
5381
 
            preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
5382
 
        }
5383
 
 
5384
 
        for (i = 0; i < preferredLanguages.length; i += 1) {
5385
 
            language = preferredLanguages[i];
5386
 
            if (!language || language === '*') {
5387
 
                continue;
5388
 
            }
5389
 
            // check the fallback sequence for one language
5390
 
            while (language.length > 0) {
5391
 
                result = scan(language);
5392
 
                if (result) {
5393
 
                    return result;
5394
 
                } else {
5395
 
                    index = language.lastIndexOf('-');
5396
 
                    if (index >= 0) {
5397
 
                        language = language.substring(0, index);
5398
 
                        // one-character subtags get cut along with the
5399
 
                        // following subtag
5400
 
                        if (index >= 2 && language.charAt(index - 2) === '-') {
5401
 
                            language = language.substring(0, index - 2);
5402
 
                        }
5403
 
                    } else {
5404
 
                        // nothing available for this language
5405
 
                        break;
5406
 
                    }
5407
 
                }
5408
 
            }
5409
 
        }
5410
 
 
5411
 
        return '';
5412
 
    }
5413
 
});
5414
 
 
5415
 
 
5416
 
}, '3.9.1', {"requires": ["yui-base"]});
5417
 
YUI.add('yui-log', function (Y, NAME) {
5418
 
 
5419
 
/**
5420
 
 * Provides console log capability and exposes a custom event for
5421
 
 * console implementations. This module is a `core` YUI module,
5422
 
 * <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>.
5423
 
 *
5424
 
 * @module yui
5425
 
 * @submodule yui-log
5426
 
 */
5427
 
 
5428
 
var INSTANCE = Y,
5429
 
    LOGEVENT = 'yui:log',
5430
 
    UNDEFINED = 'undefined',
5431
 
    LEVELS = { debug: 1,
5432
 
               info: 1,
5433
 
               warn: 1,
5434
 
               error: 1 };
5435
 
 
5436
 
/**
5437
 
 * If the 'debug' config is true, a 'yui:log' event will be
5438
 
 * dispatched, which the Console widget and anything else
5439
 
 * can consume.  If the 'useBrowserConsole' config is true, it will
5440
 
 * write to the browser console if available.  YUI-specific log
5441
 
 * messages will only be present in the -debug versions of the
5442
 
 * JS files.  The build system is supposed to remove log statements
5443
 
 * from the raw and minified versions of the files.
5444
 
 *
5445
 
 * @method log
5446
 
 * @for YUI
5447
 
 * @param  {String}  msg  The message to log.
5448
 
 * @param  {String}  cat  The log category for the message.  Default
5449
 
 *                        categories are "info", "warn", "error", time".
5450
 
 *                        Custom categories can be used as well. (opt).
5451
 
 * @param  {String}  src  The source of the the message (opt).
5452
 
 * @param  {boolean} silent If true, the log event won't fire.
5453
 
 * @return {YUI}      YUI instance.
5454
 
 */
5455
 
INSTANCE.log = function(msg, cat, src, silent) {
5456
 
    var bail, excl, incl, m, f,
5457
 
        Y = INSTANCE,
5458
 
        c = Y.config,
5459
 
        publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
5460
 
    // suppress log message if the config is off or the event stack
5461
 
    // or the event call stack contains a consumer of the yui:log event
5462
 
    if (c.debug) {
5463
 
        // apply source filters
5464
 
        src = src || "";
5465
 
        if (typeof src !== "undefined") {
5466
 
            excl = c.logExclude;
5467
 
            incl = c.logInclude;
5468
 
            if (incl && !(src in incl)) {
5469
 
                bail = 1;
5470
 
            } else if (incl && (src in incl)) {
5471
 
                bail = !incl[src];
5472
 
            } else if (excl && (src in excl)) {
5473
 
                bail = excl[src];
5474
 
            }
5475
 
        }
5476
 
        if (!bail) {
5477
 
            if (c.useBrowserConsole) {
5478
 
                m = (src) ? src + ': ' + msg : msg;
5479
 
                if (Y.Lang.isFunction(c.logFn)) {
5480
 
                    c.logFn.call(Y, msg, cat, src);
5481
 
                } else if (typeof console !== UNDEFINED && console.log) {
5482
 
                    f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
5483
 
                    console[f](m);
5484
 
                } else if (typeof opera !== UNDEFINED) {
5485
 
                    opera.postError(m);
5486
 
                }
5487
 
            }
5488
 
 
5489
 
            if (publisher && !silent) {
5490
 
 
5491
 
                if (publisher === Y && (!publisher.getEvent(LOGEVENT))) {
5492
 
                    publisher.publish(LOGEVENT, {
5493
 
                        broadcast: 2
5494
 
                    });
5495
 
                }
5496
 
 
5497
 
                publisher.fire(LOGEVENT, {
5498
 
                    msg: msg,
5499
 
                    cat: cat,
5500
 
                    src: src
5501
 
                });
5502
 
            }
5503
 
        }
5504
 
    }
5505
 
 
5506
 
    return Y;
5507
 
};
5508
 
 
5509
 
/**
5510
 
 * Write a system message.  This message will be preserved in the
5511
 
 * minified and raw versions of the YUI files, unlike log statements.
5512
 
 * @method message
5513
 
 * @for YUI
5514
 
 * @param  {String}  msg  The message to log.
5515
 
 * @param  {String}  cat  The log category for the message.  Default
5516
 
 *                        categories are "info", "warn", "error", time".
5517
 
 *                        Custom categories can be used as well. (opt).
5518
 
 * @param  {String}  src  The source of the the message (opt).
5519
 
 * @param  {boolean} silent If true, the log event won't fire.
5520
 
 * @return {YUI}      YUI instance.
5521
 
 */
5522
 
INSTANCE.message = function() {
5523
 
    return INSTANCE.log.apply(INSTANCE, arguments);
5524
 
};
5525
 
 
5526
 
 
5527
 
}, '3.9.1', {"requires": ["yui-base"]});
5528
 
YUI.add('yui-later', function (Y, NAME) {
5529
 
 
5530
 
/**
5531
 
 * Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module,
5532
 
 * <a href="../classes/YUI.html#method_later">it's documentation is located under the YUI class</a>.
5533
 
 *
5534
 
 * @module yui
5535
 
 * @submodule yui-later
5536
 
 */
5537
 
 
5538
 
var NO_ARGS = [];
5539
 
 
5540
 
/**
5541
 
 * Executes the supplied function in the context of the supplied
5542
 
 * object 'when' milliseconds later.  Executes the function a
5543
 
 * single time unless periodic is set to true.
5544
 
 * @for YUI
5545
 
 * @method later
5546
 
 * @param when {int} the number of milliseconds to wait until the fn
5547
 
 * is executed.
5548
 
 * @param o the context object.
5549
 
 * @param fn {Function|String} the function to execute or the name of
5550
 
 * the method in the 'o' object to execute.
5551
 
 * @param data [Array] data that is provided to the function.  This
5552
 
 * accepts either a single item or an array.  If an array is provided,
5553
 
 * the function is executed with one parameter for each array item.
5554
 
 * If you need to pass a single array parameter, it needs to be wrapped
5555
 
 * in an array [myarray].
5556
 
 *
5557
 
 * Note: native methods in IE may not have the call and apply methods.
5558
 
 * In this case, it will work, but you are limited to four arguments.
5559
 
 *
5560
 
 * @param periodic {boolean} if true, executes continuously at supplied
5561
 
 * interval until canceled.
5562
 
 * @return {object} a timer object. Call the cancel() method on this
5563
 
 * object to stop the timer.
5564
 
 */
5565
 
Y.later = function(when, o, fn, data, periodic) {
5566
 
    when = when || 0;
5567
 
    data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS;
5568
 
    o = o || Y.config.win || Y;
5569
 
 
5570
 
    var cancelled = false,
5571
 
        method = (o && Y.Lang.isString(fn)) ? o[fn] : fn,
5572
 
        wrapper = function() {
5573
 
            // IE 8- may execute a setInterval callback one last time
5574
 
            // after clearInterval was called, so in order to preserve
5575
 
            // the cancel() === no more runny-run, we have to jump through
5576
 
            // an extra hoop.
5577
 
            if (!cancelled) {
5578
 
                if (!method.apply) {
5579
 
                    method(data[0], data[1], data[2], data[3]);
5580
 
                } else {
5581
 
                    method.apply(o, data || NO_ARGS);
5582
 
                }
5583
 
            }
5584
 
        },
5585
 
        id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when);
5586
 
 
5587
 
    return {
5588
 
        id: id,
5589
 
        interval: periodic,
5590
 
        cancel: function() {
5591
 
            cancelled = true;
5592
 
            if (this.interval) {
5593
 
                clearInterval(id);
5594
 
            } else {
5595
 
                clearTimeout(id);
5596
 
            }
5597
 
        }
5598
 
    };
5599
 
};
5600
 
 
5601
 
Y.Lang.later = Y.later;
5602
 
 
5603
 
 
5604
 
 
5605
 
}, '3.9.1', {"requires": ["yui-base"]});
5606
 
YUI.add('yui', function (Y, NAME) {}, '3.9.1', {"use": ["get", "features", "intl-base", "yui-log", "yui-later"]});