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